@kubb/cli 5.0.0-beta.75 → 5.0.0-beta.77

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 (150) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +171 -51
  3. package/bin/kubb.js +9 -3
  4. package/dist/Telemetry-CxzkLSdD.js +284 -0
  5. package/dist/Telemetry-CxzkLSdD.js.map +1 -0
  6. package/dist/Telemetry-D8jhC5Bc.cjs +315 -0
  7. package/dist/Telemetry-D8jhC5Bc.cjs.map +1 -0
  8. package/dist/{define-Bdn8j5VM.cjs → defineCommand-Bo3yZTWI.cjs} +3 -21
  9. package/dist/defineCommand-Bo3yZTWI.cjs.map +1 -0
  10. package/dist/{define-Ctii4bel.js → defineCommand-DMEeqliP.js} +4 -16
  11. package/dist/defineCommand-DMEeqliP.js.map +1 -0
  12. package/dist/{errors-CjPmyZHy.js → errors-Dc_d7BfX.js} +2 -2
  13. package/dist/{errors-CjPmyZHy.js.map → errors-Dc_d7BfX.js.map} +1 -1
  14. package/dist/{errors-CLCjoSg0.cjs → errors-gxFK0vrp.cjs} +2 -2
  15. package/dist/{errors-CLCjoSg0.cjs.map → errors-gxFK0vrp.cjs.map} +1 -1
  16. package/dist/generate-DvnQaawe.js +77 -0
  17. package/dist/generate-DvnQaawe.js.map +1 -0
  18. package/dist/generate-Dw107fw0.cjs +76 -0
  19. package/dist/generate-Dw107fw0.cjs.map +1 -0
  20. package/dist/index.cjs +93 -149
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.ts +6 -1
  23. package/dist/index.js +93 -149
  24. package/dist/index.js.map +1 -1
  25. package/dist/init-CTY6arQX.cjs +53 -0
  26. package/dist/init-CTY6arQX.cjs.map +1 -0
  27. package/dist/init-DfWdONdA.js +53 -0
  28. package/dist/init-DfWdONdA.js.map +1 -0
  29. package/dist/mcp-Cn_LAuui.js +21 -0
  30. package/dist/mcp-Cn_LAuui.js.map +1 -0
  31. package/dist/mcp-D5bAmwu0.cjs +21 -0
  32. package/dist/mcp-D5bAmwu0.cjs.map +1 -0
  33. package/dist/{package-D5arPDnh.cjs → package-RNhs4w6c.cjs} +2 -2
  34. package/dist/package-RNhs4w6c.cjs.map +1 -0
  35. package/dist/package-pmOGZlq-.js +6 -0
  36. package/dist/package-pmOGZlq-.js.map +1 -0
  37. package/dist/run-44Zxh8Ec.js +289 -0
  38. package/dist/run-44Zxh8Ec.js.map +1 -0
  39. package/dist/run-BPLW8mrc.cjs +52 -0
  40. package/dist/run-BPLW8mrc.cjs.map +1 -0
  41. package/dist/run-DXEMoDFa.cjs +293 -0
  42. package/dist/run-DXEMoDFa.cjs.map +1 -0
  43. package/dist/run-Dv-1NGl-.js +32 -0
  44. package/dist/run-Dv-1NGl-.js.map +1 -0
  45. package/dist/run-Dzqgies_.js +1327 -0
  46. package/dist/run-Dzqgies_.js.map +1 -0
  47. package/dist/run-GFI-E4ua.cjs +33 -0
  48. package/dist/run-GFI-E4ua.cjs.map +1 -0
  49. package/dist/run-WfvBLKQY.js +51 -0
  50. package/dist/run-WfvBLKQY.js.map +1 -0
  51. package/dist/run-qhJgyKZX.cjs +1330 -0
  52. package/dist/run-qhJgyKZX.cjs.map +1 -0
  53. package/dist/tools-CZT9wSA6.cjs +175 -0
  54. package/dist/tools-CZT9wSA6.cjs.map +1 -0
  55. package/dist/tools-D0UogMU3.js +152 -0
  56. package/dist/tools-D0UogMU3.js.map +1 -0
  57. package/dist/validate-DRRJJptl.js +26 -0
  58. package/dist/validate-DRRJJptl.js.map +1 -0
  59. package/dist/validate-DYJrCiw5.cjs +26 -0
  60. package/dist/validate-DYJrCiw5.cjs.map +1 -0
  61. package/package.json +24 -28
  62. package/dist/agent-BEgI2HXH.cjs +0 -58
  63. package/dist/agent-BEgI2HXH.cjs.map +0 -1
  64. package/dist/agent-B_pirbeB.cjs +0 -116
  65. package/dist/agent-B_pirbeB.cjs.map +0 -1
  66. package/dist/agent-CTdJEHEs.js +0 -56
  67. package/dist/agent-CTdJEHEs.js.map +0 -1
  68. package/dist/agent-Ev5hU5hH.js +0 -112
  69. package/dist/agent-Ev5hU5hH.js.map +0 -1
  70. package/dist/constants-CnDXa1R6.cjs +0 -148
  71. package/dist/constants-CnDXa1R6.cjs.map +0 -1
  72. package/dist/constants-aL3CP_Wq.js +0 -95
  73. package/dist/constants-aL3CP_Wq.js.map +0 -1
  74. package/dist/define-Bdn8j5VM.cjs.map +0 -1
  75. package/dist/define-Ctii4bel.js.map +0 -1
  76. package/dist/generate-Cg8yufrw.js +0 -1753
  77. package/dist/generate-Cg8yufrw.js.map +0 -1
  78. package/dist/generate-DDCwNQNo.cjs +0 -65
  79. package/dist/generate-DDCwNQNo.cjs.map +0 -1
  80. package/dist/generate-K8MJ9aQF.cjs +0 -1756
  81. package/dist/generate-K8MJ9aQF.cjs.map +0 -1
  82. package/dist/generate-YPtfjsg4.js +0 -66
  83. package/dist/generate-YPtfjsg4.js.map +0 -1
  84. package/dist/init-Bu95ML_u.cjs +0 -25
  85. package/dist/init-Bu95ML_u.cjs.map +0 -1
  86. package/dist/init-CZ5Xq2Hd.cjs +0 -293
  87. package/dist/init-CZ5Xq2Hd.cjs.map +0 -1
  88. package/dist/init-eNRlotJK.js +0 -289
  89. package/dist/init-eNRlotJK.js.map +0 -1
  90. package/dist/init-ooJeOBGt.js +0 -25
  91. package/dist/init-ooJeOBGt.js.map +0 -1
  92. package/dist/mcp-C-d5N1wZ.js +0 -16
  93. package/dist/mcp-C-d5N1wZ.js.map +0 -1
  94. package/dist/mcp-CLcDV4Jm.cjs +0 -41
  95. package/dist/mcp-CLcDV4Jm.cjs.map +0 -1
  96. package/dist/mcp-D7EIR9fR.js +0 -40
  97. package/dist/mcp-D7EIR9fR.js.map +0 -1
  98. package/dist/mcp-Dpu8vzzj.cjs +0 -16
  99. package/dist/mcp-Dpu8vzzj.cjs.map +0 -1
  100. package/dist/package-D5arPDnh.cjs.map +0 -1
  101. package/dist/package-DqZsMLZ9.js +0 -6
  102. package/dist/package-DqZsMLZ9.js.map +0 -1
  103. package/dist/shell-475fQKaX.cjs +0 -62
  104. package/dist/shell-475fQKaX.cjs.map +0 -1
  105. package/dist/shell-DLzN4fRo.js +0 -51
  106. package/dist/shell-DLzN4fRo.js.map +0 -1
  107. package/dist/telemetry-DN95_2pF.cjs +0 -282
  108. package/dist/telemetry-DN95_2pF.cjs.map +0 -1
  109. package/dist/telemetry-LgT_sdPe.js +0 -245
  110. package/dist/telemetry-LgT_sdPe.js.map +0 -1
  111. package/dist/validate-CIR3_lZI.js +0 -25
  112. package/dist/validate-CIR3_lZI.js.map +0 -1
  113. package/dist/validate-DcqUb4DM.cjs +0 -25
  114. package/dist/validate-DcqUb4DM.cjs.map +0 -1
  115. package/dist/validate-kLJoT_hi.js +0 -33
  116. package/dist/validate-kLJoT_hi.js.map +0 -1
  117. package/dist/validate-yKKzqEZ5.cjs +0 -34
  118. package/dist/validate-yKKzqEZ5.cjs.map +0 -1
  119. package/src/commands/agent/start.ts +0 -47
  120. package/src/commands/agent.ts +0 -8
  121. package/src/commands/generate.ts +0 -57
  122. package/src/commands/init.ts +0 -20
  123. package/src/commands/mcp.ts +0 -12
  124. package/src/commands/validate.ts +0 -20
  125. package/src/constants.ts +0 -104
  126. package/src/index.ts +0 -43
  127. package/src/loggers/clackLogger.ts +0 -458
  128. package/src/loggers/fileSystemLogger.ts +0 -138
  129. package/src/loggers/githubActionsLogger.ts +0 -379
  130. package/src/loggers/plainLogger.ts +0 -254
  131. package/src/loggers/types.ts +0 -1
  132. package/src/loggers/utils.ts +0 -106
  133. package/src/runners/agent.ts +0 -149
  134. package/src/runners/generate.ts +0 -333
  135. package/src/runners/init.ts +0 -296
  136. package/src/runners/mcp.ts +0 -45
  137. package/src/runners/validate.ts +0 -39
  138. package/src/types.ts +0 -11
  139. package/src/utils/Writables.ts +0 -17
  140. package/src/utils/executeHooks.ts +0 -45
  141. package/src/utils/flags.ts +0 -9
  142. package/src/utils/getConfig.ts +0 -10
  143. package/src/utils/getCosmiConfig.ts +0 -80
  144. package/src/utils/getSummary.ts +0 -68
  145. package/src/utils/packageManager.ts +0 -23
  146. package/src/utils/runHook.ts +0 -91
  147. package/src/utils/telemetry.ts +0 -273
  148. package/src/utils/watcher.ts +0 -19
  149. /package/dist/{chunk-ByKO4r7w.cjs → rolldown-runtime-Bx3C2hgW.cjs} +0 -0
  150. /package/dist/{chunk--u3MIqq1.js → rolldown-runtime-C0LytTxp.js} +0 -0
@@ -1,254 +0,0 @@
1
- import { relative } from 'node:path'
2
- import { formatMs, toCause } from '@internals/utils'
3
- import { defineLogger, logLevel as logLevelMap } from '@kubb/core'
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'
8
-
9
- /**
10
- * Plain console adapter for non-TTY environments with simple `console.log` output.
11
- */
12
- export const plainLogger = defineLogger({
13
- name: 'plain',
14
- install(context, options) {
15
- const logLevel = options?.logLevel ?? logLevelMap.info
16
-
17
- function getMessage(message: string): string {
18
- return formatMessage(message, logLevel)
19
- }
20
-
21
- context.on('kubb:info', ({ message, info }) => {
22
- if (logLevel <= logLevelMap.silent) {
23
- return
24
- }
25
-
26
- const text = getMessage(['ℹ', message, info].join(' '))
27
-
28
- console.log(text)
29
- })
30
-
31
- context.on('kubb:success', ({ message, info = '' }) => {
32
- if (logLevel <= logLevelMap.silent) {
33
- return
34
- }
35
-
36
- const text = getMessage(['✓', message, logLevel >= logLevelMap.info ? info : undefined].filter(Boolean).join(' '))
37
-
38
- console.log(text)
39
- })
40
-
41
- context.on('kubb:warn', ({ message, info }) => {
42
- if (logLevel < logLevelMap.warn) {
43
- return
44
- }
45
-
46
- const text = getMessage(['⚠', message, logLevel >= logLevelMap.info ? info : undefined].filter(Boolean).join(' '))
47
-
48
- console.log(text)
49
- })
50
-
51
- context.on('kubb:error', ({ error }) => {
52
- const caused = toCause(error)
53
-
54
- const text = getMessage(['✗', error.message].join(' '))
55
-
56
- console.log(text)
57
-
58
- // Show stack trace in debug mode (first 3 frames)
59
- if (logLevel >= logLevelMap.debug && error.stack) {
60
- const frames = error.stack.split('\n').slice(1, 4)
61
- for (const frame of frames) {
62
- console.log(getMessage(frame.trim()))
63
- }
64
-
65
- if (caused?.stack) {
66
- console.log(`└─ caused by ${caused.message}`)
67
-
68
- const frames = caused.stack.split('\n').slice(1, 4)
69
- for (const frame of frames) {
70
- console.log(getMessage(` ${frame.trim()}`))
71
- }
72
- }
73
- }
74
- })
75
-
76
- context.on('kubb:lifecycle:start', () => {
77
- console.log('Kubb CLI 🧩')
78
- })
79
-
80
- context.on('kubb:config:start', () => {
81
- if (logLevel <= logLevelMap.silent) {
82
- return
83
- }
84
-
85
- const text = getMessage('Configuration started')
86
-
87
- console.log(text)
88
- })
89
-
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
- })
99
-
100
- context.on('kubb:generation:start', () => {
101
- const text = getMessage('Generation started')
102
-
103
- console.log(text)
104
- })
105
-
106
- context.on('kubb:plugin:start', ({ plugin }) => {
107
- if (logLevel <= logLevelMap.silent) {
108
- return
109
- }
110
- const text = getMessage(`Generating ${plugin.name}`)
111
-
112
- console.log(text)
113
- })
114
-
115
- context.on('kubb:plugin:end', ({ plugin, duration, success }) => {
116
- if (logLevel <= logLevelMap.silent) {
117
- return
118
- }
119
-
120
- const durationStr = formatMs(duration)
121
- const text = getMessage(success ? `${plugin.name} completed in ${durationStr}` : `${plugin.name} failed in ${durationStr}`)
122
-
123
- console.log(text)
124
- })
125
-
126
- context.on('kubb:files:processing:start', ({ files }) => {
127
- if (logLevel <= logLevelMap.silent) {
128
- return
129
- }
130
-
131
- const text = getMessage(`Writing ${files.length} files`)
132
-
133
- console.log(text)
134
- })
135
-
136
- context.on('kubb:file:processing:update', ({ file, config }) => {
137
- if (logLevel <= logLevelMap.silent) {
138
- return
139
- }
140
-
141
- const text = getMessage(`Writing ${relative(config.root, file.path)}`)
142
-
143
- console.log(text)
144
- })
145
-
146
- context.on('kubb:files:processing:end', () => {
147
- if (logLevel <= logLevelMap.silent) {
148
- return
149
- }
150
-
151
- const text = getMessage('Files written successfully')
152
-
153
- console.log(text)
154
- })
155
-
156
- context.on('kubb:generation:end', ({ config }) => {
157
- const text = getMessage(config.name ? `Generation completed for ${config.name}` : 'Generation completed')
158
-
159
- console.log(text)
160
- })
161
-
162
- context.on('kubb:format:start', () => {
163
- if (logLevel <= logLevelMap.silent) {
164
- return
165
- }
166
-
167
- const text = getMessage('Format started')
168
-
169
- console.log(text)
170
- })
171
-
172
- context.on('kubb:format:end', () => {
173
- if (logLevel <= logLevelMap.silent) {
174
- return
175
- }
176
-
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
185
- }
186
-
187
- const text = getMessage('Lint started')
188
-
189
- console.log(text)
190
- })
191
-
192
- context.on('kubb:lint:end', () => {
193
- if (logLevel <= logLevelMap.silent) {
194
- return
195
- }
196
-
197
- const text = getMessage('Lint completed')
198
-
199
- console.log(text)
200
- })
201
-
202
- context.on('kubb:hook:start', async ({ id, command, args }) => {
203
- const commandWithArgs = formatCommandWithArgs(command, args)
204
- const text = getMessage(`Hook ${commandWithArgs} started`)
205
-
206
- if (logLevel > logLevelMap.silent) {
207
- console.log(text)
208
- }
209
-
210
- // Skip hook execution if no id is provided (e.g., during benchmarks or tests)
211
- if (!id) {
212
- return
213
- }
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
- })
238
-
239
- context.on('kubb:generation:summary', ({ config, pluginTimings, status, hrStart, failedPlugins, filesCreated }) => {
240
- const summary = getSummary({
241
- failedPlugins,
242
- filesCreated,
243
- config,
244
- status,
245
- hrStart,
246
- pluginTimings: logLevel >= logLevelMap.verbose ? pluginTimings : undefined,
247
- })
248
-
249
- console.log(SUMMARY_SEPARATOR)
250
- console.log(summary.join('\n'))
251
- console.log(SUMMARY_SEPARATOR)
252
- })
253
- },
254
- })
@@ -1 +0,0 @@
1
- export type LoggerType = 'clack' | 'github-actions' | 'plain'
@@ -1,106 +0,0 @@
1
- import { styleText } from 'node:util'
2
- import { canUseTTY, formatHrtime, isGitHubActions } from '@internals/utils'
3
- import type { Logger, LoggerContext, LoggerOptions } from '@kubb/core'
4
- import { logLevel as logLevelMap } from '@kubb/core'
5
- import { clackLogger } from './clackLogger.ts'
6
- import { fileSystemLogger } from './fileSystemLogger.ts'
7
- import { githubActionsLogger } from './githubActionsLogger.ts'
8
- import { plainLogger } from './plainLogger.ts'
9
- import type { LoggerType } from './types.ts'
10
-
11
- /**
12
- * Optionally prefix a message with a [HH:MM:SS] timestamp when logLevel >= verbose.
13
- * Shared across all logger adapters to avoid duplication.
14
- */
15
- export function formatMessage(message: string, logLevel: number): string {
16
- if (logLevel >= logLevelMap.verbose) {
17
- const timestamp = new Date().toLocaleTimeString('en-US', {
18
- hour12: false,
19
- hour: '2-digit',
20
- minute: '2-digit',
21
- second: '2-digit',
22
- })
23
- return `${styleText('dim', `[${timestamp}]`)} ${message}`
24
- }
25
- return message
26
- }
27
-
28
- type ProgressState = {
29
- totalPlugins: number
30
- completedPlugins: number
31
- failedPlugins: number
32
- totalFiles: number
33
- processedFiles: number
34
- hrStart: [number, number]
35
- }
36
-
37
- /**
38
- * Build the progress summary line shared by clack and GitHub Actions loggers.
39
- * Returns null when there is nothing to display.
40
- */
41
- export function buildProgressLine(state: ProgressState): string | null {
42
- const parts: string[] = []
43
- const duration = formatHrtime(state.hrStart)
44
-
45
- if (state.totalPlugins > 0) {
46
- const pluginStr =
47
- state.failedPlugins > 0
48
- ? `Plugins ${styleText('green', state.completedPlugins.toString())}/${state.totalPlugins} ${styleText('red', `(${state.failedPlugins} failed)`)}`
49
- : `Plugins ${styleText('green', state.completedPlugins.toString())}/${state.totalPlugins}`
50
- parts.push(pluginStr)
51
- }
52
-
53
- if (state.totalFiles > 0) {
54
- parts.push(`Files ${styleText('green', state.processedFiles.toString())}/${state.totalFiles}`)
55
- }
56
-
57
- if (parts.length === 0) {
58
- return null
59
- }
60
-
61
- parts.push(`${styleText('green', duration)} elapsed`)
62
- return parts.join(styleText('dim', ' | '))
63
- }
64
-
65
- /**
66
- * Join a command and its optional args into a single display string.
67
- * e.g. ("prettier", ["--write", "."]) → "prettier --write ."
68
- */
69
- export function formatCommandWithArgs(command: string, args?: readonly string[]): string {
70
- return args?.length ? `${command} ${args.join(' ')}` : command
71
- }
72
-
73
- function detectLogger(): LoggerType {
74
- if (isGitHubActions()) {
75
- return 'github-actions'
76
- }
77
- if (canUseTTY()) {
78
- return 'clack'
79
- }
80
- return 'plain'
81
- }
82
-
83
- const logMapper = {
84
- clack: clackLogger,
85
- plain: plainLogger,
86
- 'github-actions': githubActionsLogger,
87
- } as const satisfies Record<LoggerType, Logger>
88
-
89
- export async function setupLogger(context: LoggerContext, { logLevel }: LoggerOptions): Promise<void> {
90
- const type = detectLogger()
91
-
92
- const logger = logMapper[type] as Logger
93
-
94
- if (!logger) {
95
- throw new Error(`Unknown adapter type: ${type}`)
96
- }
97
-
98
- // Install primary logger
99
- const cleanup = await logger.install(context, { logLevel })
100
-
101
- if (logLevel >= logLevelMap.debug) {
102
- await fileSystemLogger.install(context, { logLevel })
103
- }
104
-
105
- return cleanup
106
- }
@@ -1,149 +0,0 @@
1
- import net from 'node:net'
2
- import path from 'node:path'
3
- import * as process from 'node:process'
4
- import { fileURLToPath } from 'node:url'
5
- import { styleText } from 'node:util'
6
- import * as clack from '@clack/prompts'
7
- import { spawnAsync } from '@internals/utils'
8
- import { agentDefaults } from '../constants.ts'
9
- import { buildTelemetryEvent, sendTelemetry } from '../utils/telemetry.ts'
10
-
11
- type AgentStartOptions = {
12
- port: string | undefined
13
- host: string
14
- configPath: string | undefined
15
- allowWrite: boolean
16
- allowAll: boolean
17
- version: string
18
- }
19
-
20
- type ResolvedAgentStartEnvironment = {
21
- port: string
22
- host: string
23
- allowWrite: boolean
24
- allowAll: boolean
25
- agentConfigPath: string
26
- env: NodeJS.ProcessEnv
27
- }
28
-
29
- /**
30
- * Resolves the environment passed to the detached agent process using CLI values first, then environment values, then CLI defaults.
31
- */
32
- function resolveAgentStartEnvironment({ port, host, configPath, allowWrite, allowAll }: Omit<AgentStartOptions, 'version'>): ResolvedAgentStartEnvironment {
33
- const resolvedPort = port ?? process.env.PORT ?? agentDefaults.port
34
- const resolvedHost = host !== agentDefaults.host ? host : (process.env.HOST ?? agentDefaults.host)
35
- const resolvedAllowAll = allowAll || process.env.KUBB_AGENT_ALLOW_ALL === 'true'
36
- const resolvedAllowWrite = resolvedAllowAll || allowWrite || process.env.KUBB_AGENT_ALLOW_WRITE === 'true'
37
- const agentRoot = process.env.KUBB_AGENT_ROOT ?? process.cwd()
38
- const agentConfigPath = path.resolve(process.cwd(), configPath || process.env.KUBB_AGENT_CONFIG || agentDefaults.configFile)
39
-
40
- return {
41
- port: resolvedPort,
42
- host: resolvedHost,
43
- allowWrite: resolvedAllowWrite,
44
- allowAll: resolvedAllowAll,
45
- agentConfigPath,
46
- env: {
47
- ...process.env,
48
- PORT: resolvedPort,
49
- HOST: resolvedHost,
50
- KUBB_AGENT_ROOT: agentRoot,
51
- KUBB_AGENT_CONFIG: agentConfigPath,
52
- KUBB_AGENT_ALLOW_WRITE: String(resolvedAllowWrite),
53
- KUBB_AGENT_ALLOW_ALL: String(resolvedAllowAll),
54
- KUBB_AGENT_TOKEN: process.env.KUBB_AGENT_TOKEN,
55
- KUBB_AGENT_RETRY_TIMEOUT: process.env.KUBB_AGENT_RETRY_TIMEOUT ?? agentDefaults.retryTimeout,
56
- KUBB_STUDIO_URL: process.env.KUBB_STUDIO_URL ?? agentDefaults.studioUrl,
57
- },
58
- }
59
- }
60
-
61
- function isPortAvailable(port: number, host: string): Promise<boolean> {
62
- return new Promise((resolve) => {
63
- const server = net.createServer()
64
- server.once('error', () => resolve(false))
65
- server.once('listening', () => {
66
- server.close()
67
- resolve(true)
68
- })
69
- server.listen(port, host)
70
- })
71
- }
72
-
73
- export async function runAgentStart({ port, host, configPath, allowWrite, allowAll, version }: AgentStartOptions): Promise<void> {
74
- const hrStart = process.hrtime()
75
-
76
- try {
77
- // Load .env file into process.env using Node.js built-in (v20.12.0+)
78
- try {
79
- process.loadEnvFile()
80
- } catch {
81
- // .env file may not exist; ignore
82
- }
83
-
84
- // Resolve the @kubb/agent package path
85
- let agentPkgUrl: string
86
- try {
87
- agentPkgUrl = import.meta.resolve('@kubb/agent/package.json')
88
- } catch (_e) {
89
- console.error(`Import of '@kubb/agent' is required to start the Agent server`)
90
- process.exit(1)
91
- }
92
- const agentPkgPath = fileURLToPath(agentPkgUrl)
93
- const agentDir = path.dirname(agentPkgPath)
94
- const serverPath = path.join(agentDir, agentDefaults.serverEntryPath)
95
-
96
- const resolvedEnv = resolveAgentStartEnvironment({
97
- port,
98
- host,
99
- configPath,
100
- allowWrite,
101
- allowAll,
102
- })
103
- const numericPort = Number(resolvedEnv.port)
104
-
105
- if (!Number.isInteger(numericPort) || numericPort <= 0) {
106
- throw new Error(`Invalid port "${resolvedEnv.port}". Provide a positive integer with --port or PORT.`)
107
- }
108
-
109
- clack.log.step(styleText('cyan', 'Starting agent server...'))
110
- clack.log.info(styleText('dim', `Config: ${resolvedEnv.agentConfigPath}`))
111
- clack.log.info(styleText('dim', `Host: ${resolvedEnv.host}`))
112
- clack.log.info(styleText('dim', `Port: ${resolvedEnv.port}`))
113
- if (!resolvedEnv.allowWrite && !resolvedEnv.allowAll) {
114
- clack.log.warn(styleText('yellow', 'Filesystem writes disabled. Use --allow-write or --allow-all to enable.'))
115
- }
116
-
117
- if (!(await isPortAvailable(numericPort, resolvedEnv.host))) {
118
- clack.log.error(styleText('red', `Port ${resolvedEnv.port} is already in use. Stop the existing process or choose a different port with --port.`))
119
- process.exit(1)
120
- }
121
-
122
- // Spawns the server as a detached background process so the CLI can exit independently.
123
- await spawnAsync('node', [serverPath], {
124
- env: resolvedEnv.env,
125
- cwd: process.cwd(),
126
- })
127
-
128
- await sendTelemetry(
129
- buildTelemetryEvent({
130
- command: 'agent',
131
- kubbVersion: version,
132
- hrStart,
133
- status: 'success',
134
- }),
135
- )
136
- } catch (error) {
137
- await sendTelemetry(
138
- buildTelemetryEvent({
139
- command: 'agent',
140
- kubbVersion: version,
141
- hrStart,
142
- status: 'failed',
143
- }),
144
- )
145
- clack.log.error(styleText('red', 'Failed to start agent server'))
146
- console.error(error)
147
- process.exit(1)
148
- }
149
- }