@pikku/cli 0.12.82 → 0.12.85

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 (346) hide show
  1. package/cli.schema.json +1 -1
  2. package/console-app/assets/{index-ChcXIEhS.js → index-CEv-kj3J.js} +154 -147
  3. package/console-app/assets/index-CSzCJzBb.css +1 -0
  4. package/console-app/index.html +2 -2
  5. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +4 -2
  6. package/dist/.pikku/auth/auth.types.d.ts +4 -0
  7. package/dist/.pikku/auth/auth.types.js +5 -0
  8. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  9. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  10. package/dist/.pikku/cli/pikku-cli-channel.d.ts +4 -4
  11. package/dist/.pikku/cli/pikku-cli-channel.js +21 -1
  12. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  13. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  14. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  15. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  16. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  17. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  18. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  19. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +60 -3
  20. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  21. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  22. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  23. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  24. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  25. package/dist/.pikku/function/pikku-function-types.gen.d.ts +29 -25
  26. package/dist/.pikku/function/pikku-function-types.gen.js +3 -12
  27. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  28. package/dist/.pikku/function/pikku-functions-meta.gen.json +195 -32
  29. package/dist/.pikku/function/pikku-functions.gen.js +15 -3
  30. package/dist/.pikku/http/pikku-http-types.gen.d.ts +2 -24
  31. package/dist/.pikku/http/pikku-http-types.gen.js +2 -24
  32. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  33. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  34. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -5
  35. package/dist/.pikku/pikku-bootstrap.gen.js +1 -5
  36. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  37. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  38. package/dist/.pikku/pikku-services.gen.d.ts +4 -1
  39. package/dist/.pikku/pikku-services.gen.js +3 -0
  40. package/dist/.pikku/pikku-types.gen.d.ts +2 -1
  41. package/dist/.pikku/pikku-types.gen.js +3 -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/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  45. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +10 -2
  46. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  47. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  48. package/dist/.pikku/schemas/register.gen.js +13 -7
  49. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  50. package/dist/.pikku/schemas/schemas/PikkuGraphWiringsOutput.schema.json +1 -0
  51. package/dist/.pikku/schemas/schemas/PikkuImportN8nInput.schema.json +1 -0
  52. package/dist/.pikku/schemas/schemas/PikkuScopesInput.schema.json +1 -0
  53. package/dist/.pikku/schemas/schemas/PikkuWebhookOutput.schema.json +1 -0
  54. package/dist/.pikku/schemas/schemas/ScopesAuditInput.schema.json +1 -0
  55. package/dist/.pikku/schemas/schemas/ScopesPruneInput.schema.json +1 -0
  56. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +5 -0
  57. package/dist/.pikku/scopes/pikku-scope-types.gen.js +4 -0
  58. package/dist/.pikku/scopes/pikku-scopes-meta.gen.json +1 -0
  59. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +35 -0
  60. package/dist/.pikku/scopes/pikku-scopes.gen.js +27 -0
  61. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  62. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  63. package/dist/.pikku/secrets/pikku-secrets-meta.gen.json +1 -0
  64. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +11 -1
  65. package/dist/.pikku/secrets/pikku-secrets.gen.js +11 -1
  66. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  67. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  68. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  69. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  70. package/dist/.pikku/variables/pikku-variables-meta.gen.json +1 -0
  71. package/dist/.pikku/variables/pikku-variables.gen.d.ts +11 -1
  72. package/dist/.pikku/variables/pikku-variables.gen.js +13 -3
  73. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +49 -7
  74. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +11 -2
  75. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  76. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  77. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  78. package/dist/bin/pikku-bin.mjs +2 -2
  79. package/dist/src/cli.wiring.js +47 -4
  80. package/dist/src/deploy/analyzer/analyzer.js +6 -0
  81. package/dist/src/fabric/fabric-commands.d.ts +53 -53
  82. package/dist/src/fabric/functions/add.function.d.ts +2 -2
  83. package/dist/src/fabric/functions/addon-verify.function.d.ts +2 -2
  84. package/dist/src/fabric/functions/db-schema.function.d.ts +2 -2
  85. package/dist/src/fabric/functions/deploy-list.function.d.ts +2 -2
  86. package/dist/src/fabric/functions/deploy-units.function.d.ts +2 -2
  87. package/dist/src/fabric/functions/deploy.function.d.ts +4 -4
  88. package/dist/src/fabric/functions/domains-add.function.d.ts +2 -2
  89. package/dist/src/fabric/functions/domains-list.function.d.ts +2 -2
  90. package/dist/src/fabric/functions/domains-remove.function.d.ts +2 -2
  91. package/dist/src/fabric/functions/errors.function.d.ts +2 -2
  92. package/dist/src/fabric/functions/init.function.d.ts +2 -2
  93. package/dist/src/fabric/functions/link.function.d.ts +2 -2
  94. package/dist/src/fabric/functions/llm-key.function.d.ts +6 -6
  95. package/dist/src/fabric/functions/login.function.d.ts +2 -2
  96. package/dist/src/fabric/functions/logs.function.d.ts +2 -2
  97. package/dist/src/fabric/functions/metrics.function.d.ts +2 -2
  98. package/dist/src/fabric/functions/publish.function.d.ts +2 -2
  99. package/dist/src/fabric/functions/rollback.function.d.ts +2 -2
  100. package/dist/src/fabric/functions/secrets-list.function.d.ts +2 -2
  101. package/dist/src/fabric/functions/secrets-set.function.d.ts +2 -2
  102. package/dist/src/fabric/functions/smoke.function.d.ts +2 -2
  103. package/dist/src/fabric/functions/status.function.d.ts +2 -2
  104. package/dist/src/fabric/functions/trace.function.d.ts +2 -2
  105. package/dist/src/fabric/functions/validate.function.d.ts +2 -2
  106. package/dist/src/functions/commands/all.d.ts +1 -1
  107. package/dist/src/functions/commands/audit.d.ts +1 -1
  108. package/dist/src/functions/commands/binary.d.ts +2 -2
  109. package/dist/src/functions/commands/bootstrap.d.ts +1 -1
  110. package/dist/src/functions/commands/bootstrap.js +3 -0
  111. package/dist/src/functions/commands/db-audit.d.ts +1 -1
  112. package/dist/src/functions/commands/db-generate.d.ts +1 -1
  113. package/dist/src/functions/commands/db-migrate.d.ts +1 -1
  114. package/dist/src/functions/commands/db-reset.d.ts +1 -1
  115. package/dist/src/functions/commands/db-seed.d.ts +1 -1
  116. package/dist/src/functions/commands/deploy-apply.d.ts +2 -2
  117. package/dist/src/functions/commands/deploy-info.d.ts +1 -1
  118. package/dist/src/functions/commands/deploy-plan.d.ts +2 -2
  119. package/dist/src/functions/commands/dev.d.ts +2 -2
  120. package/dist/src/functions/commands/dev.js +14 -3
  121. package/dist/src/functions/commands/emails-init.d.ts +1 -1
  122. package/dist/src/functions/commands/enable.d.ts +8 -7
  123. package/dist/src/functions/commands/enable.js +10 -5
  124. package/dist/src/functions/commands/import-n8n.d.ts +10 -0
  125. package/dist/src/functions/commands/import-n8n.js +130 -0
  126. package/dist/src/functions/commands/info.d.ts +4 -4
  127. package/dist/src/functions/commands/info.js +0 -13
  128. package/dist/src/functions/commands/login.d.ts +5 -5
  129. package/dist/src/functions/commands/meta.d.ts +25 -25
  130. package/dist/src/functions/commands/new-addon.d.ts +13 -2
  131. package/dist/src/functions/commands/new-addon.js +71 -39
  132. package/dist/src/functions/commands/new-function.d.ts +2 -2
  133. package/dist/src/functions/commands/new-middleware.d.ts +2 -2
  134. package/dist/src/functions/commands/new-permission.d.ts +2 -2
  135. package/dist/src/functions/commands/new-wiring.d.ts +2 -2
  136. package/dist/src/functions/commands/pikku-command-bootstrap.d.ts +1 -1
  137. package/dist/src/functions/commands/pikku-command-bootstrap.js +6 -0
  138. package/dist/src/functions/commands/pikku-command-summary.d.ts +1 -1
  139. package/dist/src/functions/commands/scenario.d.ts +3 -3
  140. package/dist/src/functions/commands/scopes-audit.d.ts +1 -0
  141. package/dist/src/functions/commands/scopes-audit.js +37 -0
  142. package/dist/src/functions/commands/scopes-prune.d.ts +14 -0
  143. package/dist/src/functions/commands/scopes-prune.js +50 -0
  144. package/dist/src/functions/commands/scopes-shared.d.ts +39 -0
  145. package/dist/src/functions/commands/scopes-shared.js +83 -0
  146. package/dist/src/functions/commands/serve.d.ts +2 -2
  147. package/dist/src/functions/commands/serve.js +4 -2
  148. package/dist/src/functions/commands/skills.d.ts +4 -4
  149. package/dist/src/functions/commands/skills.js +18 -10
  150. package/dist/src/functions/commands/versions-check.d.ts +1 -1
  151. package/dist/src/functions/commands/versions-init.d.ts +2 -2
  152. package/dist/src/functions/commands/versions-update.d.ts +1 -1
  153. package/dist/src/functions/commands/watch.d.ts +2 -2
  154. package/dist/src/functions/commands/workspace-validate.d.ts +2 -2
  155. package/dist/src/functions/runtimes/fetch/index.d.ts +1 -1
  156. package/dist/src/functions/runtimes/nextjs/pikku-command-nextjs.d.ts +1 -1
  157. package/dist/src/functions/runtimes/tanstack-start/pikku-command-tanstack-start.d.ts +1 -1
  158. package/dist/src/functions/runtimes/websocket/pikku-command-websocket-typed.d.ts +1 -1
  159. package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent-types.d.ts +1 -1
  160. package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent-types.js +3 -2
  161. package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent.d.ts +1 -1
  162. package/dist/src/functions/wirings/ai-agent/pikku-command-public-agent.d.ts +1 -1
  163. package/dist/src/functions/wirings/ai-agent/serialize-ai-agent-types.d.ts +1 -1
  164. package/dist/src/functions/wirings/ai-agent/serialize-ai-agent-types.js +4 -2
  165. package/dist/src/functions/wirings/ai-agent/serialize-public-agent.js +55 -16
  166. package/dist/src/functions/wirings/auth/pikku-command-auth.d.ts +2 -2
  167. package/dist/src/functions/wirings/channels/pikku-channels.d.ts +1 -1
  168. package/dist/src/functions/wirings/channels/pikku-command-channel-types.d.ts +1 -1
  169. package/dist/src/functions/wirings/channels/pikku-command-channels-map.d.ts +1 -1
  170. package/dist/src/functions/wirings/channels/pikku-command-channels.d.ts +1 -1
  171. package/dist/src/functions/wirings/cli/pikku-command-cli-entry.d.ts +1 -1
  172. package/dist/src/functions/wirings/cli/pikku-command-cli-types.d.ts +1 -1
  173. package/dist/src/functions/wirings/cli/pikku-command-cli.d.ts +1 -1
  174. package/dist/src/functions/wirings/console/pikku-command-console-functions.d.ts +1 -1
  175. package/dist/src/functions/wirings/console/pikku-command-node-types.d.ts +1 -1
  176. package/dist/src/functions/wirings/console/pikku-command-nodes-meta.d.ts +1 -1
  177. package/dist/src/functions/wirings/console/serialize-console-functions.js +6 -0
  178. package/dist/src/functions/wirings/credentials/pikku-command-credentials.d.ts +1 -1
  179. package/dist/src/functions/wirings/credentials/serialize-credentials-types.js +22 -0
  180. package/dist/src/functions/wirings/emails/pikku-command-emails.d.ts +1 -1
  181. package/dist/src/functions/wirings/functions/pikku-command-addon-types.d.ts +1 -1
  182. package/dist/src/functions/wirings/functions/pikku-command-function-types-split.d.ts +2 -2
  183. package/dist/src/functions/wirings/functions/pikku-command-function-types-split.js +1 -1
  184. package/dist/src/functions/wirings/functions/pikku-command-function-types.d.ts +2 -2
  185. package/dist/src/functions/wirings/functions/pikku-command-function-types.js +2 -2
  186. package/dist/src/functions/wirings/functions/pikku-command-functions.d.ts +1 -1
  187. package/dist/src/functions/wirings/functions/pikku-command-services.d.ts +2 -2
  188. package/dist/src/functions/wirings/functions/pikku-command-services.js +9 -2
  189. package/dist/src/functions/wirings/functions/schemas.d.ts +1 -1
  190. package/dist/src/functions/wirings/functions/serialize-function-types.d.ts +1 -1
  191. package/dist/src/functions/wirings/functions/serialize-function-types.js +37 -28
  192. package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.d.ts +1 -1
  193. package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.js +6 -2
  194. package/dist/src/functions/wirings/gateway/pikku-command-gateway.d.ts +1 -1
  195. package/dist/src/functions/wirings/graph/pikku-command-graph-wirings.d.ts +1 -0
  196. package/dist/src/functions/wirings/graph/pikku-command-graph-wirings.js +21 -0
  197. package/dist/src/functions/wirings/graph/serialize-graph-wirings.d.ts +5 -0
  198. package/dist/src/functions/wirings/graph/serialize-graph-wirings.js +14 -0
  199. package/dist/src/functions/wirings/http/pikku-command-http-map.d.ts +1 -1
  200. package/dist/src/functions/wirings/http/pikku-command-http-routes.d.ts +1 -1
  201. package/dist/src/functions/wirings/http/pikku-command-http-types.d.ts +1 -1
  202. package/dist/src/functions/wirings/http/pikku-command-openapi.d.ts +1 -1
  203. package/dist/src/functions/wirings/http/pikku-http-routes.d.ts +1 -1
  204. package/dist/src/functions/wirings/http/serialize-http-types.js +2 -30
  205. package/dist/src/functions/wirings/mcp/pikku-command-mcp-json.d.ts +1 -1
  206. package/dist/src/functions/wirings/mcp/pikku-command-mcp-types.d.ts +1 -1
  207. package/dist/src/functions/wirings/mcp/pikku-command-mcp.d.ts +1 -1
  208. package/dist/src/functions/wirings/middleware/pikku-command-middleware.d.ts +1 -1
  209. package/dist/src/functions/wirings/package/pikku-command-package-types.d.ts +3 -2
  210. package/dist/src/functions/wirings/package/pikku-command-package-types.js +14 -1
  211. package/dist/src/functions/wirings/package/pikku-command-package.d.ts +1 -1
  212. package/dist/src/functions/wirings/package/serialize-package-types.d.ts +1 -0
  213. package/dist/src/functions/wirings/package/serialize-package-types.js +5 -0
  214. package/dist/src/functions/wirings/permissions/pikku-command-permissions.d.ts +1 -1
  215. package/dist/src/functions/wirings/permissions/pikku-command-permissions.js +1 -3
  216. package/dist/src/functions/wirings/permissions/serialize-permissions-imports.d.ts +6 -1
  217. package/dist/src/functions/wirings/permissions/serialize-permissions-imports.js +7 -64
  218. package/dist/src/functions/wirings/queue/pikku-command-queue-map.d.ts +1 -1
  219. package/dist/src/functions/wirings/queue/pikku-command-queue-service.d.ts +1 -1
  220. package/dist/src/functions/wirings/queue/pikku-command-queue-types.d.ts +1 -1
  221. package/dist/src/functions/wirings/queue/pikku-command-queue.d.ts +1 -1
  222. package/dist/src/functions/wirings/queue/pikku-queue-map.d.ts +1 -1
  223. package/dist/src/functions/wirings/queue/pikku-queue.d.ts +1 -1
  224. package/dist/src/functions/wirings/realtime/pikku-command-events-scaffold.d.ts +1 -1
  225. package/dist/src/functions/wirings/realtime/pikku-command-realtime.d.ts +1 -1
  226. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.d.ts +1 -1
  227. package/dist/src/functions/wirings/rpc/pikku-command-react-query.d.ts +1 -1
  228. package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.d.ts +1 -1
  229. package/dist/src/functions/wirings/rpc/pikku-command-rpc-client.d.ts +1 -1
  230. package/dist/src/functions/wirings/rpc/pikku-command-rpc-map.d.ts +7 -2
  231. package/dist/src/functions/wirings/rpc/pikku-command-rpc-map.js +20 -0
  232. package/dist/src/functions/wirings/rpc/pikku-command-rpc.d.ts +1 -1
  233. package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.d.ts +1 -0
  234. package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +8 -3
  235. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.d.ts +1 -1
  236. package/dist/src/functions/wirings/scheduler/pikku-command-scheduler-types.d.ts +1 -1
  237. package/dist/src/functions/wirings/scheduler/pikku-command-scheduler.d.ts +1 -1
  238. package/dist/src/functions/wirings/scopes/pikku-command-scopes.d.ts +7 -0
  239. package/dist/src/functions/wirings/scopes/pikku-command-scopes.js +34 -0
  240. package/dist/src/functions/wirings/scopes/serialize-scopes-types.d.ts +15 -0
  241. package/dist/src/functions/wirings/scopes/serialize-scopes-types.js +86 -0
  242. package/dist/src/functions/wirings/secrets/pikku-command-secrets.d.ts +1 -1
  243. package/dist/src/functions/wirings/secrets/serialize-secrets-types.js +13 -0
  244. package/dist/src/functions/wirings/triggers/pikku-command-trigger-types.d.ts +2 -2
  245. package/dist/src/functions/wirings/triggers/pikku-command-trigger.d.ts +1 -1
  246. package/dist/src/functions/wirings/variables/pikku-command-variables.d.ts +1 -1
  247. package/dist/src/functions/wirings/variables/serialize-variables-types.js +15 -2
  248. package/dist/src/functions/wirings/webhook/pikku-command-webhook.d.ts +1 -0
  249. package/dist/src/functions/wirings/webhook/pikku-command-webhook.js +25 -0
  250. package/dist/src/functions/wirings/webhook/serialize-webhook.d.ts +14 -0
  251. package/dist/src/functions/wirings/webhook/serialize-webhook.js +34 -0
  252. package/dist/src/functions/wirings/workflow/pikku-command-workflow-routes.d.ts +1 -1
  253. package/dist/src/functions/wirings/workflow/pikku-command-workflow.d.ts +1 -1
  254. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +2 -1
  255. package/dist/src/functions/wirings/workflow/serialize-workflow-routes.js +29 -0
  256. package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +1 -1
  257. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +11 -2
  258. package/dist/src/functions/workflows/all.workflow.js +23 -3
  259. package/dist/src/services.d.ts +1 -0
  260. package/dist/src/services.js +1 -0
  261. package/dist/src/utils/pikku-cli-config.js +20 -0
  262. package/dist/tsconfig.tsbuildinfo +1 -1
  263. package/package.json +9 -8
  264. package/skills/pikku-addon/SKILL.md +7 -3
  265. package/skills/pikku-ai-agent/SKILL.md +9 -6
  266. package/skills/pikku-ai-vercel/SKILL.md +6 -3
  267. package/skills/pikku-ai-voice/SKILL.md +6 -3
  268. package/skills/pikku-audit/SKILL.md +10 -3
  269. package/skills/pikku-aws/SKILL.md +9 -5
  270. package/skills/pikku-backblaze/SKILL.md +4 -3
  271. package/skills/pikku-better-auth/SKILL.md +10 -5
  272. package/skills/pikku-cli/SKILL.md +6 -3
  273. package/skills/pikku-concepts/SKILL.md +9 -4
  274. package/skills/pikku-concepts/references/concept-mapping.md +12 -10
  275. package/skills/pikku-config/SKILL.md +9 -5
  276. package/skills/pikku-cron/SKILL.md +6 -3
  277. package/skills/pikku-deploy-azure/SKILL.md +5 -3
  278. package/skills/pikku-deploy-cloudflare/SKILL.md +5 -3
  279. package/skills/pikku-deploy-express/SKILL.md +6 -3
  280. package/skills/pikku-deploy-fastify/SKILL.md +6 -3
  281. package/skills/pikku-deploy-lambda/SKILL.md +6 -3
  282. package/skills/pikku-deploy-nextjs/SKILL.md +5 -3
  283. package/skills/pikku-deploy-uws/SKILL.md +7 -4
  284. package/skills/pikku-deps/SKILL.md +13 -6
  285. package/skills/pikku-emails/SKILL.md +10 -5
  286. package/skills/pikku-feature/SKILL.md +1 -1
  287. package/skills/pikku-gateway-slack/SKILL.md +6 -3
  288. package/skills/pikku-http/SKILL.md +15 -21
  289. package/skills/pikku-http/references/http-options.md +0 -2
  290. package/skills/pikku-info/SKILL.md +9 -4
  291. package/skills/pikku-jose/SKILL.md +6 -3
  292. package/skills/pikku-kysely/SKILL.md +13 -5
  293. package/skills/pikku-machine-auth/SKILL.md +9 -3
  294. package/skills/pikku-mcp/SKILL.md +7 -3
  295. package/skills/pikku-middleware/SKILL.md +11 -6
  296. package/skills/pikku-mongodb/SKILL.md +8 -5
  297. package/skills/pikku-n8n-import/SKILL.md +109 -0
  298. package/skills/pikku-n8n-import/SPEC.md +84 -0
  299. package/skills/pikku-n8n-import/references/addon-mapping.md +121 -0
  300. package/skills/pikku-n8n-import/references/code-translation.md +121 -0
  301. package/skills/pikku-n8n-import/references/loops-and-control.md +87 -0
  302. package/skills/pikku-permissions/SKILL.md +26 -15
  303. package/skills/pikku-pino/SKILL.md +5 -3
  304. package/skills/pikku-product-second-opinion/README.md +43 -0
  305. package/skills/pikku-product-second-opinion/SKILL.md +158 -0
  306. package/skills/pikku-product-second-opinion/example/sample-report.md +90 -0
  307. package/skills/pikku-product-second-opinion/references/report-template.md +73 -0
  308. package/skills/pikku-queue/SKILL.md +7 -4
  309. package/skills/pikku-redis/SKILL.md +9 -6
  310. package/skills/pikku-rpc/SKILL.md +7 -4
  311. package/skills/pikku-rtl/SKILL.md +1 -1
  312. package/skills/pikku-scenario/SKILL.md +215 -0
  313. package/skills/pikku-schedule/SKILL.md +6 -3
  314. package/skills/pikku-schema-ajv/SKILL.md +5 -3
  315. package/skills/pikku-schema-cfworker/SKILL.md +6 -3
  316. package/skills/pikku-security/SKILL.md +8 -4
  317. package/skills/pikku-services/SKILL.md +42 -4
  318. package/skills/pikku-software-archaeology/README.md +70 -0
  319. package/skills/pikku-software-archaeology/SKILL.md +186 -0
  320. package/skills/pikku-software-archaeology/references/blueprint.schema.json +625 -0
  321. package/skills/pikku-software-archaeology/references/pikku-mapping.md +49 -0
  322. package/skills/pikku-software-archaeology/scripts/validate.mjs +173 -0
  323. package/skills/pikku-template-clone/SKILL.md +1 -1
  324. package/skills/pikku-trigger/SKILL.md +7 -3
  325. package/skills/pikku-versioning/SKILL.md +7 -3
  326. package/skills/pikku-websocket/SKILL.md +8 -4
  327. package/skills/pikku-workflow/SKILL.md +7 -3
  328. package/skills/pikku-ws/SKILL.md +5 -3
  329. package/console-app/assets/index-DwyRdRuZ.css +0 -1
  330. package/dist/.pikku/http/pikku-http-wirings-meta.gen.d.ts +0 -1
  331. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +0 -6
  332. package/dist/.pikku/http/pikku-http-wirings-meta.gen.json +0 -26
  333. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +0 -4
  334. package/dist/.pikku/http/pikku-http-wirings.gen.js +0 -5
  335. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.d.ts +0 -1
  336. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +0 -6
  337. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.json +0 -10
  338. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +0 -4
  339. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +0 -5
  340. package/dist/.pikku/schemas/schemas/RemoteRPCHandlerInput.schema.json +0 -1
  341. package/dist/src/scaffold/rpc-remote.gen.d.ts +0 -10
  342. package/dist/src/scaffold/rpc-remote.gen.js +0 -27
  343. package/skills/pikku-n8n-addon-map/SKILL.md +0 -178
  344. package/skills/pikku-n8n-code-translate/SKILL.md +0 -166
  345. package/skills/pikku-testing/SKILL.md +0 -328
  346. package/skills/pikku-testing/references/cucumber-bdd-testing.md +0 -176
@@ -0,0 +1,215 @@
1
+ ---
2
+ name: pikku-scenario
3
+ description: >-
4
+ Use when writing or running Pikku scenarios, or when asked to test Pikku functions or improve
5
+ test coverage. A scenario (pikkuScenario) drives the app the way users do — steps run as actors
6
+ over the real transport against a running server — so a flow doubles as an e2e test and a
7
+ staged/production health check. Covers scenario.do / expectEventually / expectError /
8
+ expectService, actors and environments in pikku.config.json, SCENARIO_ACTOR_SECRET, the
9
+ `pikku scenario list|run` commands, live function coverage via `pikku dev --coverage`, and
10
+ plain unit tests for pure function logic. TRIGGER when: user asks about scenarios, testing a
11
+ Pikku function, test coverage, end-to-end flows, or health checks. DO NOT TRIGGER when: user
12
+ asks about browser/UI e2e (that is @pikku/cucumber, out of scope), running an existing test
13
+ suite (use Bash), or CI configuration.
14
+ installGroups: [core]
15
+ ---
16
+
17
+ # Pikku Scenarios
18
+
19
+ ## Agent Operating Procedure
20
+
21
+ Use this skill as an execution checklist, not reference material.
22
+
23
+ 1. Discover before editing: `pikku scenario list` for what exists, `pikku info functions --verbose` for what a scenario can call.
24
+ 2. Identify the source files that own the behavior. Do not start by reading generated output, `.pikku`, `node_modules`, or build artifacts.
25
+ 3. Make the smallest source change that satisfies the task. Keep generated files generated.
26
+ 4. Validate with the narrowest relevant command first, then `pikku all --tsc` when functions, wirings or schemas may have changed.
27
+ 5. If validation fails, fix the source cause and rerun. Do not paper over generated errors by editing generated files.
28
+
29
+ **`pikku tests` does not exist.** It was removed in #865 — scenarios own coverage now. Any reference you find to it is stale.
30
+
31
+ ## What a scenario is
32
+
33
+ A scenario is a `pikkuScenario` export that drives the app **as real actors over the real transport**, against a running server. That is what lets one artifact serve as both an e2e test and a staged/production health check.
34
+
35
+ Consequences that matter, and bite if ignored:
36
+
37
+ - **There is no state reset.** A scenario runs against a live server. Scope what you create (unique ids, your own rows) and never assume a clean database.
38
+ - **Every step needs an actor.** `scenario.do(...)` without `{ actor }` throws `Scenario tried to run '<rpc>' as an internal step…`. There is no bare internal-RPC step.
39
+ - **Actors must be configured and signed in**, or the scenario cannot run.
40
+
41
+ Scenarios live in `srcDirectories` like any other function — by convention `*.scenario.ts`.
42
+
43
+ ## Writing one
44
+
45
+ `pikkuScenario` comes from the **generated** workflow types, not `@pikku/core`:
46
+
47
+ ```typescript
48
+ import { pikkuScenario } from '#pikku/workflow/pikku-workflow-types.gen.js'
49
+
50
+ export const orderSupportScenario = pikkuScenario<
51
+ { value?: number },
52
+ { doubled: number; message: string }
53
+ >({
54
+ title: 'Order support (scenario)',
55
+ tags: ['scenario'],
56
+ func: async ({ logger }, data, { scenario, actors }) => {
57
+ if (!actors?.shopper || !actors?.support) {
58
+ throw new Error(
59
+ 'orderSupportScenario needs run actors (shopper + support) — run via `pikku scenario run <environment>`'
60
+ )
61
+ }
62
+
63
+ const doubled = await scenario.do(
64
+ 'shopper doubles their order',
65
+ 'doubleValue',
66
+ { value: data?.value ?? 21 },
67
+ { actor: actors.shopper }
68
+ )
69
+
70
+ const settled = await scenario.expectEventually(
71
+ 'support sees the greeting settle',
72
+ 'formatMessage',
73
+ { greeting: 'Hello', name: 'Support' },
74
+ (out: { message: string }) => out.message.length > 0,
75
+ { actor: actors.support, within: '5s', interval: 50 }
76
+ )
77
+
78
+ return { doubled: doubled.result, message: settled.message }
79
+ },
80
+ })
81
+ ```
82
+
83
+ A scenario takes the same config fields as a workflow (`title`, `description`, `tags`, `input`/`output`, `auth`, `permissions`, `middleware`, `version`, …). The third argument is the scenario context: `{ scenario, actors }`.
84
+
85
+ ### The scenario API
86
+
87
+ | Call | Purpose |
88
+ | --- | --- |
89
+ | `scenario.do(step, rpc, data, { actor })` | Run an RPC as that actor. The step name is what appears in the run output. |
90
+ | `scenario.expectEventually(step, rpc, data, predicate, { actor, within, interval })` | Poll until `predicate(out)` passes or `within` elapses. For anything asynchronous — queues, workers, eventual state. |
91
+ | `scenario.expectError(step, rpc, data, { actor, matches })` | Assert the call **fails**. For fault injection and negative paths. |
92
+ | `scenario.expectService(step, 'service.method', { actor, calledWith })` | Assert a stubbed service was called. Requires the server to run with `--test`. |
93
+
94
+ `expectEventually` is **scenario-only**. Calling it from a `pikkuWorkflowFunc` is a critical inspector error (`PKU675`) pointing you at `pikkuScenario`.
95
+
96
+ Prefer `expectEventually` over sleeping. There is no `beforeEach`/`afterEach` — a scenario is a plain async function.
97
+
98
+ ## Configuration
99
+
100
+ Actors and environments live in `pikku.config.json`:
101
+
102
+ ```json
103
+ {
104
+ "scenarios": {
105
+ "actors": {
106
+ "shopper": {
107
+ "email": "shopper@actors.local",
108
+ "name": "Shopper",
109
+ "jobTitle": "First-time buyer",
110
+ "personality": "Impatient shopper who abandons slow checkouts"
111
+ },
112
+ "support": { "email": "support@actors.local", "name": "Support" }
113
+ },
114
+ "environments": {
115
+ "local": {
116
+ "apiUrl": "http://localhost:4077",
117
+ "signInPath": "/api/auth/sign-in/actor"
118
+ }
119
+ }
120
+ }
121
+ }
122
+ ```
123
+
124
+ - `environments.<name>.apiUrl` is required. `signInPath` defaults to `/auth/sign-in/actor`, `rpcPath` to `/rpc`.
125
+ - **`SCENARIO_ACTOR_SECRET` is an environment variable and never goes in `pikku.config.json`.** It signs actors in. `pikku scenario run` throws without it; a server auto-building actors warns and runs without them.
126
+
127
+ ## Running
128
+
129
+ ```bash
130
+ pikku scenario list # name [tags] + description; takes no options
131
+ SCENARIO_ACTOR_SECRET=… pikku scenario run local
132
+ SCENARIO_ACTOR_SECRET=… pikku scenario run local --flows orderSupportScenario
133
+ SCENARIO_ACTOR_SECRET=… pikku scenario run local --tags smoke,scenario
134
+ ```
135
+
136
+ `run` takes the environment as a **required positional** — the key from `scenarios.environments`. `--flows`/`-f` filters by scenario name, `--tags`/`-t` by tag (match-any).
137
+
138
+ Output is `PASS <name> (<ms>) → <output>` / `FAIL <name> (<ms>): <error>`, then `N/M scenarios passed against '<env>'`.
139
+
140
+ **Exit code is 1** if any scenario fails *or* if no scenario matched the filter — a typo'd `--flows` is a hard error, not a silent zero-run pass. It throws outright on an unknown environment, an unknown flow name, or a missing `SCENARIO_ACTOR_SECRET`.
141
+
142
+ ## Coverage
143
+
144
+ Coverage is attributed by running scenarios against a server that is collecting it. It is **not** derived from unit tests.
145
+
146
+ Prerequisites in `pikku.config.json`:
147
+
148
+ ```json
149
+ { "scaffold": { "scenarios": "auth" }, "verboseMeta": true }
150
+ ```
151
+
152
+ `scaffold.scenarios` generates the coverage and stub RPCs into your project (`pikkuScenarioTakeLiveCoverage`, `pikkuScenarioResetLiveCoverage`, `pikkuScenarioResetStubs`, `pikkuScenarioGetStubCalls`), so scenario runs work against any server. `verboseMeta` is required — the coverage RPC reads the verbose functions meta and returns `null` without it.
153
+
154
+ ```bash
155
+ pikku dev --coverage # V8 precise coverage, in-process
156
+ pikku dev --coverage --test # also enable stubs (needed for expectService)
157
+ SCENARIO_ACTOR_SECRET=… pikku scenario run local --coverage
158
+ ```
159
+
160
+ The run resets coverage before each scenario and snapshots after, writing **`<outDir>/coverage/scenario-coverage.json`**:
161
+
162
+ ```jsonc
163
+ { "generatedAt": "…", "environment": "local", "scenarios": { "<name>": { /* FunctionCoverageReport */ } } }
164
+ ```
165
+
166
+ Coverage is best-effort: it disables itself with a warning if the server is not collecting or the first actor cannot invoke, and it needs at least one configured actor. If you get no coverage, check those first.
167
+
168
+ **There is no AI-prompt output.** The old `--ai-out` flag died with `pikku tests`; nothing replaced it. To find what needs work, read `scenario-coverage.json` yourself and cross-reference `pikku meta functions list` for input/output schemas.
169
+
170
+ ### Filling coverage
171
+
172
+ 1. `pikku scenario run <env> --coverage`, then read `<outDir>/coverage/scenario-coverage.json` to see what is unexercised.
173
+ 2. `pikku meta functions list` for those functions' schemas.
174
+ 3. Write a `pikkuScenario` that reaches them **through a real user flow** with an actor — not a scenario per function. Scenarios are flows; coverage is a consequence.
175
+ 4. Re-run to confirm.
176
+
177
+ ## Unit tests for pure logic
178
+
179
+ Scenarios are the repo-idiomatic way to test functions, and the only thing that contributes to live coverage. For pure logic with heavy branching, a plain unit test calling `func` directly is still valid and cheap:
180
+
181
+ ```typescript
182
+ import { describe, test } from 'node:test'
183
+ import assert from 'node:assert'
184
+
185
+ describe('createTodo', () => {
186
+ test('creates a todo', async () => {
187
+ const services = { todoStore: { add: async (title: string) => ({ id: '1', title }) } }
188
+ const result = await createTodo.func(services as any, { title: 'Buy milk' })
189
+ assert.equal(result.title, 'Buy milk')
190
+ })
191
+ })
192
+ ```
193
+
194
+ ```bash
195
+ node --import tsx --test src/**/*.test.ts
196
+ ```
197
+
198
+ Services are plain objects — a Pikku function is pure business logic, so a mock is just the shape the function destructures. Build real services via the `pikkuServices` / `pikkuWireServices` factories when a test needs them.
199
+
200
+ ## Red flags
201
+
202
+ | Smell | Why it's wrong |
203
+ | --- | --- |
204
+ | `pikku tests …` | Removed in #865. Use `pikku scenario`. |
205
+ | `.feature` files / Gherkin for function tests | Scenarios are TypeScript, not Gherkin. The in-process cucumber function world was deleted. |
206
+ | `scenario.do(...)` with no `{ actor }` | Throws. Every step runs as somebody. |
207
+ | A scenario per function | Scenarios are user flows. One flow covers many functions; that is the point. |
208
+ | Assuming a clean database | There is no state reset — it may be a staging server. Scope what you create. |
209
+ | `sleep()` before asserting | Use `expectEventually`. |
210
+ | `expectEventually` in a `pikkuWorkflowFunc` | `PKU675` — scenario-only. |
211
+ | Coverage silently 0 | Server not run with `--coverage`, `verboseMeta` off, `scaffold.scenarios` unset, or no actors configured. |
212
+
213
+ `@pikku/cucumber` is a **browser/e2e** harness (`Actor`, `BrowserWorld`, `PersonaData`, `DbUtils`) — out of scope here.
214
+
215
+ See `pikku-concepts` for the core mental model.
@@ -1,8 +1,11 @@
1
1
  ---
2
2
  name: pikku-schedule
3
- description: 'Use when setting up in-memory cron scheduling in a Pikku app. Covers InMemorySchedulerService for running scheduled tasks.
4
- TRIGGER when: code uses InMemorySchedulerService, PikkuTaskScheduler, or user asks about in-memory scheduling, cron jobs without external dependencies, or @pikku/schedule.
5
- DO NOT TRIGGER when: user asks about cron wiring (use pikku-cron) or queue-based scheduling with BullMQ/PgBoss (use pikku-queue).'
3
+ description: >-
4
+ Use when setting up in-memory cron scheduling in a Pikku app. Covers InMemorySchedulerService
5
+ for running scheduled tasks. TRIGGER when: code uses InMemorySchedulerService,
6
+ PikkuTaskScheduler, or user asks about in-memory scheduling, cron jobs without external
7
+ dependencies, or @pikku/schedule. DO NOT TRIGGER when: user asks about cron wiring (use
8
+ pikku-cron) or queue-based scheduling with BullMQ/PgBoss (use pikku-queue).
6
9
  installGroups: [core]
7
10
  ---
8
11
 
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  name: pikku-schema-ajv
3
- description: 'Use when setting up JSON schema validation with AJV in a Pikku app. Covers AjvSchemaService for request/response validation.
4
- TRIGGER when: code uses AjvSchemaService, user asks about AJV, JSON schema validation, or @pikku/schema-ajv.
5
- DO NOT TRIGGER when: user asks about Cloudflare Workers schema validation (use pikku-schema-cfworker).'
3
+ description: >-
4
+ Use when setting up JSON schema validation with AJV in a Pikku app. Covers AjvSchemaService for
5
+ request/response validation. TRIGGER when: code uses AjvSchemaService, user asks about AJV, JSON
6
+ schema validation, or @pikku/schema-ajv. DO NOT TRIGGER when: user asks about Cloudflare Workers
7
+ schema validation (use pikku-schema-cfworker).
6
8
  installGroups: [core]
7
9
  ---
8
10
 
@@ -1,8 +1,11 @@
1
1
  ---
2
2
  name: pikku-schema-cfworker
3
- description: 'Use when setting up JSON schema validation for Cloudflare Workers in a Pikku app. Covers CFWorkerSchemaService as a lightweight alternative to AJV.
4
- TRIGGER when: code uses CFWorkerSchemaService, user asks about schema validation on Cloudflare Workers, or @pikku/schema-cfworker.
5
- DO NOT TRIGGER when: user asks about AJV schema validation (use pikku-schema-ajv).'
3
+ description: >-
4
+ Use when setting up JSON schema validation for Cloudflare Workers in a Pikku app. Covers
5
+ CFWorkerSchemaService as a lightweight alternative to AJV. TRIGGER when: code uses
6
+ CFWorkerSchemaService, user asks about schema validation on Cloudflare Workers, or
7
+ @pikku/schema-cfworker. DO NOT TRIGGER when: user asks about AJV schema validation (use
8
+ pikku-schema-ajv).
6
9
  installGroups: [core, fabric]
7
10
  ---
8
11
 
@@ -1,8 +1,12 @@
1
1
  ---
2
2
  name: pikku-security
3
- description: 'Use when adding authentication or session management to a Pikku app — pikkuAuth, session lifecycle (setSession/clearSession), built-in auth strategies (authBearer, authCookie, authAPIKey), or JWT setup.
4
- TRIGGER when: user asks about login, logout, session, bearer tokens, cookie auth, API keys, or JWT.
5
- DO NOT TRIGGER when: user asks about middleware (use pikku-middleware), permissions/authorization checks (use pikku-permissions), or secrets/env vars (use pikku-config).'
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).
6
10
  installGroups: [core]
7
11
  ---
8
12
 
@@ -12,7 +16,7 @@ installGroups: [core]
12
16
 
13
17
  1. Discover before editing. Run `pikku info middleware --verbose` and `pikku info functions --verbose` to understand existing auth setup.
14
18
  2. Auth strategies live in wirings files — do not put `addHTTPMiddleware` calls inside function bodies.
15
- 3. Validate with `pikku tsc` after changes; run `pikku all` if wirings changed.
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.
16
20
 
17
21
  For **middleware** (including tag middleware and service-to-service bearer auth) see `pikku-middleware`.
18
22
  For **permissions** (pikkuPermission, pikkuAuth, per-function authorization) see `pikku-permissions`.
@@ -1,8 +1,12 @@
1
1
  ---
2
2
  name: pikku-services
3
- description: 'Use when setting up dependency injection, creating custom services, or configuring the service layer in a Pikku app. Covers pikkuServices (singleton), pikkuWireServices (per-request), service typing, built-in services, and tree-shaking.
4
- TRIGGER when: code uses pikkuServices/pikkuWireServices, user asks about services.ts, dependency injection, service factories, or built-in services (ConsoleLogger, JoseJWTService).
5
- DO NOT TRIGGER when: user asks about auth middleware (use pikku-security) or secrets/variables (use pikku-config).'
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).
6
10
  installGroups: [core]
7
11
  ---
8
12
 
@@ -72,7 +76,7 @@ export const createWireServices = pikkuWireServices(
72
76
 
73
77
  ### Auto-Generated Service Manifest
74
78
 
75
- After `npx pikku prebuild`, Pikku generates `.pikku/pikku-services.gen.ts`, a manifest of which services are actually used by wired functions:
79
+ After `npx pikku all`, Pikku generates `.pikku/pikku-services.gen.ts`, a manifest of which services are actually used by wired functions:
76
80
 
77
81
  ```typescript
78
82
  export const requiredSingletonServices = {
@@ -114,6 +118,40 @@ const getUser = pikkuFunc({
114
118
  })
115
119
  ```
116
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
+
117
155
  ### Dynamic Import Optimization
118
156
 
119
157
  Use the generated manifest to conditionally import heavy dependencies — only the services actually wired get instantiated:
@@ -0,0 +1,70 @@
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
+ ```
@@ -0,0 +1,186 @@
1
+ ---
2
+ name: pikku-software-archaeology
3
+ description: 'Use when reverse-engineering an existing repository into a Product Blueprint — recovering what product an undocumented or organically-grown codebase implements so it can be rebuilt cleanly (e.g. as a Pikku app). TRIGGER when: user says "extract a blueprint", "reverse engineer this app", "what does this codebase actually do as a product", "prepare this repo for a rewrite/migration", or points at a legacy repo (any language — JS, TS, Ruby, Python, PHP, Go) and asks for its domains, workflows, business rules, or a rebuild plan. DO NOT TRIGGER for: documenting code structure, generating API docs from an already-clean codebase, or code review.'
4
+ installGroups: [fabric]
5
+ ---
6
+
7
+ # Software Archaeology
8
+
9
+ ## Overview
10
+
11
+ Extract **intent over implementation**. A repository is a fossil record of product decisions; your job is to recover the product — domains, entities, commands, queries, events, policies, workflows, invariants — not to describe the code. The output is a `.knowledge/` directory of schema-validated JSON plus a human-readable `blueprint.md`, consumable by a generator (Pikku) to rebuild the application cleanly.
12
+
13
+ **You are the parser.** Do not build or rely on regex/AST scanners — read the code with your own tools (Grep, Read, subagents). This is what makes the skill language-agnostic: an Express app, a Rails app, and a Django app all yield the same blueprint shape.
14
+
15
+ **Two layers, never merged silently:**
16
+ - **Facts** — behavior directly observed in code, schema, or tests. Cite them.
17
+ - **Inferred intent** — the product reasoning you reconstruct. Mark it with `confidence` and say what evidence it rests on.
18
+
19
+ Never present a guess as a fact. `confidence: "high"` requires file:line evidence of the behavior itself.
20
+
21
+ ## Output Contract
22
+
23
+ Everything goes in `<repo>/.knowledge/` (or a caller-specified directory):
24
+
25
+ ```
26
+ .knowledge/
27
+ ├── product.json # purpose, actors, capabilities, terminology
28
+ ├── domains.json # business domains (NEVER folder names)
29
+ ├── entities.json # domain entities: attributes, relationships, states, transitions
30
+ ├── commands.json # state-changing actions (SendInvoice, not POST /invoices/:id/send)
31
+ ├── queries.json # read operations and views
32
+ ├── events.json # business facts, past tense (InvoicePaid) — no technical events
33
+ ├── policies.json # authorization, validation, state, business-constraint rules
34
+ ├── workflows.json # user + admin + system workflows, with test-derived scenarios
35
+ ├── api.json # every surface, each mapped to a command/query/event-ingress
36
+ ├── integrations.json # external services: purpose, direction, replaceability
37
+ ├── architecture.json # components, datastores, deployment constraints worth keeping
38
+ ├── invariants.json # what must ALWAYS be true, and what enforces it today
39
+ ├── gaps.json # TODOs, hacks, duplication, dead code, open product decisions
40
+ ├── migration.json # current files -> future concepts, drops, decisions needed
41
+ ├── blueprint.md # human synthesis of all of the above
42
+
43
+ │ # OPTIONAL — the consumer-surface layer. Emit these when the repo has a
44
+ │ # frontend and/or non-HTTP consumer channels. A backend-only repo omits them
45
+ │ # and the validator does not complain.
46
+ ├── interfaces.json # every way the product is consumed: web-ui, cli, mcp, openapi-rest, sdk, realtime, webhooks
47
+ ├── frontend.json # web-UI app shape: framework, router, styling, data layer, auth (e.g. TanStack Start + better-auth + Mantine)
48
+ ├── frontend-routes.json # the page/route tree — what a user navigates to, its data + components
49
+ └── frontend-components.json# component inventory; `rebuild` splits trivial-Mantine from custom-logic-to-port
50
+ ```
51
+
52
+ The exact field shapes live in `references/blueprint.schema.json` (in this skill's directory — read it before writing any output file). After writing, ALWAYS run:
53
+
54
+ ```bash
55
+ node <skill-dir>/scripts/validate.mjs <repo>/.knowledge
56
+ ```
57
+
58
+ and fix every ERROR (WARNs are prompts to double-check, not necessarily wrong). Do not declare the extraction done with validation errors outstanding.
59
+
60
+ ## The Pipeline
61
+
62
+ Work in phases. For small repos (< ~50 source files) do them inline; for larger repos, fan out subagents per phase-3 lens and merge (see "Scaling up").
63
+
64
+ ### Phase 1 — Survey (facts only)
65
+
66
+ Build an inventory before interpreting anything:
67
+ - Manifests (`package.json`, `Gemfile`, `pyproject.toml`, `go.mod`, `composer.json`): dependencies are integration hints; scripts are entry points.
68
+ - Entry points: servers, route registrations, cron/scheduler setup, queue workers, CLI binaries.
69
+ - Data layer: migrations, schema files, model classes, raw DDL (check comments too — schemas hide in comments in migration-less repos).
70
+ - Every HTTP/GraphQL/RPC surface, webhook, scheduled job, queue consumer.
71
+ - **All consumer channels, not just HTTP**: a frontend app (`apps/`, `frontend/`, `web/`, `client/`), a CLI (`bin/`, `wireCLI`, a `cli/` dir, an `openapi`-generated command tool), an MCP server (`wireMCP`, `@modelcontextprotocol`, a `mcp`/`tools` dir), an OpenAPI/Swagger spec (`openapi.json`, `swagger`), a published/generated SDK, realtime channels (websocket/SSE). Each is an `interfaces.json` entry.
72
+ - Env vars and config files.
73
+ - TODO / FIXME / HACK / XXX / deprecated markers — each is a gaps.json candidate.
74
+ - **The test suite** — locate it now, excavate it in Phase 2.
75
+
76
+ Where intent hides, per ecosystem (read these first):
77
+
78
+ | Ecosystem | Highest-yield locations |
79
+ |---|---|
80
+ | Rails | `config/routes.rb`, model validations + callbacks + `aasm`/state machines, `app/policies` (Pundit) / `ability.rb` (CanCan), Sidekiq/ActiveJob workers, `db/schema.rb`, specs (esp. request + model specs) |
81
+ | Express/Node | route registration files, middleware chains (auth!), inline `if` guards in handlers, SQL/ORM models, `jobs/`+crontab refs, webhook handlers |
82
+ | Django | `urls.py`, model `Meta`/constraints/`clean()`, DRF serializers + permissions classes, celery tasks, admin.py (reveals internal workflows) |
83
+ | Laravel | `routes/`, FormRequests (validation), Policies/Gates, Jobs + scheduler in `Kernel.php`, migrations |
84
+ | Go | mux/router setup, middleware, struct tags, `cmd/` binaries (each is a component) |
85
+ | Frontend (React/Vue/etc.) | router config / file-based routes (pages a user reaches), the component tree, the design-system import (`@mantine/*`, `@mui/*`, Tailwind config) to judge consistency, the data layer (react-query/tRPC/fetch wrappers) to tie UI back to backend queries, charts/tables/editors (the `custom-logic` port risk), auth wiring |
86
+
87
+ ### Phase 2 — Test excavation (do not skip)
88
+
89
+ Tests are the closest thing to an executable product spec. For every test file:
90
+ - `describe`/`context`/`it` names → **scenarios** (attach to the matching workflow in `workflows.json` under `scenarios[]`, with `fromTest` set).
91
+ - User-flow/journey harnesses (`pikkuUserFlow` stories, cucumber `.feature` files, Playwright journeys) are the highest-grade scenario source — they already ARE given/when/outcome sequences; extract them verbatim.
92
+ - Assertions → confirmations of policies and invariants (upgrade their `confidence` to `high`, add the test as evidence).
93
+ - Fixtures/factories → entity attribute shapes and realistic example data.
94
+ - Edge-case tests → business rules that exist **nowhere else in the code** (e.g. "replayed webhook events are idempotent" may only be stated in a test).
95
+ - Untested-but-critical paths, or a test suite that can't run (missing helpers, broken setup) → `gaps.json`.
96
+
97
+ A rule attested by both an implementation guard AND a test is your strongest possible evidence — cite both.
98
+
99
+ ### Phase 3 — Extraction lenses
100
+
101
+ Run each lens over the surveyed material. Rules that counter the classic failure modes:
102
+
103
+ **Domains** — infer from data ownership, workflows, and vocabulary; NEVER from folder names. `controllers/` is not a domain; "Billing" is. A domain owns entities and the commands that mutate them.
104
+
105
+ **Entities** — domain concepts, not tables. Include: attributes (from schema + serializers + fixtures), relationships, **lifecycle states and transitions** (grep status/state columns, then find every write to them — each write site is a transition with a trigger), ownership (which actor's rows), constraints.
106
+
107
+ **Commands** — every way state changes: routes, jobs, webhooks, CLI, admin consoles, DB triggers. Name them imperative `VerbNoun` in domain language: `POST /api/users/:id/status` → `ActivateUser`. For each: actor, preconditions (every `if (...) return 4xx` guard is a precondition or policy), effects, events produced. Convention: authentication/token issuance is a command (`LogInUser`, effect: "issues a session/JWT") even though it writes no rows — it changes the caller's security state.
108
+
109
+ **Queries** — reads and views, `GetX`/`ListX`/`SearchX`. Record the tenancy scoping each applies (a missing `WHERE user_id=` that exists elsewhere is a gaps.json security entry).
110
+
111
+ **Events** — meaningful business facts, past tense. Most legacy apps have **implicit** events: an email send, a status flip, and a counter bump inside one handler are the event's consumers — reconstruct `InvoicePaid` from them and set `explicit: false`. Exclude technical noise (ButtonClicked, FunctionCalled). Inclusion threshold for implicit events: at least one observed consumer beyond the row write itself (an email, a downstream job, a webhook out, a derived-state flip). Plain CRUD facts with no reaction (`ClientCreated` that nothing listens to) do not become events.
112
+
113
+ **Policies** — authorization, validation, state rules, business constraints. Record **every** location enforcing each rule in `enforcedAt`; the same rule enforced in 3 places (or worse, 2 slightly different versions) is a gaps.json duplication entry.
114
+
115
+ **Workflows** — ALL of them: user journeys, admin/support operations, and **system workflows** (cron jobs, queue consumers, webhook reactions, syncs, notification sweeps). A crontab line in a comment is a workflow. Attach Phase-2 scenarios.
116
+
117
+ **API** — list every surface but map each to its concept (`mapsTo: {type: command, name: SendInvoice}`). The route is evidence; the command is the deliverable. Auth per surface (including "none" and capability-URLs like tokened public links). A webhook whose handler changes state maps to a **command** (`RecordInvoicePayment`); reserve `event-ingress` for pure relay surfaces, where `name` must be an events.json event.
118
+
119
+ **Integrations** — from deps + config + calls: purpose, data exchanged, direction, importance, replacement difficulty, env vars.
120
+
121
+ **Architecture** — components as they actually run (API process, worker, cron job, SPA), datastores, and deployment constraints that must survive the rewrite (hardcoded ports with upstream expectations, raw-body middleware ordering, webhook retry semantics).
122
+
123
+ **Invariants** — what must always hold, and `enforcedBy`: db-constraint, code-guard, convention, or `nothing` (an unenforced invariant is a gap). Include `atRiskBecause` when enforcement is fragile (e.g. read-then-insert sequence numbering races).
124
+
125
+ **Gaps** — incomplete features, TODOs, hacks (hardcoded admin emails), duplicated logic that drifted, dead code, unclear ownership, and **open product decisions** the code never resolved (a FIXME asking "should deleting a client void invoices?" is a product decision, record it in both gaps.json and migration.json `decisionsNeeded`).
126
+
127
+ **Migration** — map current file clusters → future domain + concepts; list files to drop with reasons; list decisions a human must make before rebuild.
128
+
129
+ **Interfaces** (`interfaces.json`, optional) — every way the product is CONSUMED, one entry per channel, not per route. A product is usually driven through several: a **web UI** (humans), a **CLI** (developers/operators), an **MCP server** (AI agents — in a Pikku app each MCP tool IS a `pikkuFunc`), an **OpenAPI/REST** surface (developers/external systems, often *generated* from the routes), a **generated SDK**, **realtime** (websocket/SSE), and **webhooks** (in/out). For each: `kind`, `audience`, `purpose`, roughly how many ops it exposes, whether it's `generated` vs hand-written, which domains it serves, and `status` (complete/partial/stub — an MCP server with two tools is `stub`). This layer answers "who can drive this, and how" — it is the map the second-opinion skill needs to explain that the app is usable by people, developers, and agents.
130
+
131
+ **Frontend** (`frontend.json` + `frontend-routes.json` + `frontend-components.json`, optional) — the web UI, which needs its own treatment because frontends vary wildly (framework, router, styling, state, data, auth) and the rebuild target is opinionated: **everything in one component system (Mantine), one data layer, one auth**.
132
+ - `frontend.json` records the stack as FACTS: framework (e.g. TanStack Start), rendering (SSR/streaming/SPA), router, styling/design system, `designSystemConsistency`, state management, data layer (e.g. pikku-react-query vs REST helpers), auth (e.g. better-auth), i18n. Name the real technologies — the second-opinion skill weighs their tradeoffs, so record them precisely (do NOT editorialize here; this file is facts).
133
+ - `frontend-routes.json` is the page tree: each route's `purpose` in product terms, `auth`, the `dataFrom` (query/command names it reads — reuse the backend concept names so the UI ties back to the domain), the `usesComponents`, and the `userFlows` it belongs to.
134
+ - `frontend.json.designFindings` captures **broken/inconsistent design patterns** as concrete, cited observations (not taste). Actively hunt for: *interaction inconsistency* (the same job done as a modal in one place and a drawer in another; inconsistent confirm dialogs); *theming not tokenized* (hardcoded hex colors, magic spacing/font sizes, inline styles instead of theme tokens/variables — grep for `#[0-9a-f]{3,6}`, `style={{`, raw `px` values); *cross-page inconsistency* (the same element — button, page header, card — styled differently across routes); *component duplication* (three near-identical cards/tables for one purpose); *design-system bypass* (raw HTML/CSS where a library component exists). Each finding gets an example, its impact (feels unpolished / a color change means hunting every file), and a fix (standardize on one pattern / move to tokens / extract one shared component). These are almost always cheap cleanups, and they are exactly what a non-technical owner perceives as "the app looks off" without being able to say why.
135
+ - `frontend-components.json` is where the frontend's real migration cost lives, in the **`rebuild`** field: `mantine-standard` (maps 1:1 to a Mantine component — trivial), `mantine-composition` (built from Mantine primitives — straightforward), `custom-style` (diverges only visually — normalize to Mantine), or **`custom-logic`** (bespoke behavior — a custom chart, a virtualized/complex table, a canvas, drag-and-drop, a rich editor — that must be **ported**, not re-skinned). A `custom-logic` component MUST fill `customLogic` explaining the behavior, and should list the `dependencies` (charting/table/editor libs) that make it a real port. This split — "trivially re-Mantine-able" vs "carries logic that must survive the port" — is the single most useful thing the frontend extraction produces.
136
+ - **Server-rendered / non-React frontends still get all three files — do NOT skip them.** The `rebuild` enum is named for the target stack, but the distinction it draws is target-agnostic: *trivial stock element* vs *composed from primitives* vs *visual divergence only* vs **bespoke behavior that must be ported**. A Rails app (Slim/ERB + ViewComponents + Hotwire/Stimulus), a Django app (templates + HTMX), or a Laravel app (Blade + Livewire) all have that same split, and it is just as load-bearing there. Use the enum values verbatim (the validator enforces them), classify by what the thing actually *does*, and record the vocabulary mismatch in `frontend.json.notes`. Concretely: treat a template partial + its behavior controller (Stimulus/Alpine/Livewire) as ONE component and classify the pair; a server-rendered app's `custom-logic` is the same list as a SPA's (maps, charts, video players, payment elements, drag-to-reorder, rich text, QR, live-updating regions), plus anything whose behavior rides on a streaming/partial-update contract (Turbo Streams, HTMX swaps) — get that mapping wrong on rebuild and pages show stale data. Omitting these files because "it isn't a React app" hides the frontend's entire migration cost, which is the one thing this file exists to expose.
137
+ - The `designFindings` grep hints above are React-flavored; the server-rendered equivalents are inline `style=` attributes in templates, hardcoded hex in the stylesheet tree, per-locale forked templates instead of i18n, and design-system bypass = raw markup where a component/partial already exists. Same findings, different needles.
138
+
139
+ ### Phase 4 — Cross-check, validate, synthesize
140
+
141
+ 1. Cross-checks before writing: every command has an actor and at least one precondition or policy (or you explain why it is genuinely unguarded); every state transition appears in some command/workflow — if a state is only reachable by manual/DB intervention, record the transition with trigger `"none (manual/DB-only)"` AND add a gaps.json entry; every event has a producer; every api surface maps to a defined concept; every integration is used by some command/workflow.
142
+ 2. Write all 14 JSON files, sorting **unordered identity collections** by `name` (or `path`) — on first extraction too, not just re-runs. Arrays whose order carries meaning (`workflows[].steps`, and any other observed sequence) stay in their observed order: sorting them would rewrite the behavior you extracted. Run the validator: done means `0 error(s)` and exit 0, and every WARN explicitly reviewed and either fixed or justified in your summary.
143
+ 3. Write `blueprint.md`: product summary → domain map → per-domain narrative (entities/commands/events with the interesting rules) → workflows → integrations/architecture → invariants → gaps and open decisions → rebuild recommendation. Write it for the engineer who will rebuild the product and has never seen the legacy code.
144
+
145
+ ## Evidence & Confidence Discipline
146
+
147
+ - Every concept object carries `evidence: [{file, lines, note}]` and `confidence`. (In `api.json` and `architecture.json`, `confidence` is optional — include it whenever a surface/component is inferred rather than directly observed, e.g. an SPA known only from comments.)
148
+ - `high` — the behavior itself is in the cited code/schema/test.
149
+ - `medium` — inferred from multiple converging signals (naming + partial code + a test name).
150
+ - `low` — plausible reconstruction; MUST also be phrased tentatively in blueprint.md and usually deserves a `decisionsNeeded` entry.
151
+ - Comments and docs describe *intended* behavior; code describes *actual* behavior. When they disagree, record the code's behavior as the fact and the disagreement as a gap.
152
+
153
+ ## Scaling up (large repos)
154
+
155
+ - Fan out one subagent per lens (or per candidate domain) with: the survey notes, the schema file path, and instructions to return JSON fragments with evidence. Merge, dedupe by concept name, then run Phase 4 yourself.
156
+ - Fix the domain cut YOURSELF after the survey and hand every lens agent the same canonical domain list — domains are the shared IDs everything cross-references.
157
+ - Give each lens agent ownership of whole files (never two agents writing one file), and pair coupled files under one agent (commands+queries+api must share names).
158
+ - **Budget a reconciliation pass — parallel agents WILL drift on names** (observed at real scale: 472 validator warnings from one 7-agent run). The pattern: rebuild `domains.json`'s entity/command/query/event/policy roll-up lists LAST, generated by grouping the authoritative files by their `domain` field — never hand-written before those files exist; reconcile `eventsProduced` against curated `events.json` by rename (spelling variant) / drop (CRUD noise, no consumer) / add (only with verified consumer evidence); fill empty command policies by joining `api.json`'s per-surface `auth` against `policies.json` names. The validator's warning list is the reconciliation worklist.
159
+ - **Incremental re-runs:** keep concept names stable (they are the IDs). Re-run the affected lens only, diff against the existing `.knowledge/` files, and preserve unrelated entries verbatim. Sort every array by `name` (or `path`) so diffs are meaningful.
160
+
161
+ ## Red Flags — you are about to produce a worthless blueprint
162
+
163
+ | Thought | Reality |
164
+ |---|---|
165
+ | "I'll write it up as markdown docs" | Only `blueprint.md` is prose. The 14 JSON files ARE the deliverable; a generator consumes them. |
166
+ | "The routes are the API contract" | Routes are evidence. Lift each to a command/query or you've documented plumbing, not product. |
167
+ | "This is obvious, no citation needed" | Uncited claims are indistinguishable from hallucinations. Evidence on everything. |
168
+ | "The folder structure tells me the domains" | Folders are how it grew, not what it is. Derive domains from ownership + vocabulary. |
169
+ | "Tests are just tests, skip them" | Tests are the spec. Some rules exist ONLY in tests. Phase 2 is mandatory. |
170
+ | "No events are emitted, so events: []" | Reconstruct implicit events from side-effect clusters; mark `explicit: false`. |
171
+ | "Cron jobs aren't workflows" | System workflows are workflows. Include schedules, queue consumers, webhook reactions. |
172
+ | "The frontend is just the web routes" | The web UI is ONE interface. Inventory the CLI, MCP server, OpenAPI/SDK, realtime, webhooks in `interfaces.json` too — the product is driven by people, developers, AND agents. |
173
+ | "A component list is enough" | Without the `rebuild` split, you've hidden the frontend's real cost. Flag every `custom-logic` component (chart/table/canvas/editor) and say what the logic is — that's the port work. |
174
+ | "I'll skip the validator, the JSON looks right" | Run it. Missing domains refs, dangling event names, and undescribed custom-logic components are exactly what it catches. |
175
+
176
+ ## Quick Reference
177
+
178
+ ```bash
179
+ # 1. survey + excavate + extract (you, with Read/Grep/subagents)
180
+ # 2. write <repo>/.knowledge/*.json + blueprint.md per references/blueprint.schema.json
181
+ # 3. validate:
182
+ node <skill-dir>/scripts/validate.mjs <repo>/.knowledge
183
+ ```
184
+
185
+ - Schema/contract: `references/blueprint.schema.json`
186
+ - How Pikku consumes the blueprint: `references/pikku-mapping.md`