@kubb/cli 4.28.0 → 4.29.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 (64) hide show
  1. package/dist/{agent-DrV6PuuK.js → agent-BzD6f3mV.js} +4 -5
  2. package/dist/{agent-DrV6PuuK.js.map → agent-BzD6f3mV.js.map} +1 -1
  3. package/dist/{agent-BHBMSAC7.cjs → agent-NAhMf2ot.cjs} +4 -5
  4. package/dist/{agent-BHBMSAC7.cjs.map → agent-NAhMf2ot.cjs.map} +1 -1
  5. package/dist/{chunk-C1_xRkKa.cjs → chunk-CNbaEX1y.cjs} +1 -1
  6. package/dist/{chunk-jHaXqnEa.js → chunk-DKWOrOAv.js} +1 -1
  7. package/dist/{generate-CQYwekvF.cjs → generate-C8gS4Z2F.cjs} +190 -188
  8. package/dist/generate-C8gS4Z2F.cjs.map +1 -0
  9. package/dist/{generate-Cj8cU5XB.js → generate-CnKaIwc7.js} +191 -185
  10. package/dist/generate-CnKaIwc7.js.map +1 -0
  11. package/dist/index.cjs +9 -8
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +8 -8
  15. package/dist/{init-BVwhJb7n.js → init-B5qnw1XS.js} +22 -23
  16. package/dist/init-B5qnw1XS.js.map +1 -0
  17. package/dist/{init-Ckt9G-Yf.cjs → init-BDWQO7I8.cjs} +22 -24
  18. package/dist/init-BDWQO7I8.cjs.map +1 -0
  19. package/dist/{mcp-DGyip5BX.cjs → mcp-97TXkJVX.cjs} +5 -7
  20. package/dist/mcp-97TXkJVX.cjs.map +1 -0
  21. package/dist/{mcp-C-e4yatL.js → mcp-Jboea6xH.js} +5 -6
  22. package/dist/mcp-Jboea6xH.js.map +1 -0
  23. package/dist/{package-CeCGexzv.cjs → package-oo3QhWS5.cjs} +2 -2
  24. package/dist/package-oo3QhWS5.cjs.map +1 -0
  25. package/dist/package-veMf5zNr.js +6 -0
  26. package/dist/package-veMf5zNr.js.map +1 -0
  27. package/dist/{start-jaV7_Xss.js → start-CYuU23PX.js} +27 -24
  28. package/dist/start-CYuU23PX.js.map +1 -0
  29. package/dist/{start-DqKYNdp1.cjs → start-lrn1-P52.cjs} +27 -25
  30. package/dist/start-lrn1-P52.cjs.map +1 -0
  31. package/dist/{validate-Cvb5aOEb.cjs → validate-BgYhe_55.cjs} +3 -4
  32. package/dist/{validate-Cvb5aOEb.cjs.map → validate-BgYhe_55.cjs.map} +1 -1
  33. package/dist/{validate-YI4YkVTl.js → validate-DOeZKiGx.js} +3 -4
  34. package/dist/{validate-YI4YkVTl.js.map → validate-DOeZKiGx.js.map} +1 -1
  35. package/package.json +12 -21
  36. package/src/commands/agent/start.ts +17 -16
  37. package/src/commands/generate.ts +11 -7
  38. package/src/commands/init.ts +14 -14
  39. package/src/commands/mcp.ts +2 -2
  40. package/src/loggers/clackLogger.ts +49 -40
  41. package/src/loggers/githubActionsLogger.ts +36 -32
  42. package/src/loggers/plainLogger.ts +9 -9
  43. package/src/runners/generate.ts +9 -7
  44. package/src/utils/Writables.ts +2 -2
  45. package/src/utils/executeHooks.ts +4 -5
  46. package/src/utils/formatMsWithColor.ts +4 -4
  47. package/src/utils/getIntro.ts +52 -6
  48. package/src/utils/getSummary.ts +6 -6
  49. package/src/utils/packageManager.ts +3 -9
  50. package/src/utils/randomColor.ts +5 -6
  51. package/src/utils/watcher.ts +3 -3
  52. package/dist/generate-CQYwekvF.cjs.map +0 -1
  53. package/dist/generate-Cj8cU5XB.js.map +0 -1
  54. package/dist/index.d.cts +0 -6
  55. package/dist/init-BVwhJb7n.js.map +0 -1
  56. package/dist/init-Ckt9G-Yf.cjs.map +0 -1
  57. package/dist/mcp-C-e4yatL.js.map +0 -1
  58. package/dist/mcp-DGyip5BX.cjs.map +0 -1
  59. package/dist/package-CeCGexzv.cjs.map +0 -1
  60. package/dist/package-DNxKRFpk.js +0 -6
  61. package/dist/package-DNxKRFpk.js.map +0 -1
  62. package/dist/start-DqKYNdp1.cjs.map +0 -1
  63. package/dist/start-jaV7_Xss.js.map +0 -1
  64. package/src/utils/ansiColors.ts +0 -23
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/cli",
3
- "version": "4.28.0",
3
+ "version": "4.29.0",
4
4
  "description": "Command-line interface for Kubb, enabling easy generation of TypeScript, React-Query, Zod, and other code from OpenAPI specifications.",
5
5
  "keywords": [
6
6
  "cli",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "https://github.com/kubb-labs/kubb.git",
22
+ "url": "git+https://github.com/kubb-labs/kubb.git",
23
23
  "directory": "packages/cli"
24
24
  },
25
25
  "license": "MIT",
@@ -28,14 +28,12 @@
28
28
  "type": "module",
29
29
  "exports": {
30
30
  ".": {
31
- "require": "./dist/index.cjs",
32
- "import": "./dist/index.js"
31
+ "import": "./dist/index.js",
32
+ "require": "./dist/index.cjs"
33
33
  },
34
34
  "./package.json": "./package.json"
35
35
  },
36
- "main": "./dist/index.cjs",
37
- "module": "./dist/index.js",
38
- "types": "./dist/index.d.cts",
36
+ "types": "./dist/index.d.ts",
39
37
  "bin": {
40
38
  "kubb": "bin/kubb.cjs"
41
39
  },
@@ -58,24 +56,15 @@
58
56
  "chokidar": "^5.0.0",
59
57
  "citty": "^0.1.6",
60
58
  "cosmiconfig": "^9.0.0",
61
- "dotenv": "^17.3.1",
62
- "execa": "^9.6.1",
63
- "gradient-string": "^3.0.0",
64
59
  "jiti": "2.5.1",
65
- "latest-version": "^9.0.0",
66
- "picocolors": "^1.1.1",
67
- "seedrandom": "^3.0.5",
68
- "semver": "^7.7.4",
69
- "string-argv": "^0.3.2",
70
- "@kubb/core": "4.28.0"
60
+ "tinyexec": "^1.0.2",
61
+ "@kubb/core": "4.29.0"
71
62
  },
72
63
  "devDependencies": {
73
- "@types/seedrandom": "^3.0.8",
74
- "@types/semver": "^7.7.1",
75
64
  "source-map-support": "^0.5.21",
76
- "@kubb/agent": "4.28.0",
77
- "@kubb/mcp": "4.28.0",
78
- "@kubb/oas": "4.28.0"
65
+ "@kubb/agent": "4.29.0",
66
+ "@kubb/mcp": "4.29.0",
67
+ "@kubb/oas": "4.29.0"
79
68
  },
80
69
  "engines": {
81
70
  "node": ">=20"
@@ -85,6 +74,8 @@
85
74
  "access": "public",
86
75
  "registry": "https://registry.npmjs.org/"
87
76
  },
77
+ "main": "./dist/index.cjs",
78
+ "module": "./dist/index.js",
88
79
  "scripts": {
89
80
  "build": "tsdown && size-limit",
90
81
  "clean": "npx rimraf ./dist",
@@ -1,13 +1,11 @@
1
+ import { spawn } from 'node:child_process'
1
2
  import path from 'node:path'
2
3
  import * as process from 'node:process'
3
4
  import { fileURLToPath } from 'node:url'
4
-
5
+ import { styleText } from 'node:util'
5
6
  import * as clack from '@clack/prompts'
6
7
  import type { ArgsDef } from 'citty'
7
8
  import { defineCommand } from 'citty'
8
- import { config as loadEnv } from 'dotenv'
9
- import { execa } from 'execa'
10
- import pc from 'picocolors'
11
9
 
12
10
  const args = {
13
11
  config: {
@@ -53,8 +51,12 @@ type StartServerProps = {
53
51
 
54
52
  async function startServer({ port, host, configPath, noCache, allowWrite, allowAll }: StartServerProps): Promise<void> {
55
53
  try {
56
- // Load .env files into process.env (supports .env, .env.local, .env.*.local)
57
- loadEnv() // .env
54
+ // Load .env file into process.env using Node.js built-in (v20.12.0+)
55
+ try {
56
+ process.loadEnvFile()
57
+ } catch {
58
+ // .env file may not exist; ignore
59
+ }
58
60
 
59
61
  // Resolve the @kubb/agent package path
60
62
  const agentPkgUrl = import.meta.resolve('@kubb/agent/package.json')
@@ -90,20 +92,19 @@ async function startServer({ port, host, configPath, noCache, allowWrite, allowA
90
92
  KUBB_STUDIO_URL,
91
93
  }
92
94
 
93
- clack.log.step(pc.cyan('Starting agent server...'))
94
- clack.log.info(pc.dim(`Config: ${KUBB_AGENT_CONFIG}`))
95
- clack.log.info(pc.dim(`Host: ${HOST}`))
96
- clack.log.info(pc.dim(`Port: ${PORT}`))
95
+ clack.log.step(styleText('cyan', 'Starting agent server...'))
96
+ clack.log.info(styleText('dim', `Config: ${KUBB_AGENT_CONFIG}`))
97
+ clack.log.info(styleText('dim', `Host: ${HOST}`))
98
+ clack.log.info(styleText('dim', `Port: ${PORT}`))
97
99
  if (noCache) {
98
- clack.log.info(pc.dim('Session caching: disabled'))
100
+ clack.log.info(styleText('dim', 'Session caching: disabled'))
99
101
  }
100
102
  if (!KUBB_AGENT_ALLOW_WRITE && !KUBB_AGENT_ALLOW_ALL) {
101
- clack.log.warn(pc.yellow('Filesystem writes disabled. Use --allow-write or --allow-all to enable.'))
103
+ clack.log.warn(styleText('yellow', 'Filesystem writes disabled. Use --allow-write or --allow-all to enable.'))
102
104
  }
103
105
 
104
- // Use execa to spawn the server process
105
- await execa('node', [serverPath], {
106
- env,
106
+ spawn('node', [serverPath], {
107
+ env: { ...process.env, ...env },
107
108
  stdio: 'inherit',
108
109
  cwd: process.cwd(),
109
110
  })
@@ -132,7 +133,7 @@ const command = defineCommand({
132
133
 
133
134
  await startServer({ port, host, configPath, noCache, allowWrite, allowAll })
134
135
  } catch (error) {
135
- clack.log.error(pc.red('Failed to start agent server'))
136
+ clack.log.error(styleText('red', 'Failed to start agent server'))
136
137
  console.error(error)
137
138
  process.exit(1)
138
139
  }
@@ -1,13 +1,11 @@
1
1
  import path from 'node:path'
2
2
  import * as process from 'node:process'
3
+ import { styleText } from 'node:util'
3
4
  import * as clack from '@clack/prompts'
4
5
  import { type CLIOptions, isInputPath, type KubbEvents, LogLevel, PromiseManager } from '@kubb/core'
5
6
  import { AsyncEventEmitter, executeIfOnline, getConfigs } from '@kubb/core/utils'
6
7
  import type { ArgsDef, ParsedArgs } from 'citty'
7
8
  import { defineCommand, showUsage } from 'citty'
8
- import getLatestVersion from 'latest-version'
9
- import pc from 'picocolors'
10
- import { lt } from 'semver'
11
9
  import { version } from '../../package.json'
12
10
  import { setupLogger } from '../loggers/utils.ts'
13
11
  import { generate } from '../runners/generate.ts'
@@ -94,10 +92,16 @@ const command = defineCommand({
94
92
  await setupLogger(events, { logLevel })
95
93
 
96
94
  await executeIfOnline(async () => {
97
- const latestVersion = await getLatestVersion('@kubb/cli')
95
+ try {
96
+ const res = await fetch('https://registry.npmjs.org/@kubb/cli/latest')
97
+ const data = (await res.json()) as { version: string }
98
+ const latestVersion = data.version
98
99
 
99
- if (lt(version, latestVersion)) {
100
- await events.emit('version:new', version, latestVersion)
100
+ if (latestVersion && version < latestVersion) {
101
+ await events.emit('version:new', version, latestVersion)
102
+ }
103
+ } catch {
104
+ // Ignore network errors for version check
101
105
  }
102
106
  })
103
107
 
@@ -125,7 +129,7 @@ const command = defineCommand({
125
129
  events,
126
130
  })
127
131
 
128
- clack.log.step(pc.yellow(`Watching for changes in ${paths.join(' and ')}`))
132
+ clack.log.step(styleText('yellow', `Watching for changes in ${paths.join(' and ')}`))
129
133
  })
130
134
 
131
135
  return
@@ -1,9 +1,9 @@
1
1
  import fs from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import process from 'node:process'
4
+ import { styleText } from 'node:util'
4
5
  import * as clack from '@clack/prompts'
5
6
  import { defineCommand } from 'citty'
6
- import pc from 'picocolors'
7
7
  import { version } from '../../package.json'
8
8
  import { detectPackageManager, hasPackageJson, initPackageJson, installPackages, type PackageManagerInfo } from '../utils/packageManager.ts'
9
9
 
@@ -186,7 +186,7 @@ const command = defineCommand({
186
186
  const cwd = process.cwd()
187
187
  const yes = args.yes
188
188
 
189
- clack.intro(pc.bgCyan(pc.black(' Kubb Init ')))
189
+ clack.intro(styleText('bgCyan', styleText('black', ' Kubb Init ')))
190
190
 
191
191
  try {
192
192
  // Check/create package.json
@@ -215,14 +215,14 @@ const command = defineCommand({
215
215
  spinner.stop(`Created package.json with ${packageManager.name}`)
216
216
  } else {
217
217
  packageManager = detectPackageManager(cwd)
218
- clack.log.info(`Detected package manager: ${pc.cyan(packageManager.name)}`)
218
+ clack.log.info(`Detected package manager: ${styleText('cyan', packageManager.name)}`)
219
219
  }
220
220
 
221
221
  // Prompt for OpenAPI spec path
222
222
  let inputPath: string
223
223
  if (yes) {
224
224
  inputPath = DEFAULT_INPUT_PATH
225
- clack.log.info(`Using input path: ${pc.cyan(inputPath)}`)
225
+ clack.log.info(`Using input path: ${styleText('cyan', inputPath)}`)
226
226
  } else {
227
227
  const inputPathResult = await clack.text({
228
228
  message: 'Where is your OpenAPI specification located?',
@@ -244,7 +244,7 @@ const command = defineCommand({
244
244
  let outputPath: string
245
245
  if (yes) {
246
246
  outputPath = DEFAULT_OUTPUT_PATH
247
- clack.log.info(`Using output path: ${pc.cyan(outputPath)}`)
247
+ clack.log.info(`Using output path: ${styleText('cyan', outputPath)}`)
248
248
  } else {
249
249
  const outputPathResult = await clack.text({
250
250
  message: 'Where should the generated files be output?',
@@ -266,7 +266,7 @@ const command = defineCommand({
266
266
  let selectedPlugins: PluginOption[]
267
267
  if (yes) {
268
268
  selectedPlugins = plugins.filter((plugin) => DEFAULT_PLUGINS.includes(plugin.value))
269
- clack.log.info(`Using plugins: ${pc.cyan(selectedPlugins.map((p) => p.label).join(', '))}`)
269
+ clack.log.info(`Using plugins: ${styleText('cyan', selectedPlugins.map((p) => p.label).join(', '))}`)
270
270
  } else {
271
271
  const selectedPluginValues = await clack.multiselect({
272
272
  message: 'Select plugins to use:',
@@ -338,22 +338,22 @@ const command = defineCommand({
338
338
 
339
339
  // Success message
340
340
  clack.outro(
341
- pc.green('✓ All set!') +
341
+ styleText('green', '✓ All set!') +
342
342
  '\n\n' +
343
- pc.dim('Next steps:') +
343
+ styleText('dim', 'Next steps:') +
344
344
  '\n' +
345
- pc.cyan(` 1. Make sure your OpenAPI spec is at: ${inputPath}`) +
345
+ styleText('cyan', ` 1. Make sure your OpenAPI spec is at: ${inputPath}`) +
346
346
  '\n' +
347
- pc.cyan(' 2. Generate code with: npx kubb generate') +
347
+ styleText('cyan', ' 2. Generate code with: npx kubb generate') +
348
348
  '\n' +
349
- pc.cyan(' Or start a stream server with: npx kubb start') +
349
+ styleText('cyan', ' Or start a stream server with: npx kubb start') +
350
350
  '\n' +
351
- pc.cyan(` 3. Find generated files in: ${outputPath}`) +
351
+ styleText('cyan', ` 3. Find generated files in: ${outputPath}`) +
352
352
  '\n\n' +
353
- pc.dim(`Using ${packageManager.name} • Kubb v${version}`),
353
+ styleText('dim', `Using ${packageManager.name} • Kubb v${version}`),
354
354
  )
355
355
  } catch (error) {
356
- clack.log.error(pc.red('An error occurred during initialization'))
356
+ clack.log.error(styleText('red', 'An error occurred during initialization'))
357
357
  if (error instanceof Error) {
358
358
  clack.log.error(error.message)
359
359
  }
@@ -1,7 +1,7 @@
1
+ import { styleText } from 'node:util'
1
2
  import type { ArgsDef } from 'citty'
2
3
  import { defineCommand, showUsage } from 'citty'
3
4
  import { createJiti } from 'jiti'
4
- import pc from 'picocolors'
5
5
 
6
6
  const jiti = createJiti(import.meta.url, {
7
7
  sourceMaps: true,
@@ -40,7 +40,7 @@ const command = defineCommand({
40
40
  const { run } = mod
41
41
  try {
42
42
  console.log('⏳ Starting MCP server...')
43
- console.warn(pc.yellow('This feature is still under development — use with caution'))
43
+ console.warn(styleText('yellow', 'This feature is still under development — use with caution'))
44
44
  await run()
45
45
  } catch (error) {
46
46
  console.error((error as Error)?.message)
@@ -1,10 +1,10 @@
1
1
  import { relative } from 'node:path'
2
2
  import process from 'node:process'
3
+ import { styleText } from 'node:util'
3
4
  import * as clack from '@clack/prompts'
4
5
  import { defineLogger, LogLevel } from '@kubb/core'
5
6
  import { formatHrtime, formatMs } from '@kubb/core/utils'
6
- import { type ExecaError, execa } from 'execa'
7
- import pc from 'picocolors'
7
+ import { type NonZeroExitError, x } from 'tinyexec'
8
8
  import { formatMsWithColor } from '../utils/formatMsWithColor.ts'
9
9
  import { getIntro } from '../utils/getIntro.ts'
10
10
  import { getSummary } from '../utils/getSummary.ts'
@@ -60,18 +60,18 @@ export const clackLogger = defineLogger({
60
60
  if (state.totalPlugins > 0) {
61
61
  const pluginStr =
62
62
  state.failedPlugins > 0
63
- ? `Plugins ${pc.green(state.completedPlugins.toString())}/${state.totalPlugins} ${pc.red(`(${state.failedPlugins} failed)`)}`
64
- : `Plugins ${pc.green(state.completedPlugins.toString())}/${state.totalPlugins}`
63
+ ? `Plugins ${styleText('green', state.completedPlugins.toString())}/${state.totalPlugins} ${styleText('red', `(${state.failedPlugins} failed)`)}`
64
+ : `Plugins ${styleText('green', state.completedPlugins.toString())}/${state.totalPlugins}`
65
65
  parts.push(pluginStr)
66
66
  }
67
67
 
68
68
  if (state.totalFiles > 0) {
69
- parts.push(`Files ${pc.green(state.processedFiles.toString())}/${state.totalFiles}`)
69
+ parts.push(`Files ${styleText('green', state.processedFiles.toString())}/${state.totalFiles}`)
70
70
  }
71
71
 
72
72
  if (parts.length > 0) {
73
- parts.push(`${pc.green(duration)} elapsed`)
74
- clack.log.step(getMessage(parts.join(pc.dim(' | '))))
73
+ parts.push(`${styleText('green', duration)} elapsed`)
74
+ clack.log.step(getMessage(parts.join(styleText('dim', ' | '))))
75
75
  }
76
76
  }
77
77
 
@@ -84,7 +84,7 @@ export const clackLogger = defineLogger({
84
84
  second: '2-digit',
85
85
  })
86
86
 
87
- return [pc.dim(`[${timestamp}]`), message].join(' ')
87
+ return [styleText('dim', `[${timestamp}]`), message].join(' ')
88
88
  }
89
89
 
90
90
  return message
@@ -105,7 +105,7 @@ export const clackLogger = defineLogger({
105
105
  return
106
106
  }
107
107
 
108
- const text = getMessage([pc.blue('ℹ'), message, pc.dim(info)].join(' '))
108
+ const text = getMessage([styleText('blue', 'ℹ'), message, styleText('dim', info)].join(' '))
109
109
 
110
110
  if (state.isSpinning) {
111
111
  state.spinner.message(text)
@@ -119,7 +119,7 @@ export const clackLogger = defineLogger({
119
119
  return
120
120
  }
121
121
 
122
- const text = getMessage([pc.blue('✓'), message, logLevel >= LogLevel.info ? pc.dim(info) : undefined].filter(Boolean).join(' '))
122
+ const text = getMessage([styleText('blue', '✓'), message, logLevel >= LogLevel.info ? styleText('dim', info) : undefined].filter(Boolean).join(' '))
123
123
 
124
124
  if (state.isSpinning) {
125
125
  stopSpinner(text)
@@ -133,7 +133,9 @@ export const clackLogger = defineLogger({
133
133
  return
134
134
  }
135
135
 
136
- const text = getMessage([pc.yellow('⚠'), message, logLevel >= LogLevel.info ? pc.dim(info) : undefined].filter(Boolean).join(' '))
136
+ const text = getMessage(
137
+ [styleText('yellow', '⚠'), message, logLevel >= LogLevel.info && info ? styleText('dim', info) : undefined].filter(Boolean).join(' '),
138
+ )
137
139
 
138
140
  clack.log.warn(text)
139
141
  })
@@ -141,7 +143,7 @@ export const clackLogger = defineLogger({
141
143
  context.on('error', (error) => {
142
144
  const caused = error.cause as Error | undefined
143
145
 
144
- const text = [pc.red('✗'), error.message].join(' ')
146
+ const text = [styleText('red', '✗'), error.message].join(' ')
145
147
 
146
148
  if (state.isSpinning) {
147
149
  stopSpinner(getMessage(text))
@@ -153,15 +155,15 @@ export const clackLogger = defineLogger({
153
155
  if (logLevel >= LogLevel.debug && error.stack) {
154
156
  const frames = error.stack.split('\n').slice(1, 4)
155
157
  for (const frame of frames) {
156
- clack.log.message(getMessage(pc.dim(frame.trim())))
158
+ clack.log.message(getMessage(styleText('dim', frame.trim())))
157
159
  }
158
160
 
159
161
  if (caused?.stack) {
160
- clack.log.message(pc.dim(`└─ caused by ${caused.message}`))
162
+ clack.log.message(styleText('dim', `└─ caused by ${caused.message}`))
161
163
 
162
164
  const frames = caused.stack.split('\n').slice(1, 4)
163
165
  for (const frame of frames) {
164
- clack.log.message(getMessage(` ${pc.dim(frame.trim())}`))
166
+ clack.log.message(getMessage(` ${styleText('dim', frame.trim())}`))
165
167
  }
166
168
  }
167
169
  }
@@ -178,7 +180,7 @@ Run \`npm install -g @kubb/cli\` to update`,
178
180
  'Update available for `Kubb`',
179
181
  {
180
182
  width: 'auto',
181
- formatBorder: pc.yellow,
183
+ formatBorder: (s: string) => styleText('yellow', s),
182
184
  rounded: true,
183
185
  withGuide: false,
184
186
  contentAlign: 'center',
@@ -218,7 +220,7 @@ Run \`npm install -g @kubb/cli\` to update`,
218
220
  // Initialize progress tracking
219
221
  state.totalPlugins = config.plugins?.length || 0
220
222
 
221
- const text = getMessage(['Generation started', config.name ? `for ${pc.dim(config.name)}` : undefined].filter(Boolean).join(' '))
223
+ const text = getMessage(['Generation started', config.name ? `for ${styleText('dim', config.name)}` : undefined].filter(Boolean).join(' '))
222
224
 
223
225
  clack.intro(text)
224
226
  reset()
@@ -236,7 +238,7 @@ Run \`npm install -g @kubb/cli\` to update`,
236
238
  max: 100,
237
239
  size: 30,
238
240
  })
239
- const text = getMessage(`Generating ${pc.bold(plugin.name)}`)
241
+ const text = getMessage(`Generating ${styleText('bold', plugin.name)}`)
240
242
  progressBar.start(text)
241
243
 
242
244
  const interval = setInterval(() => {
@@ -265,7 +267,9 @@ Run \`npm install -g @kubb/cli\` to update`,
265
267
 
266
268
  const durationStr = formatMsWithColor(duration)
267
269
  const text = getMessage(
268
- success ? `${pc.bold(plugin.name)} completed in ${durationStr}` : `${pc.bold(plugin.name)} failed in ${pc.red(formatMs(duration))}`,
270
+ success
271
+ ? `${styleText('bold', plugin.name)} completed in ${durationStr}`
272
+ : `${styleText('bold', plugin.name)} failed in ${styleText('red', formatMs(duration))}`,
269
273
  )
270
274
 
271
275
  active.progressBar.stop(text)
@@ -337,7 +341,7 @@ Run \`npm install -g @kubb/cli\` to update`,
337
341
  })
338
342
 
339
343
  context.on('generation:end', (config) => {
340
- const text = getMessage(config.name ? `Generation completed for ${pc.dim(config.name)}` : 'Generation completed')
344
+ const text = getMessage(config.name ? `Generation completed for ${styleText('dim', config.name)}` : 'Generation completed')
341
345
 
342
346
  clack.outro(text)
343
347
  })
@@ -384,7 +388,7 @@ Run \`npm install -g @kubb/cli\` to update`,
384
388
 
385
389
  context.on('hook:start', async ({ id, command, args }) => {
386
390
  const commandWithArgs = args?.length ? `${command} ${args.join(' ')}` : command
387
- const text = getMessage(`Hook ${pc.dim(commandWithArgs)} started`)
391
+ const text = getMessage(`Hook ${styleText('dim', commandWithArgs)} started`)
388
392
 
389
393
  // Skip hook execution if no id is provided (e.g., during benchmarks or tests)
390
394
  if (!id) {
@@ -393,14 +397,14 @@ Run \`npm install -g @kubb/cli\` to update`,
393
397
 
394
398
  if (logLevel <= LogLevel.silent) {
395
399
  try {
396
- const result = await execa(command, args, {
397
- detached: true,
398
- stripFinalNewline: true,
400
+ const result = await x(command, [...(args ?? [])], {
401
+ nodeOptions: { detached: true },
402
+ throwOnError: true,
399
403
  })
400
404
 
401
405
  await context.emit('debug', {
402
406
  date: new Date(),
403
- logs: [result.stdout],
407
+ logs: [result.stdout.trimEnd()],
404
408
  })
405
409
 
406
410
  await context.emit('hook:end', {
@@ -411,9 +415,9 @@ Run \`npm install -g @kubb/cli\` to update`,
411
415
  error: null,
412
416
  })
413
417
  } catch (err) {
414
- const error = err as ExecaError
415
- const stderr = typeof error.stderr === 'string' ? error.stderr : String(error.stderr)
416
- const stdout = typeof error.stdout === 'string' ? error.stdout : String(error.stdout)
418
+ const error = err as NonZeroExitError
419
+ const stderr = error.output?.stderr ?? ''
420
+ const stdout = error.output?.stdout ?? ''
417
421
 
418
422
  await context.emit('debug', {
419
423
  date: new Date(),
@@ -445,28 +449,33 @@ Run \`npm install -g @kubb/cli\` to update`,
445
449
  clack.intro(text)
446
450
 
447
451
  const logger = clack.taskLog({
448
- title: getMessage(['Executing hook', logLevel >= LogLevel.info ? pc.dim(commandWithArgs) : undefined].filter(Boolean).join(' ')),
452
+ title: getMessage(['Executing hook', logLevel >= LogLevel.info ? styleText('dim', commandWithArgs) : undefined].filter(Boolean).join(' ')),
449
453
  })
450
454
 
451
455
  const writable = new ClackWritable(logger)
452
456
 
453
457
  try {
454
- const result = await execa(command, args, {
455
- detached: true,
456
- stdout: ['pipe', writable],
457
- stripFinalNewline: true,
458
+ const proc = x(command, [...(args ?? [])], {
459
+ nodeOptions: { detached: true },
460
+ throwOnError: true,
458
461
  })
459
462
 
463
+ for await (const line of proc) {
464
+ writable.write(line)
465
+ }
466
+
467
+ const result = await proc
468
+
460
469
  await context.emit('debug', {
461
470
  date: new Date(),
462
- logs: [result.stdout],
471
+ logs: [result.stdout.trimEnd()],
463
472
  })
464
473
 
465
474
  await context.emit('hook:end', { command, args, id, success: true, error: null })
466
475
  } catch (err) {
467
- const error = err as ExecaError
468
- const stderr = typeof error.stderr === 'string' ? error.stderr : String(error.stderr)
469
- const stdout = typeof error.stdout === 'string' ? error.stdout : String(error.stdout)
476
+ const error = err as NonZeroExitError
477
+ const stderr = error.output?.stderr ?? ''
478
+ const stdout = error.output?.stdout ?? ''
470
479
 
471
480
  await context.emit('debug', {
472
481
  date: new Date(),
@@ -493,7 +502,7 @@ Run \`npm install -g @kubb/cli\` to update`,
493
502
  }
494
503
 
495
504
  const commandWithArgs = args?.length ? `${command} ${args.join(' ')}` : command
496
- const text = getMessage(`Hook ${pc.dim(commandWithArgs)} successfully executed`)
505
+ const text = getMessage(`Hook ${styleText('dim', commandWithArgs)} successfully executed`)
497
506
 
498
507
  clack.outro(text)
499
508
  })
@@ -515,7 +524,7 @@ Run \`npm install -g @kubb/cli\` to update`,
515
524
  if (status === 'success') {
516
525
  clack.box(summary.join('\n'), getMessage(title), {
517
526
  width: 'auto',
518
- formatBorder: pc.green,
527
+ formatBorder: (s: string) => styleText('green', s),
519
528
  rounded: true,
520
529
  withGuide: false,
521
530
  contentAlign: 'left',
@@ -527,7 +536,7 @@ Run \`npm install -g @kubb/cli\` to update`,
527
536
 
528
537
  clack.box(summary.join('\n'), getMessage(title), {
529
538
  width: 'auto',
530
- formatBorder: pc.red,
539
+ formatBorder: (s: string) => styleText('red', s),
531
540
  rounded: true,
532
541
  withGuide: false,
533
542
  contentAlign: 'left',