@kubb/cli 4.32.3 → 4.33.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 (137) hide show
  1. package/dist/agent-CJ69TqoO.js +87 -0
  2. package/dist/agent-CJ69TqoO.js.map +1 -0
  3. package/dist/agent-CduUX7Ye.cjs +91 -0
  4. package/dist/agent-CduUX7Ye.cjs.map +1 -0
  5. package/dist/agent-D0A3RQho.js +57 -0
  6. package/dist/agent-D0A3RQho.js.map +1 -0
  7. package/dist/agent-DrnwQBZf.cjs +60 -0
  8. package/dist/agent-DrnwQBZf.cjs.map +1 -0
  9. package/dist/constants-CEKRremI.js +79 -0
  10. package/dist/constants-CEKRremI.js.map +1 -0
  11. package/dist/constants-CnPOlsJq.cjs +126 -0
  12. package/dist/constants-CnPOlsJq.cjs.map +1 -0
  13. package/dist/errors-BUjJsNoe.cjs +44 -0
  14. package/dist/errors-BUjJsNoe.cjs.map +1 -0
  15. package/dist/errors-bSLTEh4e.js +27 -0
  16. package/dist/errors-bSLTEh4e.js.map +1 -0
  17. package/dist/{generate-DFdkL6Kp.cjs → generate-ByMgAV76.cjs} +423 -577
  18. package/dist/generate-ByMgAV76.cjs.map +1 -0
  19. package/dist/generate-CiUPO5ds.cjs +65 -0
  20. package/dist/generate-CiUPO5ds.cjs.map +1 -0
  21. package/dist/generate-DIIxtkWT.js +66 -0
  22. package/dist/generate-DIIxtkWT.js.map +1 -0
  23. package/dist/{generate-zZuxBP8z.js → generate-HP5ySfjV.js} +422 -577
  24. package/dist/generate-HP5ySfjV.js.map +1 -0
  25. package/dist/index.cjs +226 -35
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +226 -35
  29. package/dist/index.js.map +1 -1
  30. package/dist/init-Cd1hCb7q.cjs +296 -0
  31. package/dist/init-Cd1hCb7q.cjs.map +1 -0
  32. package/dist/init-DLNrkDF4.js +25 -0
  33. package/dist/init-DLNrkDF4.js.map +1 -0
  34. package/dist/init-Df_aXezV.cjs +24 -0
  35. package/dist/init-Df_aXezV.cjs.map +1 -0
  36. package/dist/init-DyKK2fTp.js +291 -0
  37. package/dist/init-DyKK2fTp.js.map +1 -0
  38. package/dist/jiti-BdskUHhD.cjs +16 -0
  39. package/dist/jiti-BdskUHhD.cjs.map +1 -0
  40. package/dist/jiti-Cl7t20dO.js +11 -0
  41. package/dist/jiti-Cl7t20dO.js.map +1 -0
  42. package/dist/mcp-B73FC8dF.cjs +42 -0
  43. package/dist/mcp-B73FC8dF.cjs.map +1 -0
  44. package/dist/mcp-Bd9LITaI.js +16 -0
  45. package/dist/mcp-Bd9LITaI.js.map +1 -0
  46. package/dist/mcp-Cf-1dsB-.js +41 -0
  47. package/dist/mcp-Cf-1dsB-.js.map +1 -0
  48. package/dist/mcp-Clg-Qnkr.cjs +15 -0
  49. package/dist/mcp-Clg-Qnkr.cjs.map +1 -0
  50. package/dist/package-681jTtCk.js +6 -0
  51. package/dist/package-681jTtCk.js.map +1 -0
  52. package/dist/{package-C2pulzfz.cjs → package-aKgzEJtp.cjs} +2 -2
  53. package/dist/package-aKgzEJtp.cjs.map +1 -0
  54. package/dist/{telemetry-DYWvlxqs.js → telemetry-C4gOKX2x.js} +31 -10
  55. package/dist/telemetry-C4gOKX2x.js.map +1 -0
  56. package/dist/{telemetry-BDSSqUiG.cjs → telemetry-T5IA2dWA.cjs} +40 -7
  57. package/dist/telemetry-T5IA2dWA.cjs.map +1 -0
  58. package/dist/types-CLtz0jem.js +25 -0
  59. package/dist/types-CLtz0jem.js.map +1 -0
  60. package/dist/types-Ck2lzFON.cjs +36 -0
  61. package/dist/types-Ck2lzFON.cjs.map +1 -0
  62. package/dist/validate-Chjg23AE.js +41 -0
  63. package/dist/validate-Chjg23AE.js.map +1 -0
  64. package/dist/validate-Cr26q5xX.js +25 -0
  65. package/dist/validate-Cr26q5xX.js.map +1 -0
  66. package/dist/validate-DURmg-2Q.cjs +24 -0
  67. package/dist/validate-DURmg-2Q.cjs.map +1 -0
  68. package/dist/validate-Dqi9T_c4.cjs +42 -0
  69. package/dist/validate-Dqi9T_c4.cjs.map +1 -0
  70. package/package.json +5 -6
  71. package/src/cli/adapters/nodeAdapter.ts +159 -0
  72. package/src/cli/help.ts +36 -0
  73. package/src/cli/index.ts +16 -0
  74. package/src/cli/parse.ts +18 -0
  75. package/src/cli/schema.ts +38 -0
  76. package/src/cli/types.ts +95 -0
  77. package/src/commands/agent/start.ts +27 -136
  78. package/src/commands/agent.ts +6 -25
  79. package/src/commands/generate.ts +26 -158
  80. package/src/commands/init.ts +9 -360
  81. package/src/commands/mcp.ts +7 -52
  82. package/src/commands/validate.ts +9 -60
  83. package/src/constants.ts +77 -0
  84. package/src/index.ts +36 -42
  85. package/src/loggers/clackLogger.ts +42 -140
  86. package/src/loggers/fileSystemLogger.ts +1 -12
  87. package/src/loggers/githubActionsLogger.ts +36 -101
  88. package/src/loggers/plainLogger.ts +23 -70
  89. package/src/loggers/utils.ts +66 -2
  90. package/src/runners/agent.ts +100 -0
  91. package/src/runners/generate.ts +208 -100
  92. package/src/runners/init.ts +322 -0
  93. package/src/runners/mcp.ts +32 -0
  94. package/src/runners/validate.ts +35 -0
  95. package/src/utils/Writables.ts +2 -2
  96. package/src/utils/envDetection.ts +34 -0
  97. package/src/utils/errors.ts +23 -0
  98. package/src/utils/executeHooks.ts +18 -6
  99. package/src/utils/getCosmiConfig.ts +10 -11
  100. package/src/utils/getIntro.ts +17 -18
  101. package/src/utils/getSummary.ts +11 -15
  102. package/src/utils/jiti.ts +9 -0
  103. package/src/utils/packageManager.ts +3 -3
  104. package/src/utils/randomColor.ts +3 -12
  105. package/src/utils/runHook.ts +75 -0
  106. package/src/utils/spawnAsync.ts +47 -0
  107. package/src/utils/telemetry.ts +8 -25
  108. package/src/utils/watcher.ts +2 -4
  109. package/dist/agent-BuijLPSZ.cjs +0 -20
  110. package/dist/agent-BuijLPSZ.cjs.map +0 -1
  111. package/dist/agent-Dswt_kxP.js +0 -20
  112. package/dist/agent-Dswt_kxP.js.map +0 -1
  113. package/dist/generate-DFdkL6Kp.cjs.map +0 -1
  114. package/dist/generate-zZuxBP8z.js.map +0 -1
  115. package/dist/init-CNLk2fNd.js +0 -304
  116. package/dist/init-CNLk2fNd.js.map +0 -1
  117. package/dist/init-CSP6FGaW.cjs +0 -308
  118. package/dist/init-CSP6FGaW.cjs.map +0 -1
  119. package/dist/mcp-44Od-yig.cjs +0 -57
  120. package/dist/mcp-44Od-yig.cjs.map +0 -1
  121. package/dist/mcp-CgaHrkDs.js +0 -57
  122. package/dist/mcp-CgaHrkDs.js.map +0 -1
  123. package/dist/package--eaEMq2R.js +0 -6
  124. package/dist/package--eaEMq2R.js.map +0 -1
  125. package/dist/package-C2pulzfz.cjs.map +0 -1
  126. package/dist/start-CB8afXV6.cjs +0 -134
  127. package/dist/start-CB8afXV6.cjs.map +0 -1
  128. package/dist/start-DHPjtHJj.js +0 -131
  129. package/dist/start-DHPjtHJj.js.map +0 -1
  130. package/dist/telemetry-BDSSqUiG.cjs.map +0 -1
  131. package/dist/telemetry-DYWvlxqs.js.map +0 -1
  132. package/dist/validate-C7s0cFnp.cjs +0 -66
  133. package/dist/validate-C7s0cFnp.cjs.map +0 -1
  134. package/dist/validate-_7cmvjg_.js +0 -66
  135. package/dist/validate-_7cmvjg_.js.map +0 -1
  136. package/src/loggers/envDetection.ts +0 -28
  137. package/src/loggers/index.ts +0 -5
@@ -0,0 +1,36 @@
1
+ import { styleText } from 'node:util'
2
+ import { getCommandSchema } from './schema.ts'
3
+ import type { CommandDefinition, OptionSchema } from './types.ts'
4
+
5
+ /** Prints formatted help output for a command using its `CommandDefinition`. */
6
+ export function renderHelp(def: CommandDefinition, parentName?: string): void {
7
+ const schema = getCommandSchema([def])[0]!
8
+
9
+ const programName = parentName ? `${parentName} ${schema.name}` : schema.name
10
+
11
+ const argsPart = schema.arguments?.length ? ` ${schema.arguments.join(' ')}` : ''
12
+ const subCmdPart = schema.subCommands.length ? ' <command>' : ''
13
+ console.log(`\n${styleText('bold', 'Usage:')} ${programName}${argsPart}${subCmdPart} [options]\n`)
14
+
15
+ if (schema.description) {
16
+ console.log(` ${schema.description}\n`)
17
+ }
18
+
19
+ if (schema.subCommands.length) {
20
+ console.log(styleText('bold', 'Commands:'))
21
+ for (const sub of schema.subCommands) {
22
+ console.log(` ${styleText('cyan', sub.name.padEnd(16))}${sub.description}`)
23
+ }
24
+ console.log()
25
+ }
26
+
27
+ const options: OptionSchema[] = [...schema.options, { name: 'help', flags: '-h, --help', type: 'boolean' as const, description: 'Show help' }]
28
+
29
+ console.log(styleText('bold', 'Options:'))
30
+ for (const opt of options) {
31
+ const flags = styleText('cyan', opt.flags.padEnd(30))
32
+ const defaultPart = opt.default !== undefined ? styleText('dim', ` (default: ${opt.default})`) : ''
33
+ console.log(` ${flags}${opt.description}${defaultPart}`)
34
+ }
35
+ console.log()
36
+ }
@@ -0,0 +1,16 @@
1
+ export { nodeAdapter } from './adapters/nodeAdapter.ts'
2
+ export { createCLI } from './parse.ts'
3
+ export { getCommandSchema } from './schema.ts'
4
+ export type {
5
+ BooleanOption,
6
+ CLIAdapter,
7
+ CommandDefinition,
8
+ CommandSchema,
9
+ OptionDefinition,
10
+ OptionSchema,
11
+ OptionType,
12
+ ParsedArgs,
13
+ RunOptions,
14
+ StringOption,
15
+ } from './types.ts'
16
+ export { defineCLIAdapter, defineCommand } from './types.ts'
@@ -0,0 +1,18 @@
1
+ import { nodeAdapter } from './adapters/nodeAdapter.ts'
2
+ import type { CLIAdapter, CommandDefinition, RunOptions } from './types.ts'
3
+
4
+ /**
5
+ * Create a CLI runner bound to a specific adapter.
6
+ * Defaults to the built-in `nodeAdapter` (Node.js `node:util parseArgs`).
7
+ */
8
+ export function createCLI(options?: { adapter?: CLIAdapter }): {
9
+ run(commands: CommandDefinition[], argv: string[], opts: RunOptions): Promise<void>
10
+ } {
11
+ const adapter = options?.adapter ?? nodeAdapter
12
+
13
+ return {
14
+ run(commands, argv, opts) {
15
+ return adapter.run(commands, argv, opts)
16
+ },
17
+ }
18
+ }
@@ -0,0 +1,38 @@
1
+ import type { CommandDefinition, CommandSchema, OptionDefinition, OptionSchema } from './types.ts'
2
+
3
+ /**
4
+ * Serializes `CommandDefinition[]` to a plain, JSON-serializable structure.
5
+ * Use to expose CLI capabilities to AI agents or MCP tools.
6
+ */
7
+ export function getCommandSchema(defs: CommandDefinition[]): CommandSchema[] {
8
+ return defs.map(serializeCommand)
9
+ }
10
+
11
+ function serializeCommand(def: CommandDefinition): CommandSchema {
12
+ return {
13
+ name: def.name,
14
+ description: def.description,
15
+ arguments: def.arguments,
16
+ options: serializeOptions(def.options ?? {}),
17
+ subCommands: def.subCommands ? def.subCommands.map(serializeCommand) : [],
18
+ }
19
+ }
20
+
21
+ function serializeOptions(options: Record<string, OptionDefinition>): OptionSchema[] {
22
+ return Object.entries(options).map(([name, opt]) => {
23
+ const shortPart = opt.short ? `-${opt.short}, ` : ''
24
+ const valuePart = opt.type === 'string' ? ` <${opt.hint ?? name}>` : ''
25
+ const flags = `${shortPart}--${name}${valuePart}`
26
+
27
+ return {
28
+ name,
29
+ flags,
30
+ type: opt.type,
31
+ description: opt.description,
32
+ ...(opt.default !== undefined ? { default: opt.default } : {}),
33
+ ...(opt.hint ? { hint: opt.hint } : {}),
34
+ ...(opt.enum ? { enum: opt.enum } : {}),
35
+ ...(opt.required ? { required: opt.required } : {}),
36
+ }
37
+ })
38
+ }
@@ -0,0 +1,95 @@
1
+ type BaseOption = {
2
+ /** Single-character short alias, e.g. `'c'` for `--config`. */
3
+ short?: string
4
+ description: string
5
+ hint?: string
6
+ required?: boolean
7
+ /** Allowed values for string options. Used in help output and AI/MCP tool schemas. */
8
+ enum?: string[]
9
+ }
10
+
11
+ export type StringOption = BaseOption & { type: 'string'; default?: string }
12
+ export type BooleanOption = BaseOption & { type: 'boolean'; default?: boolean }
13
+ export type OptionDefinition = StringOption | BooleanOption
14
+ export type OptionType = OptionDefinition['type']
15
+
16
+ type OptionTypeMap = { string: string; boolean: boolean }
17
+
18
+ type IsRequired<O extends OptionDefinition> = O['default'] extends string | boolean ? true : O['required'] extends true ? true : false
19
+
20
+ /** Infers typed values from an options record. Options with a `default` or `required: true` are always defined. */
21
+ type InferValues<O extends Record<string, OptionDefinition>> = {
22
+ [K in keyof O as IsRequired<O[K]> extends true ? K : never]: OptionTypeMap[O[K]['type']]
23
+ } & {
24
+ [K in keyof O as IsRequired<O[K]> extends true ? never : K]?: OptionTypeMap[O[K]['type']]
25
+ }
26
+
27
+ export type ParsedArgs = {
28
+ values: Record<string, string | boolean | undefined>
29
+ positionals: string[]
30
+ }
31
+
32
+ export type CommandDefinition = {
33
+ name: string
34
+ description: string
35
+ /** Positional argument labels shown in usage line, e.g. `['[input]']`. */
36
+ arguments?: string[]
37
+ options?: Record<string, OptionDefinition>
38
+ subCommands?: CommandDefinition[]
39
+ run?: (args: ParsedArgs) => Promise<void>
40
+ }
41
+
42
+ /**
43
+ * Returns a `CommandDefinition` with typed `values` in `run()`.
44
+ * The callback receives `values` typed from the declared options — no casts needed.
45
+ */
46
+ export function defineCommand<O extends Record<string, OptionDefinition>>(def: {
47
+ name: string
48
+ description: string
49
+ arguments?: string[]
50
+ options?: O
51
+ subCommands?: CommandDefinition[]
52
+ run?: (args: { values: InferValues<O>; positionals: string[] }) => Promise<void>
53
+ }): CommandDefinition {
54
+ const { run, ...rest } = def
55
+ if (!run) return rest
56
+ return {
57
+ ...rest,
58
+ run: (args) => run({ values: args.values as InferValues<O>, positionals: args.positionals }),
59
+ }
60
+ }
61
+
62
+ export type RunOptions = {
63
+ programName: string
64
+ defaultCommandName: string
65
+ version: string
66
+ }
67
+
68
+ export type CLIAdapter = {
69
+ run(commands: CommandDefinition[], argv: string[], opts: RunOptions): Promise<void>
70
+ renderHelp(def: CommandDefinition, parentName?: string): void
71
+ }
72
+
73
+ /** Returns a `CLIAdapter` with type inference. Pass a different adapter to `createCLI` to swap the CLI engine. */
74
+ export function defineCLIAdapter(adapter: CLIAdapter): CLIAdapter {
75
+ return adapter
76
+ }
77
+
78
+ export type OptionSchema = {
79
+ name: string
80
+ flags: string
81
+ type: OptionType
82
+ description: string
83
+ default?: string | boolean
84
+ hint?: string
85
+ required?: boolean
86
+ enum?: string[]
87
+ }
88
+
89
+ export type CommandSchema = {
90
+ name: string
91
+ description: string
92
+ arguments?: string[]
93
+ options: OptionSchema[]
94
+ subCommands: CommandSchema[]
95
+ }
@@ -1,141 +1,32 @@
1
- import { spawn } from 'node:child_process'
2
1
  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 type { ArgsDef } from 'citty'
8
- import { defineCommand } from 'citty'
9
2
  import { version } from '../../../package.json'
10
- import { buildTelemetryEvent, sendTelemetry } from '../../utils/telemetry.ts'
11
-
12
- const args = {
13
- config: {
14
- type: 'string',
15
- description: 'Path to the Kubb config',
16
- alias: 'c',
17
- },
18
- port: {
19
- type: 'string',
20
- description: 'Port for the server. If not specified, an available port is automatically selected.',
21
- alias: 'p',
22
- },
23
- host: {
24
- type: 'string',
25
- description: 'Host for the server',
26
- default: 'localhost',
27
- },
28
- 'no-cache': {
29
- type: 'boolean',
30
- description: 'Disable session caching',
31
- default: false,
32
- },
33
- 'allow-write': {
34
- type: 'boolean',
35
- description: 'Allow writing generated files to the filesystem. When not set, no files are written and the config patch is not persisted.',
36
- default: false,
37
- },
38
- 'allow-all': {
39
- type: 'boolean',
40
- description: 'Grant all permissions (implies --allow-write).',
41
- default: false,
42
- },
43
- } as const satisfies ArgsDef
44
-
45
- type StartServerProps = {
46
- port: number
47
- host: string
48
- configPath: string
49
- allowWrite: boolean
50
- allowAll: boolean
51
- }
52
-
53
- async function startServer({ port, host, configPath, allowWrite, allowAll }: StartServerProps): Promise<void> {
54
- try {
55
- // Load .env file into process.env using Node.js built-in (v20.12.0+)
56
- try {
57
- process.loadEnvFile()
58
- } catch {
59
- // .env file may not exist; ignore
60
- }
61
-
62
- // Resolve the @kubb/agent package path
63
- const agentPkgUrl = import.meta.resolve('@kubb/agent/package.json')
64
- const agentPkgPath = fileURLToPath(agentPkgUrl)
65
- const agentDir = path.dirname(agentPkgPath)
66
- const serverPath = path.join(agentDir, '.output', 'server', 'index.mjs')
67
-
68
- // nitro env
69
- const PORT = process.env.PORT || (port === 0 ? '3000' : String(port))
70
- const HOST = process.env.HOST || host || '0.0.0.0'
71
-
72
- // kubb env
73
- const KUBB_AGENT_ROOT = process.env.KUBB_AGENT_ROOT || process.cwd()
74
- const KUBB_AGENT_CONFIG = process.env.KUBB_AGENT_CONFIG || configPath || 'kubb.config.ts'
75
- const KUBB_AGENT_ALLOW_WRITE = allowAll || allowWrite ? 'true' : (process.env.KUBB_AGENT_ALLOW_WRITE ?? 'false')
76
- const KUBB_AGENT_ALLOW_ALL = allowAll ? 'true' : (process.env.KUBB_AGENT_ALLOW_ALL ?? 'false')
77
- const KUBB_AGENT_TOKEN = process.env.KUBB_AGENT_TOKEN
78
- const KUBB_AGENT_RETRY_TIMEOUT = process.env.KUBB_AGENT_RETRY_TIMEOUT || '30000'
79
- const KUBB_STUDIO_URL = process.env.KUBB_STUDIO_URL || 'https://studio.kubb.dev'
80
-
81
- // Set environment variables
82
- const env = {
83
- PORT,
84
- HOST,
85
- KUBB_AGENT_ROOT,
86
- KUBB_AGENT_CONFIG,
87
- KUBB_AGENT_ALLOW_WRITE,
88
- KUBB_AGENT_ALLOW_ALL,
89
- KUBB_AGENT_TOKEN,
90
- KUBB_AGENT_RETRY_TIMEOUT,
91
- KUBB_STUDIO_URL,
92
- }
93
-
94
- clack.log.step(styleText('cyan', 'Starting agent server...'))
95
- clack.log.info(styleText('dim', `Config: ${KUBB_AGENT_CONFIG}`))
96
- clack.log.info(styleText('dim', `Host: ${HOST}`))
97
- clack.log.info(styleText('dim', `Port: ${PORT}`))
98
- if (!KUBB_AGENT_ALLOW_WRITE && !KUBB_AGENT_ALLOW_ALL) {
99
- clack.log.warn(styleText('yellow', 'Filesystem writes disabled. Use --allow-write or --allow-all to enable.'))
100
- }
101
-
102
- spawn('node', [serverPath], {
103
- env: { ...process.env, ...env },
104
- stdio: 'inherit',
105
- cwd: process.cwd(),
3
+ import { defineCommand } from '../../cli/index.ts'
4
+ import { agentDefaults } from '../../constants.ts'
5
+
6
+ export const command = defineCommand({
7
+ name: 'start',
8
+ description: 'Start the Agent server',
9
+ options: {
10
+ config: { type: 'string', description: 'Path to the Kubb config', short: 'c' },
11
+ port: { type: 'string', description: `Port for the server (default: ${agentDefaults.port})`, short: 'p' },
12
+ host: { type: 'string', description: 'Host for the server', default: agentDefaults.host },
13
+ 'allow-write': {
14
+ type: 'boolean',
15
+ description: 'Allow writing generated files to the filesystem. When not set, no files are written and the config patch is not persisted.',
16
+ default: false,
17
+ },
18
+ 'allow-all': { type: 'boolean', description: 'Grant all permissions (implies --allow-write).', default: false },
19
+ },
20
+ async run({ values }) {
21
+ const { runAgentStart } = await import('../../runners/agent.ts')
22
+
23
+ await runAgentStart({
24
+ port: values.port !== undefined ? values.port : undefined,
25
+ host: values.host,
26
+ configPath: path.resolve(process.cwd(), values.config ?? agentDefaults.configFile),
27
+ allowWrite: values['allow-write'],
28
+ allowAll: values['allow-all'],
29
+ version,
106
30
  })
107
- } catch (error) {
108
- console.error('Failed to start agent server:', error)
109
- process.exit(1)
110
- }
111
- }
112
-
113
- const command = defineCommand({
114
- meta: {
115
- name: 'start',
116
- description: 'Start the Agent server',
117
- },
118
- args,
119
- async run(commandContext) {
120
- const { args } = commandContext
121
- const hrStart = process.hrtime()
122
-
123
- try {
124
- const configPath = path.resolve(process.cwd(), args.config || 'kubb.config.ts')
125
- const port = args.port ? Number.parseInt(args.port, 10) : 0
126
- const host = args.host
127
- const allowWrite = args['allow-write']
128
- const allowAll = args['allow-all']
129
-
130
- startServer({ port, host, configPath, allowWrite, allowAll })
131
- await sendTelemetry(buildTelemetryEvent({ command: 'agent', kubbVersion: version, hrStart, status: 'success' }))
132
- } catch (error) {
133
- await sendTelemetry(buildTelemetryEvent({ command: 'agent', kubbVersion: version, hrStart, status: 'failed' }))
134
- clack.log.error(styleText('red', 'Failed to start agent server'))
135
- console.error(error)
136
- process.exit(1)
137
- }
138
31
  },
139
32
  })
140
-
141
- export default command
@@ -1,27 +1,8 @@
1
- import type { ArgsDef } from 'citty'
2
- import { defineCommand, showUsage } from 'citty'
1
+ import { defineCommand } from '../cli/index.ts'
2
+ import { command as startCommand } from './agent/start.ts'
3
3
 
4
- const args = {
5
- help: {
6
- type: 'boolean',
7
- description: 'Show help',
8
- alias: 'h',
9
- default: false,
10
- },
11
- } as const satisfies ArgsDef
12
-
13
- const command = defineCommand({
14
- args,
15
- subCommands: {
16
- start: () => import('./agent/start.ts').then((m) => m.default),
17
- },
18
- async run(commandContext) {
19
- const { args } = commandContext
20
-
21
- if (args.help) {
22
- return showUsage(command)
23
- }
24
- },
4
+ export const command = defineCommand({
5
+ name: 'agent',
6
+ description: 'Manage the Kubb Agent server',
7
+ subCommands: [startCommand],
25
8
  })
26
-
27
- export default command
@@ -1,160 +1,28 @@
1
- import path from 'node:path'
2
- import * as process from 'node:process'
3
- import { styleText } from 'node:util'
4
- import * as clack from '@clack/prompts'
5
- import { type CLIOptions, isInputPath, type KubbEvents, LogLevel, PromiseManager } from '@kubb/core'
6
- import { AsyncEventEmitter, executeIfOnline, getConfigs } from '@kubb/core/utils'
7
- import type { ArgsDef, ParsedArgs } from 'citty'
8
- import { defineCommand, showUsage } from 'citty'
9
- import { version } from '../../package.json'
10
- import { setupLogger } from '../loggers/utils.ts'
11
- import { generate } from '../runners/generate.ts'
12
- import { getCosmiConfig } from '../utils/getCosmiConfig.ts'
13
- import { startWatcher } from '../utils/watcher.ts'
14
-
15
- const args = {
16
- config: {
17
- type: 'string',
18
- description: 'Path to the Kubb config',
19
- alias: 'c',
20
- },
21
- logLevel: {
22
- type: 'string',
23
- description: 'Info, silent, verbose or debug',
24
- alias: 'l',
25
- default: 'info',
26
- valueHint: 'silent|info|verbose|debug',
27
- },
28
- watch: {
29
- type: 'boolean',
30
- description: 'Watch mode based on the input file',
31
- alias: 'w',
32
- default: false,
33
- },
34
- debug: {
35
- type: 'boolean',
36
- description: 'Override logLevel to debug',
37
- alias: 'd',
38
- default: false,
39
- },
40
- verbose: {
41
- type: 'boolean',
42
- description: 'Override logLevel to verbose',
43
- alias: 'v',
44
- default: false,
45
- },
46
- silent: {
47
- type: 'boolean',
48
- description: 'Override logLevel to silent',
49
- alias: 's',
50
- default: false,
51
- },
52
- help: {
53
- type: 'boolean',
54
- description: 'Show help',
55
- alias: 'h',
56
- default: false,
57
- },
58
- } as const satisfies ArgsDef
59
-
60
- export type Args = ParsedArgs<typeof args>
61
-
62
- const command = defineCommand({
63
- meta: {
64
- name: 'generate',
65
- description: "[input] Generate files based on a 'kubb.config.ts' file",
66
- },
67
- args,
68
- async run(commandContext) {
69
- const { args } = commandContext
70
- const input = args._[0]
71
- const events = new AsyncEventEmitter<KubbEvents>()
72
- const promiseManager = new PromiseManager()
73
-
74
- if (args.help) {
75
- return showUsage(command)
76
- }
77
-
78
- if (args.debug) {
79
- args.logLevel = 'debug'
80
- }
81
-
82
- if (args.verbose) {
83
- args.logLevel = 'verbose'
84
- }
85
-
86
- if (args.silent) {
87
- args.logLevel = 'silent'
88
- }
89
-
90
- const logLevel = LogLevel[args.logLevel as keyof typeof LogLevel] || 3
91
-
92
- await setupLogger(events, { logLevel })
93
-
94
- await executeIfOnline(async () => {
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
99
-
100
- if (latestVersion && version < latestVersion) {
101
- await events.emit('version:new', version, latestVersion)
102
- }
103
- } catch {
104
- // Ignore network errors for version check
105
- }
106
- })
107
-
108
- try {
109
- const result = await getCosmiConfig('kubb', args.config)
110
- const configs = await getConfigs(result.config, args as CLIOptions)
111
-
112
- await events.emit('config:start')
113
-
114
- await events.emit('info', 'Config loaded', path.relative(process.cwd(), result.filepath))
115
-
116
- await events.emit('success', 'Config loaded successfully', path.relative(process.cwd(), result.filepath))
117
- await events.emit('config:end', configs)
118
-
119
- await events.emit('lifecycle:start', version)
120
-
121
- const promises = configs.map((config) => {
122
- return async () => {
123
- if (isInputPath(config) && args.watch) {
124
- await startWatcher([input || config.input.path], async (paths) => {
125
- // remove to avoid duplicate listeners after each change
126
- events.removeAll()
127
-
128
- await generate({
129
- input,
130
- config,
131
- logLevel,
132
- events,
133
- })
134
-
135
- clack.log.step(styleText('yellow', `Watching for changes in ${paths.join(' and ')}`))
136
- })
137
-
138
- return
139
- }
140
-
141
- await generate({
142
- input,
143
- config,
144
- logLevel,
145
- events,
146
- })
147
- }
148
- })
149
-
150
- await promiseManager.run('seq', promises)
151
-
152
- await events.emit('lifecycle:end')
153
- } catch (error) {
154
- await events.emit('error', error as Error)
155
- process.exit(1)
156
- }
1
+ import { defineCommand } from '../cli/index.ts'
2
+
3
+ export const command = defineCommand({
4
+ name: 'generate',
5
+ description: "[input] Generate files based on a 'kubb.config.ts' file",
6
+ arguments: ['[input]'],
7
+ options: {
8
+ config: { type: 'string', description: 'Path to the Kubb config', short: 'c' },
9
+ logLevel: {
10
+ type: 'string',
11
+ description: 'Info, silent, verbose or debug',
12
+ short: 'l',
13
+ default: 'info',
14
+ hint: 'silent|info|verbose|debug',
15
+ enum: ['silent', 'info', 'verbose', 'debug'],
16
+ },
17
+ watch: { type: 'boolean', description: 'Watch mode based on the input file', short: 'w', default: false },
18
+ debug: { type: 'boolean', description: 'Override logLevel to debug', short: 'd', default: false },
19
+ verbose: { type: 'boolean', description: 'Override logLevel to verbose', short: 'v', default: false },
20
+ silent: { type: 'boolean', description: 'Override logLevel to silent', short: 's', default: false },
21
+ },
22
+ async run({ values, positionals }) {
23
+ const logLevel = values.debug ? 'debug' : values.verbose ? 'verbose' : values.silent ? 'silent' : values.logLevel
24
+ const { runGenerateCommand } = await import('../runners/generate.ts')
25
+
26
+ await runGenerateCommand({ input: positionals[0], configPath: values.config, logLevel, watch: values.watch })
157
27
  },
158
28
  })
159
-
160
- export default command