@pikku/cli 0.10.1 → 0.11.0

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 (214) hide show
  1. package/.pikku/channel/pikku-channel-types.gen.ts +4 -3
  2. package/.pikku/channel/pikku-channels-map.gen.d.ts +5 -2
  3. package/.pikku/channel/pikku-channels-meta.gen.ts +1 -1
  4. package/.pikku/channel/pikku-channels.gen.ts +1 -1
  5. package/.pikku/cli/pikku-cli-types.gen.ts +23 -1
  6. package/.pikku/cli/pikku-cli-wirings-meta.gen.ts +8 -116
  7. package/.pikku/cli/pikku-cli-wirings.gen.ts +2 -3
  8. package/.pikku/function/pikku-function-types.gen.ts +1 -1
  9. package/.pikku/function/pikku-functions-meta.gen.ts +265 -138
  10. package/.pikku/function/pikku-functions-meta.min.gen.ts +62 -32
  11. package/.pikku/function/pikku-functions.gen.ts +9 -1
  12. package/.pikku/http/pikku-http-types.gen.ts +1 -1
  13. package/.pikku/http/pikku-http-wirings-map.gen.d.ts +5 -2
  14. package/.pikku/http/pikku-http-wirings-meta.gen.ts +1 -1
  15. package/.pikku/http/pikku-http-wirings.gen.ts +1 -1
  16. package/.pikku/mcp/pikku-mcp-types.gen.ts +1 -1
  17. package/.pikku/mcp/pikku-mcp-wirings-meta.gen.ts +1 -1
  18. package/.pikku/mcp/pikku-mcp-wirings.gen.ts +1 -1
  19. package/.pikku/pikku-bootstrap.gen.ts +4 -1
  20. package/.pikku/pikku-services.gen.ts +21 -12
  21. package/.pikku/pikku-types.gen.ts +1 -1
  22. package/.pikku/pikku-websocket.gen.ts +15 -1
  23. package/.pikku/queue/pikku-queue-types.gen.ts +1 -1
  24. package/.pikku/queue/pikku-queue-workers-wirings-map.gen.d.ts +5 -2
  25. package/.pikku/queue/pikku-queue-workers-wirings-meta.gen.ts +7 -2
  26. package/.pikku/queue/pikku-queue-workers-wirings.gen.ts +1 -1
  27. package/.pikku/rpc/pikku-remote-rpc-workers.gen.ts +27 -0
  28. package/.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts +13 -3
  29. package/.pikku/rpc/pikku-rpc-wirings-map.internal.gen.d.ts +26 -10
  30. package/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.ts +15 -9
  31. package/.pikku/scheduler/pikku-scheduler-types.gen.ts +1 -1
  32. package/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.ts +1 -1
  33. package/.pikku/scheduler/pikku-schedulers-wirings.gen.ts +1 -1
  34. package/.pikku/schemas/register.gen.ts +17 -5
  35. package/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  36. package/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
  37. package/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -0
  38. package/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -0
  39. package/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
  40. package/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -0
  41. package/.pikku/workflow/pikku-workflow-map.gen.d.ts +62 -0
  42. package/.pikku/workflow/pikku-workflow-types.gen.ts +92 -0
  43. package/.pikku/workflow/pikku-workflow-wirings-meta.gen.ts +5 -0
  44. package/.pikku/workflow/pikku-workflow-wirings.gen.ts +4 -0
  45. package/CHANGELOG.md +57 -0
  46. package/bin/pikku.ts +30 -21
  47. package/cli.schema.json +1 -1
  48. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +4 -3
  49. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  50. package/dist/.pikku/channel/pikku-channels-meta.gen.js +1 -1
  51. package/dist/.pikku/channel/pikku-channels.gen.d.ts +1 -1
  52. package/dist/.pikku/channel/pikku-channels.gen.js +1 -1
  53. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +18 -1
  54. package/dist/.pikku/cli/pikku-cli-types.gen.js +20 -1
  55. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +8 -116
  56. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -2
  57. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -2
  58. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  59. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  60. package/dist/.pikku/function/pikku-functions-meta.gen.js +265 -138
  61. package/dist/.pikku/function/pikku-functions-meta.min.gen.js +62 -32
  62. package/dist/.pikku/function/pikku-functions.gen.js +9 -1
  63. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  64. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  65. package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
  66. package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
  67. package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
  68. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  69. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  70. package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.js +1 -1
  71. package/dist/.pikku/mcp/pikku-mcp-wirings.gen.d.ts +1 -1
  72. package/dist/.pikku/mcp/pikku-mcp-wirings.gen.js +1 -1
  73. package/dist/.pikku/pikku-bootstrap.gen.d.ts +4 -1
  74. package/dist/.pikku/pikku-bootstrap.gen.js +4 -1
  75. package/dist/.pikku/pikku-services.gen.d.ts +15 -6
  76. package/dist/.pikku/pikku-services.gen.js +14 -2
  77. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  78. package/dist/.pikku/pikku-types.gen.js +1 -1
  79. package/dist/.pikku/pikku-websocket.gen.d.ts +15 -1
  80. package/dist/.pikku/pikku-websocket.gen.js +15 -1
  81. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  82. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  83. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +7 -2
  84. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  85. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  86. package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.d.ts +17 -0
  87. package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.js +22 -0
  88. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +15 -9
  89. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  90. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  91. package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.js +1 -1
  92. package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.d.ts +1 -1
  93. package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.js +1 -1
  94. package/dist/.pikku/schemas/register.gen.js +9 -3
  95. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  96. package/dist/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
  97. package/dist/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -0
  98. package/dist/.pikku/schemas/schemas/PikkuRemoteInternalRPCInput.schema.json +1 -0
  99. package/dist/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -0
  100. package/dist/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
  101. package/dist/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -0
  102. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +58 -0
  103. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +28 -0
  104. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +5 -0
  105. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.d.ts +4 -0
  106. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +5 -0
  107. package/dist/bin/pikku.js +24 -19
  108. package/dist/src/cli.wiring.js +107 -99
  109. package/dist/src/functions/commands/all.js +51 -2
  110. package/dist/src/functions/commands/bootstrap.d.ts +1 -0
  111. package/dist/src/functions/commands/bootstrap.js +24 -0
  112. package/dist/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.js +46 -2
  113. package/dist/src/functions/wirings/channels/serialize-channel-types.js +3 -2
  114. package/dist/src/functions/wirings/channels/serialize-websocket-wrapper.js +14 -0
  115. package/dist/src/functions/wirings/cli/pikku-command-cli-entry.js +4 -4
  116. package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +20 -7
  117. package/dist/src/functions/wirings/cli/serialize-channel-cli.js +32 -7
  118. package/dist/src/functions/wirings/cli/serialize-cli-types.js +22 -0
  119. package/dist/src/functions/wirings/functions/pikku-command-services.d.ts +1 -1
  120. package/dist/src/functions/wirings/functions/pikku-command-services.js +54 -26
  121. package/dist/src/functions/wirings/functions/schemas.js +2 -2
  122. package/dist/src/functions/wirings/http/pikku-command-openapi.js +1 -1
  123. package/dist/src/functions/wirings/middleware/pikku-command-middleware.js +3 -10
  124. package/dist/src/functions/wirings/queue/pikku-queue.js +9 -1
  125. package/dist/src/functions/wirings/queue/serialize-queue-map.d.ts +2 -2
  126. package/dist/src/functions/wirings/queue/serialize-queue-meta.d.ts +2 -2
  127. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.d.ts +1 -0
  128. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +23 -0
  129. package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.d.ts +1 -0
  130. package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.js +23 -0
  131. package/dist/src/functions/wirings/rpc/serialize-public-rpc.d.ts +4 -0
  132. package/dist/src/functions/wirings/rpc/serialize-public-rpc.js +30 -0
  133. package/dist/src/functions/wirings/rpc/serialize-remote-rpc.d.ts +4 -0
  134. package/dist/src/functions/wirings/rpc/serialize-remote-rpc.js +30 -0
  135. package/dist/src/functions/wirings/rpc/serialize-rpc-wrapper.js +2 -2
  136. package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +27 -3
  137. package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.d.ts +1 -0
  138. package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.js +12 -0
  139. package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.d.ts +1 -0
  140. package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.js +11 -0
  141. package/dist/src/functions/wirings/workflow/pikku-command-workflow.d.ts +1 -0
  142. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +55 -0
  143. package/dist/src/functions/wirings/workflow/serialize-workflow-map.d.ts +4 -0
  144. package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +79 -0
  145. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.d.ts +2 -0
  146. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +10 -0
  147. package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +4 -0
  148. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +95 -0
  149. package/dist/src/functions/wirings/workflow/serialize-workflow-workers.d.ts +4 -0
  150. package/dist/src/functions/wirings/workflow/serialize-workflow-workers.js +60 -0
  151. package/dist/src/middleware/log-command-info-and-time.d.ts +1 -1
  152. package/dist/src/middleware/log-command-info-and-time.js +8 -5
  153. package/dist/src/services/cli-logger-forwarder.service.js +1 -1
  154. package/dist/src/services/cli-logger.service.d.ts +7 -2
  155. package/dist/src/services/cli-logger.service.js +17 -5
  156. package/dist/src/services.js +77 -12
  157. package/dist/src/utils/command-summary.d.ts +44 -0
  158. package/dist/src/utils/command-summary.js +74 -0
  159. package/dist/src/utils/file-writer.js +2 -2
  160. package/dist/src/utils/pikku-cli-config.js +48 -0
  161. package/dist/src/utils/schema-generator.d.ts +2 -2
  162. package/dist/src/utils/schema-generator.js +31 -10
  163. package/dist/tsconfig.tsbuildinfo +1 -1
  164. package/package.json +3 -4
  165. package/pikku.config.json +5 -2
  166. package/src/cli.wiring.ts +106 -101
  167. package/src/functions/commands/all.ts +66 -2
  168. package/src/functions/commands/bootstrap.ts +28 -0
  169. package/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.ts +46 -2
  170. package/src/functions/wirings/channels/serialize-channel-types.ts +3 -2
  171. package/src/functions/wirings/channels/serialize-websocket-wrapper.ts +14 -0
  172. package/src/functions/wirings/cli/pikku-command-cli-entry.ts +4 -4
  173. package/src/functions/wirings/cli/serialize-channel-cli-client.ts +20 -7
  174. package/src/functions/wirings/cli/serialize-channel-cli.ts +40 -8
  175. package/src/functions/wirings/cli/serialize-cli-types.ts +22 -0
  176. package/src/functions/wirings/functions/pikku-command-services.ts +57 -28
  177. package/src/functions/wirings/functions/schemas.ts +4 -3
  178. package/src/functions/wirings/http/pikku-command-openapi.ts +2 -1
  179. package/src/functions/wirings/middleware/pikku-command-middleware.ts +11 -22
  180. package/src/functions/wirings/queue/pikku-queue.ts +10 -1
  181. package/src/functions/wirings/queue/serialize-queue-map.ts +3 -3
  182. package/src/functions/wirings/queue/serialize-queue-meta.ts +2 -2
  183. package/src/functions/wirings/rpc/pikku-command-public-rpc.ts +32 -0
  184. package/src/functions/wirings/rpc/pikku-command-remote-rpc.ts +35 -0
  185. package/src/functions/wirings/rpc/serialize-public-rpc.ts +30 -0
  186. package/src/functions/wirings/rpc/serialize-remote-rpc.ts +30 -0
  187. package/src/functions/wirings/rpc/serialize-rpc-wrapper.ts +2 -2
  188. package/src/functions/wirings/rpc/serialize-typed-rpc-map.ts +26 -3
  189. package/src/functions/wirings/workflow/pikku-command-workflow-map.ts +24 -0
  190. package/src/functions/wirings/workflow/pikku-command-workflow-types.ts +22 -0
  191. package/src/functions/wirings/workflow/pikku-command-workflow.ts +123 -0
  192. package/src/functions/wirings/workflow/serialize-workflow-map.ts +123 -0
  193. package/src/functions/wirings/workflow/serialize-workflow-meta.ts +16 -0
  194. package/src/functions/wirings/workflow/serialize-workflow-types.ts +95 -0
  195. package/src/functions/wirings/workflow/serialize-workflow-workers.ts +60 -0
  196. package/src/middleware/log-command-info-and-time.ts +8 -5
  197. package/src/services/cli-logger-forwarder.service.ts +1 -1
  198. package/src/services/cli-logger.service.ts +21 -6
  199. package/src/services.ts +86 -11
  200. package/src/utils/command-summary.ts +103 -0
  201. package/src/utils/file-writer.ts +2 -2
  202. package/src/utils/pikku-cli-config.ts +68 -0
  203. package/src/utils/schema-generator.ts +30 -11
  204. package/types/application-types.d.ts +5 -1
  205. package/types/config.d.ts +61 -6
  206. package/.pikku/cli/pikku-cli-channel.gen.ts +0 -34
  207. package/.pikku/cli/pikku-cli-client.gen.ts +0 -43
  208. package/.pikku/cli/pikku-cli.gen.ts +0 -41
  209. package/dist/.pikku/cli/pikku-cli-channel.gen.js +0 -33
  210. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +0 -10
  211. package/dist/.pikku/cli/pikku-cli-client.gen.js +0 -34
  212. package/dist/.pikku/cli/pikku-cli.gen.d.ts +0 -10
  213. package/dist/.pikku/cli/pikku-cli.gen.js +0 -38
  214. /package/dist/.pikku/{cli/pikku-cli-channel.gen.d.ts → workflow/pikku-workflow-wirings-meta.gen.d.ts} +0 -0
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Generate queue workers and RPC functions for workflow steps and orchestrator
3
+ */
4
+ export const serializeWorkflowWorkers = (pathToPikkuTypes: string) => {
5
+ return `/**
6
+ * Auto-generated workflow queue workers and RPC functions
7
+ * Do not edit manually - regenerate with 'npx pikku'
8
+ */
9
+ import { pikkuSessionlessFunc, wireQueueWorker } from '${pathToPikkuTypes}'
10
+
11
+ /**
12
+ * Worker input types for generated queue workers
13
+ */
14
+ export type WorkflowStepInput = {
15
+ runId: string
16
+ stepName: string
17
+ rpcName: string
18
+ data: any
19
+ }
20
+
21
+ export const pikkuWorkflowWorker = pikkuSessionlessFunc<
22
+ WorkflowStepInput,
23
+ void
24
+ >({
25
+ func: async ({ workflowService, rpc }, { runId, stepName, rpcName, data }) => {
26
+ await workflowService!.executeWorkflowStep(runId, stepName, rpcName, data, rpc)
27
+ }
28
+ })
29
+
30
+ export const pikkuWorkflowOrchestrator = pikkuSessionlessFunc<
31
+ { runId: string },
32
+ void
33
+ >({
34
+ func: async ({ workflowService, rpc }, { runId }) => {
35
+ await workflowService!.orchestrateWorkflow(runId, rpc)
36
+ }
37
+ })
38
+
39
+ export const pikkuWorkflowSleeper = pikkuSessionlessFunc<
40
+ { runId: string, stepId: string },
41
+ void
42
+ >({
43
+ func: async ({ workflowService }, { runId, stepId }) => {
44
+ await workflowService!.executeWorkflowSleep(runId, stepId)
45
+ },
46
+ name: 'pikkuWorkflowStepSleeper',
47
+ internal: true,
48
+ })
49
+
50
+ wireQueueWorker({
51
+ queueName: 'pikku-workflow-step-worker',
52
+ func: pikkuWorkflowWorker,
53
+ })
54
+
55
+ wireQueueWorker({
56
+ queueName: 'pikku-workflow-orchestrator',
57
+ func: pikkuWorkflowOrchestrator,
58
+ })
59
+ `
60
+ }
@@ -15,21 +15,24 @@ export interface LogCommandInfoOptions {
15
15
 
16
16
  /**
17
17
  * Middleware to log command execution timing and status
18
- * Replaces the logCommandInfoAndTime wrapper function
18
+ * Uses debug level so it only shows with --verbose flag
19
19
  */
20
20
  export const logCommandInfoAndTime = ({
21
21
  commandStart,
22
22
  commandEnd,
23
23
  }: LogCommandInfoOptions): PikkuMiddleware => {
24
24
  return async ({ logger }, _interaction, next) => {
25
- // Log start
25
+ // Log start (debug level - only shows with --verbose)
26
26
  const start = Date.now()
27
- logger.info(`• ${commandStart}...`)
27
+ logger.debug(`• ${commandStart}...`)
28
28
 
29
29
  // Execute the function
30
30
  await next()
31
31
 
32
- // Log completion
33
- logger.info(`✓ ${commandEnd} in ${Date.now() - start}ms.`)
32
+ // Log completion (debug level - only shows with --verbose)
33
+ logger.debug({
34
+ type: 'success',
35
+ message: `✓ ${commandEnd} in ${Date.now() - start}ms.`,
36
+ })
34
37
  }
35
38
  }
@@ -78,7 +78,7 @@ export class CLILoggerForwarder implements Logger {
78
78
  }
79
79
 
80
80
  critical(code: ErrorCode, message: string) {
81
- const url = `https://pikku.dev/docs/cli-errors/${code.toLowerCase()}`
81
+ const url = `https://pikku.dev/docs/pikku-cli/errors/${code.toLowerCase()}`
82
82
  const formattedMessage = `[${code}] ${message}\n → ${url}`
83
83
  this.error(formattedMessage)
84
84
  }
@@ -11,11 +11,11 @@ const logo = `
11
11
  |_| |_|_| _)_| _)____/
12
12
  `
13
13
 
14
- const BASE_ERROR_URL = 'https://pikku.dev/errors'
14
+ const BASE_ERROR_URL = 'https://pikku.dev/docs/pikku-cli/errors'
15
15
 
16
16
  export class CLILogger implements Logger {
17
17
  private silent: boolean
18
- private level: LogLevel = LogLevel.info
18
+ private level: LogLevel = LogLevel.warn // default to warn level
19
19
  private criticalErrors: string[] = []
20
20
 
21
21
  constructor({
@@ -27,7 +27,7 @@ export class CLILogger implements Logger {
27
27
  }) {
28
28
  this.silent = silent
29
29
  if (logLogo && !silent) {
30
- this.logPikkuLogo()
30
+ this.logLogo()
31
31
  }
32
32
  }
33
33
 
@@ -35,6 +35,14 @@ export class CLILogger implements Logger {
35
35
  this.level = level
36
36
  }
37
37
 
38
+ setSilent(silent: boolean): void {
39
+ this.silent = silent
40
+ }
41
+
42
+ isSilent(): boolean {
43
+ return this.silent
44
+ }
45
+
38
46
  info(message: string | { message: string; type?: string }) {
39
47
  if (this.level > LogLevel.info || this.silent) return
40
48
 
@@ -59,9 +67,16 @@ export class CLILogger implements Logger {
59
67
  console.error(chalk.yellow(message))
60
68
  }
61
69
 
62
- debug(message: string) {
70
+ debug(message: string | { message: string; type?: string }) {
63
71
  if (this.level > LogLevel.debug || this.silent) return
64
- console.log(chalk.gray(message))
72
+
73
+ let c = chalk.gray
74
+ if (typeof message === 'object') {
75
+ if (message.type === 'success') {
76
+ c = chalk.green
77
+ }
78
+ }
79
+ console.log(c(typeof message === 'string' ? message : message.message))
65
80
  }
66
81
 
67
82
  critical(code: ErrorCode, message: string) {
@@ -75,7 +90,7 @@ export class CLILogger implements Logger {
75
90
  return this.criticalErrors.length > 0
76
91
  }
77
92
 
78
- private logPikkuLogo() {
93
+ logLogo() {
79
94
  this.primary(logo)
80
95
  // // When running from dist/, __filename is dist/src/services/cli-logger.service.js
81
96
  // // So we need to go up 3 levels: dist/src/services -> dist/src -> dist -> package.json
package/src/services.ts CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  CreateSingletonServices,
11
11
  } from '@pikku/core'
12
12
  import { pikkuCLIRender } from '@pikku/core/cli'
13
- import { LocalVariablesService } from '@pikku/core/services'
13
+ import { LocalVariablesService, LogLevel } from '@pikku/core/services'
14
14
  import { CLILogger } from './services/cli-logger.service.js'
15
15
  import { getPikkuCLIConfig } from './utils/pikku-cli-config.js'
16
16
  import {
@@ -20,6 +20,7 @@ import {
20
20
  serializeInspectorState,
21
21
  deserializeInspectorState,
22
22
  filterInspectorState,
23
+ getInitialInspectorState,
23
24
  } from '@pikku/inspector'
24
25
  import { glob } from 'tinyglobby'
25
26
  import path from 'path'
@@ -30,7 +31,9 @@ import {
30
31
  } from './services/cli-logger-forwarder.service.js'
31
32
  import { readFile, writeFile } from 'fs/promises'
32
33
 
33
- const logger = new CLILogger({ logLogo: true, silent: false })
34
+ // Logger instance will be configured with log level from CLI flags in createConfig
35
+ // Logo will be displayed conditionally in createConfig based on --silent flag
36
+ const logger = new CLILogger({ logLogo: false, silent: false })
34
37
 
35
38
  /**
36
39
  * Parse a comma-separated string or array into an array of trimmed, non-empty strings
@@ -94,7 +97,7 @@ function parseCLIFilters(data: any): InspectorFilters {
94
97
  export const defaultCLIRenderer = pikkuCLIRender<
95
98
  ForwardedLogMessage,
96
99
  SingletonServices
97
- >((_services, data) => {
100
+ >(({ logger }, data) => {
98
101
  if (data) {
99
102
  logger[data.level]({ message: data.message, type: data.type })
100
103
  }
@@ -105,11 +108,9 @@ export const defaultCLIRenderer = pikkuCLIRender<
105
108
  * This renderer can be used in CLI-over-channel clients
106
109
  */
107
110
  export const clientCLIRenderer = pikkuCLIRender<ForwardedLogMessage>(
108
- (_services, data) => {
111
+ ({ logger }, data) => {
109
112
  if (data) {
110
- // Simple console output without service dependencies
111
- const prefix = data.type ? `[${data.type}] ` : ''
112
- console.log(`${prefix}${data.message}`)
113
+ logger[data.level]?.({ message: data.message, type: data.type } as any)
113
114
  }
114
115
  }
115
116
  )
@@ -118,6 +119,37 @@ export const createConfig: CreateConfig<Config, [PikkuCLIConfig]> = async (
118
119
  _variablesService,
119
120
  data
120
121
  ) => {
122
+ // Determine log level based on CLI flags with precedence:
123
+ // --silent > --loglevel > --verbose > --info > default (warn)
124
+ let logLevel: LogLevel = LogLevel.warn // default
125
+ let isSilent = false
126
+
127
+ if ((data as any).silent) {
128
+ logLevel = LogLevel.critical
129
+ isSilent = true
130
+ } else if ((data as any).loglevel) {
131
+ const levelStr = (data as any).loglevel
132
+ if (LogLevel[levelStr] !== undefined) {
133
+ logLevel = LogLevel[levelStr as keyof typeof LogLevel]
134
+ } else {
135
+ logger.warn(
136
+ `Invalid log level "${levelStr}". Valid levels: trace, debug, info, warn, error, critical. Using default (warn).`
137
+ )
138
+ }
139
+ } else if ((data as any).verbose) {
140
+ logLevel = LogLevel.debug
141
+ } else if ((data as any).info) {
142
+ logLevel = LogLevel.info
143
+ }
144
+
145
+ logger.setLevel(logLevel)
146
+ logger.setSilent(isSilent)
147
+
148
+ // Display logo unless in silent mode
149
+ if (!isSilent) {
150
+ logger.logLogo()
151
+ }
152
+
121
153
  const cliConfig = await getPikkuCLIConfig(logger, data.configFile, [], true)
122
154
 
123
155
  // Load inspector state from file if stateInput is provided
@@ -170,19 +202,62 @@ export const createSingletonServices: CreateSingletonServices<
170
202
  | Omit<InspectorState, 'typesLookup'>
171
203
  | undefined = preloadedInspectorState
172
204
 
173
- const getInspectorState = async (refresh: boolean = false) => {
205
+ const getInspectorState = async (
206
+ refresh: boolean = false,
207
+ setupOnly: boolean = false,
208
+ bootstrapMode: boolean = false
209
+ ) => {
210
+ // In bootstrap mode, return a minimal "zero state" with core types
211
+ // This allows bootstrap to run immediately without inspecting the codebase
212
+ if (bootstrapMode) {
213
+ const corePackagePath = '@pikku/core'
214
+ const initialState = getInitialInspectorState(rootDir)
215
+
216
+ // Populate filesAndMethods with core types from @pikku/core
217
+ initialState.filesAndMethods = {
218
+ userSessionType: {
219
+ file: corePackagePath,
220
+ variable: 'CoreUserSession',
221
+ type: 'CoreUserSession',
222
+ typePath: corePackagePath,
223
+ },
224
+ sessionServicesType: {
225
+ file: corePackagePath,
226
+ variable: 'CoreServices',
227
+ type: 'CoreServices',
228
+ typePath: corePackagePath,
229
+ },
230
+ singletonServicesType: {
231
+ file: corePackagePath,
232
+ variable: 'CoreSingletonServices',
233
+ type: 'CoreSingletonServices',
234
+ typePath: corePackagePath,
235
+ },
236
+ pikkuConfigType: {
237
+ file: corePackagePath,
238
+ variable: 'CoreConfig',
239
+ type: 'CoreConfig',
240
+ typePath: corePackagePath,
241
+ },
242
+ }
243
+
244
+ return initialState
245
+ }
246
+
174
247
  // Get or refresh the unfiltered state
175
248
  if (!unfilteredState || refresh) {
176
249
  // Run inspector WITHOUT filters to get full state
177
250
  const wiringFiles = (
178
251
  await Promise.all(
179
252
  srcDirectories.map((dir) =>
180
- glob(`${path.join(rootDir, dir)}/**/*.ts`)
253
+ glob(`${path.join(rootDir, dir)}/**/*.ts`, {
254
+ ignore: config.ignoreFiles || [],
255
+ })
181
256
  )
182
257
  )
183
258
  ).flat()
184
- unfilteredState = await inspect(logger, wiringFiles, {
185
- // NO filters here - inspector returns full unfiltered state
259
+ unfilteredState = inspect(logger, wiringFiles, {
260
+ setupOnly,
186
261
  types: {
187
262
  configFileType: config.configFile,
188
263
  userSessionType: config.userSessionType,
@@ -0,0 +1,103 @@
1
+ import chalk from 'chalk'
2
+
3
+ export interface CommandSummaryStats {
4
+ httpRoutes?: number
5
+ channels?: number
6
+ functions?: number
7
+ scheduledTasks?: number
8
+ queueWorkers?: number
9
+ mcpEndpoints?: number
10
+ cliCommands?: number
11
+ workflows?: number
12
+ [key: string]: number | undefined
13
+ }
14
+
15
+ /**
16
+ * Utility class to collect and display command execution summaries
17
+ */
18
+ export class CommandSummary {
19
+ private stats: CommandSummaryStats = {}
20
+ private startTime: number
21
+ private commandName: string
22
+
23
+ constructor(commandName: string) {
24
+ this.commandName = commandName
25
+ this.startTime = Date.now()
26
+ }
27
+
28
+ /**
29
+ * Increment a stat counter
30
+ */
31
+ increment(key: keyof CommandSummaryStats, count: number = 1): void {
32
+ this.stats[key] = (this.stats[key] || 0) + count
33
+ }
34
+
35
+ /**
36
+ * Set a stat value directly
37
+ */
38
+ set(key: keyof CommandSummaryStats, value: number): void {
39
+ this.stats[key] = value
40
+ }
41
+
42
+ /**
43
+ * Get current stats
44
+ */
45
+ getStats(): CommandSummaryStats {
46
+ return { ...this.stats }
47
+ }
48
+
49
+ /**
50
+ * Get elapsed time in milliseconds
51
+ */
52
+ getElapsedTime(): number {
53
+ return Date.now() - this.startTime
54
+ }
55
+
56
+ /**
57
+ * Format the summary for display
58
+ */
59
+ format(): string {
60
+ const elapsed = this.getElapsedTime()
61
+ const lines: string[] = []
62
+
63
+ // Header with timing
64
+ lines.push(
65
+ chalk.green(`\npikku ${this.commandName} (completed in ${elapsed}ms)`)
66
+ )
67
+
68
+ // Stats
69
+ const statLabels: Record<keyof CommandSummaryStats, string> = {
70
+ httpRoutes: 'HTTP route',
71
+ channels: 'WebSocket channel',
72
+ functions: 'Function',
73
+ scheduledTasks: 'Scheduled task',
74
+ queueWorkers: 'Queue worker',
75
+ mcpEndpoints: 'MCP endpoint',
76
+ cliCommands: 'CLI command',
77
+ workflows: 'Workflow',
78
+ }
79
+
80
+ for (const [key, label] of Object.entries(statLabels)) {
81
+ const value = this.stats[key]
82
+ if (value !== undefined && value > 0) {
83
+ lines.push(chalk.gray(` • ${value} ${label}${value > 1 ? 's' : ''}`))
84
+ }
85
+ }
86
+
87
+ // If no stats, show a simple completion message
88
+ if (Object.values(this.stats).every((v) => !v || v === 0)) {
89
+ return chalk.green(
90
+ `\npikku ${this.commandName} (completed in ${elapsed}ms)\n`
91
+ )
92
+ }
93
+
94
+ return lines.join('\n') + '\n'
95
+ }
96
+
97
+ /**
98
+ * Check if there are any stats to display
99
+ */
100
+ hasStats(): boolean {
101
+ return Object.values(this.stats).some((v) => v && v > 0)
102
+ }
103
+ }
@@ -51,7 +51,7 @@ export const writeFileInDir = async (
51
51
  await writeFile(path, content, 'utf-8')
52
52
 
53
53
  if (logWrite) {
54
- logger.info({ message: `✓ File written to ${path}`, type: 'success' })
54
+ logger.debug({ message: `✓ File written to ${path}`, type: 'success' })
55
55
  }
56
56
  }
57
57
  }
@@ -66,7 +66,7 @@ export const removeFileInDir = async (
66
66
  await rm(path, { force: true })
67
67
 
68
68
  if (logRemove) {
69
- logger.info({ message: `✓ File removed at ${path}`, type: 'success' })
69
+ logger.debug({ message: `✓ File removed at ${path}`, type: 'success' })
70
70
  }
71
71
  }
72
72
  }
@@ -64,6 +64,19 @@ const _getPikkuCLIConfig = async (
64
64
  ...extendedConfig.packageMappings,
65
65
  ...config.packageMappings,
66
66
  },
67
+ ignoreFiles: config.ignoreFiles ??
68
+ extendedConfig.ignoreFiles ?? [
69
+ '**/*.test.ts',
70
+ '**/*.spec.ts',
71
+ '**/node_modules/**',
72
+ '**/dist/**',
73
+ ],
74
+ schema: {
75
+ additionalProperties: false,
76
+ supportsImportAttributes: false,
77
+ ...extendedConfig.schema,
78
+ ...config.schema,
79
+ },
67
80
  }
68
81
  } else {
69
82
  result = {
@@ -73,6 +86,17 @@ const _getPikkuCLIConfig = async (
73
86
  rootDir: config.rootDir
74
87
  ? resolve(configDir, config.rootDir)
75
88
  : configDir,
89
+ ignoreFiles: config.ignoreFiles ?? [
90
+ '**/*.test.ts',
91
+ '**/*.spec.ts',
92
+ '**/node_modules/**',
93
+ '**/dist/**',
94
+ ],
95
+ schema: {
96
+ additionalProperties: false,
97
+ supportsImportAttributes: false,
98
+ ...config.schema,
99
+ },
76
100
  }
77
101
  }
78
102
 
@@ -83,6 +107,7 @@ const _getPikkuCLIConfig = async (
83
107
  const rpcDir = join(result.outDir, 'rpc')
84
108
  const schedulerDir = join(result.outDir, 'scheduler')
85
109
  const queueDir = join(result.outDir, 'queue')
110
+ const workflowDir = join(result.outDir, 'workflow')
86
111
  const mcpDir = join(result.outDir, 'mcp')
87
112
  const cliDir = join(result.outDir, 'cli')
88
113
  const middlewareDir = join(result.outDir, 'middleware')
@@ -181,6 +206,17 @@ const _getPikkuCLIConfig = async (
181
206
  )
182
207
  }
183
208
 
209
+ // RPC config defaults
210
+ if (!result.rpc) {
211
+ result.rpc = {}
212
+ }
213
+ if (!result.rpc.remoteRpcWorkersPath) {
214
+ result.rpc.remoteRpcWorkersPath = join(
215
+ rpcDir,
216
+ 'pikku-remote-rpc-workers.gen.ts'
217
+ )
218
+ }
219
+
184
220
  // Scheduler
185
221
  if (!result.schedulersWiringFile) {
186
222
  result.schedulersWiringFile = join(
@@ -224,6 +260,38 @@ const _getPikkuCLIConfig = async (
224
260
  result.queueTypesFile = join(queueDir, 'pikku-queue-types.gen.ts')
225
261
  }
226
262
 
263
+ // Workflows
264
+ if (!result.workflowsWiringFile) {
265
+ result.workflowsWiringFile = join(
266
+ workflowDir,
267
+ 'pikku-workflow-wirings.gen.ts'
268
+ )
269
+ }
270
+ if (!result.workflowsWiringMetaFile) {
271
+ result.workflowsWiringMetaFile = join(
272
+ workflowDir,
273
+ 'pikku-workflow-wirings-meta.gen.ts'
274
+ )
275
+ }
276
+ if (!result.workflowsWorkersFile) {
277
+ result.workflowsWorkersFile = join(
278
+ workflowDir,
279
+ 'pikku-workflow-workers.gen.ts'
280
+ )
281
+ }
282
+ if (!result.workflowMapDeclarationFile) {
283
+ result.workflowMapDeclarationFile = join(
284
+ workflowDir,
285
+ 'pikku-workflow-map.gen.d.ts'
286
+ )
287
+ }
288
+ if (!result.workflowTypesFile) {
289
+ result.workflowTypesFile = join(
290
+ workflowDir,
291
+ 'pikku-workflow-types.gen.ts'
292
+ )
293
+ }
294
+
227
295
  // Services
228
296
  if (!result.servicesFile) {
229
297
  result.servicesFile = join(result.outDir, 'pikku-services.gen.ts')
@@ -12,15 +12,20 @@ export async function generateSchemas(
12
12
  typesMap: TypesMap,
13
13
  functionMeta: FunctionsMeta,
14
14
  httpWiringsMeta: HTTPWiringsMeta,
15
- additionalTypes?: string[]
15
+ additionalTypes?: string[],
16
+ additionalProperties: boolean = false
16
17
  ): Promise<Record<string, JSONValue>> {
17
18
  const schemasSet = new Set(typesMap.customTypes.keys())
18
19
  for (const { inputs, outputs } of Object.values(functionMeta)) {
19
20
  const types = [...(inputs || []), ...(outputs || [])]
20
21
  for (const type of types) {
21
- const uniqueName = typesMap.getUniqueName(type)
22
- if (uniqueName) {
23
- schemasSet.add(uniqueName)
22
+ try {
23
+ const uniqueName = typesMap.getUniqueName(type)
24
+ if (uniqueName) {
25
+ schemasSet.add(uniqueName)
26
+ }
27
+ } catch {
28
+ // Skip types not in typesMap (e.g., inline types in generated workflow workers)
24
29
  }
25
30
  }
26
31
  }
@@ -56,7 +61,7 @@ export async function generateSchemas(
56
61
  sortProps: true,
57
62
  strictTuples: false,
58
63
  encodeRefs: false,
59
- additionalProperties: false,
64
+ additionalProperties,
60
65
  })
61
66
  const schemas: Record<string, JSONValue> = {}
62
67
 
@@ -86,8 +91,8 @@ export async function saveSchemas(
86
91
  schemas: Record<string, JSONValue>,
87
92
  typesMap: TypesMap,
88
93
  functionsMeta: FunctionsMeta,
89
- supportsImportAttributes: boolean,
90
- additionalTypes?: string[]
94
+ additionalTypes?: string[],
95
+ supportsImportAttributes: boolean = false
91
96
  ) {
92
97
  await writeFileInDir(
93
98
  logger,
@@ -97,10 +102,24 @@ export async function saveSchemas(
97
102
 
98
103
  const desiredSchemas = new Set<string>([
99
104
  ...Object.values(functionsMeta)
100
- .map(({ inputs, outputs }) => [
101
- inputs?.[0] ? typesMap.getUniqueName(inputs[0]) : undefined,
102
- outputs?.[0] ? typesMap.getUniqueName(outputs[0]) : undefined,
103
- ])
105
+ .map(({ inputs, outputs }) => {
106
+ const types: (string | undefined)[] = []
107
+ if (inputs?.[0]) {
108
+ try {
109
+ types.push(typesMap.getUniqueName(inputs[0]))
110
+ } catch {
111
+ // Skip types not in typesMap (e.g., inline types in generated workflow workers)
112
+ }
113
+ }
114
+ if (outputs?.[0]) {
115
+ try {
116
+ types.push(typesMap.getUniqueName(outputs[0]))
117
+ } catch {
118
+ // Skip types not in typesMap (e.g., inline types in generated workflow workers)
119
+ }
120
+ }
121
+ return types
122
+ })
104
123
  .flat()
105
124
  .filter(
106
125
  (s): s is string =>
@@ -15,7 +15,11 @@ export interface Config extends CoreConfig<PikkuCLIConfig> {
15
15
 
16
16
  export interface SingletonServices extends CoreSingletonServices<Config> {
17
17
  logger: CLILogger
18
- getInspectorState: (refresh?: boolean = false) => Promise<InspectorState>
18
+ getInspectorState: (
19
+ refresh?: boolean,
20
+ setupOnly?: boolean,
21
+ bootstrapMode?: boolean
22
+ ) => Promise<InspectorState>
19
23
  }
20
24
 
21
25
  export interface Services extends CoreServices<SingletonServices, {}> {}