@pikku/cli 0.11.2 → 0.11.3

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 (301) hide show
  1. package/.pikku/channel/pikku-channel-types.gen.ts +63 -6
  2. package/.pikku/channel/pikku-channels-map.gen.d.ts +4 -4
  3. package/.pikku/channel/pikku-channels-meta.gen.ts +4 -2
  4. package/.pikku/channel/pikku-channels.gen.ts +1 -1
  5. package/.pikku/cli/pikku-cli-channel.ts +1 -1
  6. package/.pikku/cli/pikku-cli-client.gen.ts +1 -1
  7. package/.pikku/cli/pikku-cli-types.gen.ts +1 -1
  8. package/.pikku/cli/pikku-cli-wirings-meta.gen.json +2 -1
  9. package/.pikku/cli/pikku-cli-wirings-meta.gen.ts +2 -2
  10. package/.pikku/cli/pikku-cli-wirings.gen.ts +1 -1
  11. package/.pikku/cli/pikku-cli.gen.ts +1 -1
  12. package/.pikku/forge/pikku-forge-types.gen.ts +83 -0
  13. package/.pikku/function/pikku-function-types.gen.ts +181 -35
  14. package/.pikku/function/pikku-functions-meta-verbose.gen.json +1030 -0
  15. package/.pikku/function/pikku-functions-meta.gen.json +88 -420
  16. package/.pikku/function/pikku-functions-meta.gen.ts +2 -2
  17. package/.pikku/http/pikku-http-types.gen.ts +19 -3
  18. package/.pikku/http/pikku-http-wirings-map.gen.d.ts +4 -4
  19. package/.pikku/http/pikku-http-wirings-meta.gen.json +9 -0
  20. package/.pikku/http/pikku-http-wirings-meta.gen.ts +4 -10
  21. package/.pikku/http/pikku-http-wirings.gen.ts +1 -1
  22. package/.pikku/mcp/pikku-mcp-types.gen.ts +69 -17
  23. package/.pikku/mcp/pikku-mcp-wirings-meta.gen.ts +4 -4
  24. package/.pikku/mcp/pikku-mcp-wirings.gen.ts +1 -1
  25. package/.pikku/pikku-bootstrap.gen.ts +7 -9
  26. package/.pikku/pikku-services.gen.ts +3 -2
  27. package/.pikku/pikku-types.gen.ts +4 -1
  28. package/.pikku/pikku-websocket.gen.ts +1 -1
  29. package/.pikku/queue/pikku-queue-types.gen.ts +1 -1
  30. package/.pikku/queue/pikku-queue-workers-wirings-map.gen.d.ts +4 -4
  31. package/.pikku/queue/pikku-queue-workers-wirings-meta.gen.ts +2 -2
  32. package/.pikku/queue/pikku-queue-workers-wirings.gen.ts +1 -1
  33. package/.pikku/rpc/pikku-remote-rpc-workers.gen.ts +4 -1
  34. package/.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts +12 -7
  35. package/.pikku/rpc/pikku-rpc-wirings-map.internal.gen.d.ts +15 -9
  36. package/.pikku/scheduler/pikku-scheduler-types.gen.ts +1 -1
  37. package/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.ts +2 -2
  38. package/.pikku/scheduler/pikku-schedulers-wirings.gen.ts +1 -1
  39. package/.pikku/schemas/register.gen.ts +9 -1
  40. package/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  41. package/.pikku/schemas/schemas/PikkuCLIOutput.schema.json +1 -1
  42. package/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
  43. package/.pikku/schemas/schemas/PikkuForgeNodesOutput.schema.json +1 -0
  44. package/.pikku/schemas/schemas/PikkuFunctionsOutput.schema.json +1 -1
  45. package/.pikku/schemas/schemas/PikkuHTTPOutput.schema.json +1 -1
  46. package/.pikku/schemas/schemas/PikkuMCPOutput.schema.json +1 -1
  47. package/.pikku/schemas/schemas/PikkuMiddlewareOutput.schema.json +1 -1
  48. package/.pikku/schemas/schemas/PikkuPackageOutput.schema.json +1 -0
  49. package/.pikku/schemas/schemas/PikkuPermissionsOutput.schema.json +1 -1
  50. package/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -1
  51. package/.pikku/schemas/schemas/PikkuQueueOutput.schema.json +1 -1
  52. package/.pikku/schemas/schemas/PikkuRPCOutput.schema.json +1 -1
  53. package/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -1
  54. package/.pikku/schemas/schemas/PikkuSchedulerOutput.schema.json +1 -1
  55. package/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
  56. package/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -1
  57. package/.pikku/services/config.gen.json +11 -6
  58. package/.pikku/services/getInspectorState.gen.json +2 -2
  59. package/.pikku/services/jwt.gen.json +2 -2
  60. package/.pikku/services/logger.gen.json +2 -2
  61. package/.pikku/services/queueService.gen.json +2 -2
  62. package/.pikku/services/schedulerService.gen.json +2 -2
  63. package/.pikku/services/schema.gen.json +2 -2
  64. package/.pikku/services/secrets.gen.json +13 -0
  65. package/.pikku/services/variables.gen.json +2 -2
  66. package/.pikku/services/workflowService.gen.json +6 -6
  67. package/.pikku/workflow/pikku-workflow-map.gen.d.ts +2 -36
  68. package/.pikku/workflow/pikku-workflow-types.gen.ts +297 -45
  69. package/.pikku/workflow/pikku-workflow-wirings-meta.gen.ts +5 -4
  70. package/.pikku/workflow/pikku-workflow-wirings.gen.ts +1 -6
  71. package/CHANGELOG.md +23 -1
  72. package/cli.schema.json +1 -1
  73. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +47 -5
  74. package/dist/.pikku/channel/pikku-channel-types.gen.js +3 -13
  75. package/dist/.pikku/channel/pikku-channels-meta.gen.js +3 -2
  76. package/dist/.pikku/channel/pikku-channels.gen.d.ts +1 -1
  77. package/dist/.pikku/channel/pikku-channels.gen.js +1 -1
  78. package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
  79. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  80. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  81. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  82. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  83. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +2 -2
  84. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +2 -1
  85. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  86. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  87. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  88. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  89. package/dist/.pikku/forge/pikku-forge-types.gen.d.ts +72 -0
  90. package/dist/.pikku/forge/pikku-forge-types.gen.js +55 -0
  91. package/dist/.pikku/function/pikku-function-types.gen.d.ts +123 -31
  92. package/dist/.pikku/function/pikku-function-types.gen.js +37 -51
  93. package/dist/.pikku/function/pikku-functions-meta.gen.js +2 -2
  94. package/dist/.pikku/function/pikku-functions-meta.gen.json +88 -420
  95. package/dist/.pikku/http/pikku-http-types.gen.d.ts +18 -3
  96. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  97. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +3 -10
  98. package/dist/.pikku/http/pikku-http-wirings-meta.gen.json +9 -0
  99. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
  100. package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
  101. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +54 -14
  102. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +7 -31
  103. package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.js +4 -4
  104. package/dist/.pikku/mcp/pikku-mcp-wirings.gen.d.ts +1 -1
  105. package/dist/.pikku/mcp/pikku-mcp-wirings.gen.js +1 -1
  106. package/dist/.pikku/pikku-bootstrap.gen.d.ts +7 -9
  107. package/dist/.pikku/pikku-bootstrap.gen.js +7 -9
  108. package/dist/.pikku/pikku-services.gen.d.ts +3 -2
  109. package/dist/.pikku/pikku-services.gen.js +1 -0
  110. package/dist/.pikku/pikku-types.gen.d.ts +2 -1
  111. package/dist/.pikku/pikku-types.gen.js +3 -1
  112. package/dist/.pikku/pikku-websocket.gen.d.ts +1 -1
  113. package/dist/.pikku/pikku-websocket.gen.js +1 -1
  114. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  115. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  116. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +2 -2
  117. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  118. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  119. package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.d.ts +4 -1
  120. package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.js +4 -1
  121. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  122. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  123. package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.js +2 -2
  124. package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.d.ts +1 -1
  125. package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.js +1 -1
  126. package/dist/.pikku/schemas/register.gen.js +5 -1
  127. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  128. package/dist/.pikku/schemas/schemas/PikkuCLIOutput.schema.json +1 -1
  129. package/dist/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
  130. package/dist/.pikku/schemas/schemas/PikkuForgeNodesOutput.schema.json +1 -0
  131. package/dist/.pikku/schemas/schemas/PikkuFunctionsOutput.schema.json +1 -1
  132. package/dist/.pikku/schemas/schemas/PikkuHTTPOutput.schema.json +1 -1
  133. package/dist/.pikku/schemas/schemas/PikkuMCPOutput.schema.json +1 -1
  134. package/dist/.pikku/schemas/schemas/PikkuMiddlewareOutput.schema.json +1 -1
  135. package/dist/.pikku/schemas/schemas/PikkuPackageOutput.schema.json +1 -0
  136. package/dist/.pikku/schemas/schemas/PikkuPermissionsOutput.schema.json +1 -1
  137. package/dist/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -1
  138. package/dist/.pikku/schemas/schemas/PikkuQueueOutput.schema.json +1 -1
  139. package/dist/.pikku/schemas/schemas/PikkuRPCOutput.schema.json +1 -1
  140. package/dist/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -1
  141. package/dist/.pikku/schemas/schemas/PikkuSchedulerOutput.schema.json +1 -1
  142. package/dist/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
  143. package/dist/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -1
  144. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +207 -37
  145. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +104 -28
  146. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +3 -3
  147. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.d.ts +2 -6
  148. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +2 -6
  149. package/dist/src/functions/commands/all.js +117 -79
  150. package/dist/src/functions/commands/bootstrap.js +2 -9
  151. package/dist/src/functions/runtimes/nextjs/pikku-command-nextjs.js +0 -1
  152. package/dist/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.js +49 -35
  153. package/dist/src/functions/runtimes/nextjs/serialize-nextjs-http-wrapper.js +49 -35
  154. package/dist/src/functions/wirings/channels/pikku-channels.js +1 -1
  155. package/dist/src/functions/wirings/channels/pikku-command-channels.js +18 -2
  156. package/dist/src/functions/wirings/channels/serialize-channel-types.js +62 -5
  157. package/dist/src/functions/wirings/channels/serialize-typed-channel-map.js +1 -2
  158. package/dist/src/functions/wirings/cli/pikku-command-cli.js +10 -2
  159. package/dist/src/functions/wirings/forge/pikku-command-forge-nodes.d.ts +1 -0
  160. package/dist/src/functions/wirings/forge/pikku-command-forge-nodes.js +90 -0
  161. package/dist/src/functions/wirings/forge/pikku-command-forge-types.d.ts +1 -0
  162. package/dist/src/functions/wirings/forge/pikku-command-forge-types.js +26 -0
  163. package/dist/src/functions/wirings/forge/serialize-forge-types.d.ts +4 -0
  164. package/dist/src/functions/wirings/forge/serialize-forge-types.js +90 -0
  165. package/dist/src/functions/wirings/functions/pikku-command-function-types-split.js +1 -1
  166. package/dist/src/functions/wirings/functions/pikku-command-function-types.js +7 -2
  167. package/dist/src/functions/wirings/functions/pikku-command-functions.js +33 -18
  168. package/dist/src/functions/wirings/functions/pikku-command-services.js +1 -1
  169. package/dist/src/functions/wirings/functions/pikku-function-types.js +2 -2
  170. package/dist/src/functions/wirings/functions/schemas.d.ts +1 -1
  171. package/dist/src/functions/wirings/functions/schemas.js +5 -4
  172. package/dist/src/functions/wirings/functions/serialize-function-imports.d.ts +3 -1
  173. package/dist/src/functions/wirings/functions/serialize-function-imports.js +7 -3
  174. package/dist/src/functions/wirings/functions/serialize-function-types.d.ts +1 -1
  175. package/dist/src/functions/wirings/functions/serialize-function-types.js +181 -34
  176. package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.d.ts +1 -1
  177. package/dist/src/functions/wirings/functions/serialize-pikku-types-hub.js +19 -21
  178. package/dist/src/functions/wirings/http/openapi-spec-generator.js +1 -1
  179. package/dist/src/functions/wirings/http/pikku-command-http-routes.js +18 -2
  180. package/dist/src/functions/wirings/http/pikku-command-openapi.js +2 -2
  181. package/dist/src/functions/wirings/http/pikku-http-routes.js +1 -1
  182. package/dist/src/functions/wirings/http/serialize-http-types.js +18 -2
  183. package/dist/src/functions/wirings/http/serialize-typed-http-map.js +33 -8
  184. package/dist/src/functions/wirings/mcp/pikku-command-mcp.js +15 -6
  185. package/dist/src/functions/wirings/mcp/serialize-mcp-json.js +3 -2
  186. package/dist/src/functions/wirings/mcp/serialize-mcp-types.js +68 -16
  187. package/dist/src/functions/wirings/middleware/pikku-command-middleware.js +5 -2
  188. package/dist/src/functions/wirings/package/pikku-command-package.d.ts +1 -0
  189. package/dist/src/functions/wirings/package/pikku-command-package.js +58 -0
  190. package/dist/src/functions/wirings/package/serialize-package.d.ts +5 -0
  191. package/dist/src/functions/wirings/package/serialize-package.js +32 -0
  192. package/dist/src/functions/wirings/queue/pikku-command-queue.js +10 -2
  193. package/dist/src/functions/wirings/queue/pikku-queue.js +1 -9
  194. package/dist/src/functions/wirings/queue/serialize-queue-map.js +20 -3
  195. package/dist/src/functions/wirings/queue/serialize-queue-meta.js +1 -1
  196. package/dist/src/functions/wirings/rpc/pikku-command-rpc-map.js +4 -4
  197. package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +1 -1
  198. package/dist/src/functions/wirings/rpc/serialize-remote-rpc.js +3 -0
  199. package/dist/src/functions/wirings/rpc/serialize-rpc-wrapper.js +1 -1
  200. package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.d.ts +1 -1
  201. package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +54 -8
  202. package/dist/src/functions/wirings/scheduler/pikku-command-scheduler.js +10 -1
  203. package/dist/src/functions/wirings/scheduler/serialize-scheduler-meta.js +1 -1
  204. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +56 -18
  205. package/dist/src/functions/wirings/workflow/serialize-workflow-map.d.ts +3 -0
  206. package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +30 -32
  207. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.d.ts +1 -3
  208. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +43 -18
  209. package/dist/src/functions/wirings/workflow/serialize-workflow-registration.d.ts +7 -0
  210. package/dist/src/functions/wirings/workflow/serialize-workflow-registration.js +53 -0
  211. package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +3 -1
  212. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +299 -45
  213. package/dist/src/functions/wirings/workflow/serialize-workflow-workers.d.ts +1 -1
  214. package/dist/src/functions/wirings/workflow/serialize-workflow-workers.js +14 -27
  215. package/dist/src/services.js +4 -1
  216. package/dist/src/utils/command-summary.d.ts +2 -0
  217. package/dist/src/utils/command-summary.js +2 -0
  218. package/dist/src/utils/custom-types-generator.js +13 -15
  219. package/dist/src/utils/generate-bootstrap-file.js +1 -1
  220. package/dist/src/utils/pikku-cli-config.js +37 -9
  221. package/dist/src/utils/schema-generator.d.ts +4 -3
  222. package/dist/src/utils/schema-generator.js +135 -15
  223. package/dist/src/utils/strip-verbose-meta.d.ts +43 -0
  224. package/dist/src/utils/strip-verbose-meta.js +210 -0
  225. package/dist/tsconfig.tsbuildinfo +1 -1
  226. package/package.json +7 -4
  227. package/src/functions/commands/all.ts +144 -97
  228. package/src/functions/commands/bootstrap.ts +2 -10
  229. package/src/functions/runtimes/nextjs/pikku-command-nextjs.ts +0 -1
  230. package/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.ts +49 -35
  231. package/src/functions/runtimes/nextjs/serialize-nextjs-http-wrapper.ts +49 -35
  232. package/src/functions/wirings/channels/pikku-channels.ts +1 -1
  233. package/src/functions/wirings/channels/pikku-command-channels.ts +46 -3
  234. package/src/functions/wirings/channels/serialize-channel-types.ts +62 -5
  235. package/src/functions/wirings/channels/serialize-typed-channel-map.ts +3 -2
  236. package/src/functions/wirings/cli/pikku-command-cli.ts +21 -2
  237. package/src/functions/wirings/forge/pikku-command-forge-nodes.ts +135 -0
  238. package/src/functions/wirings/forge/pikku-command-forge-types.ts +38 -0
  239. package/src/functions/wirings/forge/serialize-forge-types.ts +94 -0
  240. package/src/functions/wirings/functions/pikku-command-function-types-split.ts +3 -2
  241. package/src/functions/wirings/functions/pikku-command-function-types.ts +17 -10
  242. package/src/functions/wirings/functions/pikku-command-functions.ts +47 -37
  243. package/src/functions/wirings/functions/pikku-command-services.ts +1 -1
  244. package/src/functions/wirings/functions/pikku-function-types.ts +3 -1
  245. package/src/functions/wirings/functions/schemas.ts +14 -4
  246. package/src/functions/wirings/functions/serialize-function-imports.ts +12 -3
  247. package/src/functions/wirings/functions/serialize-function-types.ts +182 -34
  248. package/src/functions/wirings/functions/serialize-pikku-types-hub.ts +27 -26
  249. package/src/functions/wirings/http/openapi-spec-generator.ts +1 -1
  250. package/src/functions/wirings/http/pikku-command-http-routes.ts +46 -2
  251. package/src/functions/wirings/http/pikku-command-openapi.ts +3 -2
  252. package/src/functions/wirings/http/pikku-http-routes.ts +1 -1
  253. package/src/functions/wirings/http/serialize-http-types.ts +18 -2
  254. package/src/functions/wirings/http/serialize-typed-http-map.ts +32 -8
  255. package/src/functions/wirings/mcp/pikku-command-mcp.ts +32 -10
  256. package/src/functions/wirings/mcp/serialize-mcp-json.ts +8 -6
  257. package/src/functions/wirings/mcp/serialize-mcp-types.ts +68 -16
  258. package/src/functions/wirings/middleware/pikku-command-middleware.ts +6 -2
  259. package/src/functions/wirings/package/pikku-command-package.ts +81 -0
  260. package/src/functions/wirings/package/serialize-package.ts +69 -0
  261. package/src/functions/wirings/queue/pikku-command-queue.ts +22 -2
  262. package/src/functions/wirings/queue/pikku-queue.ts +1 -10
  263. package/src/functions/wirings/queue/serialize-queue-map.ts +18 -3
  264. package/src/functions/wirings/queue/serialize-queue-meta.ts +1 -1
  265. package/src/functions/wirings/rpc/pikku-command-rpc-map.ts +7 -4
  266. package/src/functions/wirings/rpc/pikku-command-rpc.ts +1 -1
  267. package/src/functions/wirings/rpc/serialize-remote-rpc.ts +3 -0
  268. package/src/functions/wirings/rpc/serialize-rpc-wrapper.ts +1 -1
  269. package/src/functions/wirings/rpc/serialize-typed-rpc-map.ts +74 -8
  270. package/src/functions/wirings/scheduler/pikku-command-scheduler.ts +22 -1
  271. package/src/functions/wirings/scheduler/serialize-scheduler-meta.ts +1 -1
  272. package/src/functions/wirings/workflow/pikku-command-workflow.ts +104 -37
  273. package/src/functions/wirings/workflow/serialize-workflow-map.ts +38 -40
  274. package/src/functions/wirings/workflow/serialize-workflow-meta.ts +66 -26
  275. package/src/functions/wirings/workflow/serialize-workflow-registration.ts +83 -0
  276. package/src/functions/wirings/workflow/serialize-workflow-types.ts +299 -45
  277. package/src/functions/wirings/workflow/serialize-workflow-workers.ts +14 -27
  278. package/src/services.ts +8 -1
  279. package/src/utils/command-summary.ts +4 -0
  280. package/src/utils/custom-types-generator.ts +15 -15
  281. package/src/utils/generate-bootstrap-file.ts +1 -1
  282. package/src/utils/pikku-cli-config.ts +51 -18
  283. package/src/utils/schema-generator.ts +185 -22
  284. package/src/utils/strip-verbose-meta.ts +254 -0
  285. package/types/config.d.ts +37 -3
  286. package/.pikku/function/pikku-functions-meta.min.gen.json +0 -212
  287. package/.pikku/function/pikku-functions-meta.min.gen.ts +0 -6
  288. package/dist/.pikku/function/pikku-functions-meta.min.gen.d.ts +0 -1
  289. package/dist/.pikku/function/pikku-functions-meta.min.gen.js +0 -6
  290. package/dist/.pikku/function/pikku-functions-meta.min.gen.json +0 -212
  291. package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.d.ts +0 -1
  292. package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.js +0 -12
  293. package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.d.ts +0 -1
  294. package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.js +0 -13
  295. package/dist/src/functions/wirings/workflow/serialize-workflow-wirings.d.ts +0 -8
  296. package/dist/src/functions/wirings/workflow/serialize-workflow-wirings.js +0 -30
  297. package/src/functions/wirings/workflow/pikku-command-workflow-map.ts +0 -24
  298. package/src/functions/wirings/workflow/pikku-command-workflow-types.ts +0 -29
  299. package/src/functions/wirings/workflow/serialize-workflow-wirings.ts +0 -47
  300. /package/.pikku/{workflow/pikku-workflow-wirings-meta.gen.json → channel/pikku-channels-meta.gen.json} +0 -0
  301. /package/dist/.pikku/{workflow/pikku-workflow-wirings-meta.gen.json → channel/pikku-channels-meta.gen.json} +0 -0
@@ -64,6 +64,10 @@ const _getPikkuCLIConfig = async (
64
64
  ...extendedConfig.packageMappings,
65
65
  ...config.packageMappings,
66
66
  },
67
+ externalPackages: {
68
+ ...extendedConfig.externalPackages,
69
+ ...config.externalPackages,
70
+ },
67
71
  ignoreFiles: config.ignoreFiles ??
68
72
  extendedConfig.ignoreFiles ?? [
69
73
  '**/*.test.ts',
@@ -83,6 +87,7 @@ const _getPikkuCLIConfig = async (
83
87
  ...config,
84
88
  configDir,
85
89
  packageMappings: config.packageMappings || {},
90
+ externalPackages: config.externalPackages || {},
86
91
  rootDir: config.rootDir
87
92
  ? resolve(configDir, config.rootDir)
88
93
  : configDir,
@@ -134,18 +139,6 @@ const _getPikkuCLIConfig = async (
134
139
  'pikku-functions-meta.gen.json'
135
140
  )
136
141
  }
137
- if (!result.functionsMetaMinFile) {
138
- result.functionsMetaMinFile = join(
139
- functionDir,
140
- 'pikku-functions-meta.min.gen.ts'
141
- )
142
- }
143
- if (!result.functionsMetaMinJsonFile) {
144
- result.functionsMetaMinJsonFile = join(
145
- functionDir,
146
- 'pikku-functions-meta.min.gen.json'
147
- )
148
- }
149
142
  if (!result.functionTypesFile) {
150
143
  result.functionTypesFile = join(
151
144
  functionDir,
@@ -316,12 +309,6 @@ const _getPikkuCLIConfig = async (
316
309
  'pikku-workflow-wirings-meta.gen.ts'
317
310
  )
318
311
  }
319
- if (!result.workflowsWiringMetaJsonFile) {
320
- result.workflowsWiringMetaJsonFile = join(
321
- workflowDir,
322
- 'pikku-workflow-wirings-meta.gen.json'
323
- )
324
- }
325
312
  if (!result.workflowsWorkersFile) {
326
313
  result.workflowsWorkersFile = join(
327
314
  workflowDir,
@@ -341,6 +328,11 @@ const _getPikkuCLIConfig = async (
341
328
  )
342
329
  }
343
330
 
331
+ // Workflow meta directory (individual JSON files for each workflow)
332
+ if (!result.workflowMetaDir) {
333
+ result.workflowMetaDir = join(workflowDir, 'meta')
334
+ }
335
+
344
336
  // Services
345
337
  if (!result.servicesFile) {
346
338
  result.servicesFile = join(result.outDir, 'pikku-services.gen.ts')
@@ -374,6 +366,11 @@ const _getPikkuCLIConfig = async (
374
366
  result.bootstrapFile = join(result.outDir, 'pikku-bootstrap.gen.ts')
375
367
  }
376
368
 
369
+ // Package service factories (for external packages)
370
+ if (!result.packageFile) {
371
+ result.packageFile = join(result.outDir, 'pikku-package.gen.ts')
372
+ }
373
+
377
374
  // MCP
378
375
  if (!result.mcpWiringsMetaFile) {
379
376
  result.mcpWiringsMetaFile = join(mcpDir, 'pikku-mcp-wirings-meta.gen.ts')
@@ -414,6 +411,18 @@ const _getPikkuCLIConfig = async (
414
411
  result.cliTypesFile = join(cliDir, 'pikku-cli-types.gen.ts')
415
412
  }
416
413
 
414
+ // Forge
415
+ const forgeDir = join(result.outDir, 'forge')
416
+ if (!result.forgeNodesMetaJsonFile) {
417
+ result.forgeNodesMetaJsonFile = join(
418
+ forgeDir,
419
+ 'pikku-forge-nodes-meta.gen.json'
420
+ )
421
+ }
422
+ if (!result.forgeTypesFile) {
423
+ result.forgeTypesFile = join(forgeDir, 'pikku-forge-types.gen.ts')
424
+ }
425
+
417
426
  if (requiredFields.length > 0) {
418
427
  validateCLIConfig(result, requiredFields)
419
428
  }
@@ -436,6 +445,30 @@ const _getPikkuCLIConfig = async (
436
445
  result.tsconfig = join(result.rootDir, result.tsconfig)
437
446
  }
438
447
 
448
+ if (result.externalPackage) {
449
+ const packageJsonPath = join(result.rootDir, 'package.json')
450
+ try {
451
+ const packageJsonContent = await readFile(packageJsonPath, 'utf-8')
452
+ const packageJson = JSON.parse(packageJsonContent)
453
+
454
+ if (
455
+ !packageJson.name ||
456
+ typeof packageJson.name !== 'string' ||
457
+ packageJson.name.trim() === ''
458
+ ) {
459
+ throw new Error(
460
+ `package.json at ${packageJsonPath} is missing a valid "name" field`
461
+ )
462
+ }
463
+
464
+ result.externalPackageName = packageJson.name
465
+ } catch (e: any) {
466
+ throw new Error(
467
+ `externalPackage is true but could not read or parse package.json at ${packageJsonPath}: ${e.message}`
468
+ )
469
+ }
470
+ }
471
+
439
472
  return result
440
473
  } catch (e: any) {
441
474
  logger.error(e)
@@ -3,8 +3,88 @@ import { writeFileInDir } from './file-writer.js'
3
3
  import { mkdir, writeFile } from 'fs/promises'
4
4
  import { FunctionsMeta, JSONValue } from '@pikku/core'
5
5
  import { HTTPWiringsMeta } from '@pikku/core/http'
6
- import { TypesMap, ErrorCode } from '@pikku/inspector'
6
+ import { TypesMap, ErrorCode, ZodSchemaRef } from '@pikku/inspector'
7
7
  import { CLILogger } from '../services/cli-logger.service.js'
8
+ import { tsImport } from 'tsx/esm/api'
9
+ import * as z from 'zod'
10
+ import { zodToTs, createAuxiliaryTypeStore } from 'zod-to-ts'
11
+ import {
12
+ createPrinter,
13
+ createSourceFile,
14
+ EmitHint,
15
+ ScriptKind,
16
+ ScriptTarget,
17
+ } from 'typescript'
18
+
19
+ /**
20
+ * Convert a name to a valid JavaScript identifier.
21
+ * Replaces hyphens and other invalid characters with underscores.
22
+ */
23
+ function toValidIdentifier(name: string): string {
24
+ let result = name.replace(/[-./]/g, '_')
25
+ if (/^\d/.test(result)) {
26
+ result = '_' + result
27
+ }
28
+ return result
29
+ }
30
+
31
+ const PRIMITIVE_TYPES = new Set([
32
+ 'boolean',
33
+ 'string',
34
+ 'number',
35
+ 'null',
36
+ 'undefined',
37
+ 'void',
38
+ 'any',
39
+ 'unknown',
40
+ 'never',
41
+ ])
42
+
43
+ /** Map TypeScript type strings to JSON Schema. Returns null if no schema should be generated. */
44
+ function primitiveTypeToSchema(typeStr: string): JSONValue | null {
45
+ const normalized = typeStr.trim()
46
+
47
+ // void/undefined/never mean no data - don't generate a schema
48
+ if (
49
+ normalized === 'void' ||
50
+ normalized === 'undefined' ||
51
+ normalized === 'never'
52
+ ) {
53
+ return null
54
+ }
55
+
56
+ // Handle boolean literals
57
+ if (
58
+ normalized === 'boolean' ||
59
+ normalized === 'false | true' ||
60
+ normalized === 'true | false'
61
+ ) {
62
+ return { type: 'boolean' }
63
+ }
64
+ if (normalized === 'true') {
65
+ return { const: true }
66
+ }
67
+ if (normalized === 'false') {
68
+ return { const: false }
69
+ }
70
+
71
+ // Handle string
72
+ if (normalized === 'string') {
73
+ return { type: 'string' }
74
+ }
75
+
76
+ // Handle number
77
+ if (normalized === 'number') {
78
+ return { type: 'number' }
79
+ }
80
+
81
+ // Handle null
82
+ if (normalized === 'null') {
83
+ return { type: 'null' }
84
+ }
85
+
86
+ return null
87
+ }
8
88
 
9
89
  export async function generateSchemas(
10
90
  logger: CLILogger,
@@ -13,7 +93,8 @@ export async function generateSchemas(
13
93
  functionMeta: FunctionsMeta,
14
94
  httpWiringsMeta: HTTPWiringsMeta,
15
95
  additionalTypes?: string[],
16
- additionalProperties: boolean = false
96
+ additionalProperties: boolean = false,
97
+ zodLookup?: Map<string, ZodSchemaRef>
17
98
  ): Promise<Record<string, JSONValue>> {
18
99
  const schemasSet = new Set(typesMap.customTypes.keys())
19
100
  for (const { inputs, outputs } of Object.values(functionMeta)) {
@@ -44,7 +125,6 @@ export async function generateSchemas(
44
125
  }
45
126
  }
46
127
 
47
- // Add additional types from schemasFromTypes config
48
128
  if (additionalTypes) {
49
129
  for (const type of additionalTypes) {
50
130
  schemasSet.add(type)
@@ -66,18 +146,28 @@ export async function generateSchemas(
66
146
  const schemas: Record<string, JSONValue> = {}
67
147
 
68
148
  schemasSet.forEach((schema) => {
149
+ if (PRIMITIVE_TYPES.has(schema)) {
150
+ return
151
+ }
152
+ if (zodLookup?.has(schema)) {
153
+ return
154
+ }
69
155
  try {
70
156
  schemas[schema] = generator.createSchema(schema) as JSONValue
71
157
  } catch (e) {
72
- // Ignore rootless errors
73
158
  if (e instanceof RootlessError) {
74
- logger.error(
75
- `[${ErrorCode.SCHEMA_NO_ROOT}] Error generating schema since it has no root: ${schema}`
76
- )
159
+ const customType = typesMap.customTypes.get(schema)
160
+ if (customType) {
161
+ const primitiveSchema = primitiveTypeToSchema(customType.type)
162
+ if (primitiveSchema) {
163
+ schemas[schema] = primitiveSchema
164
+ }
165
+ }
77
166
  return
78
167
  }
168
+ const customType = typesMap.customTypes.get(schema)
79
169
  logger.error(
80
- `[${ErrorCode.SCHEMA_GENERATION_ERROR}] Error generating schema: ${schema}. Message: ${e.message}`
170
+ `[${ErrorCode.SCHEMA_GENERATION_ERROR}] Error generating schema: ${schema}. Message: ${e.message}. Type info: ${customType ? `type=${customType.type}` : 'not in typesMap'}`
81
171
  )
82
172
  }
83
173
  })
@@ -85,6 +175,68 @@ export async function generateSchemas(
85
175
  return schemas
86
176
  }
87
177
 
178
+ export async function generateZodSchemas(
179
+ logger: CLILogger,
180
+ zodLookup: Map<string, ZodSchemaRef>,
181
+ typesMap: TypesMap
182
+ ): Promise<Record<string, JSONValue>> {
183
+ const schemas: Record<string, JSONValue> = {}
184
+ const auxiliaryTypeStore = createAuxiliaryTypeStore()
185
+ const printer = createPrinter()
186
+ const fakeSourceFile = createSourceFile(
187
+ 'zod-types.ts',
188
+ '',
189
+ ScriptTarget.ESNext,
190
+ false,
191
+ ScriptKind.TS
192
+ )
193
+
194
+ for (const [schemaName, ref] of zodLookup.entries()) {
195
+ try {
196
+ const module = await tsImport(ref.sourceFile, import.meta.url)
197
+ const zodSchema = module[ref.variableName]
198
+ if (!zodSchema) {
199
+ logger.warn(
200
+ `Could not find exported schema '${ref.variableName}' in ${ref.sourceFile} for ${schemaName}. Available exports: ${Object.keys(module).join(', ')}`
201
+ )
202
+ continue
203
+ }
204
+
205
+ const schema = z.toJSONSchema(zodSchema) as any
206
+
207
+ // Remove fields with defaults from the required array
208
+ // Fields with defaults are semantically optional in input validation
209
+ if (schema.required && schema.properties) {
210
+ schema.required = schema.required.filter((fieldName: string) => {
211
+ const prop = schema.properties[fieldName]
212
+ return prop && prop.default === undefined
213
+ })
214
+ if (schema.required.length === 0) {
215
+ delete schema.required
216
+ }
217
+ }
218
+
219
+ schemas[schemaName] = schema
220
+ const { node: tsType } = zodToTs(zodSchema, { auxiliaryTypeStore })
221
+
222
+ const typeText = printer.printNode(
223
+ EmitHint.Unspecified,
224
+ tsType,
225
+ fakeSourceFile
226
+ )
227
+
228
+ typesMap.addCustomType(schemaName, typeText, [])
229
+ logger.info(`• Generated schema from Zod: ${schemaName}`)
230
+ } catch (e) {
231
+ logger.warn(
232
+ `Could not convert Zod schema '${schemaName}': ${e instanceof Error ? e.message : e}`
233
+ )
234
+ }
235
+ }
236
+
237
+ return schemas
238
+ }
239
+
88
240
  export async function saveSchemas(
89
241
  logger: CLILogger,
90
242
  schemaParentDir: string,
@@ -92,7 +244,9 @@ export async function saveSchemas(
92
244
  typesMap: TypesMap,
93
245
  functionsMeta: FunctionsMeta,
94
246
  supportsImportAttributes: boolean,
95
- additionalTypes?: string[]
247
+ additionalTypes?: string[],
248
+ zodLookup?: Map<string, ZodSchemaRef>,
249
+ packageName?: string | null
96
250
  ) {
97
251
  await writeFileInDir(
98
252
  logger,
@@ -108,26 +262,25 @@ export async function saveSchemas(
108
262
  try {
109
263
  types.push(typesMap.getUniqueName(inputs[0]))
110
264
  } catch {
111
- // Skip types not in typesMap (e.g., inline types in generated workflow workers)
265
+ // Skip types not in typesMap - might be a zod schema name
266
+ types.push(inputs[0])
112
267
  }
113
268
  }
114
269
  if (outputs?.[0]) {
115
270
  try {
116
271
  types.push(typesMap.getUniqueName(outputs[0]))
117
272
  } catch {
118
- // Skip types not in typesMap (e.g., inline types in generated workflow workers)
273
+ // Skip types not in typesMap - might be a zod schema name
274
+ types.push(outputs[0])
119
275
  }
120
276
  }
121
277
  return types
122
278
  })
123
279
  .flat()
124
- .filter(
125
- (s): s is string =>
126
- !!s &&
127
- !['boolean', 'string', 'number', 'null', 'undefined'].includes(s)
128
- ),
280
+ .filter((s): s is string => !!s && !PRIMITIVE_TYPES.has(s)),
129
281
  ...typesMap.customTypes.keys(),
130
282
  ...(additionalTypes || []),
283
+ ...(zodLookup ? Array.from(zodLookup.keys()) : []),
131
284
  ])
132
285
 
133
286
  if (desiredSchemas.size === 0) {
@@ -153,19 +306,29 @@ export async function saveSchemas(
153
306
  (schema) => schemas[schema]
154
307
  )
155
308
 
309
+ // Generate the packageName argument for addSchema calls
310
+ const packageNameArg = packageName ? `, '${packageName}'` : ''
311
+
156
312
  const schemaImports = availableSchemas
157
- .map(
158
- (schema) => `
159
- import * as ${schema} from './schemas/${schema}.schema.json' ${supportsImportAttributes ? `with { type: 'json' }` : ''}
160
- addSchema('${schema}', ${schema})
313
+ .map((schema) => {
314
+ const identifier = toValidIdentifier(schema)
315
+ return `
316
+ import * as ${identifier} from './schemas/${schema}.schema.json' ${supportsImportAttributes ? `with { type: 'json' }` : ''}
317
+ addSchema('${schema}', ${identifier}${packageNameArg})
161
318
  `
162
- )
319
+ })
163
320
  .join('\n')
164
321
 
322
+ // Only import addSchema if there are schemas to register
323
+ const importStatement =
324
+ availableSchemas.length > 0
325
+ ? `import { addSchema } from '@pikku/core/schema'`
326
+ : '// No schemas to register'
327
+
165
328
  await writeFileInDir(
166
329
  logger,
167
330
  `${schemaParentDir}/register.gen.ts`,
168
- `import { addSchema } from '@pikku/core/schema'
331
+ `${importStatement}
169
332
  ${schemaImports}`,
170
333
  { logWrite: true }
171
334
  )
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Utility functions to strip verbose/visualization-only fields from meta objects
3
+ * for creating minimal runtime-only versions.
4
+ *
5
+ * Verbose fields are those used for UI/visualization but not needed at runtime:
6
+ * - tags, description, summary, errors
7
+ * - title, displayName
8
+ * - usedWires, isDirectFunction, services
9
+ * - stepName (in workflow nodes)
10
+ *
11
+ * Note: middleware and permissions are NOT verbose - they're needed at runtime
12
+ * for resolving tag middleware and permissions in function-runner.ts
13
+ *
14
+ * IMPORTANT: We only strip verbose fields at the direct meta entry level.
15
+ * For most meta types (HTTP, Queue, Scheduler, etc.), entries have pikkuFuncName.
16
+ * For workflow graphs, we strip at the root level AND from nodes.
17
+ * We do NOT strip from deeply nested structures like CLI options where 'description' is required.
18
+ */
19
+
20
+ const VERBOSE_FIELDS = new Set([
21
+ 'tags',
22
+ 'description',
23
+ 'summary',
24
+ 'errors',
25
+ 'title',
26
+ 'displayName',
27
+ // Note: middleware and permissions are NOT verbose - they're needed at runtime
28
+ // for resolving tag middleware and permissions in function-runner.ts
29
+ 'usedWires',
30
+ 'isDirectFunction',
31
+ 'services',
32
+ ])
33
+
34
+ /**
35
+ * Fields that are verbose only at the node level (workflow nodes)
36
+ */
37
+ const NODE_VERBOSE_FIELDS = new Set(['stepName'])
38
+
39
+ /**
40
+ * Strip verbose fields from an object (shallow - only direct properties)
41
+ */
42
+ function stripVerboseShallow<T>(obj: T, additionalFields?: Set<string>): T {
43
+ if (
44
+ obj === null ||
45
+ obj === undefined ||
46
+ typeof obj !== 'object' ||
47
+ Array.isArray(obj)
48
+ ) {
49
+ return obj
50
+ }
51
+
52
+ const result: Record<string, unknown> = {}
53
+ const fieldsToStrip = additionalFields
54
+ ? new Set([...VERBOSE_FIELDS, ...additionalFields])
55
+ : VERBOSE_FIELDS
56
+
57
+ for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {
58
+ if (fieldsToStrip.has(key)) {
59
+ continue
60
+ }
61
+ result[key] = value
62
+ }
63
+
64
+ return result as T
65
+ }
66
+
67
+ /**
68
+ * Check if an object has any verbose fields (shallow check)
69
+ */
70
+ function hasVerboseShallow(
71
+ obj: unknown,
72
+ additionalFields?: Set<string>
73
+ ): boolean {
74
+ if (
75
+ obj === null ||
76
+ obj === undefined ||
77
+ typeof obj !== 'object' ||
78
+ Array.isArray(obj)
79
+ ) {
80
+ return false
81
+ }
82
+
83
+ const fieldsToCheck = additionalFields
84
+ ? new Set([...VERBOSE_FIELDS, ...additionalFields])
85
+ : VERBOSE_FIELDS
86
+
87
+ for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {
88
+ if (fieldsToCheck.has(key) && value !== undefined) {
89
+ return true
90
+ }
91
+ }
92
+
93
+ return false
94
+ }
95
+
96
+ /**
97
+ * Strip verbose fields from a meta object.
98
+ *
99
+ * Handles different meta structure patterns:
100
+ * 1. Single workflow graph: { name, pikkuFuncName, nodes: {...}, description, tags }
101
+ * -> Strips description, tags at root; strips stepName from each node
102
+ * 2. Record of meta entries: { "entryName": { pikkuFuncName, description, tags, ... } }
103
+ * -> Strips description, tags from each entry (one level deep only)
104
+ * 3. CLI meta and others with complex nesting: preserved as-is except for pikkuFuncName entries
105
+ */
106
+ export function stripVerboseFields<T>(obj: T): T {
107
+ if (obj === null || obj === undefined || typeof obj !== 'object') {
108
+ return obj
109
+ }
110
+
111
+ if (Array.isArray(obj)) {
112
+ // Array of entries - strip from each
113
+ return obj.map((item) => {
114
+ if (
115
+ typeof item === 'object' &&
116
+ item !== null &&
117
+ 'pikkuFuncName' in (item as Record<string, unknown>)
118
+ ) {
119
+ return stripVerboseShallow(item)
120
+ }
121
+ return item
122
+ }) as T
123
+ }
124
+
125
+ const objRecord = obj as Record<string, unknown>
126
+
127
+ // Case 1: Single workflow graph (has 'nodes' and 'pikkuFuncName' at root)
128
+ if ('nodes' in objRecord && 'pikkuFuncName' in objRecord) {
129
+ const result: Record<string, unknown> = {}
130
+
131
+ for (const [key, value] of Object.entries(objRecord)) {
132
+ if (VERBOSE_FIELDS.has(key)) {
133
+ continue
134
+ }
135
+
136
+ if (key === 'nodes' && typeof value === 'object' && value !== null) {
137
+ // Strip stepName from each node
138
+ const nodes: Record<string, unknown> = {}
139
+ for (const [nodeId, node] of Object.entries(
140
+ value as Record<string, unknown>
141
+ )) {
142
+ nodes[nodeId] = stripVerboseShallow(node, NODE_VERBOSE_FIELDS)
143
+ }
144
+ result[key] = nodes
145
+ } else {
146
+ result[key] = value
147
+ }
148
+ }
149
+
150
+ return result as T
151
+ }
152
+
153
+ // Case 2: Record of meta entries (each entry has pikkuFuncName)
154
+ // Only strip at exactly one level deep - the immediate children
155
+ const result: Record<string, unknown> = {}
156
+
157
+ for (const [key, value] of Object.entries(objRecord)) {
158
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
159
+ const valueObj = value as Record<string, unknown>
160
+ // Only strip from entries that look like meta entries (have pikkuFuncName)
161
+ if ('pikkuFuncName' in valueObj) {
162
+ result[key] = stripVerboseShallow(value)
163
+ } else {
164
+ // Keep nested structures as-is (e.g., CLI programs, options)
165
+ result[key] = value
166
+ }
167
+ } else {
168
+ result[key] = value
169
+ }
170
+ }
171
+
172
+ return result as T
173
+ }
174
+
175
+ /**
176
+ * Check if an object has any verbose fields that would be stripped
177
+ */
178
+ export function hasVerboseFields(obj: unknown): boolean {
179
+ if (obj === null || obj === undefined || typeof obj !== 'object') {
180
+ return false
181
+ }
182
+
183
+ if (Array.isArray(obj)) {
184
+ return obj.some((item) => {
185
+ if (
186
+ typeof item === 'object' &&
187
+ item !== null &&
188
+ 'pikkuFuncName' in (item as Record<string, unknown>)
189
+ ) {
190
+ return hasVerboseShallow(item)
191
+ }
192
+ return false
193
+ })
194
+ }
195
+
196
+ const objRecord = obj as Record<string, unknown>
197
+
198
+ // Case 1: Single workflow graph
199
+ if ('nodes' in objRecord && 'pikkuFuncName' in objRecord) {
200
+ // Check root level
201
+ if (hasVerboseShallow(objRecord)) {
202
+ return true
203
+ }
204
+ // Check nodes for stepName
205
+ const nodes = objRecord.nodes
206
+ if (typeof nodes === 'object' && nodes !== null) {
207
+ for (const node of Object.values(nodes as Record<string, unknown>)) {
208
+ if (hasVerboseShallow(node, NODE_VERBOSE_FIELDS)) {
209
+ return true
210
+ }
211
+ }
212
+ }
213
+ return false
214
+ }
215
+
216
+ // Case 2: Record of meta entries
217
+ for (const value of Object.values(objRecord)) {
218
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
219
+ const valueObj = value as Record<string, unknown>
220
+ if ('pikkuFuncName' in valueObj && hasVerboseShallow(value)) {
221
+ return true
222
+ }
223
+ }
224
+ }
225
+
226
+ return false
227
+ }
228
+
229
+ /**
230
+ * Write both minimal and verbose meta files
231
+ * Only writes verbose file if it differs from minimal
232
+ *
233
+ * @returns Object with paths that were written
234
+ */
235
+ export async function writeMetaFiles(
236
+ writeFile: (path: string, content: string) => Promise<void>,
237
+ basePath: string,
238
+ meta: unknown
239
+ ): Promise<{ minimal: string; verbose?: string }> {
240
+ const minimalMeta = stripVerboseFields(meta)
241
+ const minimalPath = basePath.replace(/\.gen\.json$/, '.gen.json')
242
+ const verbosePath = basePath.replace(/\.gen\.json$/, '-verbose.gen.json')
243
+
244
+ // Always write minimal
245
+ await writeFile(minimalPath, JSON.stringify(minimalMeta, null, 2))
246
+
247
+ // Only write verbose if it has additional fields
248
+ if (hasVerboseFields(meta)) {
249
+ await writeFile(verbosePath, JSON.stringify(meta, null, 2))
250
+ return { minimal: minimalPath, verbose: verbosePath }
251
+ }
252
+
253
+ return { minimal: minimalPath }
254
+ }