@kubb/cli 5.0.0-beta.3 → 5.0.0-beta.31

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 (151) hide show
  1. package/README.md +177 -26
  2. package/dist/agent-BAAO2W7u.cjs +70 -0
  3. package/dist/agent-BAAO2W7u.cjs.map +1 -0
  4. package/dist/agent-WLRLgsEM.js +68 -0
  5. package/dist/agent-WLRLgsEM.js.map +1 -0
  6. package/dist/{chunk--u3MIqq1.js → chunk-BvFE5Tac.js} +1 -0
  7. package/dist/constants-B2JTeRBb.js +42 -0
  8. package/dist/constants-B2JTeRBb.js.map +1 -0
  9. package/dist/constants-BINTA5VZ.cjs +77 -0
  10. package/dist/constants-BINTA5VZ.cjs.map +1 -0
  11. package/dist/constants-BYGmiFs0.cjs +139 -0
  12. package/dist/constants-BYGmiFs0.cjs.map +1 -0
  13. package/dist/constants-DSJ-Xrbv.js +116 -0
  14. package/dist/constants-DSJ-Xrbv.js.map +1 -0
  15. package/dist/define-Bdn8j5VM.cjs.map +1 -1
  16. package/dist/{define-Ctii4bel.js → define-m_fp-Aqm.js} +2 -2
  17. package/dist/{define-Ctii4bel.js.map → define-m_fp-Aqm.js.map} +1 -1
  18. package/dist/{errors-CjPmyZHy.js → errors-CINO1EIv.js} +2 -2
  19. package/dist/{errors-CjPmyZHy.js.map → errors-CINO1EIv.js.map} +1 -1
  20. package/dist/errors-CLCjoSg0.cjs.map +1 -1
  21. package/dist/{generate-CTdVvIaP.js → generate-C4iw5Nou.js} +12 -6
  22. package/dist/generate-C4iw5Nou.js.map +1 -0
  23. package/dist/{generate-BzCMyyNN.cjs → generate-DKtBY8eR.cjs} +10 -4
  24. package/dist/generate-DKtBY8eR.cjs.map +1 -0
  25. package/dist/index.cjs +20 -11
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +22 -13
  29. package/dist/index.js.map +1 -1
  30. package/dist/init-DE_judaK.js +53 -0
  31. package/dist/init-DE_judaK.js.map +1 -0
  32. package/dist/init-berpsF2G.cjs +53 -0
  33. package/dist/init-berpsF2G.cjs.map +1 -0
  34. package/dist/mcp-Ce6errt_.js +39 -0
  35. package/dist/mcp-Ce6errt_.js.map +1 -0
  36. package/dist/mcp-DcohdQTl.cjs +39 -0
  37. package/dist/mcp-DcohdQTl.cjs.map +1 -0
  38. package/dist/package-C0vNpFXU.js +6 -0
  39. package/dist/package-C0vNpFXU.js.map +1 -0
  40. package/dist/{package-DcmDg_mw.cjs → package-DZDnoPgZ.cjs} +2 -2
  41. package/dist/package-DZDnoPgZ.cjs.map +1 -0
  42. package/dist/run-B11-UaUs.cjs +33 -0
  43. package/dist/run-B11-UaUs.cjs.map +1 -0
  44. package/dist/{init-eNRlotJK.js → run-BNqMQygv.js} +107 -149
  45. package/dist/run-BNqMQygv.js.map +1 -0
  46. package/dist/{generate-BL-Kp5GY.js → run-BgM41TQT.js} +561 -493
  47. package/dist/run-BgM41TQT.js.map +1 -0
  48. package/dist/{init-CZ5Xq2Hd.cjs → run-BnGfi7Cp.cjs} +105 -147
  49. package/dist/run-BnGfi7Cp.cjs.map +1 -0
  50. package/dist/{agent-sdYBBgrd.js → run-BzpYYOQs.js} +46 -43
  51. package/dist/run-BzpYYOQs.js.map +1 -0
  52. package/dist/run-CCZ24VKk.js +51 -0
  53. package/dist/run-CCZ24VKk.js.map +1 -0
  54. package/dist/run-CQbj3ley.cjs +52 -0
  55. package/dist/run-CQbj3ley.cjs.map +1 -0
  56. package/dist/{generate-DMqdAYqy.cjs → run-DeWgpA6S.cjs} +558 -490
  57. package/dist/run-DeWgpA6S.cjs.map +1 -0
  58. package/dist/{agent-B4cAAab2.cjs → run-DwdAwnLG.cjs} +44 -41
  59. package/dist/run-DwdAwnLG.cjs.map +1 -0
  60. package/dist/run-PSA9X7ci.js +32 -0
  61. package/dist/run-PSA9X7ci.js.map +1 -0
  62. package/dist/shell-475fQKaX.cjs.map +1 -1
  63. package/dist/{shell-DLzN4fRo.js → shell-CN6DNqeC.js} +2 -2
  64. package/dist/{shell-DLzN4fRo.js.map → shell-CN6DNqeC.js.map} +1 -1
  65. package/dist/{telemetry-DN95_2pF.cjs → telemetry-B2iWkY5e.cjs} +5 -7
  66. package/dist/telemetry-B2iWkY5e.cjs.map +1 -0
  67. package/dist/{telemetry-LgT_sdPe.js → telemetry-BkektVz6.js} +6 -8
  68. package/dist/telemetry-BkektVz6.js.map +1 -0
  69. package/dist/validate-DVeCYyIS.js +26 -0
  70. package/dist/validate-DVeCYyIS.js.map +1 -0
  71. package/dist/validate-ymG_XDSU.cjs +26 -0
  72. package/dist/validate-ymG_XDSU.cjs.map +1 -0
  73. package/package.json +14 -14
  74. package/src/commands/agent/start.ts +10 -7
  75. package/src/commands/agent.ts +3 -1
  76. package/src/commands/generate.ts +5 -3
  77. package/src/commands/init.ts +34 -3
  78. package/src/commands/mcp.ts +28 -4
  79. package/src/commands/validate.ts +6 -4
  80. package/src/constants.ts +2 -58
  81. package/src/index.ts +5 -3
  82. package/src/loggers/clackLogger.ts +85 -118
  83. package/src/loggers/fileSystemLogger.ts +28 -15
  84. package/src/loggers/githubActionsLogger.ts +87 -96
  85. package/src/loggers/plainLogger.ts +48 -81
  86. package/src/loggers/types.ts +6 -0
  87. package/src/loggers/utils.ts +235 -11
  88. package/src/runners/agent/run.ts +113 -0
  89. package/src/runners/agent/utils.ts +98 -0
  90. package/src/runners/generate/run.ts +321 -0
  91. package/src/runners/generate/utils.ts +225 -0
  92. package/src/runners/init/run.ts +212 -0
  93. package/src/{utils/packageManager.ts → runners/init/utils.ts} +12 -2
  94. package/src/runners/mcp/run.ts +37 -0
  95. package/src/runners/validate/run.ts +63 -0
  96. package/src/{utils/telemetry.ts → telemetry.ts} +27 -20
  97. package/dist/agent-B4cAAab2.cjs.map +0 -1
  98. package/dist/agent-BFACosbG.cjs +0 -58
  99. package/dist/agent-BFACosbG.cjs.map +0 -1
  100. package/dist/agent-s7TqqoTg.js +0 -56
  101. package/dist/agent-s7TqqoTg.js.map +0 -1
  102. package/dist/agent-sdYBBgrd.js.map +0 -1
  103. package/dist/constants-CnDXa1R6.cjs +0 -148
  104. package/dist/constants-CnDXa1R6.cjs.map +0 -1
  105. package/dist/constants-aL3CP_Wq.js +0 -95
  106. package/dist/constants-aL3CP_Wq.js.map +0 -1
  107. package/dist/generate-BL-Kp5GY.js.map +0 -1
  108. package/dist/generate-BzCMyyNN.cjs.map +0 -1
  109. package/dist/generate-CTdVvIaP.js.map +0 -1
  110. package/dist/generate-DMqdAYqy.cjs.map +0 -1
  111. package/dist/init-BHMGbly9.cjs +0 -25
  112. package/dist/init-BHMGbly9.cjs.map +0 -1
  113. package/dist/init-CZ5Xq2Hd.cjs.map +0 -1
  114. package/dist/init-eNRlotJK.js.map +0 -1
  115. package/dist/init-qgpg-iRW.js +0 -25
  116. package/dist/init-qgpg-iRW.js.map +0 -1
  117. package/dist/mcp-BRp-2Rdc.js +0 -16
  118. package/dist/mcp-BRp-2Rdc.js.map +0 -1
  119. package/dist/mcp-CYOgxB82.cjs +0 -47
  120. package/dist/mcp-CYOgxB82.cjs.map +0 -1
  121. package/dist/mcp-DmJm3TrU.js +0 -46
  122. package/dist/mcp-DmJm3TrU.js.map +0 -1
  123. package/dist/mcp-N3mRyVuO.cjs +0 -16
  124. package/dist/mcp-N3mRyVuO.cjs.map +0 -1
  125. package/dist/package-DcmDg_mw.cjs.map +0 -1
  126. package/dist/package-DtuyzAVW.js +0 -6
  127. package/dist/package-DtuyzAVW.js.map +0 -1
  128. package/dist/telemetry-DN95_2pF.cjs.map +0 -1
  129. package/dist/telemetry-LgT_sdPe.js.map +0 -1
  130. package/dist/validate-CJpTOzKA.js +0 -25
  131. package/dist/validate-CJpTOzKA.js.map +0 -1
  132. package/dist/validate-DyTbv7Bc.cjs +0 -25
  133. package/dist/validate-DyTbv7Bc.cjs.map +0 -1
  134. package/dist/validate-kLJoT_hi.js +0 -33
  135. package/dist/validate-kLJoT_hi.js.map +0 -1
  136. package/dist/validate-yKKzqEZ5.cjs +0 -34
  137. package/dist/validate-yKKzqEZ5.cjs.map +0 -1
  138. package/src/runners/agent.ts +0 -155
  139. package/src/runners/generate.ts +0 -333
  140. package/src/runners/init.ts +0 -296
  141. package/src/runners/mcp.ts +0 -51
  142. package/src/runners/validate.ts +0 -39
  143. package/src/types.ts +0 -11
  144. package/src/utils/Writables.ts +0 -17
  145. package/src/utils/executeHooks.ts +0 -45
  146. package/src/utils/flags.ts +0 -9
  147. package/src/utils/getConfig.ts +0 -10
  148. package/src/utils/getCosmiConfig.ts +0 -80
  149. package/src/utils/getSummary.ts +0 -68
  150. package/src/utils/runHook.ts +0 -91
  151. package/src/utils/watcher.ts +0 -19
@@ -1,8 +1,15 @@
1
1
  import { styleText } from 'node:util'
2
2
  import { formatHrtime, formatMs, formatMsWithColor, toCause } from '@internals/utils'
3
- import { type Config, defineLogger, logLevel as logLevelMap } from '@kubb/core'
4
- import { runHook } from '../utils/runHook.ts'
5
- import { buildProgressLine, formatCommandWithArgs, formatMessage } from './utils.ts'
3
+ import { type Config, defineLogger, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'
4
+ import {
5
+ buildProgressLine,
6
+ createHookTimer,
7
+ createProgressCounters,
8
+ formatCommandWithArgs,
9
+ formatMessage,
10
+ recordPluginResult,
11
+ resetProgressCounters,
12
+ } from './utils.ts'
6
13
 
7
14
  /**
8
15
  * GitHub Actions logger using group annotations for collapsible sections in CI.
@@ -12,23 +19,17 @@ export const githubActionsLogger = defineLogger({
12
19
  install(context, options) {
13
20
  const logLevel = options?.logLevel ?? logLevelMap.info
14
21
  const state = {
15
- totalPlugins: 0,
16
- completedPlugins: 0,
17
- failedPlugins: 0,
18
- totalFiles: 0,
19
- processedFiles: 0,
20
- hrStart: process.hrtime(),
22
+ ...createProgressCounters(),
21
23
  currentConfigs: [] as Array<Config>,
24
+ openGroupDepth: 0,
22
25
  }
26
+ const hookTimer = createHookTimer()
23
27
 
24
28
  function reset() {
25
- state.totalPlugins = 0
26
- state.completedPlugins = 0
27
- state.failedPlugins = 0
28
- state.totalFiles = 0
29
- state.processedFiles = 0
30
- state.hrStart = process.hrtime()
29
+ closeAllGroups()
30
+ resetProgressCounters(state)
31
31
  state.currentConfigs = []
32
+ hookTimer.clear()
32
33
  }
33
34
 
34
35
  function showProgressStep() {
@@ -48,10 +49,45 @@ export const githubActionsLogger = defineLogger({
48
49
 
49
50
  function openGroup(name: string) {
50
51
  console.log(`::group::${name}`)
52
+ state.openGroupDepth++
51
53
  }
52
54
 
53
55
  function closeGroup(_name: string) {
54
56
  console.log('::endgroup::')
57
+ if (state.openGroupDepth > 0) state.openGroupDepth--
58
+ }
59
+
60
+ function closeAllGroups() {
61
+ while (state.openGroupDepth > 0) {
62
+ console.log('::endgroup::')
63
+ state.openGroupDepth--
64
+ }
65
+ }
66
+
67
+ // Opens a group (only for single-config runs) then logs the step message.
68
+ function onGroupStart<E extends keyof KubbHooks>(event: E, message: string, group: string): void {
69
+ context.on(event, () => {
70
+ if (logLevel <= logLevelMap.silent) {
71
+ return
72
+ }
73
+ if (state.currentConfigs.length === 1) {
74
+ openGroup(group)
75
+ }
76
+ console.log(getMessage(message))
77
+ })
78
+ }
79
+
80
+ // Logs the step message then closes the matching group (single-config runs).
81
+ function onGroupEnd<E extends keyof KubbHooks>(event: E, message: string, group: string): void {
82
+ context.on(event, () => {
83
+ if (logLevel <= logLevelMap.silent) {
84
+ return
85
+ }
86
+ console.log(getMessage(message))
87
+ if (state.currentConfigs.length === 1) {
88
+ closeGroup(group)
89
+ }
90
+ })
55
91
  }
56
92
 
57
93
  context.on('kubb:info', ({ message, info = '' }) => {
@@ -87,6 +123,10 @@ export const githubActionsLogger = defineLogger({
87
123
  context.on('kubb:error', ({ error }) => {
88
124
  const caused = toCause(error)
89
125
 
126
+ // Always release any unclosed groups so a thrown :start without a matching :end
127
+ // (e.g., when getConfigs or kubb.setup throws) doesn't leak an open section.
128
+ closeAllGroups()
129
+
90
130
  if (logLevel <= logLevelMap.silent) {
91
131
  return
92
132
  }
@@ -116,6 +156,10 @@ export const githubActionsLogger = defineLogger({
116
156
  reset()
117
157
  })
118
158
 
159
+ context.on('kubb:version:new', ({ currentVersion, latestVersion }) => {
160
+ console.log(`::notice::Update available for Kubb: v${currentVersion} → v${latestVersion}. Run \`npm install -g @kubb/cli\` to update.`)
161
+ })
162
+
119
163
  context.on('kubb:config:start', () => {
120
164
  if (logLevel <= logLevelMap.silent) {
121
165
  return
@@ -177,11 +221,7 @@ export const githubActionsLogger = defineLogger({
177
221
  return
178
222
  }
179
223
 
180
- if (success) {
181
- state.completedPlugins++
182
- } else {
183
- state.failedPlugins++
184
- }
224
+ recordPluginResult(state, success)
185
225
 
186
226
  const durationStr = formatMsWithColor(duration)
187
227
  const text = getMessage(
@@ -235,12 +275,12 @@ export const githubActionsLogger = defineLogger({
235
275
  showProgressStep()
236
276
  })
237
277
 
238
- context.on('kubb:file:processing:update', () => {
278
+ context.on('kubb:files:processing:update', ({ files }) => {
239
279
  if (logLevel <= logLevelMap.silent) {
240
280
  return
241
281
  }
242
282
 
243
- state.processedFiles++
283
+ state.processedFiles += files.length
244
284
  })
245
285
 
246
286
  context.on('kubb:generation:end', ({ config }) => {
@@ -251,102 +291,48 @@ export const githubActionsLogger = defineLogger({
251
291
  console.log(text)
252
292
  })
253
293
 
254
- context.on('kubb:format:start', () => {
255
- if (logLevel <= logLevelMap.silent) {
256
- return
257
- }
258
-
259
- const text = getMessage('Format started')
260
-
261
- if (state.currentConfigs.length === 1) {
262
- openGroup('Formatting')
263
- }
264
-
265
- console.log(text)
266
- })
294
+ onGroupStart('kubb:format:start', 'Format started', 'Formatting')
295
+ onGroupEnd('kubb:format:end', 'Format completed', 'Formatting')
296
+ onGroupStart('kubb:lint:start', 'Lint started', 'Linting')
297
+ onGroupEnd('kubb:lint:end', 'Lint completed', 'Linting')
298
+ onGroupStart('kubb:hooks:start', 'Hooks started', 'Hooks')
299
+ onGroupEnd('kubb:hooks:end', 'Hooks completed', 'Hooks')
267
300
 
268
- context.on('kubb:format:end', () => {
301
+ context.on('kubb:hook:start', ({ id, command, args }) => {
269
302
  if (logLevel <= logLevelMap.silent) {
270
303
  return
271
304
  }
272
305
 
273
- const text = getMessage('Format completed')
274
-
275
- console.log(text)
276
-
277
- if (state.currentConfigs.length === 1) {
278
- closeGroup('Formatting')
279
- }
280
- })
281
-
282
- context.on('kubb:lint:start', () => {
283
- if (logLevel <= logLevelMap.silent) {
284
- return
306
+ if (id) {
307
+ hookTimer.start(id)
285
308
  }
286
309
 
287
- const text = getMessage('Lint started')
310
+ const commandWithArgs = formatCommandWithArgs(command, args)
311
+ const text = getMessage(`Hook ${styleText('dim', commandWithArgs)} started`)
288
312
 
289
313
  if (state.currentConfigs.length === 1) {
290
- openGroup('Linting')
314
+ openGroup(`Hook ${commandWithArgs}`)
291
315
  }
292
-
293
316
  console.log(text)
294
317
  })
295
318
 
296
- context.on('kubb:lint:end', () => {
319
+ context.on('kubb:hook:end', ({ id, command, args, success, error }) => {
297
320
  if (logLevel <= logLevelMap.silent) {
298
321
  return
299
322
  }
300
323
 
301
- const text = getMessage('Lint completed')
302
-
303
- console.log(text)
304
-
305
- if (state.currentConfigs.length === 1) {
306
- closeGroup('Linting')
307
- }
308
- })
324
+ const ms = id ? hookTimer.end(id) : undefined
325
+ const durationStr = ms !== undefined ? ` in ${formatMsWithColor(ms)}` : ''
309
326
 
310
- context.on('kubb:hook:start', async ({ id, command, args }) => {
311
327
  const commandWithArgs = formatCommandWithArgs(command, args)
312
- const text = getMessage(`Hook ${styleText('dim', commandWithArgs)} started`)
313
328
 
314
- if (logLevel > logLevelMap.silent) {
315
- if (state.currentConfigs.length === 1) {
316
- openGroup(`Hook ${commandWithArgs}`)
317
- }
318
- console.log(text)
319
- }
320
-
321
- // Skip hook execution if no id is provided (e.g., during benchmarks or tests)
322
- if (!id) {
323
- return
324
- }
325
-
326
- await runHook({
327
- id,
328
- command,
329
- args,
330
- commandWithArgs,
331
- context,
332
- sink: {
333
- // GHA formats errors with the ::error:: annotation
334
- onStdout: logLevel > logLevelMap.silent ? (s) => console.log(s) : undefined,
335
- onStderr: logLevel > logLevelMap.silent ? (s) => console.error(`::error::${s}`) : undefined,
336
- },
337
- })
338
- })
339
-
340
- context.on('kubb:hook:end', ({ command, args }) => {
341
- if (logLevel <= logLevelMap.silent) {
342
- return
329
+ if (success) {
330
+ console.log(getMessage(`${styleText('green', '✓')} Hook ${styleText('dim', commandWithArgs)} completed${durationStr}`))
331
+ } else {
332
+ const reason = error?.message ? ` (${error.message})` : ''
333
+ console.log(`::error::Hook ${commandWithArgs} failed${durationStr}${reason}`)
343
334
  }
344
335
 
345
- const commandWithArgs = formatCommandWithArgs(command, args)
346
- const text = getMessage(`Hook ${styleText('dim', commandWithArgs)} completed`)
347
-
348
- console.log(text)
349
-
350
336
  if (state.currentConfigs.length === 1) {
351
337
  closeGroup(`Hook ${commandWithArgs}`)
352
338
  }
@@ -375,5 +361,10 @@ export const githubActionsLogger = defineLogger({
375
361
  context.on('kubb:lifecycle:end', () => {
376
362
  reset()
377
363
  })
364
+
365
+ return (_commandWithArgs: string, _hookId: string) => ({
366
+ onStdout: logLevel > logLevelMap.silent ? (s: string) => console.log(s) : undefined,
367
+ onStderr: logLevel > logLevelMap.silent ? (s: string) => console.error(`::error::${s}`) : undefined,
368
+ })
378
369
  },
379
370
  })
@@ -1,10 +1,9 @@
1
1
  import { relative } from 'node:path'
2
2
  import { formatMs, toCause } from '@internals/utils'
3
- import { defineLogger, logLevel as logLevelMap } from '@kubb/core'
3
+ import { defineLogger, type KubbHooks, logLevel as logLevelMap } from '@kubb/core'
4
4
  import { SUMMARY_SEPARATOR } from '../constants.ts'
5
- import { getSummary } from '../utils/getSummary.ts'
6
- import { runHook } from '../utils/runHook.ts'
7
- import { formatCommandWithArgs, formatMessage } from './utils.ts'
5
+ import { getSummary } from './utils.ts'
6
+ import { createHookTimer, formatCommandWithArgs, formatMessage } from './utils.ts'
8
7
 
9
8
  /**
10
9
  * Plain console adapter for non-TTY environments with simple `console.log` output.
@@ -13,11 +12,22 @@ export const plainLogger = defineLogger({
13
12
  name: 'plain',
14
13
  install(context, options) {
15
14
  const logLevel = options?.logLevel ?? logLevelMap.info
15
+ const hookTimer = createHookTimer()
16
16
 
17
17
  function getMessage(message: string): string {
18
18
  return formatMessage(message, logLevel)
19
19
  }
20
20
 
21
+ // Registers a handler that logs a fixed message, skipped at silent level.
22
+ function onStep<E extends keyof KubbHooks>(event: E, message: string): void {
23
+ context.on(event, () => {
24
+ if (logLevel <= logLevelMap.silent) {
25
+ return
26
+ }
27
+ console.log(getMessage(message))
28
+ })
29
+ }
30
+
21
31
  context.on('kubb:info', ({ message, info }) => {
22
32
  if (logLevel <= logLevelMap.silent) {
23
33
  return
@@ -73,29 +83,20 @@ export const plainLogger = defineLogger({
73
83
  }
74
84
  })
75
85
 
76
- context.on('kubb:lifecycle:start', () => {
77
- console.log('Kubb CLI 🧩')
86
+ context.on('kubb:lifecycle:start', ({ version }) => {
87
+ console.log(`Kubb CLI v${version}`)
78
88
  })
79
89
 
80
- context.on('kubb:config:start', () => {
90
+ context.on('kubb:version:new', ({ currentVersion, latestVersion }) => {
81
91
  if (logLevel <= logLevelMap.silent) {
82
92
  return
83
93
  }
84
94
 
85
- const text = getMessage('Configuration started')
86
-
87
- console.log(text)
95
+ console.log(getMessage(`Update available: v${currentVersion} v${latestVersion}. Run \`npm install -g @kubb/cli\` to update.`))
88
96
  })
89
97
 
90
- context.on('kubb:config:end', () => {
91
- if (logLevel <= logLevelMap.silent) {
92
- return
93
- }
94
-
95
- const text = getMessage('Configuration completed')
96
-
97
- console.log(text)
98
- })
98
+ onStep('kubb:config:start', 'Configuration started')
99
+ onStep('kubb:config:end', 'Configuration completed')
99
100
 
100
101
  context.on('kubb:generation:start', () => {
101
102
  const text = getMessage('Generation started')
@@ -133,14 +134,14 @@ export const plainLogger = defineLogger({
133
134
  console.log(text)
134
135
  })
135
136
 
136
- context.on('kubb:file:processing:update', ({ file, config }) => {
137
+ context.on('kubb:files:processing:update', ({ files }) => {
137
138
  if (logLevel <= logLevelMap.silent) {
138
139
  return
139
140
  }
140
141
 
141
- const text = getMessage(`Writing ${relative(config.root, file.path)}`)
142
-
143
- console.log(text)
142
+ for (const { file, config } of files) {
143
+ console.log(getMessage(`Writing ${relative(config.root, file.path)}`))
144
+ }
144
145
  })
145
146
 
146
147
  context.on('kubb:files:processing:end', () => {
@@ -159,81 +160,42 @@ export const plainLogger = defineLogger({
159
160
  console.log(text)
160
161
  })
161
162
 
162
- context.on('kubb:format:start', () => {
163
- if (logLevel <= logLevelMap.silent) {
164
- return
165
- }
166
-
167
- const text = getMessage('Format started')
163
+ onStep('kubb:format:start', 'Format started')
164
+ onStep('kubb:format:end', 'Format completed')
165
+ onStep('kubb:lint:start', 'Lint started')
166
+ onStep('kubb:lint:end', 'Lint completed')
167
+ onStep('kubb:hooks:start', 'Hooks started')
168
+ onStep('kubb:hooks:end', 'Hooks completed')
168
169
 
169
- console.log(text)
170
- })
171
-
172
- context.on('kubb:format:end', () => {
170
+ context.on('kubb:hook:start', ({ id, command, args }) => {
173
171
  if (logLevel <= logLevelMap.silent) {
174
172
  return
175
173
  }
176
174
 
177
- const text = getMessage('Format completed')
178
-
179
- console.log(text)
180
- })
181
-
182
- context.on('kubb:lint:start', () => {
183
- if (logLevel <= logLevelMap.silent) {
184
- return
175
+ if (id) {
176
+ hookTimer.start(id)
185
177
  }
186
178
 
187
- const text = getMessage('Lint started')
188
-
189
- console.log(text)
179
+ const commandWithArgs = formatCommandWithArgs(command, args)
180
+ console.log(getMessage(`Hook ${commandWithArgs} started`))
190
181
  })
191
182
 
192
- context.on('kubb:lint:end', () => {
183
+ context.on('kubb:hook:end', ({ id, command, args, success, error }) => {
193
184
  if (logLevel <= logLevelMap.silent) {
194
185
  return
195
186
  }
196
187
 
197
- const text = getMessage('Lint completed')
188
+ const ms = id ? hookTimer.end(id) : undefined
189
+ const durationStr = ms !== undefined ? ` in ${formatMs(ms)}` : ''
198
190
 
199
- console.log(text)
200
- })
201
-
202
- context.on('kubb:hook:start', async ({ id, command, args }) => {
203
191
  const commandWithArgs = formatCommandWithArgs(command, args)
204
- const text = getMessage(`Hook ${commandWithArgs} started`)
205
-
206
- if (logLevel > logLevelMap.silent) {
207
- console.log(text)
208
- }
209
192
 
210
- // Skip hook execution if no id is provided (e.g., during benchmarks or tests)
211
- if (!id) {
212
- return
193
+ if (success) {
194
+ console.log(getMessage(`✓ Hook ${commandWithArgs} completed${durationStr}`))
195
+ } else {
196
+ const reason = error?.message ? ` (${error.message})` : ''
197
+ console.log(getMessage(`✗ Hook ${commandWithArgs} failed${durationStr}${reason}`))
213
198
  }
214
-
215
- await runHook({
216
- id,
217
- command,
218
- args,
219
- commandWithArgs,
220
- context,
221
- sink: {
222
- onStdout: logLevel > logLevelMap.silent ? (s) => console.log(s) : undefined,
223
- onStderr: logLevel > logLevelMap.silent ? (s) => console.error(s) : undefined,
224
- },
225
- })
226
- })
227
-
228
- context.on('kubb:hook:end', ({ command, args }) => {
229
- if (logLevel <= logLevelMap.silent) {
230
- return
231
- }
232
-
233
- const commandWithArgs = formatCommandWithArgs(command, args)
234
- const text = getMessage(`Hook ${commandWithArgs} completed`)
235
-
236
- console.log(text)
237
199
  })
238
200
 
239
201
  context.on('kubb:generation:summary', ({ config, pluginTimings, status, hrStart, failedPlugins, filesCreated }) => {
@@ -250,5 +212,10 @@ export const plainLogger = defineLogger({
250
212
  console.log(summary.join('\n'))
251
213
  console.log(SUMMARY_SEPARATOR)
252
214
  })
215
+
216
+ return (_commandWithArgs: string, _hookId: string) => ({
217
+ onStdout: logLevel > logLevelMap.silent ? (s: string) => console.log(s) : undefined,
218
+ onStderr: logLevel > logLevelMap.silent ? (s: string) => console.error(s) : undefined,
219
+ })
253
220
  },
254
221
  })
@@ -1 +1,7 @@
1
+ /**
2
+ * Logger adapter selected by `setupLogger` based on the runtime environment.
3
+ * - `'clack'`: TTY-aware output with spinners and progress bars.
4
+ * - `'github-actions'`: CI output using `::group::` annotations.
5
+ * - `'plain'`: Plain `console.log` output for non-TTY environments.
6
+ */
1
7
  export type LoggerType = 'clack' | 'github-actions' | 'plain'