@forinda/kickjs-cli 5.4.2 → 5.4.4

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 (24) hide show
  1. package/dist/{builtins-CB0cpCRy.mjs → builtins-B9mT_e0x.mjs} +136 -136
  2. package/dist/{builtins-DNnIUbGs.mjs → builtins-f9GCF9UO.mjs} +73 -73
  3. package/dist/{builtins-DNnIUbGs.mjs.map → builtins-f9GCF9UO.mjs.map} +1 -1
  4. package/dist/cli.mjs +2 -2
  5. package/dist/{config-f_GHcOYT.mjs → config-DDTX-zCM.mjs} +3 -3
  6. package/dist/config-DDTX-zCM.mjs.map +1 -0
  7. package/dist/{config-CAjDTnMg.mjs → config-DO_ZcO15.mjs} +2 -2
  8. package/dist/{generator-extension-Ds2fzYZS.mjs → generator-extension-B0VOAwMA.mjs} +3 -3
  9. package/dist/{generator-extension-Ds2fzYZS.mjs.map → generator-extension-B0VOAwMA.mjs.map} +1 -1
  10. package/dist/index.d.mts +57 -1
  11. package/dist/index.d.mts.map +1 -1
  12. package/dist/index.mjs +2 -2
  13. package/dist/{plugin-CiWyeMpX.mjs → plugin-BWHJGpYB.mjs} +3 -3
  14. package/dist/{plugin-CiWyeMpX.mjs.map → plugin-BWHJGpYB.mjs.map} +1 -1
  15. package/dist/{plugin-Dz0Yu4Ow.mjs → plugin-DLnoaSX8.mjs} +2 -2
  16. package/dist/{rolldown-runtime-iJll81ez.mjs → rolldown-runtime-Bdez_B3Y.mjs} +1 -1
  17. package/dist/{run-plugins-DBOc1G96.mjs → run-plugins-GWzfZyd_.mjs} +2 -2
  18. package/dist/{typegen-COBqEd4w.mjs → typegen-B05WVNbq.mjs} +3 -3
  19. package/dist/{typegen-DzmDwZvN.mjs → typegen-BEWcYO4F.mjs} +4 -4
  20. package/dist/{typegen-DzmDwZvN.mjs.map → typegen-BEWcYO4F.mjs.map} +1 -1
  21. package/dist/{types-DucsCMzP.mjs → types-CjlT7_CZ.mjs} +2 -2
  22. package/dist/{types-DucsCMzP.mjs.map → types-CjlT7_CZ.mjs.map} +1 -1
  23. package/package.json +3 -3
  24. package/dist/config-f_GHcOYT.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v5.4.2
2
+ * @forinda/kickjs-cli v5.4.4
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{t as e}from"./rolldown-runtime-iJll81ez.mjs";import{a as t,i as n,r,t as i}from"./config-CAjDTnMg.mjs";import{n as a,r as o}from"./plugin-Dz0Yu4Ow.mjs";import{a as s,c,i as l,n as u,o as d,s as f,t as p}from"./typegen-COBqEd4w.mjs";import{createRequire as m}from"node:module";import{cpSync as h,existsSync as g,mkdirSync as _,readFileSync as v,readdirSync as y,rmSync as ee,statSync as te,writeFileSync as ne}from"node:fs";import b,{basename as re,dirname as x,extname as ie,isAbsolute as ae,join as S,relative as C,resolve as w,sep as oe}from"node:path";import{fileURLToPath as se,pathToFileURL as T}from"node:url";import{execFileSync as ce,execSync as E,fork as le,spawn as ue,spawnSync as de}from"node:child_process";import{access as fe,copyFile as pe,mkdir as me,readFile as D,readdir as he,rm as ge,stat as _e,writeFile as O}from"node:fs/promises";import*as k from"@clack/prompts";import A from"picocolors";import ve from"pluralize";import{glob as ye}from"glob";import{groupAssetKeys as be}from"@forinda/kickjs";import{arch as xe,platform as Se,release as Ce}from"node:os";import{generate as we,migrateDown as Te,migrateLatest as Ee,migrateRollback as De,migrateStatus as Oe,migrateUp as ke,renderSchemaSource as Ae,resolveDbConfig as je}from"@forinda/kickjs-db";function Me(e,t,n){E(e,{cwd:t,stdio:`inherit`,env:n?{...process.env,...n}:process.env})}function Ne(e,t,n){let r=de(process.execPath,[e],{cwd:n,stdio:`inherit`,env:{...process.env,...t}});r.status!==0&&process.exit(r.status??1)}let Pe=!1;function j(e){Pe=e}const Fe=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`,`.md`]);async function M(e,t){Pe||(await me(x(e),{recursive:!0}),await O(e,t,`utf-8`),Fe.has(ie(e))&&await Le(e,t).catch(()=>{}))}let N;async function Ie(e){if(N!==void 0)return N;try{N=await import(m(S(e,`package.json`)).resolve(`oxfmt`))}catch{N=null}return N}async function Le(e,t){let n=await Ie(process.cwd());if(!n)return;let r=await Re(e);if(r===null)return;let i=await n.format(e,t,r);i.code!==t&&await O(e,i.code,`utf-8`)}const P=new Map;async function Re(e){let t=x(e),n=t;if(P.has(n))return P.get(n);for(;;){let e=S(t,`.oxfmtrc.json`);if(g(e))try{let t=await D(e,`utf-8`),r=JSON.parse(t);return delete r.$schema,delete r.ignorePatterns,P.set(n,r),r}catch{return P.set(n,null),null}let r=x(t);if(r===t)return P.set(n,null),null;t=r}}async function ze(e){try{return await fe(e),!0}catch{return!1}}const Be={auth:`@forinda/kickjs-auth`,swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`};function Ve(e,t){let n=e[t];if(!n)throw Error(`generatePackageJson: missing resolved version for ${t}. Add it to SIBLING_PACKAGES in generators/project.ts.`);return n}function He(e,t,n,r=[]){let i={"@forinda/kickjs":Ve(n,`@forinda/kickjs`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,zod:`^4.3.6`,pino:`^10.3.1`,"pino-pretty":`^13.1.3`};for(let e of r){let t=Be[e];t&&!i[t]&&(i[t]=Ve(n,t))}return JSON.stringify({name:e,version:`0.0.0`,type:`module`,scripts:{dev:`vite`,"dev:debug":`kick dev:debug`,build:`kick build`,start:`kick start`,test:`vitest run`,"test:watch":`vitest`,typecheck:`tsc --noEmit`,typegen:`kick typegen`,lint:`eslint src/`,format:`prettier --write src/`},dependencies:i,devDependencies:{"@forinda/kickjs-cli":Ve(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":Ve(n,`@forinda/kickjs-vite`),"@swc/core":`^1.15.21`,"@types/express":`^5.0.6`,"@types/node":`^25.0.0`,"unplugin-swc":`^1.5.9`,vite:`^8.0.3`,vitest:`^4.1.2`,typescript:`^6.0.3`,prettier:`^3.8.1`}},null,2)}function Ue(){return`import { defineConfig } from 'vite'
11
+ import{t as e}from"./rolldown-runtime-Bdez_B3Y.mjs";import{a as t,i as n,r,t as i}from"./config-DO_ZcO15.mjs";import{n as a,r as o}from"./plugin-DLnoaSX8.mjs";import{a as s,c,i as l,n as u,o as d,s as f,t as p}from"./typegen-B05WVNbq.mjs";import{createRequire as m}from"node:module";import{cpSync as h,existsSync as g,mkdirSync as _,readFileSync as v,readdirSync as y,rmSync as ee,statSync as te,writeFileSync as ne}from"node:fs";import b,{basename as re,dirname as x,extname as ie,isAbsolute as ae,join as S,relative as C,resolve as w,sep as oe}from"node:path";import{fileURLToPath as se,pathToFileURL as T}from"node:url";import{execFileSync as ce,execSync as E,fork as le,spawn as ue,spawnSync as de}from"node:child_process";import{access as fe,copyFile as pe,mkdir as me,readFile as D,readdir as he,rm as ge,stat as _e,writeFile as O}from"node:fs/promises";import*as k from"@clack/prompts";import A from"picocolors";import ve from"pluralize";import{glob as ye}from"glob";import{groupAssetKeys as be}from"@forinda/kickjs";import{arch as xe,platform as Se,release as Ce}from"node:os";import{detectCompositeReferences as we,generate as Te,migrateDown as Ee,migrateLatest as De,migrateRollback as Oe,migrateStatus as ke,migrateUp as Ae,renderSchemaSource as je,resolveDbConfig as Me}from"@forinda/kickjs-db";function Ne(e,t,n){E(e,{cwd:t,stdio:`inherit`,env:n?{...process.env,...n}:process.env})}function Pe(e,t,n){let r=de(process.execPath,[e],{cwd:n,stdio:`inherit`,env:{...process.env,...t}});r.status!==0&&process.exit(r.status??1)}let Fe=!1;function j(e){Fe=e}const Ie=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`,`.md`]);async function M(e,t){Fe||(await me(x(e),{recursive:!0}),await O(e,t,`utf-8`),Ie.has(ie(e))&&await Re(e,t).catch(()=>{}))}let N;async function Le(e){if(N!==void 0)return N;try{N=await import(m(S(e,`package.json`)).resolve(`oxfmt`))}catch{N=null}return N}async function Re(e,t){let n=await Le(process.cwd());if(!n)return;let r=await ze(e);if(r===null)return;let i=await n.format(e,t,r);i.code!==t&&await O(e,i.code,`utf-8`)}const P=new Map;async function ze(e){let t=x(e),n=t;if(P.has(n))return P.get(n);for(;;){let e=S(t,`.oxfmtrc.json`);if(g(e))try{let t=await D(e,`utf-8`),r=JSON.parse(t);return delete r.$schema,delete r.ignorePatterns,P.set(n,r),r}catch{return P.set(n,null),null}let r=x(t);if(r===t)return P.set(n,null),null;t=r}}async function Be(e){try{return await fe(e),!0}catch{return!1}}const Ve={auth:`@forinda/kickjs-auth`,swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`};function He(e,t){let n=e[t];if(!n)throw Error(`generatePackageJson: missing resolved version for ${t}. Add it to SIBLING_PACKAGES in generators/project.ts.`);return n}function Ue(e,t,n,r=[]){let i={"@forinda/kickjs":He(n,`@forinda/kickjs`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,zod:`^4.3.6`,pino:`^10.3.1`,"pino-pretty":`^13.1.3`};for(let e of r){let t=Ve[e];t&&!i[t]&&(i[t]=He(n,t))}return JSON.stringify({name:e,version:`0.0.0`,type:`module`,scripts:{dev:`vite`,"dev:debug":`kick dev:debug`,build:`kick build`,start:`kick start`,test:`vitest run`,"test:watch":`vitest`,typecheck:`tsc --noEmit`,typegen:`kick typegen`,lint:`eslint src/`,format:`prettier --write src/`},dependencies:i,devDependencies:{"@forinda/kickjs-cli":He(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":He(n,`@forinda/kickjs-vite`),"@swc/core":`^1.15.21`,"@types/express":`^5.0.6`,"@types/node":`^25.0.0`,"unplugin-swc":`^1.5.9`,vite:`^8.0.3`,vitest:`^4.1.2`,typescript:`^6.0.3`,prettier:`^3.8.1`}},null,2)}function We(){return`import { defineConfig } from 'vite'
12
12
  import { resolve } from 'node:path'
13
13
  import swc from 'unplugin-swc'
14
14
  import { kickjsVitePlugin, envWatchPlugin } from '@forinda/kickjs-vite'
@@ -43,7 +43,7 @@ export default defineConfig({
43
43
  },
44
44
  },
45
45
  })
46
- `}function We(){return JSON.stringify({compilerOptions:{target:`ES2022`,module:`ESNext`,moduleResolution:`bundler`,lib:[`ES2022`],types:[`node`,`vite/client`],strict:!0,esModuleInterop:!0,skipLibCheck:!0,sourceMap:!0,declaration:!0,experimentalDecorators:!0,emitDecoratorMetadata:!0,outDir:`dist`,paths:{"@/*":[`./src/*`]}},include:[`src`,`.kickjs/types/**/*.d.ts`,`.kickjs/types/**/*.ts`]},null,2)}function Ge(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function Ke(){return`# https://editorconfig.org
46
+ `}function Ge(){return JSON.stringify({compilerOptions:{target:`ES2022`,module:`ESNext`,moduleResolution:`bundler`,lib:[`ES2022`],types:[`node`,`vite/client`],strict:!0,esModuleInterop:!0,skipLibCheck:!0,sourceMap:!0,declaration:!0,experimentalDecorators:!0,emitDecoratorMetadata:!0,outDir:`dist`,paths:{"@/*":[`./src/*`]}},include:[`src`,`.kickjs/types/**/*.d.ts`,`.kickjs/types/**/*.ts`]},null,2)}function Ke(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function qe(){return`# https://editorconfig.org
47
47
  root = true
48
48
 
49
49
  [*]
@@ -56,14 +56,14 @@ insert_final_newline = true
56
56
 
57
57
  [*.md]
58
58
  trim_trailing_whitespace = false
59
- `}function qe(){return`node_modules/
59
+ `}function Je(){return`node_modules/
60
60
  dist/
61
61
  .env
62
62
  coverage/
63
63
  .DS_Store
64
64
  *.tsbuildinfo
65
65
  .kickjs/
66
- `}function Je(){return`# Auto-detect text files and normalise line endings to LF
66
+ `}function Ye(){return`# Auto-detect text files and normalise line endings to LF
67
67
  * text=auto eol=lf
68
68
 
69
69
  # Explicitly mark generated / binary files
@@ -81,11 +81,11 @@ coverage/
81
81
  pnpm-lock.yaml -diff linguist-generated
82
82
  yarn.lock -diff linguist-generated
83
83
  package-lock.json -diff linguist-generated
84
- `}function Ye(){return`PORT=3000
85
- NODE_ENV=development
86
84
  `}function Xe(){return`PORT=3000
87
85
  NODE_ENV=development
88
- `}function Ze(){return`import { defineConfig } from 'vitest/config'
86
+ `}function Ze(){return`PORT=3000
87
+ NODE_ENV=development
88
+ `}function Qe(){return`import { defineConfig } from 'vitest/config'
89
89
  import swc from 'unplugin-swc'
90
90
 
91
91
  export default defineConfig({
@@ -96,7 +96,7 @@ export default defineConfig({
96
96
  include: ['src/**/*.test.ts'],
97
97
  },
98
98
  })
99
- `}function Qe(e,t,n,r=[]){switch(t){case`cqrs`:{let t=[],i=[];return r.includes(`devtools`)&&(t.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`),i.push(` DevToolsAdapter(),`)),r.includes(`swagger`)&&(t.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`),i.push(` SwaggerAdapter({\n info: { title: '${e}', version: '${n}' },\n }),`)),`import 'reflect-metadata'
99
+ `}function $e(e,t,n,r=[]){switch(t){case`cqrs`:{let t=[],i=[];return r.includes(`devtools`)&&(t.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`),i.push(` DevToolsAdapter(),`)),r.includes(`swagger`)&&(t.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`),i.push(` SwaggerAdapter({\n info: { title: '${e}', version: '${n}' },\n }),`)),`import 'reflect-metadata'
100
100
  // Side-effect import — registers the extended env schema with kickjs
101
101
  // **before** any controller / service / @Value gets resolved. Without
102
102
  // this line ConfigService.get('YOUR_KEY') returns undefined because the
@@ -166,14 +166,14 @@ export const app = await bootstrap({
166
166
  express.json(),
167
167
  ],
168
168
  })
169
- `}}}function $e(){return`import { defineModules } from '@forinda/kickjs'
169
+ `}}}function et(){return`import { defineModules } from '@forinda/kickjs'
170
170
  import { HelloModule } from './hello/hello.module'
171
171
 
172
172
  // Remove HelloModule and run: kick g module <name>
173
173
  // \`defineModules()\` returns a chainable list — \`kick g module\` appends
174
174
  // \`.mount(NewModule())\` to the chain on every generation.
175
175
  export const modules = defineModules().mount(HelloModule())
176
- `}function et(){return`import { defineEnv, loadEnv } from '@forinda/kickjs/config'
176
+ `}function tt(){return`import { defineEnv, loadEnv } from '@forinda/kickjs/config'
177
177
  import { z } from 'zod'
178
178
 
179
179
  /**
@@ -208,7 +208,7 @@ const envSchema = defineEnv((base) =>
208
208
  export const env = loadEnv(envSchema)
209
209
 
210
210
  export default envSchema
211
- `}function tt(){return`import { Service } from '@forinda/kickjs'
211
+ `}function nt(){return`import { Service } from '@forinda/kickjs'
212
212
 
213
213
  @Service()
214
214
  export class HelloService {
@@ -220,7 +220,7 @@ export class HelloService {
220
220
  return { status: 'ok', uptime: process.uptime() }
221
221
  }
222
222
  }
223
- `}function nt(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
223
+ `}function rt(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
224
224
  import { HelloService } from './hello.service'
225
225
 
226
226
  // \`Ctx<KickRoutes.HelloController['<method>']>\` is generated by
@@ -242,7 +242,7 @@ export class HelloController {
242
242
  ctx.json(this.helloService.healthCheck())
243
243
  }
244
244
  }
245
- `}function rt(){return`import { defineModule } from '@forinda/kickjs'
245
+ `}function it(){return`import { defineModule } from '@forinda/kickjs'
246
246
  import { HelloController } from './hello.controller'
247
247
 
248
248
  export const HelloModule = defineModule({
@@ -263,7 +263,7 @@ export const HelloModule = defineModule({
263
263
  },
264
264
  }),
265
265
  })
266
- `}function it(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
266
+ `}function at(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
267
267
 
268
268
  export default defineConfig({
269
269
  pattern: '${e}',
@@ -307,7 +307,7 @@ export default defineConfig({
307
307
  },
308
308
  ],
309
309
  })
310
- `}function at(e,t,n){let r={rest:`REST API`,ddd:`Domain-Driven Design`,cqrs:`CQRS + Event-Driven`,minimal:`Minimal`},i=[`@forinda/kickjs`,`@forinda/kickjs-vite`];return t!==`minimal`&&i.push(`@forinda/kickjs-swagger`,`@forinda/kickjs-devtools`),t===`cqrs`&&i.push(`@forinda/kickjs-queue`,`@forinda/kickjs-ws`),`# ${e}
310
+ `}function ot(e,t,n){let r={rest:`REST API`,ddd:`Domain-Driven Design`,cqrs:`CQRS + Event-Driven`,minimal:`Minimal`},i=[`@forinda/kickjs`,`@forinda/kickjs-vite`];return t!==`minimal`&&i.push(`@forinda/kickjs-swagger`,`@forinda/kickjs-devtools`),t===`cqrs`&&i.push(`@forinda/kickjs-queue`,`@forinda/kickjs-ws`),`# ${e}
311
311
 
312
312
  A **${r[t]??`REST API`}** built with [KickJS](https://forinda.github.io/kick-js/) — a decorator-driven Node.js framework on Express 5 and TypeScript.
313
313
 
@@ -370,7 +370,7 @@ Copy \`.env.example\` to \`.env\` and configure:
370
370
 
371
371
  - [KickJS Documentation](https://forinda.github.io/kick-js/)
372
372
  - [CLI Reference](https://forinda.github.io/kick-js/api/cli.html)
373
- `}function ot(e,t,n){return`# CLAUDE.md — ${e}
373
+ `}function st(e,t,n){return`# CLAUDE.md — ${e}
374
374
 
375
375
  **Read \`./AGENTS.md\` first.** It is the canonical, multi-agent
376
376
  reference for this project (Claude, Copilot, Codex, Gemini, etc.) —
@@ -436,7 +436,7 @@ When generating or modifying code in this project, stay aligned with the v4 conv
436
436
  - **Refresh these files**: \`kick g agents -f\` regenerates \`AGENTS.md\` + \`CLAUDE.md\` from the latest CLI templates. Hand-edited content is overwritten — keep customisation in \`AGENTS.local.md\`.
437
437
 
438
438
  For everything else (controllers, services, modules, RequestContext API, generators, CLI commands, package additions, env wiring, troubleshooting) → \`AGENTS.md\`.
439
- `}function st(e,t,n){return`# AGENTS.md — AI Agent Guide for ${e}
439
+ `}function ct(e,t,n){return`# AGENTS.md — AI Agent Guide for ${e}
440
440
 
441
441
  This guide is the **canonical, multi-agent reference** for this KickJS
442
442
  application — Claude, Copilot, Codex, Gemini, etc. all read it first.
@@ -943,7 +943,7 @@ ${t===`cqrs`?`### Background Jobs
943
943
  - [Decorators Guide](https://forinda.github.io/kick-js/guide/decorators.html)
944
944
  - [DI System](https://forinda.github.io/kick-js/guide/dependency-injection.html)
945
945
  - [Testing](https://forinda.github.io/kick-js/api/testing.html)
946
- `}function ct(e,t,n){return`# kickjs-skills.md — Task Skills for AI Agents (${e})
946
+ `}function lt(e,t,n){return`# kickjs-skills.md — Task Skills for AI Agents (${e})
947
947
 
948
948
  This file is the agent-facing **skills index** for KickJS work in this
949
949
  repo. Each block below is a short, rigid workflow keyed to a specific
@@ -1192,16 +1192,16 @@ description: Patterns to refuse outright when the user asks for them — they br
1192
1192
  - [Decorators](https://forinda.github.io/kick-js/guide/decorators.html)
1193
1193
  - [Context Decorators](https://forinda.github.io/kick-js/guide/context-decorators.html)
1194
1194
  - [Testing](https://forinda.github.io/kick-js/api/testing.html)
1195
- `}const lt=x(se(import.meta.url)),ut=JSON.parse(v(S(lt,`..`,`package.json`),`utf-8`)),dt=`^${ut.version}`,ft=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-vite`,`@forinda/kickjs-auth`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function pt(){let e=await Promise.all(ft.map(async e=>{try{let t=ce(`npm`,[`view`,e,`version`],{encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim();if(t&&/^\d+\.\d+\.\d+/.test(t))return[e,`^${t}`]}catch{}return[e,dt]}));return Object.fromEntries(e)}async function mt(e){let{name:t,directory:n,packageManager:r=`pnpm`,template:i=`rest`,defaultRepo:a=`inmemory`,packages:o=[]}=e,s=n,c=e=>console.log(` ${e}`);console.log(`\n Creating KickJS project: ${t}\n`),c(`Resolving package versions...`);let l=await pt();if(await M(S(s,`package.json`),He(t,i,l,o)),await M(S(s,`vite.config.ts`),Ue()),await M(S(s,`tsconfig.json`),We()),await M(S(s,`.prettierrc`),Ge()),await M(S(s,`.editorconfig`),Ke()),await M(S(s,`.gitignore`),qe()),await M(S(s,`.gitattributes`),Je()),await M(S(s,`.env`),Ye()),await M(S(s,`.env.example`),Xe()),await M(S(s,`src/config/index.ts`),et()),await M(S(s,`src/index.ts`),Qe(t,i,ut.version,o)),await M(S(s,`src/modules/index.ts`),$e()),await M(S(s,`src/modules/hello/hello.service.ts`),tt()),await M(S(s,`src/modules/hello/hello.controller.ts`),nt()),await M(S(s,`src/modules/hello/hello.module.ts`),rt()),await M(S(s,`kick.config.ts`),it(i,a,r)),await M(S(s,`vitest.config.ts`),Ze()),await M(S(s,`README.md`),at(t,i,r)),await M(S(s,`CLAUDE.md`),ot(t,i,r)),await M(S(s,`AGENTS.md`),st(t,i,r)),await M(S(s,`kickjs-skills.md`),ct(t,i,r)),e.installDeps){console.log(`\n Installing dependencies with ${r}...\n`);try{E(`${r} install`,{cwd:s,stdio:`inherit`}),console.log(`
1196
- Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${r} install failed. Run it manually.`)}}try{let{runTypegen:e}=await import(`./typegen-COBqEd4w.mjs`).then(e=>e.r);await e({cwd:s,allowDuplicates:!0,silent:!0})}catch{}if(e.initGit)try{E(`git init`,{cwd:s,stdio:`pipe`}),E(`git branch -M main`,{cwd:s,stdio:`pipe`}),E(`git add -A`,{cwd:s,stdio:`pipe`}),E(`git commit -m "chore: initial commit from kick new"`,{cwd:s,stdio:`pipe`}),c(`Git repository initialized`)}catch{c(`Warning: git init failed (git may not be installed)`)}console.log(`
1197
- Project scaffolded successfully!`),console.log();let u=s!==process.cwd();c(`Next steps:`),u&&c(` cd ${t}`),e.installDeps||c(` ${r} install`);let d={rest:`kick g module user`,ddd:`kick g module user --repo drizzle`,cqrs:`kick g module user --pattern cqrs`,minimal:`# add your routes to src/index.ts`};c(` ${d[i]??d.rest}`),c(` kick dev`),c(``),c(`Commands:`),c(` kick dev Start dev server with Vite HMR`),c(` kick build Production build via Vite`),c(` kick start Run production build`),c(``),c(`Generators:`),c(` kick g module <name> Full DDD module (controller, DTOs, use-cases, repo)`),c(` kick g scaffold <n> <f..> CRUD module from field definitions`),c(` kick g controller <name> Standalone controller`),c(` kick g service <name> @Service() class`),c(` kick g middleware <name> Express middleware`),c(` kick g guard <name> Route guard (auth, roles, etc.)`),c(` kick g adapter <name> AppAdapter with lifecycle hooks`),c(` kick g dto <name> Zod DTO schema`),i===`cqrs`&&c(` kick g job <name> Queue job processor`),c(` kick g config Generate kick.config.ts`),c(``),c(`Add packages:`),c(` kick add <pkg> Install a KickJS package + peers`),c(` kick add --list Show all available packages`),c(``),c(`Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing`),c(``)}const ht={GET:A.green,POST:A.cyan,PUT:A.yellow,PATCH:A.magenta,DELETE:A.red};function gt(e){return(ht[e]??A.dim)(e.padEnd(7))}function _t(e){let t=`[${e}]`.padEnd(10);switch(e){case`CRITICAL`:return A.red(t);case`WARNING`:return A.yellow(t);case`INFO`:return A.blue(A.dim(t));default:return t}}A.green(`✓`),A.red(`✖`),A.yellow(`⚠`),A.blue(`ℹ`);function vt(e){k.intro(A.bgCyan(A.black(` ${e} `)))}function yt(e){k.outro(e)}function bt(e){k.isCancel(e)&&(k.cancel(`Operation cancelled.`),process.exit(0))}async function xt(e){let t=await k.text(e);return bt(t),t}async function St(e){let t=await k.select(e);return bt(t),t}async function Ct(e){let t=await k.multiselect(e);return bt(t),t}async function F(e){let t=await k.confirm(e);return bt(t),t}function wt(){return k.spinner()}const I=k.log,Tt={kickjs:{pkg:`@forinda/kickjs`,peers:[`express`],description:`Unified framework: DI, decorators, routing, middleware`,core:!0},vite:{pkg:`@forinda/kickjs-vite`,peers:[`vite`],description:`Vite plugin: dev server, HMR, module discovery`,dev:!0,core:!0},cli:{pkg:`@forinda/kickjs-cli`,peers:[],description:`CLI tool and code generators`,dev:!0,core:!0},swagger:{pkg:`@forinda/kickjs-swagger`,peers:[],description:`OpenAPI spec + Swagger UI + ReDoc`},db:{pkg:`@forinda/kickjs-db`,peers:[],description:`kick/db core — schema DSL, migrations, KickDbClient, customType`},"db-pg":{pkg:`@forinda/kickjs-db-pg`,peers:[`pg`],description:`kick/db PostgreSQL dialect + adapter (pgDialect, pgAdapter)`},drizzle:{pkg:`@forinda/kickjs-drizzle`,peers:[`drizzle-orm`],description:`Drizzle ORM adapter + query builder`},prisma:{pkg:`@forinda/kickjs-prisma`,peers:[`@prisma/client`],description:`Prisma adapter + query builder`},ws:{pkg:`@forinda/kickjs-ws`,peers:[`socket.io`],description:`WebSocket with @WsController decorators`},devtools:{pkg:`@forinda/kickjs-devtools`,peers:[],description:`Development dashboard — routes, DI, metrics, health`,dev:!0},auth:{pkg:`@forinda/kickjs-auth`,peers:[`jsonwebtoken`],description:`Authentication — JWT, API key, and custom strategies`},queue:{pkg:`@forinda/kickjs-queue`,peers:[],description:`Queue adapter (BullMQ/RabbitMQ/Kafka)`},"queue:bullmq":{pkg:`@forinda/kickjs-queue`,peers:[`bullmq`,`ioredis`],description:`Queue with BullMQ + Redis`},"queue:rabbitmq":{pkg:`@forinda/kickjs-queue`,peers:[`amqplib`],description:`Queue with RabbitMQ`},"queue:kafka":{pkg:`@forinda/kickjs-queue`,peers:[`kafkajs`],description:`Queue with Kafka`},mcp:{pkg:`@forinda/kickjs-mcp`,peers:[`@modelcontextprotocol/sdk`],description:`Model Context Protocol server — expose @Controller endpoints as AI tools`},testing:{pkg:`@forinda/kickjs-testing`,peers:[],description:`Test utilities and TestModule builder`,dev:!0}};function L(e,t=process.cwd()){let n=t;for(;;){if(g(w(n,e)))return n;let t=x(n);if(t===n)return null;n=t}}function Et(){return L(`pnpm-lock.yaml`)?`pnpm`:L(`yarn.lock`)?`yarn`:L(`bun.lockb`)||L(`bun.lock`)?`bun`:L(`package-lock.json`)?`npm`:null}function Dt(){let e=process.cwd();for(;e;){let t=w(e,`package.json`);if(g(t))try{let e=JSON.parse(v(t,`utf-8`)).packageManager;if(typeof e==`string`){let t=e.split(`@`)[0];if(i.includes(t))return t}}catch{}let n=x(e);if(n===e)return null;e=n}return null}async function Ot(e){if(e&&i.includes(e))return{pm:e,source:`flag`};let t=await r(process.cwd());if(t?.packageManager&&i.includes(t.packageManager))return{pm:t.packageManager,source:`config`};let n=Dt();if(n)return{pm:n,source:`package.json`};let a=Et();return a?{pm:a,source:`lockfile`}:{pm:`npm`,source:`default`}}async function kt(e){let{pm:t}=await Ot(e);return t}function At(e=!1){let t=Object.entries(Tt),n=Math.max(...t.map(([e])=>e.length)),r=t.filter(([,e])=>e.core),i=t.filter(([,e])=>!e.core),a=([e,t])=>{let r=e.padEnd(n+2),i=t.peers.length?` (+ ${t.peers.join(`, `)})`:``;return` ${r} ${t.description}${i}`};console.log(`
1195
+ `}const ut=x(se(import.meta.url)),dt=JSON.parse(v(S(ut,`..`,`package.json`),`utf-8`)),ft=`^${dt.version}`,pt=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-vite`,`@forinda/kickjs-auth`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function mt(){let e=await Promise.all(pt.map(async e=>{try{let t=ce(`npm`,[`view`,e,`version`],{encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim();if(t&&/^\d+\.\d+\.\d+/.test(t))return[e,`^${t}`]}catch{}return[e,ft]}));return Object.fromEntries(e)}async function ht(e){let{name:t,directory:n,packageManager:r=`pnpm`,template:i=`rest`,defaultRepo:a=`inmemory`,packages:o=[]}=e,s=n,c=e=>console.log(` ${e}`);console.log(`\n Creating KickJS project: ${t}\n`),c(`Resolving package versions...`);let l=await mt();if(await M(S(s,`package.json`),Ue(t,i,l,o)),await M(S(s,`vite.config.ts`),We()),await M(S(s,`tsconfig.json`),Ge()),await M(S(s,`.prettierrc`),Ke()),await M(S(s,`.editorconfig`),qe()),await M(S(s,`.gitignore`),Je()),await M(S(s,`.gitattributes`),Ye()),await M(S(s,`.env`),Xe()),await M(S(s,`.env.example`),Ze()),await M(S(s,`src/config/index.ts`),tt()),await M(S(s,`src/index.ts`),$e(t,i,dt.version,o)),await M(S(s,`src/modules/index.ts`),et()),await M(S(s,`src/modules/hello/hello.service.ts`),nt()),await M(S(s,`src/modules/hello/hello.controller.ts`),rt()),await M(S(s,`src/modules/hello/hello.module.ts`),it()),await M(S(s,`kick.config.ts`),at(i,a,r)),await M(S(s,`vitest.config.ts`),Qe()),await M(S(s,`README.md`),ot(t,i,r)),await M(S(s,`CLAUDE.md`),st(t,i,r)),await M(S(s,`AGENTS.md`),ct(t,i,r)),await M(S(s,`kickjs-skills.md`),lt(t,i,r)),e.installDeps){console.log(`\n Installing dependencies with ${r}...\n`);try{E(`${r} install`,{cwd:s,stdio:`inherit`}),console.log(`
1196
+ Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${r} install failed. Run it manually.`)}}try{let{runTypegen:e}=await import(`./typegen-B05WVNbq.mjs`).then(e=>e.r);await e({cwd:s,allowDuplicates:!0,silent:!0})}catch{}if(e.initGit)try{E(`git init`,{cwd:s,stdio:`pipe`}),E(`git branch -M main`,{cwd:s,stdio:`pipe`}),E(`git add -A`,{cwd:s,stdio:`pipe`}),E(`git commit -m "chore: initial commit from kick new"`,{cwd:s,stdio:`pipe`}),c(`Git repository initialized`)}catch{c(`Warning: git init failed (git may not be installed)`)}console.log(`
1197
+ Project scaffolded successfully!`),console.log();let u=s!==process.cwd();c(`Next steps:`),u&&c(` cd ${t}`),e.installDeps||c(` ${r} install`);let d={rest:`kick g module user`,ddd:`kick g module user --repo drizzle`,cqrs:`kick g module user --pattern cqrs`,minimal:`# add your routes to src/index.ts`};c(` ${d[i]??d.rest}`),c(` kick dev`),c(``),c(`Commands:`),c(` kick dev Start dev server with Vite HMR`),c(` kick build Production build via Vite`),c(` kick start Run production build`),c(``),c(`Generators:`),c(` kick g module <name> Full DDD module (controller, DTOs, use-cases, repo)`),c(` kick g scaffold <n> <f..> CRUD module from field definitions`),c(` kick g controller <name> Standalone controller`),c(` kick g service <name> @Service() class`),c(` kick g middleware <name> Express middleware`),c(` kick g guard <name> Route guard (auth, roles, etc.)`),c(` kick g adapter <name> AppAdapter with lifecycle hooks`),c(` kick g dto <name> Zod DTO schema`),i===`cqrs`&&c(` kick g job <name> Queue job processor`),c(` kick g config Generate kick.config.ts`),c(``),c(`Add packages:`),c(` kick add <pkg> Install a KickJS package + peers`),c(` kick add --list Show all available packages`),c(``),c(`Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing`),c(``)}const gt={GET:A.green,POST:A.cyan,PUT:A.yellow,PATCH:A.magenta,DELETE:A.red};function _t(e){return(gt[e]??A.dim)(e.padEnd(7))}function vt(e){let t=`[${e}]`.padEnd(10);switch(e){case`CRITICAL`:return A.red(t);case`WARNING`:return A.yellow(t);case`INFO`:return A.blue(A.dim(t));default:return t}}A.green(`✓`),A.red(`✖`),A.yellow(`⚠`),A.blue(`ℹ`);function yt(e){k.intro(A.bgCyan(A.black(` ${e} `)))}function bt(e){k.outro(e)}function xt(e){k.isCancel(e)&&(k.cancel(`Operation cancelled.`),process.exit(0))}async function St(e){let t=await k.text(e);return xt(t),t}async function Ct(e){let t=await k.select(e);return xt(t),t}async function wt(e){let t=await k.multiselect(e);return xt(t),t}async function F(e){let t=await k.confirm(e);return xt(t),t}function Tt(){return k.spinner()}const I=k.log,Et={kickjs:{pkg:`@forinda/kickjs`,peers:[`express`],description:`Unified framework: DI, decorators, routing, middleware`,core:!0},vite:{pkg:`@forinda/kickjs-vite`,peers:[`vite`],description:`Vite plugin: dev server, HMR, module discovery`,dev:!0,core:!0},cli:{pkg:`@forinda/kickjs-cli`,peers:[],description:`CLI tool and code generators`,dev:!0,core:!0},swagger:{pkg:`@forinda/kickjs-swagger`,peers:[],description:`OpenAPI spec + Swagger UI + ReDoc`},db:{pkg:`@forinda/kickjs-db`,peers:[],description:`kick/db core — schema DSL, migrations, KickDbClient, customType`},"db-pg":{pkg:`@forinda/kickjs-db-pg`,peers:[`pg`],description:`kick/db PostgreSQL dialect + adapter (pgDialect, pgAdapter)`},drizzle:{pkg:`@forinda/kickjs-drizzle`,peers:[`drizzle-orm`],description:`Drizzle ORM adapter + query builder`},prisma:{pkg:`@forinda/kickjs-prisma`,peers:[`@prisma/client`],description:`Prisma adapter + query builder`},ws:{pkg:`@forinda/kickjs-ws`,peers:[`socket.io`],description:`WebSocket with @WsController decorators`},devtools:{pkg:`@forinda/kickjs-devtools`,peers:[],description:`Development dashboard — routes, DI, metrics, health`,dev:!0},auth:{pkg:`@forinda/kickjs-auth`,peers:[`jsonwebtoken`],description:`Authentication — JWT, API key, and custom strategies`},queue:{pkg:`@forinda/kickjs-queue`,peers:[],description:`Queue adapter (BullMQ/RabbitMQ/Kafka)`},"queue:bullmq":{pkg:`@forinda/kickjs-queue`,peers:[`bullmq`,`ioredis`],description:`Queue with BullMQ + Redis`},"queue:rabbitmq":{pkg:`@forinda/kickjs-queue`,peers:[`amqplib`],description:`Queue with RabbitMQ`},"queue:kafka":{pkg:`@forinda/kickjs-queue`,peers:[`kafkajs`],description:`Queue with Kafka`},mcp:{pkg:`@forinda/kickjs-mcp`,peers:[`@modelcontextprotocol/sdk`],description:`Model Context Protocol server — expose @Controller endpoints as AI tools`},testing:{pkg:`@forinda/kickjs-testing`,peers:[],description:`Test utilities and TestModule builder`,dev:!0}};function L(e,t=process.cwd()){let n=t;for(;;){if(g(w(n,e)))return n;let t=x(n);if(t===n)return null;n=t}}function Dt(){return L(`pnpm-lock.yaml`)?`pnpm`:L(`yarn.lock`)?`yarn`:L(`bun.lockb`)||L(`bun.lock`)?`bun`:L(`package-lock.json`)?`npm`:null}function Ot(){let e=process.cwd();for(;e;){let t=w(e,`package.json`);if(g(t))try{let e=JSON.parse(v(t,`utf-8`)).packageManager;if(typeof e==`string`){let t=e.split(`@`)[0];if(i.includes(t))return t}}catch{}let n=x(e);if(n===e)return null;e=n}return null}async function kt(e){if(e&&i.includes(e))return{pm:e,source:`flag`};let t=await r(process.cwd());if(t?.packageManager&&i.includes(t.packageManager))return{pm:t.packageManager,source:`config`};let n=Ot();if(n)return{pm:n,source:`package.json`};let a=Dt();return a?{pm:a,source:`lockfile`}:{pm:`npm`,source:`default`}}async function At(e){let{pm:t}=await kt(e);return t}function jt(e=!1){let t=Object.entries(Et),n=Math.max(...t.map(([e])=>e.length)),r=t.filter(([,e])=>e.core),i=t.filter(([,e])=>!e.core),a=([e,t])=>{let r=e.padEnd(n+2),i=t.peers.length?` (+ ${t.peers.join(`, `)})`:``;return` ${r} ${t.description}${i}`};console.log(`
1198
1198
  Core packages (always installed by \`kick new\`):
1199
1199
  `);for(let e of r)console.log(a(e));if(e){console.log(`
1200
1200
  Optional packages (add as needed):
1201
1201
  `);for(let e of i)console.log(a(e))}else console.log(`\n Plus ${i.length} optional packages (auth, swagger, db, queue, …).`),console.log(" Run `kick add --list --all` for the full catalog.");console.log(`
1202
- Usage: kick add auth drizzle swagger`),console.log(` kick add queue:bullmq`),console.log()}function jt(e){e.command(`list`).alias(`ls`).description(`List KickJS packages (core only; pair with --all for the full catalog)`).option(`--all`,`Include the full optional catalog`).action(e=>{At(!!e.all)})}function Mt(e){e.command(`add [packages...]`).description(`Add KickJS packages with their required dependencies`).option(`--pm <manager>`,`Package manager override`).option(`-D, --dev`,`Install as dev dependency`).option(`--list`,`List packages (core only by default; pair with --all)`).option(`--all`,`When listing, include the full optional catalog`).action(async(e,t)=>{if(t.list||e.length===0){At(!!t.all);return}let{pm:n,source:r}=await Ot(t.pm);console.log(`\n Using ${n} (resolved from ${r})`);let i=t.dev,a=new Set,o=new Set,s=[];for(let t of e){let e=Tt[t];if(!e){s.push(t);continue}let n=i||e.dev?o:a;n.add(e.pkg);for(let t of e.peers)n.add(t)}if(!(s.length>0&&(console.log(`\n Unknown packages: ${s.join(`, `)}`),console.log(` Run "kick add --list" to see available packages.
1202
+ Usage: kick add auth drizzle swagger`),console.log(` kick add queue:bullmq`),console.log()}function Mt(e){e.command(`list`).alias(`ls`).description(`List KickJS packages (core only; pair with --all for the full catalog)`).option(`--all`,`Include the full optional catalog`).action(e=>{jt(!!e.all)})}function Nt(e){e.command(`add [packages...]`).description(`Add KickJS packages with their required dependencies`).option(`--pm <manager>`,`Package manager override`).option(`-D, --dev`,`Install as dev dependency`).option(`--list`,`List packages (core only by default; pair with --all)`).option(`--all`,`When listing, include the full optional catalog`).action(async(e,t)=>{if(t.list||e.length===0){jt(!!t.all);return}let{pm:n,source:r}=await kt(t.pm);console.log(`\n Using ${n} (resolved from ${r})`);let i=t.dev,a=new Set,o=new Set,s=[];for(let t of e){let e=Et[t];if(!e){s.push(t);continue}let n=i||e.dev?o:a;n.add(e.pkg);for(let t of e.peers)n.add(t)}if(!(s.length>0&&(console.log(`\n Unknown packages: ${s.join(`, `)}`),console.log(` Run "kick add --list" to see available packages.
1203
1203
  `),a.size===0&&o.size===0))){if(a.size>0){let e=Array.from(a),t=`${n} add ${e.join(` `)}`;console.log(`\n Installing ${e.length} dependency(ies):`);for(let t of e)console.log(` + ${t}`);console.log();try{E(t,{stdio:`inherit`})}catch{console.log(`\n Installation failed. Run manually:\n ${t}\n`)}}if(o.size>0){let e=Array.from(o),t=`${n} add -D ${e.join(` `)}`;console.log(`\n Installing ${e.length} dev dependency(ies):`);for(let t of e)console.log(` + ${t} (dev)`);console.log();try{E(t,{stdio:`inherit`})}catch{console.log(`\n Installation failed. Run manually:\n ${t}\n`)}}console.log(` Done!
1204
- `)}})}const Nt=[{value:`auth`,label:`Auth`,hint:`JWT, OAuth, API keys`},{value:`swagger`,label:`Swagger`,hint:`OpenAPI docs`},{value:`ws`,label:`WebSocket`,hint:`rooms, heartbeat`},{value:`queue`,label:`Queue`,hint:`BullMQ/RabbitMQ/Kafka`},{value:`devtools`,label:`DevTools`,hint:`debug dashboard`}];function Pt(e){e.command(`new [name]`).alias(`init`).description(`Create a new KickJS project (use "." for current directory)`).option(`-d, --directory <dir>`,`Target directory (defaults to project name)`).option(`--pm <manager>`,`Package manager: pnpm | npm | yarn | bun`).option(`--git`,`Initialize git repository`).option(`--no-git`,`Skip git initialization`).option(`--install`,`Install dependencies after scaffolding`).option(`--no-install`,`Skip dependency installation`).option(`-f, --force`,`Remove existing files without prompting`).option(`-t, --template <type>`,`Project template: rest | ddd | cqrs | minimal`).option(`-r, --repo <type>`,`Default repository: prisma | drizzle | inmemory | custom`).option(`--packages <packages>`,`Comma-separated packages to include (e.g. auth,swagger,ws,queue)`).option(`-y, --yes`,`Pick safe defaults for every prompt (template=minimal, repo=inmemory, no extras, git+install on)`).option(`--non-interactive`,`alias for --yes`).action(async(e,t)=>{vt(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await xt({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let r;if(e===`.`?(r=w(`.`),e=re(r)):r=w(t.directory||e),g(r)){let i=y(r);if(i.length>0){if(t.force)I.warn(`Clearing existing files in ${r}`);else if(n){I.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),yt(`Aborted.`);return}else{I.warn(`Directory "${e}" is not empty:`);let t=i.slice(0,5);for(let e of t)I.message(` - ${e}`);if(i.length>5&&I.message(` ... and ${i.length-5} more`),!await F({message:A.red(`Remove all existing files and proceed?`),initialValue:!1})){yt(`Aborted.`);return}}for(let e of i)ee(w(r,e),{recursive:!0,force:!0})}}let i=t.template;i||=n?`minimal`:await St({message:`Project template`,options:[{value:`rest`,label:`REST API`,hint:`Express + Swagger`},{value:`ddd`,label:`DDD`,hint:`Domain-Driven Design modules`},{value:`cqrs`,label:`CQRS`,hint:`Commands, Queries, Events + WS/Queue`},{value:`minimal`,label:`Minimal`,hint:`bare Express`}]});let a=t.pm;a||=n?await kt(void 0):await St({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let o=t.repo;o||(n?o=`inmemory`:(o=await St({message:`Default repository/ORM`,options:[{value:`prisma`,label:`Prisma`},{value:`drizzle`,label:`Drizzle`},{value:`inmemory`,label:`In-Memory`},{value:`custom`,label:`Custom`,hint:`specify later`}]}),o===`custom`&&(o=await xt({message:`Custom repository name`,defaultValue:`custom`}))));let s;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();s=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else s=n?[]:await Ct({message:`Select packages to include`,options:[...Nt],required:!1});let c;c=t.git===void 0?n?!0:await F({message:`Initialize git repository?`,initialValue:!0}):t.git;let l;l=t.install===void 0?n?!0:await F({message:`Install dependencies?`,initialValue:!0}):t.install,await mt({name:e,directory:r,packageManager:a,initGit:c,installDeps:l,template:i,defaultRepo:o,packages:s}),yt(`Done! Next steps: ${A.cyan(`cd ${e} && ${a} dev`)}`)})}function R(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function z(e){let t=R(e);return t.charAt(0).toLowerCase()+t.slice(1)}function B(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function V(e){return ve.plural(e)}function Ft(e){return ve.plural(e)}function It(e){return B(e).replace(/-/g,`_`)}function Lt(e){let t=e.cwd??process.cwd(),n=e.pluralize??!0,r=R(e.name),i=z(e.name),a=B(e.name),o=It(e.name),s={name:e.name,pascal:r,camel:i,kebab:a,snake:o,modulesDir:e.modulesDir??`src/modules`,cwd:t,args:e.args??[],flags:e.flags??{}};if(n){let e=V(a);s.pluralKebab=e,s.pluralPascal=R(e),s.pluralCamel=z(e)}return s}function Rt(e,t){return w(e.cwd,t)}async function zt(e){return import(T(e).href)}const Bt=new Map;async function Vt(e){let t=Bt.get(e);if(t)return t;let n=Ht(e);return Bt.set(e,n),n}async function Ht(e){let t=w(e,`package.json`);if(!g(t))return{generators:[],loaded:[],failed:[]};let n=Ut(JSON.parse(await D(t,`utf-8`))),r=m(w(e,`package.json`)),i=[],a=[],o=[];for(let e of n){let t;try{t=r.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await D(t,`utf-8`))}catch(t){o.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let s=n.kickjs.generators,c=w(x(t),s);if(!g(c)){o.push({source:e,reason:`kickjs.generators points to missing file: ${s}`});continue}let l;try{l=await zt(c)}catch(t){o.push({source:e,reason:`failed to import manifest: ${t}`});continue}let u=l.default;if(!Array.isArray(u)){o.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of u){if(!Wt(t)){o.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}i.push({source:e,spec:t})}a.push(e)}return{generators:i,loaded:a,failed:o}}function Ut(e){let t=new Set;for(let n of[e.dependencies,e.devDependencies,e.peerDependencies])if(n)for(let e of Object.keys(n))t.add(e);return Array.from(t)}function Wt(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function Gt(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return Jt(r.spec,r.source,e,n);let i=qt(await Vt(n),e.generatorName);return i?Jt(i.spec,i.source,e,n):null}async function Kt(e,t=[]){let n=await Vt(e),r=new Set(t.map(e=>e.spec.name)),i=n.generators.filter(e=>!r.has(e.spec.name));return{generators:[...t,...i],loaded:n.loaded,failed:n.failed}}function qt(e,t){return e.generators.find(e=>e.spec.name===t)}async function Jt(e,t,n,r){let i=Lt({name:n.itemName,args:n.args,flags:n.flags,modulesDir:n.modulesDir,pluralize:n.pluralize,cwd:r}),a=await e.files(i),o=[];for(let e of a){let t=Rt(i,e.path);await M(t,e.content),o.push(t)}return{files:o,source:t}}function H(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const Yt={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function Xt(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function Zt(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function Qt(e){return Yt[e]??Xt(e)}function $t(e,t,n){let r={inmemory:`InMemory${e}Repository`,drizzle:`Drizzle${e}Repository`,prisma:`Prisma${e}Repository`},i={inmemory:`in-memory-${t}`,drizzle:`drizzle-${t}`,prisma:`prisma-${t}`};return{repoClass:r[n]??`${Xt(n)}${e}Repository`,repoFile:i[n]??`${Zt(n)}-${t}`}}function en(e){return e??`define`}function tn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=$t(t,n,i),c=en(a),l=`/**
1204
+ `)}})}const Pt=[{value:`auth`,label:`Auth`,hint:`JWT, OAuth, API keys`},{value:`swagger`,label:`Swagger`,hint:`OpenAPI docs`},{value:`ws`,label:`WebSocket`,hint:`rooms, heartbeat`},{value:`queue`,label:`Queue`,hint:`BullMQ/RabbitMQ/Kafka`},{value:`devtools`,label:`DevTools`,hint:`debug dashboard`}];function Ft(e){e.command(`new [name]`).alias(`init`).description(`Create a new KickJS project (use "." for current directory)`).option(`-d, --directory <dir>`,`Target directory (defaults to project name)`).option(`--pm <manager>`,`Package manager: pnpm | npm | yarn | bun`).option(`--git`,`Initialize git repository`).option(`--no-git`,`Skip git initialization`).option(`--install`,`Install dependencies after scaffolding`).option(`--no-install`,`Skip dependency installation`).option(`-f, --force`,`Remove existing files without prompting`).option(`-t, --template <type>`,`Project template: rest | ddd | cqrs | minimal`).option(`-r, --repo <type>`,`Default repository: prisma | drizzle | inmemory | custom`).option(`--packages <packages>`,`Comma-separated packages to include (e.g. auth,swagger,ws,queue)`).option(`-y, --yes`,`Pick safe defaults for every prompt (template=minimal, repo=inmemory, no extras, git+install on)`).option(`--non-interactive`,`alias for --yes`).action(async(e,t)=>{yt(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await St({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let r;if(e===`.`?(r=w(`.`),e=re(r)):r=w(t.directory||e),g(r)){let i=y(r);if(i.length>0){if(t.force)I.warn(`Clearing existing files in ${r}`);else if(n){I.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),bt(`Aborted.`);return}else{I.warn(`Directory "${e}" is not empty:`);let t=i.slice(0,5);for(let e of t)I.message(` - ${e}`);if(i.length>5&&I.message(` ... and ${i.length-5} more`),!await F({message:A.red(`Remove all existing files and proceed?`),initialValue:!1})){bt(`Aborted.`);return}}for(let e of i)ee(w(r,e),{recursive:!0,force:!0})}}let i=t.template;i||=n?`minimal`:await Ct({message:`Project template`,options:[{value:`rest`,label:`REST API`,hint:`Express + Swagger`},{value:`ddd`,label:`DDD`,hint:`Domain-Driven Design modules`},{value:`cqrs`,label:`CQRS`,hint:`Commands, Queries, Events + WS/Queue`},{value:`minimal`,label:`Minimal`,hint:`bare Express`}]});let a=t.pm;a||=n?await At(void 0):await Ct({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let o=t.repo;o||(n?o=`inmemory`:(o=await Ct({message:`Default repository/ORM`,options:[{value:`prisma`,label:`Prisma`},{value:`drizzle`,label:`Drizzle`},{value:`inmemory`,label:`In-Memory`},{value:`custom`,label:`Custom`,hint:`specify later`}]}),o===`custom`&&(o=await St({message:`Custom repository name`,defaultValue:`custom`}))));let s;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();s=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else s=n?[]:await wt({message:`Select packages to include`,options:[...Pt],required:!1});let c;c=t.git===void 0?n?!0:await F({message:`Initialize git repository?`,initialValue:!0}):t.git;let l;l=t.install===void 0?n?!0:await F({message:`Install dependencies?`,initialValue:!0}):t.install,await ht({name:e,directory:r,packageManager:a,initGit:c,installDeps:l,template:i,defaultRepo:o,packages:s}),bt(`Done! Next steps: ${A.cyan(`cd ${e} && ${a} dev`)}`)})}function R(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function z(e){let t=R(e);return t.charAt(0).toLowerCase()+t.slice(1)}function B(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function V(e){return ve.plural(e)}function It(e){return ve.plural(e)}function Lt(e){return B(e).replace(/-/g,`_`)}function Rt(e){let t=e.cwd??process.cwd(),n=e.pluralize??!0,r=R(e.name),i=z(e.name),a=B(e.name),o=Lt(e.name),s={name:e.name,pascal:r,camel:i,kebab:a,snake:o,modulesDir:e.modulesDir??`src/modules`,cwd:t,args:e.args??[],flags:e.flags??{}};if(n){let e=V(a);s.pluralKebab=e,s.pluralPascal=R(e),s.pluralCamel=z(e)}return s}function zt(e,t){return w(e.cwd,t)}async function Bt(e){return import(T(e).href)}const Vt=new Map;async function Ht(e){let t=Vt.get(e);if(t)return t;let n=Ut(e);return Vt.set(e,n),n}async function Ut(e){let t=w(e,`package.json`);if(!g(t))return{generators:[],loaded:[],failed:[]};let n=Wt(JSON.parse(await D(t,`utf-8`))),r=m(w(e,`package.json`)),i=[],a=[],o=[];for(let e of n){let t;try{t=r.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await D(t,`utf-8`))}catch(t){o.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let s=n.kickjs.generators,c=w(x(t),s);if(!g(c)){o.push({source:e,reason:`kickjs.generators points to missing file: ${s}`});continue}let l;try{l=await Bt(c)}catch(t){o.push({source:e,reason:`failed to import manifest: ${t}`});continue}let u=l.default;if(!Array.isArray(u)){o.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of u){if(!Gt(t)){o.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}i.push({source:e,spec:t})}a.push(e)}return{generators:i,loaded:a,failed:o}}function Wt(e){let t=new Set;for(let n of[e.dependencies,e.devDependencies,e.peerDependencies])if(n)for(let e of Object.keys(n))t.add(e);return Array.from(t)}function Gt(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function Kt(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return Yt(r.spec,r.source,e,n);let i=Jt(await Ht(n),e.generatorName);return i?Yt(i.spec,i.source,e,n):null}async function qt(e,t=[]){let n=await Ht(e),r=new Set(t.map(e=>e.spec.name)),i=n.generators.filter(e=>!r.has(e.spec.name));return{generators:[...t,...i],loaded:n.loaded,failed:n.failed}}function Jt(e,t){return e.generators.find(e=>e.spec.name===t)}async function Yt(e,t,n,r){let i=Rt({name:n.itemName,args:n.args,flags:n.flags,modulesDir:n.modulesDir,pluralize:n.pluralize,cwd:r}),a=await e.files(i),o=[];for(let e of a){let t=zt(i,e.path);await M(t,e.content),o.push(t)}return{files:o,source:t}}function H(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const Xt={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function Zt(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function Qt(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function $t(e){return Xt[e]??Zt(e)}function en(e,t,n){let r={inmemory:`InMemory${e}Repository`,drizzle:`Drizzle${e}Repository`,prisma:`Prisma${e}Repository`},i={inmemory:`in-memory-${t}`,drizzle:`drizzle-${t}`,prisma:`prisma-${t}`};return{repoClass:r[n]??`${Zt(n)}${e}Repository`,repoFile:i[n]??`${Qt(n)}-${t}`}}function tn(e){return e??`define`}function nn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=en(t,n,i),c=tn(a),l=`/**
1205
1205
  * ${t} Module
1206
1206
  *
1207
1207
  * Self-contained feature module following Domain-Driven Design (DDD).
@@ -1211,7 +1211,7 @@ description: Patterns to refuse outright when the user asks for them — they br
1211
1211
  * presentation/ — HTTP controllers (entry points)
1212
1212
  * application/ — Use cases (orchestration) and DTOs (validation)
1213
1213
  * domain/ — Entities, value objects, repository interfaces, domain services
1214
- * infrastructure/ — Repository implementations (currently ${Qt(i)})
1214
+ * infrastructure/ — Repository implementations (currently ${$t(i)})
1215
1215
  */`,u=`import { ${t.toUpperCase()}_REPOSITORY } from './domain/repositories/${n}.repository'
1216
1216
  import { ${o} } from './infrastructure/repositories/${s}.repository'
1217
1217
  import { ${t}Controller } from './presentation/${n}.controller'
@@ -1245,7 +1245,7 @@ export class ${t}Module implements AppModule {
1245
1245
  /**
1246
1246
  * Register module dependencies in the DI container.
1247
1247
  * Bind repository interface tokens to their implementations here.
1248
- * Currently wired to ${Qt(i)}. To swap implementations, change the factory target.
1248
+ * Currently wired to ${$t(i)}. To swap implementations, change the factory target.
1249
1249
  */
1250
1250
  register(container: Container): void {
1251
1251
  container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
@@ -1271,7 +1271,7 @@ export const ${t}Module = defineModule({
1271
1271
  /**
1272
1272
  * Register module dependencies in the DI container.
1273
1273
  * Bind repository interface tokens to their implementations here.
1274
- * Currently wired to ${Qt(i)}. To swap implementations, change the factory target.
1274
+ * Currently wired to ${$t(i)}. To swap implementations, change the factory target.
1275
1275
  */
1276
1276
  register(container) {
1277
1277
  container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
@@ -1288,7 +1288,7 @@ ${d}
1288
1288
  },
1289
1289
  }),
1290
1290
  })
1291
- `}function nn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=$t(t,n,i),c=en(a),l=`/**
1291
+ `}function rn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=en(t,n,i),c=tn(a),l=`/**
1292
1292
  * ${t} Module
1293
1293
  *
1294
1294
  * REST module with a flat folder structure.
@@ -1360,7 +1360,7 @@ ${d}
1360
1360
  },
1361
1361
  }),
1362
1362
  })
1363
- `}function rn(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=en(i),o=` /**
1363
+ `}function an(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=tn(i),o=` /**
1364
1364
  * Declare HTTP routes. Return value shape:
1365
1365
  *
1366
1366
  * - \`path\` — URL prefix for this route set.
@@ -1400,7 +1400,7 @@ ${o}
1400
1400
  },
1401
1401
  }),
1402
1402
  })
1403
- `}function an(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
1403
+ `}function on(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
1404
1404
  import { ApiTags } from '@forinda/kickjs-swagger'
1405
1405
  import { Create${t}UseCase } from '../application/use-cases/create-${n}.use-case'
1406
1406
  import { Get${t}UseCase } from '../application/use-cases/get-${n}.use-case'
@@ -1463,7 +1463,7 @@ export class ${t}Controller {
1463
1463
  ctx.noContent()
1464
1464
  }
1465
1465
  }
1466
- `}function on(e){let{pascal:t,kebab:n}=e,r=t.charAt(0).toLowerCase()+t.slice(1);return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
1466
+ `}function sn(e){let{pascal:t,kebab:n}=e,r=t.charAt(0).toLowerCase()+t.slice(1);return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
1467
1467
  import { ApiTags } from '@forinda/kickjs-swagger'
1468
1468
  import { ${t}Service } from './${n}.service'
1469
1469
  import { create${t}Schema } from './dtos/create-${n}.dto'
@@ -1518,14 +1518,14 @@ export class ${t}Controller {
1518
1518
  ctx.noContent()
1519
1519
  }
1520
1520
  }
1521
- `}function sn(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
1521
+ `}function cn(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
1522
1522
 
1523
1523
  export const ${t.toUpperCase()}_QUERY_CONFIG: QueryParamsConfig = {
1524
1524
  filterable: ['name'],
1525
1525
  sortable: ['name', 'createdAt'],
1526
1526
  searchable: ['name'],
1527
1527
  }
1528
- `}function cn(e){let{pascal:t}=e;return`import { z } from 'zod'
1528
+ `}function ln(e){let{pascal:t}=e;return`import { z } from 'zod'
1529
1529
 
1530
1530
  /**
1531
1531
  * Create ${t} DTO — Zod schema for validating POST request bodies.
@@ -1541,20 +1541,20 @@ export const create${t}Schema = z.object({
1541
1541
  })
1542
1542
 
1543
1543
  export type Create${t}DTO = z.infer<typeof create${t}Schema>
1544
- `}function ln(e){let{pascal:t}=e;return`import { z } from 'zod'
1544
+ `}function un(e){let{pascal:t}=e;return`import { z } from 'zod'
1545
1545
 
1546
1546
  export const update${t}Schema = z.object({
1547
1547
  name: z.string().min(1).max(200).optional(),
1548
1548
  })
1549
1549
 
1550
1550
  export type Update${t}DTO = z.infer<typeof update${t}Schema>
1551
- `}function un(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
1551
+ `}function dn(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
1552
1552
  id: string
1553
1553
  name: string
1554
1554
  createdAt: string
1555
1555
  updatedAt: string
1556
1556
  }
1557
- `}function dn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
1557
+ `}function fn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
1558
1558
  * Create ${t} Use Case
1559
1559
  *
1560
1560
  * Application layer — orchestrates a single business operation.
@@ -1632,7 +1632,7 @@ export class Delete${t}UseCase {
1632
1632
  await this.repo.delete(id)
1633
1633
  }
1634
1634
  }
1635
- `}]}function fn(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
1635
+ `}]}function pn(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
1636
1636
  * ${t} Repository Interface
1637
1637
  *
1638
1638
  * Defines the contract for data access.
@@ -1727,7 +1727,7 @@ export class InMemory${t}Repository implements I${t}Repository {
1727
1727
  this.store.delete(id)
1728
1728
  }
1729
1729
  }
1730
- `}function pn(e){let{pascal:t,kebab:n,repoType:r=``,repoPrefix:i=`../../domain/repositories`,dtoPrefix:a=`../../application/dtos`}=e,o=r.charAt(0).toUpperCase()+r.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
1730
+ `}function mn(e){let{pascal:t,kebab:n,repoType:r=``,repoPrefix:i=`../../domain/repositories`,dtoPrefix:a=`../../application/dtos`}=e,o=r.charAt(0).toUpperCase()+r.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
1731
1731
  * ${o} ${t} Repository
1732
1732
  *
1733
1733
  * Stub implementation for a custom '${r}' repository.
@@ -1796,7 +1796,7 @@ export class ${o}${t}Repository implements I${t}Repository {
1796
1796
  this.store.delete(id)
1797
1797
  }
1798
1798
  }
1799
- `}function mn(e){let{pascal:t,kebab:n}=e;return`/**
1799
+ `}function hn(e){let{pascal:t,kebab:n}=e;return`/**
1800
1800
  * ${t} Domain Service
1801
1801
  *
1802
1802
  * Domain layer — contains business rules that don't belong to a single entity.
@@ -1819,7 +1819,7 @@ export class ${t}DomainService {
1819
1819
  }
1820
1820
  }
1821
1821
  }
1822
- `}function hn(e){let{pascal:t,kebab:n}=e;return`/**
1822
+ `}function gn(e){let{pascal:t,kebab:n}=e;return`/**
1823
1823
  * ${t} Entity
1824
1824
  *
1825
1825
  * Domain layer — the core business object.
@@ -1888,7 +1888,7 @@ export class ${t} {
1888
1888
  }
1889
1889
  }
1890
1890
  }
1891
- `}function gn(e){let{pascal:t}=e;return`/**
1891
+ `}function _n(e){let{pascal:t}=e;return`/**
1892
1892
  * ${t} ID Value Object
1893
1893
  *
1894
1894
  * Domain layer — wraps a primitive ID with type safety and validation.
@@ -1922,7 +1922,7 @@ export class ${t}Id {
1922
1922
  return this.value === other.value
1923
1923
  }
1924
1924
  }
1925
- `}function _n(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
1925
+ `}function vn(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
1926
1926
  import { Container } from '@forinda/kickjs'
1927
1927
 
1928
1928
  describe('${t}Controller', () => {
@@ -1974,7 +1974,7 @@ describe('${t}Controller', () => {
1974
1974
  })
1975
1975
  })
1976
1976
  })
1977
- `}function vn(e){let{pascal:t,kebab:n,plural:r=``,repoPrefix:i=`../infrastructure/repositories/in-memory-${n}.repository`}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
1977
+ `}function yn(e){let{pascal:t,kebab:n,plural:r=``,repoPrefix:i=`../infrastructure/repositories/in-memory-${n}.repository`}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
1978
1978
  import { InMemory${t}Repository } from '${i}'
1979
1979
 
1980
1980
  describe('InMemory${t}Repository', () => {
@@ -2036,7 +2036,7 @@ describe('InMemory${t}Repository', () => {
2036
2036
  expect(found).toBeNull()
2037
2037
  })
2038
2038
  })
2039
- `}function yn(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
2039
+ `}function bn(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
2040
2040
  import type { ParsedQuery } from '@forinda/kickjs'
2041
2041
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from './${n}.repository'
2042
2042
  import type { ${t}ResponseDTO } from './dtos/${n}-response.dto'
@@ -2073,14 +2073,14 @@ export class ${t}Service {
2073
2073
  await this.repo.delete(id)
2074
2074
  }
2075
2075
  }
2076
- `}function bn(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
2076
+ `}function xn(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
2077
2077
 
2078
2078
  export const ${t.toUpperCase()}_QUERY_CONFIG: QueryFieldConfig = {
2079
2079
  filterable: ['name'],
2080
2080
  sortable: ['name', 'createdAt'],
2081
2081
  searchable: ['name'],
2082
2082
  }
2083
- `}function xn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,o={inmemory:`InMemory${t}Repository`,drizzle:`Drizzle${t}Repository`,prisma:`Prisma${t}Repository`},s={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},c=o[i]??o.inmemory,l=s[i]??s.inmemory,u=a??`define`,d=`/**
2083
+ `}function Sn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,o={inmemory:`InMemory${t}Repository`,drizzle:`Drizzle${t}Repository`,prisma:`Prisma${t}Repository`},s={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},c=o[i]??o.inmemory,l=s[i]??s.inmemory,u=a??`define`,d=`/**
2084
2084
  * ${t} Module — CQRS Pattern
2085
2085
  *
2086
2086
  * Separates read (queries) and write (commands) operations.
@@ -2159,7 +2159,7 @@ ${p}
2159
2159
  },
2160
2160
  }),
2161
2161
  })
2162
- `}function Sn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
2162
+ `}function Cn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
2163
2163
  import { ApiTags } from '@forinda/kickjs-swagger'
2164
2164
  import { Create${t}Command } from './commands/create-${n}.command'
2165
2165
  import { Update${t}Command } from './commands/update-${n}.command'
@@ -2222,7 +2222,7 @@ export class ${t}Controller {
2222
2222
  ctx.noContent()
2223
2223
  }
2224
2224
  }
2225
- `}function Cn(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2225
+ `}function wn(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2226
2226
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
2227
2227
  import type { Create${t}DTO } from '../dtos/create-${n}.dto'
2228
2228
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
@@ -2276,7 +2276,7 @@ export class Delete${t}Command {
2276
2276
  this.events.emit('${n}.deleted', { id })
2277
2277
  }
2278
2278
  }
2279
- `}]}function wn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2279
+ `}]}function Tn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2280
2280
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
2281
2281
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
2282
2282
 
@@ -2304,7 +2304,7 @@ export class List${i}Query {
2304
2304
  return this.repo.findPaginated(parsed)
2305
2305
  }
2306
2306
  }
2307
- `}]}function Tn(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
2307
+ `}]}function En(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
2308
2308
  import { EventEmitter } from 'node:events'
2309
2309
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
2310
2310
 
@@ -2390,7 +2390,7 @@ export class On${t}ChangeHandler {
2390
2390
  })
2391
2391
  }
2392
2392
  }
2393
- `}]}function En(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
2393
+ `}]}function Dn(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
2394
2394
  * Drizzle ${t} Repository
2395
2395
  *
2396
2396
  * Implements the repository interface using Drizzle ORM.
@@ -2472,7 +2472,7 @@ export class Drizzle${t}Repository implements I${t}Repository {
2472
2472
  throw new Error('Drizzle ${t} repository not yet implemented')
2473
2473
  }
2474
2474
  }
2475
- `}function Dn(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
2475
+ `}function On(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
2476
2476
  // TODO: Import your schema table and reference actual columns for type safety
2477
2477
  // import { ${n}s } from '@/db/schema'
2478
2478
 
@@ -2490,7 +2490,7 @@ export const ${t.toUpperCase()}_QUERY_CONFIG: DrizzleQueryParamsConfig = {
2490
2490
  // ${n}s.name,
2491
2491
  ],
2492
2492
  }
2493
- `}function On(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e,a=n.replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
2493
+ `}function kn(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e,a=n.replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
2494
2494
  * Prisma ${t} Repository
2495
2495
  *
2496
2496
  * Implements the repository interface using Prisma Client.
@@ -2548,7 +2548,7 @@ export class Prisma${t}Repository implements I${t}Repository {
2548
2548
  await this.prisma.${a}.deleteMany({ where: { id } })
2549
2549
  }
2550
2550
  }
2551
- `}async function kn(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,rn({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
2551
+ `}async function An(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,an({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
2552
2552
 
2553
2553
  // \`Ctx<KickRoutes.${t}Controller['<method>']>\` is generated by
2554
2554
  // \`kick typegen\` (auto-run on \`kick dev\`).
@@ -2560,7 +2560,7 @@ export class ${t}Controller {
2560
2560
  ctx.json({ message: '${t} list' })
2561
2561
  }
2562
2562
  }
2563
- `)}async function An(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,nn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,bn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,on({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,yn({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,cn({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,ln({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,un({pascal:t,kebab:n})),await u(`${n}.repository.ts`,fn({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let d={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},f={inmemory:()=>U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>En({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>On({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${B(a)}-${n}`,m=f[a]??(()=>pn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${p}.repository.ts`,m()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,_n({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,vn({pascal:t,kebab:n,plural:r,repoPrefix:`../${d.inmemory??`in-memory-${n}`}.repository`})))}async function jn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,xn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,bn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Sn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,cn({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,ln({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,un({pascal:t,kebab:n}));let d=Cn({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=wn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=Tn({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,fn({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let m={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},h={inmemory:()=>U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>En({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>On({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${B(a)}-${n}`,_=h[a]??(()=>pn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,_n({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,vn({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function Mn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noEntity:o,noTests:s,prismaClientPath:c,tokenScope:l,style:u,write:d}=e;await d(`${n}.module.ts`,tn({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?Dn({pascal:t,kebab:n}):sn({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,an({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,cn({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,ln({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,un({pascal:t,kebab:n}));let f=dn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await d(`application/use-cases/${e.file}`,e.content);await d(`domain/repositories/${n}.repository.ts`,fn({pascal:t,kebab:n,tokenScope:l})),await d(`domain/services/${n}-domain.service.ts`,mn({pascal:t,kebab:n}));let p={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},m={inmemory:()=>U({pascal:t,kebab:n}),drizzle:()=>En({pascal:t,kebab:n}),prisma:()=>On({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${B(a)}-${n}`,g=m[a]??(()=>pn({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,hn({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,gn({pascal:t,kebab:n}))),s||(a!==`inmemory`&&await d(`infrastructure/repositories/in-memory-${n}.repository.ts`,U({pascal:t,kebab:n})),await d(`__tests__/${n}.controller.test.ts`,_n({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,vn({pascal:t,kebab:n,plural:r})))}function Nn(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Pn(e){let{name:t,modulesDir:n,noEntity:r,noTests:i,repo:a=`inmemory`,force:o,dryRun:s}=e,c=e.pluralize!==!1,l=e.pattern??`ddd`;e.minimal&&(l=`minimal`);let u=B(t),d=R(t),f=c?V(u):u,p=c?Ft(d):d,m=S(n,f),h=[],g=o??!1,_={kebab:u,pascal:d,plural:f,pluralPascal:p,moduleDir:m,repo:a,noEntity:r??!1,noTests:i??!1,prismaClientPath:e.prismaClientPath??`@prisma/client`,tokenScope:e.tokenScope??`app`,style:e.style??`define`,write:async(e,t)=>{let n=S(m,e);if(s){h.push(n);return}if(!g&&await ze(n)&&!await F({message:`File exists: ${A.dim(e)}. Overwrite?`,initialValue:!1})){I.warn(`Skipped: ${e}`);return}await M(n,t),h.push(n)},files:h};switch(l){case`minimal`:await kn(_);break;case`rest`:await An(_);break;case`cqrs`:await jn(_);break;default:await Mn(_);break}return s||await Fn(n,d,f,u,_.style),h}async function Fn(e,t,n,r,i=`define`){let a=S(e,`index.ts`),o=await ze(a),s=`./${n}/${r}.module`,c=i===`class`?`${t}Module`:`${t}Module()`;if(!o){await M(a,i===`class`?`import type { AppModuleEntry } from '@forinda/kickjs'
2563
+ `)}async function jn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,rn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,xn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,sn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,bn({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,ln({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,un({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,dn({pascal:t,kebab:n})),await u(`${n}.repository.ts`,pn({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let d={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},f={inmemory:()=>U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Dn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>kn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${B(a)}-${n}`,m=f[a]??(()=>mn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${p}.repository.ts`,m()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,vn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,yn({pascal:t,kebab:n,plural:r,repoPrefix:`../${d.inmemory??`in-memory-${n}`}.repository`})))}async function Mn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,Sn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,xn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Cn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,ln({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,un({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,dn({pascal:t,kebab:n}));let d=wn({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=Tn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=En({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,pn({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let m={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},h={inmemory:()=>U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Dn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>kn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${B(a)}-${n}`,_=h[a]??(()=>mn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,vn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,yn({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function Nn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noEntity:o,noTests:s,prismaClientPath:c,tokenScope:l,style:u,write:d}=e;await d(`${n}.module.ts`,nn({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?On({pascal:t,kebab:n}):cn({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,on({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,ln({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,un({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,dn({pascal:t,kebab:n}));let f=fn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await d(`application/use-cases/${e.file}`,e.content);await d(`domain/repositories/${n}.repository.ts`,pn({pascal:t,kebab:n,tokenScope:l})),await d(`domain/services/${n}-domain.service.ts`,hn({pascal:t,kebab:n}));let p={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},m={inmemory:()=>U({pascal:t,kebab:n}),drizzle:()=>Dn({pascal:t,kebab:n}),prisma:()=>kn({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${B(a)}-${n}`,g=m[a]??(()=>mn({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,gn({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,_n({pascal:t,kebab:n}))),s||(a!==`inmemory`&&await d(`infrastructure/repositories/in-memory-${n}.repository.ts`,U({pascal:t,kebab:n})),await d(`__tests__/${n}.controller.test.ts`,vn({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,yn({pascal:t,kebab:n,plural:r})))}function Pn(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Fn(e){let{name:t,modulesDir:n,noEntity:r,noTests:i,repo:a=`inmemory`,force:o,dryRun:s}=e,c=e.pluralize!==!1,l=e.pattern??`ddd`;e.minimal&&(l=`minimal`);let u=B(t),d=R(t),f=c?V(u):u,p=c?It(d):d,m=S(n,f),h=[],g=o??!1,_={kebab:u,pascal:d,plural:f,pluralPascal:p,moduleDir:m,repo:a,noEntity:r??!1,noTests:i??!1,prismaClientPath:e.prismaClientPath??`@prisma/client`,tokenScope:e.tokenScope??`app`,style:e.style??`define`,write:async(e,t)=>{let n=S(m,e);if(s){h.push(n);return}if(!g&&await Be(n)&&!await F({message:`File exists: ${A.dim(e)}. Overwrite?`,initialValue:!1})){I.warn(`Skipped: ${e}`);return}await M(n,t),h.push(n)},files:h};switch(l){case`minimal`:await An(_);break;case`rest`:await jn(_);break;case`cqrs`:await Mn(_);break;default:await Nn(_);break}return s||await In(n,d,f,u,_.style),h}async function In(e,t,n,r,i=`define`){let a=S(e,`index.ts`),o=await Be(a),s=`./${n}/${r}.module`,c=i===`class`?`${t}Module`:`${t}Module()`;if(!o){await M(a,i===`class`?`import type { AppModuleEntry } from '@forinda/kickjs'
2564
2564
  import { ${t}Module } from '${s}'
2565
2565
 
2566
2566
  export const modules: AppModuleEntry[] = [${c}]
@@ -2571,8 +2571,8 @@ export const modules = defineModules().mount(${c})
2571
2571
  `);return}let l=await D(a,`utf-8`),u=`import { ${t}Module } from '${s}'`,d=H(s);if(!RegExp(`^import\\s*\\{[^}]*\\b${H(t)}Module\\b[^}]*\\}\\s*from\\s*['"]${d}['"]`,`m`).test(l)){let e=l.lastIndexOf(`import `);if(e!==-1){let t=l.indexOf(`
2572
2572
  `,e);l=l.slice(0,t+1)+u+`
2573
2573
  `+l.slice(t+1)}else l=u+`
2574
- `+l}let f=Ln(l);if(f){let e=l.slice(f.rhsStart,f.rhsEnd+1);RegExp(`\\b${H(t)}Module\\b`).test(e)||(l=In(l,c))}else l=In(l,c);await O(a,l,`utf-8`)}function In(e,t){let n=Ln(e);if(!n)return e;if(n.shape===`array`){let r=e.slice(n.rhsStart+1,n.rhsEnd),i=r.trim(),a;if(!i)a=`[${t}]`;else{let e=i.endsWith(`,`)?``:`,`;a=`[${r.trimEnd()}${e} ${t}]`}return e.slice(0,n.rhsStart)+a+e.slice(n.rhsEnd+1)}return`${e.slice(0,n.chainEnd)}\n .mount(${t})${e.slice(n.chainEnd)}`}function Ln(e){let t=/export\s+const\s+modules\b[^=]*=/.exec(e);if(!t)return null;let n=t.index+t[0].length;for(;n<e.length&&/\s/.test(e[n]??``);)n++;if(e[n]===`[`){let t=Bn(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=Rn(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function Rn(e,t=0){let n=/defineModules\s*\(/g;n.lastIndex=t;let r=n.exec(e);if(!r)return-1;let i=r.index+r[0].length-1;if(e[i]!==`(`||(i=Vn(e,i),i===-1))return-1;for(i++;;){let t=i;for(;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`.`||e.slice(t,t+6)!==`.mount`)break;for(t+=6;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`(`)break;let n=Vn(e,t);if(n===-1)break;i=n+1}return i}function zn(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
2575
- `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function Bn(e,t){if(e[t]!==`[`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=zn(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`[`)n++;else if(i===`]`&&(n--,n===0))return r;r++}return-1}function Vn(e,t){if(e[t]!==`(`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=zn(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`(`)n++;else if(i===`)`&&(n--,n===0))return r;r++}return-1}async function Hn(e){let{name:t,outDir:n}=e,r=B(t),i=R(t),a=[],o=S(n,`${r}.adapter.ts`);return await M(o,`import {
2574
+ `+l}let f=Rn(l);if(f){let e=l.slice(f.rhsStart,f.rhsEnd+1);RegExp(`\\b${H(t)}Module\\b`).test(e)||(l=Ln(l,c))}else l=Ln(l,c);await O(a,l,`utf-8`)}function Ln(e,t){let n=Rn(e);if(!n)return e;if(n.shape===`array`){let r=e.slice(n.rhsStart+1,n.rhsEnd),i=r.trim(),a;if(!i)a=`[${t}]`;else{let e=i.endsWith(`,`)?``:`,`;a=`[${r.trimEnd()}${e} ${t}]`}return e.slice(0,n.rhsStart)+a+e.slice(n.rhsEnd+1)}return`${e.slice(0,n.chainEnd)}\n .mount(${t})${e.slice(n.chainEnd)}`}function Rn(e){let t=/export\s+const\s+modules\b[^=]*=/.exec(e);if(!t)return null;let n=t.index+t[0].length;for(;n<e.length&&/\s/.test(e[n]??``);)n++;if(e[n]===`[`){let t=Vn(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=zn(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function zn(e,t=0){let n=/defineModules\s*\(/g;n.lastIndex=t;let r=n.exec(e);if(!r)return-1;let i=r.index+r[0].length-1;if(e[i]!==`(`||(i=Hn(e,i),i===-1))return-1;for(i++;;){let t=i;for(;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`.`||e.slice(t,t+6)!==`.mount`)break;for(t+=6;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`(`)break;let n=Hn(e,t);if(n===-1)break;i=n+1}return i}function Bn(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
2575
+ `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function Vn(e,t){if(e[t]!==`[`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=Bn(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`[`)n++;else if(i===`]`&&(n--,n===0))return r;r++}return-1}function Hn(e,t){if(e[t]!==`(`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=Bn(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`(`)n++;else if(i===`)`&&(n--,n===0))return r;r++}return-1}async function Un(e){let{name:t,outDir:n}=e,r=B(t),i=R(t),a=[],o=S(n,`${r}.adapter.ts`);return await M(o,`import {
2576
2576
  defineAdapter,
2577
2577
  type AdapterContext,
2578
2578
  type AdapterMiddleware,
@@ -2741,7 +2741,7 @@ export const ${i}Adapter = defineAdapter<${i}AdapterConfig>({
2741
2741
  }
2742
2742
  },
2743
2743
  })
2744
- `),a.push(o),a}async function Un(e){let{name:t,outDir:n}=e,r=B(t),i=R(t),a=[],o=S(n,`${r}.plugin.ts`);return await M(o,`import {
2744
+ `),a.push(o),a}async function Wn(e){let{name:t,outDir:n}=e,r=B(t),i=R(t),a=[],o=S(n,`${r}.plugin.ts`);return await M(o,`import {
2745
2745
  definePlugin,
2746
2746
  type AppAdapter,
2747
2747
  type AppModuleEntry,
@@ -2885,7 +2885,7 @@ export const ${i}Plugin = definePlugin<${i}PluginConfig>({
2885
2885
  },
2886
2886
  }),
2887
2887
  })
2888
- `),a.push(o),a}const Wn={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`},Gn={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`},Kn={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,command:`commands`,query:`queries`,event:`events`};function W(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,pattern:o=`ddd`,shouldPluralize:s=!0}=e;if(n)return w(n);if(r){let e=o===`ddd`?Wn:o===`cqrs`?Kn:Gn,n=B(r),a=s?V(n):n,c=e[t]??``,l=S(i,a);return w(c?S(l,c):l)}return w(a)}async function qn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`middleware`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/middleware`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=z(t),c=[],l=S(a,`${o}.middleware.ts`);return await M(l,`import type { Request, Response, NextFunction } from 'express'
2888
+ `),a.push(o),a}const Gn={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`},Kn={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`},qn={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,command:`commands`,query:`queries`,event:`events`};function W(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,pattern:o=`ddd`,shouldPluralize:s=!0}=e;if(n)return w(n);if(r){let e=o===`ddd`?Gn:o===`cqrs`?qn:Kn,n=B(r),a=s?V(n):n,c=e[t]??``,l=S(i,a);return w(c?S(l,c):l)}return w(a)}async function Jn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`middleware`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/middleware`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=z(t),c=[],l=S(a,`${o}.middleware.ts`);return await M(l,`import type { Request, Response, NextFunction } from 'express'
2889
2889
 
2890
2890
  export interface ${R(t)}Options {
2891
2891
  // Add configuration options here
@@ -2909,7 +2909,7 @@ export function ${s}(options: ${R(t)}Options = {}) {
2909
2909
  next()
2910
2910
  }
2911
2911
  }
2912
- `),c.push(l),c}async function Jn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`guard`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/guards`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=z(t),c=R(t),l=[],u=S(a,`${o}.guard.ts`);return await M(u,`import { Container, HttpException } from '@forinda/kickjs'
2912
+ `),c.push(l),c}async function Yn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`guard`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/guards`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=z(t),c=R(t),l=[],u=S(a,`${o}.guard.ts`);return await M(u,`import { Container, HttpException } from '@forinda/kickjs'
2913
2913
  import type { RequestContext } from '@forinda/kickjs'
2914
2914
 
2915
2915
  /**
@@ -2945,7 +2945,7 @@ export async function ${s}Guard(ctx: RequestContext, next: () => void): Promise<
2945
2945
  ctx.res.status(401).json({ message: 'Invalid or expired token' })
2946
2946
  }
2947
2947
  }
2948
- `),l.push(u),l}async function Yn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`service`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/services`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=R(t),c=[],l=S(a,`${o}.service.ts`);return await M(l,`import { Service } from '@forinda/kickjs'
2948
+ `),l.push(u),l}async function Xn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`service`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/services`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=R(t),c=[],l=S(a,`${o}.service.ts`);return await M(l,`import { Service } from '@forinda/kickjs'
2949
2949
 
2950
2950
  @Service()
2951
2951
  export class ${s}Service {
@@ -2954,7 +2954,7 @@ export class ${s}Service {
2954
2954
  // @Inject(MY_REPO) private readonly repo: IMyRepository,
2955
2955
  // ) {}
2956
2956
  }
2957
- `),c.push(l),c}async function Xn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`controller`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/controllers`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=R(t),c=[],l=S(a,`${o}.controller.ts`);return await M(l,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
2957
+ `),c.push(l),c}async function Zn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`controller`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/controllers`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=R(t),c=[],l=S(a,`${o}.controller.ts`);return await M(l,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
2958
2958
 
2959
2959
  // \`Ctx<KickRoutes.${s}Controller['<method>']>\` is generated by
2960
2960
  // \`kick typegen\` (auto-run on \`kick dev\`). After the first run, your IDE
@@ -2975,7 +2975,7 @@ export class ${s}Controller {
2975
2975
  ctx.created({ message: '${s} created', data: ctx.body })
2976
2976
  }
2977
2977
  }
2978
- `),c.push(l),c}async function Zn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`dto`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/dtos`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=R(t),c=z(t),l=[],u=S(a,`${o}.dto.ts`);return await M(u,`import { z } from 'zod'
2978
+ `),c.push(l),c}async function Qn(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=W({type:`dto`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/dtos`,pattern:i,shouldPluralize:e.pluralize??!0}),o=B(t),s=R(t),c=z(t),l=[],u=S(a,`${o}.dto.ts`);return await M(u,`import { z } from 'zod'
2979
2979
 
2980
2980
  export const ${c}Schema = z.object({
2981
2981
  // Define your schema fields here
@@ -2983,7 +2983,7 @@ export const ${c}Schema = z.object({
2983
2983
  })
2984
2984
 
2985
2985
  export type ${s}DTO = z.infer<typeof ${c}Schema>
2986
- `),l.push(u),l}async function Qn(e){let t=S(e.outDir,`kick.config.ts`),n=e.modulesDir??`src/modules`,r=e.defaultRepo??`inmemory`;return g(t)&&!e.force&&!await F({message:`kick.config.ts already exists. Overwrite?`,initialValue:!1})?(console.log(`
2986
+ `),l.push(u),l}async function $n(e){let t=S(e.outDir,`kick.config.ts`),n=e.modulesDir??`src/modules`,r=e.defaultRepo??`inmemory`;return g(t)&&!e.force&&!await F({message:`kick.config.ts already exists. Overwrite?`,initialValue:!1})?(console.log(`
2987
2987
  Skipped — existing kick.config.ts preserved.`),[]):(await M(t,`import { defineConfig } from '@forinda/kickjs-cli'
2988
2988
 
2989
2989
  export default defineConfig({
@@ -3021,18 +3021,18 @@ export default defineConfig({
3021
3021
  },
3022
3022
  ],
3023
3023
  })
3024
- `),[t])}const $n=new Set([`rest`,`ddd`,`cqrs`,`minimal`]);function er(e,t){if(t)return t;try{let t=JSON.parse(v(S(e,`package.json`),`utf-8`));if(t.name)return t.name.replace(/^@[^/]+\//,``)}catch{}return e.split(`/`).findLast(Boolean)??`app`}function tr(e,t){if(t)return t;try{let t=JSON.parse(v(S(e,`package.json`),`utf-8`));if(t.packageManager)return t.packageManager.split(`@`)[0]}catch{}return`pnpm`}async function nr(e,t){if(t)return t;try{let t=(await r(e))?.pattern;if(t&&$n.has(t))return t}catch{}return`ddd`}async function rr(e){let t=e.only??`all`,n=er(e.outDir,e.name),r=tr(e.outDir,e.pm),i=await nr(e.outDir,e.template),a=t===`agents`||t===`both`||t===`all`,o=t===`claude`||t===`both`||t===`all`,s=t===`skills`||t===`all`,c=[];a&&c.push({file:S(e.outDir,`AGENTS.md`),render:()=>st(n,i,r)}),o&&c.push({file:S(e.outDir,`CLAUDE.md`),render:()=>ot(n,i,r)}),s&&c.push({file:S(e.outDir,`kickjs-skills.md`),render:()=>ct(n,i,r)});let l=[];for(let{file:t,render:n}of c){if(g(t)&&!e.force&&!await F({message:`${t.replace(e.outDir+`/`,``)} already exists. Overwrite?`,initialValue:!1})){console.log(` Skipped — existing ${t.replace(e.outDir+`/`,``)} preserved.`);continue}await M(t,n()),l.push(t)}return l}function ir(e,t){if(e[t]!==`{`)return-1;let n=1;for(let r=t+1;r<e.length;r++){let t=e[r];if(t===`{`)n++;else if(t===`}`&&(n--,n===0))return r}return-1}function G(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=ir(e,r);return i===-1?null:e.slice(r+1,i)}function K(e,t,n){let r=` `.repeat(n);return e.split(`
3024
+ `),[t])}const er=new Set([`rest`,`ddd`,`cqrs`,`minimal`]);function tr(e,t){if(t)return t;try{let t=JSON.parse(v(S(e,`package.json`),`utf-8`));if(t.name)return t.name.replace(/^@[^/]+\//,``)}catch{}return e.split(`/`).findLast(Boolean)??`app`}function nr(e,t){if(t)return t;try{let t=JSON.parse(v(S(e,`package.json`),`utf-8`));if(t.packageManager)return t.packageManager.split(`@`)[0]}catch{}return`pnpm`}async function rr(e,t){if(t)return t;try{let t=(await r(e))?.pattern;if(t&&er.has(t))return t}catch{}return`ddd`}async function ir(e){let t=e.only??`all`,n=tr(e.outDir,e.name),r=nr(e.outDir,e.pm),i=await rr(e.outDir,e.template),a=t===`agents`||t===`both`||t===`all`,o=t===`claude`||t===`both`||t===`all`,s=t===`skills`||t===`all`,c=[];a&&c.push({file:S(e.outDir,`AGENTS.md`),render:()=>ct(n,i,r)}),o&&c.push({file:S(e.outDir,`CLAUDE.md`),render:()=>st(n,i,r)}),s&&c.push({file:S(e.outDir,`kickjs-skills.md`),render:()=>lt(n,i,r)});let l=[];for(let{file:t,render:n}of c){if(g(t)&&!e.force&&!await F({message:`${t.replace(e.outDir+`/`,``)} already exists. Overwrite?`,initialValue:!1})){console.log(` Skipped — existing ${t.replace(e.outDir+`/`,``)} preserved.`);continue}await M(t,n()),l.push(t)}return l}function ar(e,t){if(e[t]!==`{`)return-1;let n=1;for(let r=t+1;r<e.length;r++){let t=e[r];if(t===`{`)n++;else if(t===`}`&&(n--,n===0))return r}return-1}function G(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=ar(e,r);return i===-1?null:e.slice(r+1,i)}function K(e,t,n){let r=` `.repeat(n);return e.split(`
3025
3025
  `).map(e=>{if(e.trim()===``)return e;let n=RegExp(`^ {0,${t}}`);return r+e.replace(n,``)}).join(`
3026
- `)}function ar(e){return e.replaceAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*'@forinda\/kickjs'/g,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(e=>e&&e!==`Container`&&e!==`type Container`&&e!==`type AppModule`&&e!==`AppModule`&&e!==`type ModuleRoutes`&&e!==`ModuleRoutes`);return n.includes(`defineModule`)||n.push(`defineModule`),`import { ${n.join(`, `)} } from '@forinda/kickjs'`})}function or(e,t){return e.replaceAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*'@forinda\/kickjs'/g,(e,n)=>{let r=n.split(`,`).map(e=>e.trim()).filter(e=>e&&e!==`defineModule`);return t.container&&!r.includes(`Container`)&&r.push(`Container`),t.appModule&&!r.some(e=>e===`AppModule`||e===`type AppModule`)&&r.push(`type AppModule`),t.moduleRoutes&&!r.some(e=>e===`ModuleRoutes`||e===`type ModuleRoutes`)&&r.push(`type ModuleRoutes`),t.contributorRegistrations&&!r.some(e=>e===`ContributorRegistrations`||e===`type ContributorRegistrations`)&&r.push(`type ContributorRegistrations`),`import { ${r.join(`, `)} } from '@forinda/kickjs'`})}function sr(e){if(/\bdefineModule\s*\(/.test(e))return{migrated:null,reason:`already in target form`};let t=[...e.matchAll(/export\s+class\s+(\w+Module)\s+implements\s+AppModule\s*\{/g)];if(t.length===0)return{migrated:null,reason:`no class form detected`};if(t.length>1)return{migrated:null,reason:`multiple module classes in one file — migrate manually`};let n=t[0],r=n[1],i=n.index+n[0].length-1,a=ir(e,i);if(a===-1)return{migrated:null,reason:`unbalanced class braces`};let o=e.slice(i+1,a),s=e.slice(0,n.index),c=e.slice(a+1),l=G(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=G(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=G(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=ar(s),p=``;return l&&(p+=` register(container) {${K(l,4,6)} },\n\n`),u&&(p+=` contributors() {${K(u,4,6)} },\n\n`),p+=` routes() {${K(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
3026
+ `)}function or(e){return e.replaceAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*'@forinda\/kickjs'/g,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(e=>e&&e!==`Container`&&e!==`type Container`&&e!==`type AppModule`&&e!==`AppModule`&&e!==`type ModuleRoutes`&&e!==`ModuleRoutes`);return n.includes(`defineModule`)||n.push(`defineModule`),`import { ${n.join(`, `)} } from '@forinda/kickjs'`})}function sr(e,t){return e.replaceAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*'@forinda\/kickjs'/g,(e,n)=>{let r=n.split(`,`).map(e=>e.trim()).filter(e=>e&&e!==`defineModule`);return t.container&&!r.includes(`Container`)&&r.push(`Container`),t.appModule&&!r.some(e=>e===`AppModule`||e===`type AppModule`)&&r.push(`type AppModule`),t.moduleRoutes&&!r.some(e=>e===`ModuleRoutes`||e===`type ModuleRoutes`)&&r.push(`type ModuleRoutes`),t.contributorRegistrations&&!r.some(e=>e===`ContributorRegistrations`||e===`type ContributorRegistrations`)&&r.push(`type ContributorRegistrations`),`import { ${r.join(`, `)} } from '@forinda/kickjs'`})}function cr(e){if(/\bdefineModule\s*\(/.test(e))return{migrated:null,reason:`already in target form`};let t=[...e.matchAll(/export\s+class\s+(\w+Module)\s+implements\s+AppModule\s*\{/g)];if(t.length===0)return{migrated:null,reason:`no class form detected`};if(t.length>1)return{migrated:null,reason:`multiple module classes in one file — migrate manually`};let n=t[0],r=n[1],i=n.index+n[0].length-1,a=ar(e,i);if(a===-1)return{migrated:null,reason:`unbalanced class braces`};let o=e.slice(i+1,a),s=e.slice(0,n.index),c=e.slice(a+1),l=G(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=G(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=G(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=or(s),p=``;return l&&(p+=` register(container) {${K(l,4,6)} },\n\n`),u&&(p+=` contributors() {${K(u,4,6)} },\n\n`),p+=` routes() {${K(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
3027
3027
  name: '${r}',
3028
3028
  build: () => ({
3029
3029
  ${p}
3030
3030
  }),
3031
- })`}${c}`}}function cr(e){if(/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/.test(e))return{migrated:null,reason:`already in target form`};let t=[...e.matchAll(/export\s+const\s+(\w+Module)\s*=\s*defineModule\s*\(\s*\{/g)];if(t.length===0)return{migrated:null,reason:`no defineModule form detected`};if(t.length>1)return{migrated:null,reason:`multiple defineModule blocks in one file — migrate manually`};let n=t[0],r=n[1],i=n.index+n[0].length-1,a=ir(e,i);if(a===-1)return{migrated:null,reason:`unbalanced defineModule braces`};let o=e.indexOf(`)`,a);if(o===-1)return{migrated:null,reason:`unbalanced defineModule call parens`};let s=e.slice(i+1,a),c=e.slice(0,n.index),l=o+1;for(;l<e.length&&(e[l]===`
3032
- `||e[l]===`\r`);)l++;let u=e.slice(l),d=/build\s*:\s*\([^)]*\)\s*=>\s*\(\s*\{/g.exec(s);if(!d)return{migrated:null,reason:`build: () => ({...}) not found in defineModule`};let f=d.index+d[0].length-1,p=ir(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=G(m,/register\s*\(([^)]*)\)\s*\{/),g=G(m,/contributors\s*\(\s*\)\s*\{/),_=G(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=or(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${K(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${K(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${K(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
3031
+ })`}${c}`}}function lr(e){if(/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/.test(e))return{migrated:null,reason:`already in target form`};let t=[...e.matchAll(/export\s+const\s+(\w+Module)\s*=\s*defineModule\s*\(\s*\{/g)];if(t.length===0)return{migrated:null,reason:`no defineModule form detected`};if(t.length>1)return{migrated:null,reason:`multiple defineModule blocks in one file — migrate manually`};let n=t[0],r=n[1],i=n.index+n[0].length-1,a=ar(e,i);if(a===-1)return{migrated:null,reason:`unbalanced defineModule braces`};let o=e.indexOf(`)`,a);if(o===-1)return{migrated:null,reason:`unbalanced defineModule call parens`};let s=e.slice(i+1,a),c=e.slice(0,n.index),l=o+1;for(;l<e.length&&(e[l]===`
3032
+ `||e[l]===`\r`);)l++;let u=e.slice(l),d=/build\s*:\s*\([^)]*\)\s*=>\s*\(\s*\{/g.exec(s);if(!d)return{migrated:null,reason:`build: () => ({...}) not found in defineModule`};let f=d.index+d[0].length-1,p=ar(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=G(m,/register\s*\(([^)]*)\)\s*\{/),g=G(m,/contributors\s*\(\s*\)\s*\{/),_=G(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=sr(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${K(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${K(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${K(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
3033
3033
  ${y}
3034
3034
  }
3035
- `}${u}`}}function lr(e,t){return t===`class`?cr(e):sr(e)}function ur(e,t){let n=e,r=!1;if(t===`define`){/\bAppModuleClass\b/.test(n)&&(n=n.replaceAll(/\bAppModuleClass\b/g,`AppModuleEntry`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)(?![(.])/g,`$1()`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}else{/\bAppModuleEntry\b/.test(n)&&(n=n.replaceAll(/\bAppModuleEntry\b/g,`AppModuleClass`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)\s*\(\s*\)/g,`$1`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}return r?{migrated:n}:{migrated:null,reason:`no changes needed`}}async function dr(e){let t=[];return await n(w(e),0),t;async function n(e,r){let i;try{i=await he(e)}catch{return}for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=S(e,a),o;try{o=await _e(i)}catch{continue}o.isDirectory()?await n(i,r+1):(a.endsWith(`.module.ts`)||a===`index.ts`&&r===1)&&t.push(i)}}}async function fr(e,t){let n=0;return await r(e,t),n;async function r(e,t){let i;try{i=await he(e)}catch{return}await me(t,{recursive:!0});for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=S(e,a),o=S(t,a),s;try{s=await _e(i)}catch{continue}s.isDirectory()?await r(i,o):(await pe(i,o),n++)}}}function pr(e){return S(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function mr(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await dr(e),s=await D(S(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=pr(r),await fr(e,c));let l=[];for(let e of o){let t=lr(await D(e,`utf-8`),i);if(t.migrated==null){l.push({path:e,status:`skipped`,reason:t.reason});continue}n||await O(e,t.migrated,`utf-8`),l.push({path:e,status:`migrated`})}let u=S(e,`index.ts`),d=null;try{d=await D(u,`utf-8`)}catch{return{target:i,files:l,indexStatus:`not-found`,indexPath:u,backupDir:c}}let f=ur(d,i);return f.migrated==null?{target:i,files:l,indexStatus:`skipped`,indexPath:u,indexReason:f.reason,backupDir:c}:(n||await O(u,f.migrated,`utf-8`),{target:i,files:l,indexStatus:`migrated`,indexPath:u,backupDir:c})}async function hr(e,t){let n=await dr(e),r=[],i=t===`define`?/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/:/export\s+const\s+\w+Module\s*=\s*defineModule\s*\(/;for(let e of n){let t=await D(e,`utf-8`);i.test(t)&&r.push(e)}return r}async function gr(e={}){let t=e.strategy??`jwt`,n=e.outDir??`src/modules/auth`,r=S(n,`dto`),i=[],a=S(n,`auth.module.ts`);await M(a,`import { Module } from '@forinda/kickjs'
3035
+ `}${u}`}}function ur(e,t){return t===`class`?lr(e):cr(e)}function dr(e,t){let n=e,r=!1;if(t===`define`){/\bAppModuleClass\b/.test(n)&&(n=n.replaceAll(/\bAppModuleClass\b/g,`AppModuleEntry`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)(?![(.])/g,`$1()`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}else{/\bAppModuleEntry\b/.test(n)&&(n=n.replaceAll(/\bAppModuleEntry\b/g,`AppModuleClass`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)\s*\(\s*\)/g,`$1`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}return r?{migrated:n}:{migrated:null,reason:`no changes needed`}}async function fr(e){let t=[];return await n(w(e),0),t;async function n(e,r){let i;try{i=await he(e)}catch{return}for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=S(e,a),o;try{o=await _e(i)}catch{continue}o.isDirectory()?await n(i,r+1):(a.endsWith(`.module.ts`)||a===`index.ts`&&r===1)&&t.push(i)}}}async function pr(e,t){let n=0;return await r(e,t),n;async function r(e,t){let i;try{i=await he(e)}catch{return}await me(t,{recursive:!0});for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=S(e,a),o=S(t,a),s;try{s=await _e(i)}catch{continue}s.isDirectory()?await r(i,o):(await pe(i,o),n++)}}}function mr(e){return S(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function hr(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await fr(e),s=await D(S(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=mr(r),await pr(e,c));let l=[];for(let e of o){let t=ur(await D(e,`utf-8`),i);if(t.migrated==null){l.push({path:e,status:`skipped`,reason:t.reason});continue}n||await O(e,t.migrated,`utf-8`),l.push({path:e,status:`migrated`})}let u=S(e,`index.ts`),d=null;try{d=await D(u,`utf-8`)}catch{return{target:i,files:l,indexStatus:`not-found`,indexPath:u,backupDir:c}}let f=dr(d,i);return f.migrated==null?{target:i,files:l,indexStatus:`skipped`,indexPath:u,indexReason:f.reason,backupDir:c}:(n||await O(u,f.migrated,`utf-8`),{target:i,files:l,indexStatus:`migrated`,indexPath:u,backupDir:c})}async function gr(e,t){let n=await fr(e),r=[],i=t===`define`?/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/:/export\s+const\s+\w+Module\s*=\s*defineModule\s*\(/;for(let e of n){let t=await D(e,`utf-8`);i.test(t)&&r.push(e)}return r}async function _r(e={}){let t=e.strategy??`jwt`,n=e.outDir??`src/modules/auth`,r=S(n,`dto`),i=[],a=S(n,`auth.module.ts`);await M(a,`import { Module } from '@forinda/kickjs'
3036
3036
  import { AuthController } from './auth.controller'
3037
3037
  import { AuthService } from './auth.service'
3038
3038
 
@@ -3041,7 +3041,7 @@ import { AuthService } from './auth.service'
3041
3041
  services: [AuthService],
3042
3042
  })
3043
3043
  export class AuthModule {}
3044
- `),i.push(a);let o=S(n,`auth.controller.ts`);await M(o,t===`jwt`?_r():yr()),i.push(o);let s=S(n,`auth.service.ts`);await M(s,t===`jwt`?vr():br()),i.push(s);let c=S(r,`register.dto.ts`);await M(c,`import { z } from 'zod'
3044
+ `),i.push(a);let o=S(n,`auth.controller.ts`);await M(o,t===`jwt`?vr():br()),i.push(o);let s=S(n,`auth.service.ts`);await M(s,t===`jwt`?yr():xr()),i.push(s);let c=S(r,`register.dto.ts`);await M(c,`import { z } from 'zod'
3045
3045
 
3046
3046
  export const RegisterDto = z.object({
3047
3047
  email: z.string().email(),
@@ -3078,7 +3078,7 @@ describe('Auth Module', () => {
3078
3078
  */
3079
3079
  export const AdminOnly = Roles('admin')
3080
3080
  export const ManagerOnly = Roles('manager')
3081
- `),i.push(e)}return i}function _r(){return`import { Controller, Post, Get } from '@forinda/kickjs'
3081
+ `),i.push(e)}return i}function vr(){return`import { Controller, Post, Get } from '@forinda/kickjs'
3082
3082
  import { Authenticated, Public } from '@forinda/kickjs-auth'
3083
3083
  import type { RequestContext } from '@forinda/kickjs'
3084
3084
  import { Autowired } from '@forinda/kickjs'
@@ -3114,7 +3114,7 @@ export class AuthController {
3114
3114
  return ctx.json({ user: ctx.user })
3115
3115
  }
3116
3116
  }
3117
- `}function vr(){return`import { Service, Autowired } from '@forinda/kickjs'
3117
+ `}function yr(){return`import { Service, Autowired } from '@forinda/kickjs'
3118
3118
  import { PasswordService } from '@forinda/kickjs-auth'
3119
3119
  import type { RegisterInput } from './dto/register.dto'
3120
3120
  import type { LoginInput } from './dto/login.dto'
@@ -3153,7 +3153,7 @@ export class AuthService {
3153
3153
  return { user: { id: user.id, email: user.email, name: user.name } }
3154
3154
  }
3155
3155
  }
3156
- `}function yr(){return`import { Controller, Post, Get } from '@forinda/kickjs'
3156
+ `}function br(){return`import { Controller, Post, Get } from '@forinda/kickjs'
3157
3157
  import { Authenticated, Public } from '@forinda/kickjs-auth'
3158
3158
  import { sessionLogin, sessionLogout } from '@forinda/kickjs-auth'
3159
3159
  import type { RequestContext } from '@forinda/kickjs'
@@ -3192,7 +3192,7 @@ export class AuthController {
3192
3192
  return ctx.json({ user: ctx.user })
3193
3193
  }
3194
3194
  }
3195
- `}function br(){return`import { Service, Autowired } from '@forinda/kickjs'
3195
+ `}function xr(){return`import { Service, Autowired } from '@forinda/kickjs'
3196
3196
  import { PasswordService } from '@forinda/kickjs-auth'
3197
3197
  import type { RegisterInput } from './dto/register.dto'
3198
3198
  import type { LoginInput } from './dto/login.dto'
@@ -3229,7 +3229,7 @@ export class AuthService {
3229
3229
  return { id: user.id, email: user.email, name: user.name }
3230
3230
  }
3231
3231
  }
3232
- `}async function xr(e){let{name:t,outDir:n}=e,r=R(t),i=B(t),a=z(t),o=e.queue??`${i}-queue`,s=[];return await(async(e,t)=>{let r=S(n,e);await M(r,t),s.push(r)})(`${i}.job.ts`,`import { Inject } from '@forinda/kickjs'
3232
+ `}async function Sr(e){let{name:t,outDir:n}=e,r=R(t),i=B(t),a=z(t),o=e.queue??`${i}-queue`,s=[];return await(async(e,t)=>{let r=S(n,e);await M(r,t),s.push(r)})(`${i}.job.ts`,`import { Inject } from '@forinda/kickjs'
3233
3233
  import { Job, Process, QUEUE_MANAGER, type QueueService } from '@forinda/kickjs-queue'
3234
3234
 
3235
3235
  /**
@@ -3262,7 +3262,7 @@ export class ${r}Job {
3262
3262
  // Handle high-priority variant of this job
3263
3263
  }
3264
3264
  }
3265
- `),s}const Sr={string:{ts:`string`,zod:`z.string()`},text:{ts:`string`,zod:`z.string()`},number:{ts:`number`,zod:`z.number()`},int:{ts:`number`,zod:`z.number().int()`},float:{ts:`number`,zod:`z.number()`},boolean:{ts:`boolean`,zod:`z.boolean()`},date:{ts:`string`,zod:`z.string().datetime()`},email:{ts:`string`,zod:`z.string().email()`},url:{ts:`string`,zod:`z.string().url()`},uuid:{ts:`string`,zod:`z.string().uuid()`},json:{ts:`any`,zod:`z.any()`}};function Cr(e){return e.map(e=>{let t=e.indexOf(`:`);if(t===-1)throw Error(`Invalid field: "${e}". Use format: name:type (e.g. title:string)`);let n=e.slice(0,t),r=e.slice(t+1);if(!n||!r)throw Error(`Invalid field: "${e}". Use format: name:type (e.g. title:string)`);let i=!1;r.endsWith(`:optional`)&&(r=r.slice(0,-9),i=!0),n.endsWith(`?`)&&(n=n.slice(0,-1),i=!0),r.endsWith(`?`)&&(r=r.slice(0,-1),i=!0);let a=r;if(a.startsWith(`enum:`)){let e=a.slice(5).split(`,`);return{name:n,type:`enum`,tsType:e.map(e=>`'${e}'`).join(` | `),zodType:`z.enum([${e.map(e=>`'${e}'`).join(`, `)}])`,optional:i}}let o=Sr[a];if(!o){let e=[...Object.keys(Sr),`enum:a,b,c`].join(`, `);throw Error(`Unknown field type: "${a}". Valid types: ${e}`)}return{name:n,type:a,tsType:o.ts,zodType:o.zod,optional:i}})}async function wr(e){let{name:t,fields:n,modulesDir:r,noEntity:i,noTests:a,repo:o=`inmemory`,tokenScope:s=`app`,style:c=`define`}=e,l=e.pluralize!==!1,u=B(t),d=R(t);z(t);let f=l?V(u):u,p=l?Ft(d):d,m=S(r,f),h=[],g=async(e,t)=>{let n=S(m,e);await M(n,t),h.push(n)};await g(`${u}.module.ts`,Mr(d,u,f,c)),await g(`constants.ts`,Or(d,n)),await g(`presentation/${u}.controller.ts`,Nr(d,u,f,p)),await g(`application/dtos/create-${u}.dto.ts`,Tr(d,n)),await g(`application/dtos/update-${u}.dto.ts`,Er(d,n)),await g(`application/dtos/${u}-response.dto.ts`,Dr(d,n));let _=Ir(d,u,f,p);for(let e of _)await g(`application/use-cases/${e.file}`,e.content);return await g(`domain/repositories/${u}.repository.ts`,Pr(d,u,s)),await g(`domain/services/${u}-domain.service.ts`,Fr(d,u)),o===`inmemory`&&await g(`infrastructure/repositories/in-memory-${u}.repository.ts`,kr(d,u,n)),i||(await g(`domain/entities/${u}.entity.ts`,Ar(d,u,n)),await g(`domain/value-objects/${u}-id.vo.ts`,jr(d))),await Fn(r,d,f,u,c),h}function Tr(e,t){return`import { z } from 'zod'
3265
+ `),s}const Cr={string:{ts:`string`,zod:`z.string()`},text:{ts:`string`,zod:`z.string()`},number:{ts:`number`,zod:`z.number()`},int:{ts:`number`,zod:`z.number().int()`},float:{ts:`number`,zod:`z.number()`},boolean:{ts:`boolean`,zod:`z.boolean()`},date:{ts:`string`,zod:`z.string().datetime()`},email:{ts:`string`,zod:`z.string().email()`},url:{ts:`string`,zod:`z.string().url()`},uuid:{ts:`string`,zod:`z.string().uuid()`},json:{ts:`any`,zod:`z.any()`}};function wr(e){return e.map(e=>{let t=e.indexOf(`:`);if(t===-1)throw Error(`Invalid field: "${e}". Use format: name:type (e.g. title:string)`);let n=e.slice(0,t),r=e.slice(t+1);if(!n||!r)throw Error(`Invalid field: "${e}". Use format: name:type (e.g. title:string)`);let i=!1;r.endsWith(`:optional`)&&(r=r.slice(0,-9),i=!0),n.endsWith(`?`)&&(n=n.slice(0,-1),i=!0),r.endsWith(`?`)&&(r=r.slice(0,-1),i=!0);let a=r;if(a.startsWith(`enum:`)){let e=a.slice(5).split(`,`);return{name:n,type:`enum`,tsType:e.map(e=>`'${e}'`).join(` | `),zodType:`z.enum([${e.map(e=>`'${e}'`).join(`, `)}])`,optional:i}}let o=Cr[a];if(!o){let e=[...Object.keys(Cr),`enum:a,b,c`].join(`, `);throw Error(`Unknown field type: "${a}". Valid types: ${e}`)}return{name:n,type:a,tsType:o.ts,zodType:o.zod,optional:i}})}async function Tr(e){let{name:t,fields:n,modulesDir:r,noEntity:i,noTests:a,repo:o=`inmemory`,tokenScope:s=`app`,style:c=`define`}=e,l=e.pluralize!==!1,u=B(t),d=R(t);z(t);let f=l?V(u):u,p=l?It(d):d,m=S(r,f),h=[],g=async(e,t)=>{let n=S(m,e);await M(n,t),h.push(n)};await g(`${u}.module.ts`,Nr(d,u,f,c)),await g(`constants.ts`,kr(d,n)),await g(`presentation/${u}.controller.ts`,Pr(d,u,f,p)),await g(`application/dtos/create-${u}.dto.ts`,Er(d,n)),await g(`application/dtos/update-${u}.dto.ts`,Dr(d,n)),await g(`application/dtos/${u}-response.dto.ts`,Or(d,n));let _=Lr(d,u,f,p);for(let e of _)await g(`application/use-cases/${e.file}`,e.content);return await g(`domain/repositories/${u}.repository.ts`,Fr(d,u,s)),await g(`domain/services/${u}-domain.service.ts`,Ir(d,u)),o===`inmemory`&&await g(`infrastructure/repositories/in-memory-${u}.repository.ts`,Ar(d,u,n)),i||(await g(`domain/entities/${u}.entity.ts`,jr(d,u,n)),await g(`domain/value-objects/${u}-id.vo.ts`,Mr(d))),await In(r,d,f,u,c),h}function Er(e,t){return`import { z } from 'zod'
3266
3266
 
3267
3267
  export const create${e}Schema = z.object({
3268
3268
  ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:``},`}).join(`
@@ -3270,7 +3270,7 @@ ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:`
3270
3270
  })
3271
3271
 
3272
3272
  export type Create${e}DTO = z.infer<typeof create${e}Schema>
3273
- `}function Er(e,t){return`import { z } from 'zod'
3273
+ `}function Dr(e,t){return`import { z } from 'zod'
3274
3274
 
3275
3275
  export const update${e}Schema = z.object({
3276
3276
  ${t.map(e=>` ${e.name}: ${e.zodType}.optional(),`).join(`
@@ -3278,21 +3278,21 @@ ${t.map(e=>` ${e.name}: ${e.zodType}.optional(),`).join(`
3278
3278
  })
3279
3279
 
3280
3280
  export type Update${e}DTO = z.infer<typeof update${e}Schema>
3281
- `}function Dr(e,t){return`export interface ${e}ResponseDTO {
3281
+ `}function Or(e,t){return`export interface ${e}ResponseDTO {
3282
3282
  id: string
3283
3283
  ${t.map(e=>` ${e.name}${e.optional?`?`:``}: ${e.tsType}`).join(`
3284
3284
  `)}
3285
3285
  createdAt: string
3286
3286
  updatedAt: string
3287
3287
  }
3288
- `}function Or(e,t){let n=t.filter(e=>e.tsType===`string`).map(e=>`'${e.name}'`);t.filter(e=>e.tsType===`number`).map(e=>`'${e.name}'`);let r=t.map(e=>`'${e.name}'`),i=[...r].join(`, `),a=[...r,`'createdAt'`,`'updatedAt'`].join(`, `),o=n.length>0?n.join(`, `):`'name'`;return`import type { ApiQueryParamsConfig } from '@forinda/kickjs'
3288
+ `}function kr(e,t){let n=t.filter(e=>e.tsType===`string`).map(e=>`'${e.name}'`);t.filter(e=>e.tsType===`number`).map(e=>`'${e.name}'`);let r=t.map(e=>`'${e.name}'`),i=[...r].join(`, `),a=[...r,`'createdAt'`,`'updatedAt'`].join(`, `),o=n.length>0?n.join(`, `):`'name'`;return`import type { ApiQueryParamsConfig } from '@forinda/kickjs'
3289
3289
 
3290
3290
  export const ${e.toUpperCase()}_QUERY_CONFIG: ApiQueryParamsConfig = {
3291
3291
  filterable: [${i}],
3292
3292
  sortable: [${a}],
3293
3293
  searchable: [${o}],
3294
3294
  }
3295
- `}function kr(e,t,n){return`import { randomUUID } from 'node:crypto'
3295
+ `}function Ar(e,t,n){return`import { randomUUID } from 'node:crypto'
3296
3296
  import { Repository, HttpException } from '@forinda/kickjs'
3297
3297
  import type { ParsedQuery } from '@forinda/kickjs'
3298
3298
  import type { I${e}Repository } from '../../domain/repositories/${t}.repository'
@@ -3344,7 +3344,7 @@ ${n.map(e=>` ${e.name}: dto.${e.name},`).join(`
3344
3344
  this.store.delete(id)
3345
3345
  }
3346
3346
  }
3347
- `}function Ar(e,t,n){return`import { ${e}Id } from '../value-objects/${t}-id.vo'
3347
+ `}function jr(e,t,n){return`import { ${e}Id } from '../value-objects/${t}-id.vo'
3348
3348
 
3349
3349
  interface ${e}Props {
3350
3350
  id: ${e}Id
@@ -3390,7 +3390,7 @@ ${n.map(e=>` ${e.name}: this.props.${e.name},`).join(`
3390
3390
  }
3391
3391
  }
3392
3392
  }
3393
- `}function jr(e){return`import { randomUUID } from 'node:crypto'
3393
+ `}function Mr(e){return`import { randomUUID } from 'node:crypto'
3394
3394
 
3395
3395
  export class ${e}Id {
3396
3396
  private constructor(private readonly value: string) {}
@@ -3405,7 +3405,7 @@ export class ${e}Id {
3405
3405
  toString(): string { return this.value }
3406
3406
  equals(other: ${e}Id): boolean { return this.value === other.value }
3407
3407
  }
3408
- `}function Mr(e,t,n,r=`define`){let i=`import { ${e}Controller } from './presentation/${t}.controller'
3408
+ `}function Nr(e,t,n,r=`define`){let i=`import { ${e}Controller } from './presentation/${t}.controller'
3409
3409
  import { ${e.toUpperCase()}_REPOSITORY } from './domain/repositories/${t}.repository'
3410
3410
  import { InMemory${e}Repository } from './infrastructure/repositories/in-memory-${t}.repository'
3411
3411
 
@@ -3478,7 +3478,7 @@ ${a}
3478
3478
  },
3479
3479
  }),
3480
3480
  })
3481
- `}function Nr(e,t,n,r){return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
3481
+ `}function Pr(e,t,n,r){return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
3482
3482
  import { ApiTags } from '@forinda/kickjs-swagger'
3483
3483
  import { Create${e}UseCase } from '../application/use-cases/create-${t}.use-case'
3484
3484
  import { Get${e}UseCase } from '../application/use-cases/get-${t}.use-case'
@@ -3541,7 +3541,7 @@ export class ${e}Controller {
3541
3541
  ctx.noContent()
3542
3542
  }
3543
3543
  }
3544
- `}function Pr(e,t,n){return`import { createToken } from '@forinda/kickjs'
3544
+ `}function Fr(e,t,n){return`import { createToken } from '@forinda/kickjs'
3545
3545
  import type { ${e}ResponseDTO } from '../../application/dtos/${t}-response.dto'
3546
3546
  import type { Create${e}DTO } from '../../application/dtos/create-${t}.dto'
3547
3547
  import type { Update${e}DTO } from '../../application/dtos/update-${t}.dto'
@@ -3567,7 +3567,7 @@ export interface I${e}Repository {
3567
3567
  * adopters must NOT use the reserved \`'kick/'\` namespace.
3568
3568
  */
3569
3569
  export const ${e.toUpperCase()}_REPOSITORY = createToken<I${e}Repository>('${n}/${e}/repository')
3570
- `}function Fr(e,t){return`import { Service, Inject, HttpException } from '@forinda/kickjs'
3570
+ `}function Ir(e,t){return`import { Service, Inject, HttpException } from '@forinda/kickjs'
3571
3571
  import { ${e.toUpperCase()}_REPOSITORY, type I${e}Repository } from '../repositories/${t}.repository'
3572
3572
 
3573
3573
  @Service()
@@ -3581,7 +3581,7 @@ export class ${e}DomainService {
3581
3581
  if (!entity) throw HttpException.notFound('${e} not found')
3582
3582
  }
3583
3583
  }
3584
- `}function Ir(e,t,n,r){return[{file:`create-${t}.use-case.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
3584
+ `}function Lr(e,t,n,r){return[{file:`create-${t}.use-case.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
3585
3585
  import { ${e.toUpperCase()}_REPOSITORY, type I${e}Repository } from '../../domain/repositories/${t}.repository'
3586
3586
  import type { Create${e}DTO } from '../dtos/create-${t}.dto'
3587
3587
 
@@ -3624,7 +3624,7 @@ export class Delete${e}UseCase {
3624
3624
  constructor(@Inject(${e.toUpperCase()}_REPOSITORY) private repo: I${e}Repository) {}
3625
3625
  async execute(id: string) { return this.repo.delete(id) }
3626
3626
  }
3627
- `}]}async function Lr(e){let{name:t,moduleName:n,modulesDir:r}=e,i=e.pluralize??!0,a=B(t),o=R(t),s=[],c;if(e.outDir)c=w(e.outDir);else if(n){let e=B(n),t=i?V(e):e;c=w(S(r??`src/modules`,t,`__tests__`))}else c=w(`src/__tests__`);let l=S(c,`${a}.test.ts`);return await M(l,`import { describe, it, expect, beforeEach } from 'vitest'
3627
+ `}]}async function Rr(e){let{name:t,moduleName:n,modulesDir:r}=e,i=e.pluralize??!0,a=B(t),o=R(t),s=[],c;if(e.outDir)c=w(e.outDir);else if(n){let e=B(n),t=i?V(e):e;c=w(S(r??`src/modules`,t,`__tests__`))}else c=w(`src/__tests__`);let l=S(c,`${a}.test.ts`);return await M(l,`import { describe, it, expect, beforeEach } from 'vitest'
3628
3628
  import { Container } from '@forinda/kickjs'
3629
3629
 
3630
3630
  describe('${o}', () => {
@@ -3647,20 +3647,20 @@ describe('${o}', () => {
3647
3647
  expect(true).toBe(true)
3648
3648
  })
3649
3649
  })
3650
- `),s.push(l),s}const Rr=[`agents`,`claude`,`skills`,`both`,`all`];function q(e){return e.parent?.opts()?.dryRun??!1}function J(e,t=!1){let n=process.cwd();console.log(`\n ${t?`Would generate`:`Generated`} ${e.length} file${e.length===1?``:`s`}:`);for(let t of e)console.log(` ${t.replace(n+`/`,``)}`);t&&console.log(`
3651
- (dry run — no files were written)`),console.log()}async function zr(e){if(!e)try{let e=await r(process.cwd());await p({cwd:process.cwd(),allowDuplicates:!0,silent:!0,schemaValidator:e?.typegen?.schemaValidator??`zod`,envFile:e?.typegen?.envFile,srcDir:e?.typegen?.srcDir,outDir:e?.typegen?.outDir})}catch{}}const Br=[{name:`module <name>`,description:`Full DDD module (controller, DTOs, use-cases, repo)`},{name:`scaffold <name> <fields...>`,description:`CRUD module from field definitions`},{name:`controller <name>`,description:`@Controller() class [-m module]`},{name:`service <name>`,description:`@Service() singleton [-m module]`},{name:`middleware <name>`,description:`Express middleware function [-m module]`},{name:`guard <name>`,description:`Route guard (auth, roles, etc.) [-m module]`},{name:`dto <name>`,description:`Zod DTO schema [-m module]`},{name:`adapter <name>`,description:`AppAdapter with lifecycle hooks (app-level only)`},{name:`test <name>`,description:`Vitest test scaffold [-m module]`},{name:`job <name>`,description:`Queue @Job processor`},{name:`config`,description:`Generate kick.config.ts`},{name:`agents`,description:`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md from upstream templates`}];async function Vr(){console.log(`
3650
+ `),s.push(l),s}const zr=[`agents`,`claude`,`skills`,`both`,`all`];function q(e){return e.parent?.opts()?.dryRun??!1}function J(e,t=!1){let n=process.cwd();console.log(`\n ${t?`Would generate`:`Generated`} ${e.length} file${e.length===1?``:`s`}:`);for(let t of e)console.log(` ${t.replace(n+`/`,``)}`);t&&console.log(`
3651
+ (dry run — no files were written)`),console.log()}async function Br(e){if(!e)try{let e=await r(process.cwd());await p({cwd:process.cwd(),allowDuplicates:!0,silent:!0,schemaValidator:e?.typegen?.schemaValidator??`zod`,envFile:e?.typegen?.envFile,srcDir:e?.typegen?.srcDir,outDir:e?.typegen?.outDir})}catch{}}const Vr=[{name:`module <name>`,description:`Full DDD module (controller, DTOs, use-cases, repo)`},{name:`scaffold <name> <fields...>`,description:`CRUD module from field definitions`},{name:`controller <name>`,description:`@Controller() class [-m module]`},{name:`service <name>`,description:`@Service() singleton [-m module]`},{name:`middleware <name>`,description:`Express middleware function [-m module]`},{name:`guard <name>`,description:`Route guard (auth, roles, etc.) [-m module]`},{name:`dto <name>`,description:`Zod DTO schema [-m module]`},{name:`adapter <name>`,description:`AppAdapter with lifecycle hooks (app-level only)`},{name:`test <name>`,description:`Vitest test scaffold [-m module]`},{name:`job <name>`,description:`Queue @Job processor`},{name:`config`,description:`Generate kick.config.ts`},{name:`agents`,description:`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md from upstream templates`}];async function Hr(){console.log(`
3652
3652
  Built-in generators:
3653
- `);let e=Math.max(...Br.map(e=>e.name.length));for(let t of Br)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await r(process.cwd()),n=a(t?.plugins??[],t?.commands??[]),i=await Kt(process.cwd(),n.generators);if(i.generators.length>0){console.log(`
3653
+ `);let e=Math.max(...Vr.map(e=>e.name.length));for(let t of Vr)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await r(process.cwd()),n=a(t?.plugins??[],t?.commands??[]),i=await qt(process.cwd(),n.generators);if(i.generators.length>0){console.log(`
3654
3654
  Plugin generators:
3655
3655
  `);let e=Math.max(...i.generators.map(e=>`${e.spec.name} <name>`.length));for(let{source:t,spec:n}of i.generators){let r=`${n.name} <name>`;console.log(` kick g ${r.padEnd(e+2)} ${n.description} [${t}]`)}}if(i.failed.length>0){console.log(`
3656
3656
  Failed to load:
3657
- `);for(let{source:e,reason:t}of i.failed)console.log(` ${e} — ${t}`)}console.log()}async function Hr(e,i,a){let o=await r(process.cwd()),s=n(o),c=i.modulesDir??s.dir??`src/modules`,l=i.repo??Nn(s.repo),u=i.pattern??o?.pattern??`ddd`,d=i.pluralize===!1?!1:s.pluralize??!0,f=t(o,process.cwd()),p=s.style??`define`;if(!a&&p===`define`){let e=await hr(w(c),`define`);if(e.length>0){console.error(`\n ${A.red(`Error:`)} ${e.length} module file(s) still use the legacy \`class … implements AppModule\` shape.\n ${A.dim(`Project setting:`)} modules.style: 'define' (default)\n\n ${A.bold(`Files needing migration:`)}`);for(let t of e.slice(0,5))console.error(` - ${t}`);e.length>5&&console.error(` … and ${e.length-5} more`),console.error(`\n ${A.bold(`Pick one:`)}\n 1. Migrate everything to defineModule:\n ${A.dim(`$`)} kick codemod modules --experimental --apply\n 2. Keep the class form — pin it in kick.config.ts:\n ${A.dim(`// kick.config.ts`)}\n ${A.dim(`export default defineConfig({ modules: { style: 'class' } })`)}\n`),process.exit(1)}}let m=[];for(let t of e){let e=await Pn({name:t,modulesDir:w(c),noEntity:i.entity===!1,noTests:i.tests===!1,repo:l,minimal:i.minimal,force:i.force,pattern:u,dryRun:a,pluralize:d,prismaClientPath:s.prismaClientPath,tokenScope:f,style:s.style});m.push(...e)}J(m,a),await zr(a)}function Ur(e){let i=e.command(`generate [names...]`).alias(`g`).description("Generate code scaffolds — bare form `kick g <name>` is shorthand for `kick g module <name>`").option(`--list`,`List all available generators`).option(`--dry-run`,`Preview files that would be generated without writing them`).option(`--no-entity`,`Skip entity and value object generation (module shortcut)`).option(`--no-tests`,`Skip test file generation (module shortcut)`).option(`--repo <type>`,`Repository implementation: inmemory | drizzle | prisma`).option(`--pattern <pattern>`,`Override project pattern: rest | ddd | cqrs | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t,n)=>{if(t.list){await Vr();return}if(!e||e.length===0){i.help();return}let o=q(n);if(j(o),e.length>=2){let[n,i,...s]=e,c=await r(process.cwd()),l=a(c?.plugins??[],c?.commands??[]),u=await Gt({generatorName:n,itemName:i,args:s,flags:t,cwd:process.cwd()},l.generators);if(u){J(u.files,o);return}}await Hr(e,t,o)});i.command(`module <names...>`).description(`Generate one or more modules (e.g. kick g module user task project)`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--repo <type>`,`Repository implementation: inmemory | drizzle | prisma`).option(`--pattern <pattern>`,`Override project pattern: rest | ddd | cqrs | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t,n)=>{let r=q(n);j(r),await Hr(e,{...n.optsWithGlobals(),...t},r)}),i.command(`adapter <name>`).description(`Generate an AppAdapter with lifecycle hooks and middleware support`).option(`-o, --out <dir>`,`Output directory`,`src/adapters`).action(async(e,t,n)=>{let r=q(n);j(r),J(await Hn({name:e,outDir:w(t.out)}),r)}),i.command(`plugin <name>`).description(`Generate a KickPlugin with DI, modules, adapters, middleware, and lifecycle hooks`).option(`-o, --out <dir>`,`Output directory`,`src/plugins`).action(async(e,t,n)=>{let r=q(n);j(r),J(await Un({name:e,outDir:w(t.out)}),r)}),i.command(`middleware <name>`).description(`Generate an Express middleware function
3658
- Use -m to scope it to a module: kick g middleware auth -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await qn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a)}),i.command(`guard <name>`).description(`Generate a route guard (auth, roles, etc.)
3659
- Use -m to scope it to a module: kick g guard admin -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Jn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a)}),i.command(`service <name>`).description(`Generate a @Service() class
3660
- Use -m to scope it to a module: kick g service payment -m orders`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Yn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a)}),i.command(`controller <name>`).description(`Generate a @Controller() class with basic routes
3661
- Use -m to scope it to a module: kick g controller auth -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Xn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a),await zr(a)}),i.command(`dto <name>`).description(`Generate a Zod DTO schema
3662
- Use -m to scope it to a module: kick g dto create-user -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Zn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a)}),i.command(`test <name>`).description(`Generate a Vitest test scaffold
3663
- Use -m to scope it to a module: kick g test user-service -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module's __tests__/ folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=n(await r(process.cwd())),s=o.dir??`src/modules`;J(await Lr({name:e,outDir:t.out,moduleName:t.module,modulesDir:s,pluralize:o.pluralize??!0}),a)}),i.command(`job <name>`).description(`Generate a @Job queue processor with @Process handlers`).option(`-o, --out <dir>`,`Output directory`,`src/jobs`).option(`-q, --queue <name>`,`Queue name (default: <name>-queue)`).action(async(e,t,n)=>{let r=q(n);j(r),J(await xr({name:e,outDir:w(t.out),queue:t.queue}),r)}),i.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
3657
+ `);for(let{source:e,reason:t}of i.failed)console.log(` ${e} — ${t}`)}console.log()}async function Ur(e,i,a){let o=await r(process.cwd()),s=n(o),c=i.modulesDir??s.dir??`src/modules`,l=i.repo??Pn(s.repo),u=i.pattern??o?.pattern??`ddd`,d=i.pluralize===!1?!1:s.pluralize??!0,f=t(o,process.cwd()),p=s.style??`define`;if(!a&&p===`define`){let e=await gr(w(c),`define`);if(e.length>0){console.error(`\n ${A.red(`Error:`)} ${e.length} module file(s) still use the legacy \`class … implements AppModule\` shape.\n ${A.dim(`Project setting:`)} modules.style: 'define' (default)\n\n ${A.bold(`Files needing migration:`)}`);for(let t of e.slice(0,5))console.error(` - ${t}`);e.length>5&&console.error(` … and ${e.length-5} more`),console.error(`\n ${A.bold(`Pick one:`)}\n 1. Migrate everything to defineModule:\n ${A.dim(`$`)} kick codemod modules --experimental --apply\n 2. Keep the class form — pin it in kick.config.ts:\n ${A.dim(`// kick.config.ts`)}\n ${A.dim(`export default defineConfig({ modules: { style: 'class' } })`)}\n`),process.exit(1)}}let m=[];for(let t of e){let e=await Fn({name:t,modulesDir:w(c),noEntity:i.entity===!1,noTests:i.tests===!1,repo:l,minimal:i.minimal,force:i.force,pattern:u,dryRun:a,pluralize:d,prismaClientPath:s.prismaClientPath,tokenScope:f,style:s.style});m.push(...e)}J(m,a),await Br(a)}function Wr(e){let i=e.command(`generate [names...]`).alias(`g`).description("Generate code scaffolds — bare form `kick g <name>` is shorthand for `kick g module <name>`").option(`--list`,`List all available generators`).option(`--dry-run`,`Preview files that would be generated without writing them`).option(`--no-entity`,`Skip entity and value object generation (module shortcut)`).option(`--no-tests`,`Skip test file generation (module shortcut)`).option(`--repo <type>`,`Repository implementation: inmemory | drizzle | prisma`).option(`--pattern <pattern>`,`Override project pattern: rest | ddd | cqrs | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t,n)=>{if(t.list){await Hr();return}if(!e||e.length===0){i.help();return}let o=q(n);if(j(o),e.length>=2){let[n,i,...s]=e,c=await r(process.cwd()),l=a(c?.plugins??[],c?.commands??[]),u=await Kt({generatorName:n,itemName:i,args:s,flags:t,cwd:process.cwd()},l.generators);if(u){J(u.files,o);return}}await Ur(e,t,o)});i.command(`module <names...>`).description(`Generate one or more modules (e.g. kick g module user task project)`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--repo <type>`,`Repository implementation: inmemory | drizzle | prisma`).option(`--pattern <pattern>`,`Override project pattern: rest | ddd | cqrs | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t,n)=>{let r=q(n);j(r),await Ur(e,{...n.optsWithGlobals(),...t},r)}),i.command(`adapter <name>`).description(`Generate an AppAdapter with lifecycle hooks and middleware support`).option(`-o, --out <dir>`,`Output directory`,`src/adapters`).action(async(e,t,n)=>{let r=q(n);j(r),J(await Un({name:e,outDir:w(t.out)}),r)}),i.command(`plugin <name>`).description(`Generate a KickPlugin with DI, modules, adapters, middleware, and lifecycle hooks`).option(`-o, --out <dir>`,`Output directory`,`src/plugins`).action(async(e,t,n)=>{let r=q(n);j(r),J(await Wn({name:e,outDir:w(t.out)}),r)}),i.command(`middleware <name>`).description(`Generate an Express middleware function
3658
+ Use -m to scope it to a module: kick g middleware auth -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Jn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a)}),i.command(`guard <name>`).description(`Generate a route guard (auth, roles, etc.)
3659
+ Use -m to scope it to a module: kick g guard admin -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Yn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a)}),i.command(`service <name>`).description(`Generate a @Service() class
3660
+ Use -m to scope it to a module: kick g service payment -m orders`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Xn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a)}),i.command(`controller <name>`).description(`Generate a @Controller() class with basic routes
3661
+ Use -m to scope it to a module: kick g controller auth -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Zn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a),await Br(a)}),i.command(`dto <name>`).description(`Generate a Zod DTO schema
3662
+ Use -m to scope it to a module: kick g dto create-user -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=await r(process.cwd()),s=n(o),c=s.dir??`src/modules`;J(await Qn({name:e,outDir:t.out,moduleName:t.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),a)}),i.command(`test <name>`).description(`Generate a Vitest test scaffold
3663
+ Use -m to scope it to a module: kick g test user-service -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module's __tests__/ folder`).action(async(e,t,i)=>{let a=q(i);j(a);let o=n(await r(process.cwd())),s=o.dir??`src/modules`;J(await Rr({name:e,outDir:t.out,moduleName:t.module,modulesDir:s,pluralize:o.pluralize??!0}),a)}),i.command(`job <name>`).description(`Generate a @Job queue processor with @Process handlers`).option(`-o, --out <dir>`,`Output directory`,`src/jobs`).option(`-q, --queue <name>`,`Queue name (default: <name>-queue)`).action(async(e,t,n)=>{let r=q(n);j(r),J(await Sr({name:e,outDir:w(t.out),queue:t.queue}),r)}),i.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
3664
3664
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
3665
3665
  Types: string, text, number, int, float, boolean, date, email, url, uuid, json, enum:a,b,c
3666
3666
  Optional: append :optional (shell-safe): description:text:optional
@@ -3669,12 +3669,12 @@ describe('${o}', () => {
3669
3669
  Usage: kick g scaffold <name> <field:type> [field:type...]
3670
3670
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
3671
3671
  Optional: append :optional (shell-safe, no quoting needed)
3672
- `),process.exit(1));let c=await r(process.cwd()),l=n(c),u=a.modulesDir??l.dir??`src/modules`,d=Cr(i),f=t(c,process.cwd()),p=c?.pattern??`ddd`;p!==`ddd`&&(console.error(`\n Error: 'kick g scaffold' currently only supports the DDD pattern.\n Detected project pattern: '${p}'.\n Workarounds:\n - Run 'kick g module ${e}' for the ${p} layout (no fields), then add fields manually.\n - Override the pattern for this scaffold by setting kick.config.ts pattern: 'ddd'.\n`),process.exit(1));let m=await wr({name:e,fields:d,modulesDir:w(u),noEntity:a.entity===!1,noTests:a.tests===!1,pluralize:a.pluralize===!1?!1:l.pluralize??!0,tokenScope:f,style:l.style});console.log(`\n Scaffolded ${e} with ${d.length} field(s):`);for(let e of d)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);J(m,s),await zr(s)}),i.command(`auth-scaffold`).description(`Generate a complete auth module (register, login, logout, password hashing)
3673
- Includes controller, service, DTOs, and test stubs.`).option(`-s, --strategy <type>`,`Auth strategy: jwt | session`).option(`--role-guards`,`Generate role-based guards (default: true)`).option(`--no-role-guards`,`Skip role-based guard generation`).option(`-o, --out <dir>`,`Output directory`,`src/modules/auth`).action(async(e,t)=>{let n=q(t);j(n);let r=e.strategy;r||=await St({message:`Auth strategy`,options:[{value:`jwt`,label:`JWT`,hint:`stateless token-based auth`},{value:`session`,label:`Session`,hint:`server-side session with cookies`}]});let i=e.roleGuards;i===void 0&&(i=await F({message:`Generate role-based guards?`,initialValue:!0})),J(await gr({strategy:r,outDir:e.out,roleGuards:i}),n)}),i.command(`config`).description(`Generate a kick.config.ts at the project root`).option(`--modules-dir <dir>`,`Modules directory path`,`src/modules`).option(`--repo <type>`,`Default repository type: inmemory | drizzle | prisma`,`inmemory`).option(`-f, --force`,`Overwrite existing kick.config.ts without prompting`).action(async(e,t)=>{let n=q(t);j(n),J(await Qn({outDir:w(`.`),modulesDir:e.modulesDir,defaultRepo:e.repo,force:e.force}),n)}),i.command(`agents`).alias(`agent-docs`).alias(`ai-docs`).description(`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md (sync after framework upgrades)`).option(`--only <which>`,`Limit scope: agents | claude | skills | both (agents+claude) | all (default: all)`,`all`).option(`--name <name>`,`Project name (defaults to package.json name)`).option(`--pm <pm>`,`Package manager (defaults to package.json packageManager)`).option(`--template <template>`,`Template: rest | ddd | cqrs | minimal`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t)=>{let n=q(t);j(n);let r=e.only??`all`;if(!Rr.includes(r)){console.error(` Invalid --only value: ${r}. Expected: ${Rr.join(` | `)}`),process.exitCode=1;return}J(await rr({outDir:w(`.`),only:r,name:e.name,pm:e.pm,template:e.template,force:e.force}),n)})}async function Wr(e){let t=b.resolve(e.cwd,`.kickjs/types`);await me(t,{recursive:!0});let n=new Map,r=e.scan??c,i={cwd:e.cwd,config:e.config,async importTs(e){return await import(T(e).href)},async writeFile(t,n){let r=b.resolve(e.cwd,t);await me(b.dirname(r),{recursive:!0}),await O(r,n,`utf8`)},getScanResult:e=>{let t=Gr(e),i=n.get(t);return i||(i=r(e),n.set(t,i)),i},log:console},a=[];for(let n of e.plugins){let r=await n.generate(i);if(r===null){a.push({id:n.id,status:`skipped`});continue}let o=n.outExtension??`.d.ts`,s=b.join(t,`${n.id.replace(/\//g,`__`)}${o}`),c=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: ${n.id} */\n\n`+r+`
3674
- `,l=``;if(g(s)&&(l=await D(s,`utf8`)),l===c){a.push({id:n.id,status:`unchanged`,outFile:s});continue}if(e.check)throw Error(`kick typegen --check: drift detected for ${n.id} (${s})`);await O(s,c,`utf8`),a.push({id:n.id,status:`written`,outFile:s})}return a}function Gr(e){let t=(e.extensions??[]).slice().toSorted().join(`,`),n=(e.exclude??[]).slice().toSorted().join(`,`);return[`root=${e.root}`,`cwd=${e.cwd}`,`extensions=${t}`,`exclude=${n}`,`envFile=${e.envFile??``}`].join(`|`)}function Kr(e,t){let n=new Set(t),r=[],i=[],a=new Set;for(let t of e)n.has(t.id)?(i.push(t),a.add(t.id)):r.push(t);return{enabled:r,skipped:i,unknown:[...n].filter(e=>!a.has(e))}}var qr=e({applyDisableFilter:()=>Kr,runAllPluginTypegens:()=>Jr});async function Jr(e){let{enabled:t,skipped:n,unknown:r}=Kr(a([...Aa,...e.config?.plugins??[]],e.config?.commands??[]).typegens,e.config?.typegen?.disable??[]);if(!e.silent&&n.length>0)for(let e of n)console.log(` ${e.id}: disabled (typegen.disable)`);if(!e.silent&&r.length>0&&console.warn(` kick typegen: disable list references unknown id(s): ${r.map(e=>`'${e}'`).join(`, `)}. Run \`kick typegen --list\` to see registered ids.`),t.length===0)return[];try{let n=await Wr({cwd:e.cwd,config:e.config??{},plugins:t,check:e.check});if(!e.silent)for(let e of n)console.log(` ${e.id}: ${e.status}`);return n}catch(t){if(!e.silent){let e=t instanceof Error?t.message:String(t);console.warn(` kick typegen plugins: skipped (${e})`)}return[]}}async function Yr(e,t){let{cwd:n,silent:r=!1}=t,i=t.distDir??e?.build?.outDir??`dist`,a=e?.assetMap;if(!a||Object.keys(a).length===0)return null;let o=r?()=>{}:console.log,s=w(n,i);_(s,{recursive:!0});let c=[],l={};for(let[e,t]of Object.entries(a)){let r=await Xr(e,t,n,s);c.push(r.entrySummary),Object.assign(l,r.manifestSlice),o(` ✓ ${e}: ${r.entrySummary.filesCopied} file(s) → ${r.entrySummary.dest}`)}let u={version:1,entries:l},d=S(s,`.kickjs-assets.json`);return ne(d,JSON.stringify(u,null,2)+`
3675
- `,`utf-8`),o(` ✓ wrote manifest → ${C(n,d)} (${Object.keys(l).length} entries)`),{manifestPath:d,entries:c,manifest:u}}async function Xr(e,t,n,r){let i=w(n,t.src),a=t.dest?w(n,t.dest):S(r,e);if(Qr(a,n))return console.warn(` ⚠ assetMap.${e}.dest ('${t.dest}') resolves outside the project root — skipping copy`),{entrySummary:{namespace:e,src:t.src,dest:C(n,a),filesCopied:0},manifestSlice:{}};if(!g(i)||!$r(i))return{entrySummary:{namespace:e,src:t.src,dest:C(n,a),filesCopied:0},manifestSlice:{}};let o=await ye(t.glob??`**/*`,{cwd:i,nodir:!0,dot:!1,posix:!0});_(a,{recursive:!0});let s={},{pairs:c,collisionGroupsResolved:l}=be(e,[...o].toSorted(),{strategy:t.keys??`auto`});for(let{rel:e,key:t}of c){let n=S(i,e),o=S(a,e);_(x(o),{recursive:!0}),h(n,o),s[t]=Zr(r,o)}return l>0&&console.log(` ℹ assetMap.${e}: auto-resolved ${l} basename collision(s) by keeping extensions (set 'keys: "strip"' to opt back into legacy last-write-wins behaviour, or 'keys: "with-extension"' to keep all keys verbose).`),{entrySummary:{namespace:e,src:t.src,dest:C(n,a),filesCopied:o.length},manifestSlice:s}}function Zr(e,t){return C(e,t).split(/[\\/]/).filter(Boolean).join(`/`)}function Qr(e,t){let n=C(t,e);return n===``?!1:n.startsWith(`..`)||ae(n)}function $r(e){try{return te(e).isDirectory()}catch{return!1}}function ei(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function ti(e,t,n={}){t&&(process.env.PORT=t);let i=ei(n.polling),a=process.cwd(),o=await r(a),s=o?.typegen?.schemaValidator??`zod`,c=o?.typegen?.envFile;try{await p({cwd:a,allowDuplicates:!0,schemaValidator:s,envFile:c,srcDir:o?.typegen?.srcDir,outDir:o?.typegen?.outDir,assetMap:o?.assetMap,runPlugins:!1})}catch(e){console.warn(` kick typegen: skipped (${e?.message??e})`)}await Jr({cwd:a,config:o});let{createRequire:l}=await import(`node:module`),{createServer:u}=await import(T(l(w(`package.json`)).resolve(`vite`)).href),d=await u({configFile:w(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...i?{watch:{usePolling:!0,interval:100}}:{}}}),f=o?.assetMap?Object.values(o.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>w(a,e)):[],m=e=>f.some(t=>e===t||e.startsWith(`${t}/`)),h=null,g=e=>{if(e.includes(`.kickjs`)||e.endsWith(`.d.ts`))return;let t=/\.(ts|tsx|mts|cts)$/.test(e),n=m(e);!t&&!n||(h&&clearTimeout(h),h=setTimeout(()=>{p({cwd:a,silent:!0,allowDuplicates:!0,schemaValidator:s,envFile:c,srcDir:o?.typegen?.srcDir,outDir:o?.typegen?.outDir,assetMap:o?.assetMap,runPlugins:!1}).catch(()=>{}),Jr({cwd:a,config:o,silent:!0}).catch(()=>{})},100))};d.watcher.on(`add`,g),d.watcher.on(`unlink`,g),d.watcher.on(`change`,g),f.length>0&&d.watcher.add(f),await d.listen(),d.printUrls(),console.log(`
3672
+ `),process.exit(1));let c=await r(process.cwd()),l=n(c),u=a.modulesDir??l.dir??`src/modules`,d=wr(i),f=t(c,process.cwd()),p=c?.pattern??`ddd`;p!==`ddd`&&(console.error(`\n Error: 'kick g scaffold' currently only supports the DDD pattern.\n Detected project pattern: '${p}'.\n Workarounds:\n - Run 'kick g module ${e}' for the ${p} layout (no fields), then add fields manually.\n - Override the pattern for this scaffold by setting kick.config.ts pattern: 'ddd'.\n`),process.exit(1));let m=await Tr({name:e,fields:d,modulesDir:w(u),noEntity:a.entity===!1,noTests:a.tests===!1,pluralize:a.pluralize===!1?!1:l.pluralize??!0,tokenScope:f,style:l.style});console.log(`\n Scaffolded ${e} with ${d.length} field(s):`);for(let e of d)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);J(m,s),await Br(s)}),i.command(`auth-scaffold`).description(`Generate a complete auth module (register, login, logout, password hashing)
3673
+ Includes controller, service, DTOs, and test stubs.`).option(`-s, --strategy <type>`,`Auth strategy: jwt | session`).option(`--role-guards`,`Generate role-based guards (default: true)`).option(`--no-role-guards`,`Skip role-based guard generation`).option(`-o, --out <dir>`,`Output directory`,`src/modules/auth`).action(async(e,t)=>{let n=q(t);j(n);let r=e.strategy;r||=await Ct({message:`Auth strategy`,options:[{value:`jwt`,label:`JWT`,hint:`stateless token-based auth`},{value:`session`,label:`Session`,hint:`server-side session with cookies`}]});let i=e.roleGuards;i===void 0&&(i=await F({message:`Generate role-based guards?`,initialValue:!0})),J(await _r({strategy:r,outDir:e.out,roleGuards:i}),n)}),i.command(`config`).description(`Generate a kick.config.ts at the project root`).option(`--modules-dir <dir>`,`Modules directory path`,`src/modules`).option(`--repo <type>`,`Default repository type: inmemory | drizzle | prisma`,`inmemory`).option(`-f, --force`,`Overwrite existing kick.config.ts without prompting`).action(async(e,t)=>{let n=q(t);j(n),J(await $n({outDir:w(`.`),modulesDir:e.modulesDir,defaultRepo:e.repo,force:e.force}),n)}),i.command(`agents`).alias(`agent-docs`).alias(`ai-docs`).description(`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md (sync after framework upgrades)`).option(`--only <which>`,`Limit scope: agents | claude | skills | both (agents+claude) | all (default: all)`,`all`).option(`--name <name>`,`Project name (defaults to package.json name)`).option(`--pm <pm>`,`Package manager (defaults to package.json packageManager)`).option(`--template <template>`,`Template: rest | ddd | cqrs | minimal`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t)=>{let n=q(t);j(n);let r=e.only??`all`;if(!zr.includes(r)){console.error(` Invalid --only value: ${r}. Expected: ${zr.join(` | `)}`),process.exitCode=1;return}J(await ir({outDir:w(`.`),only:r,name:e.name,pm:e.pm,template:e.template,force:e.force}),n)})}async function Gr(e){let t=b.resolve(e.cwd,`.kickjs/types`);await me(t,{recursive:!0});let n=new Map,r=e.scan??c,i={cwd:e.cwd,config:e.config,async importTs(e){return await import(T(e).href)},async writeFile(t,n){let r=b.resolve(e.cwd,t);await me(b.dirname(r),{recursive:!0}),await O(r,n,`utf8`)},getScanResult:e=>{let t=Kr(e),i=n.get(t);return i||(i=r(e),n.set(t,i)),i},log:console},a=[];for(let n of e.plugins){let r=await n.generate(i);if(r===null){a.push({id:n.id,status:`skipped`});continue}let o=n.outExtension??`.d.ts`,s=b.join(t,`${n.id.replace(/\//g,`__`)}${o}`),c=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: ${n.id} */\n\n`+r+`
3674
+ `,l=``;if(g(s)&&(l=await D(s,`utf8`)),l===c){a.push({id:n.id,status:`unchanged`,outFile:s});continue}if(e.check)throw Error(`kick typegen --check: drift detected for ${n.id} (${s})`);await O(s,c,`utf8`),a.push({id:n.id,status:`written`,outFile:s})}return a}function Kr(e){let t=(e.extensions??[]).slice().toSorted().join(`,`),n=(e.exclude??[]).slice().toSorted().join(`,`);return[`root=${e.root}`,`cwd=${e.cwd}`,`extensions=${t}`,`exclude=${n}`,`envFile=${e.envFile??``}`].join(`|`)}function qr(e,t){let n=new Set(t),r=[],i=[],a=new Set;for(let t of e)n.has(t.id)?(i.push(t),a.add(t.id)):r.push(t);return{enabled:r,skipped:i,unknown:[...n].filter(e=>!a.has(e))}}var Jr=e({applyDisableFilter:()=>qr,runAllPluginTypegens:()=>Yr});async function Yr(e){let{enabled:t,skipped:n,unknown:r}=qr(a([...Ma,...e.config?.plugins??[]],e.config?.commands??[]).typegens,e.config?.typegen?.disable??[]);if(!e.silent&&n.length>0)for(let e of n)console.log(` ${e.id}: disabled (typegen.disable)`);if(!e.silent&&r.length>0&&console.warn(` kick typegen: disable list references unknown id(s): ${r.map(e=>`'${e}'`).join(`, `)}. Run \`kick typegen --list\` to see registered ids.`),t.length===0)return[];try{let n=await Gr({cwd:e.cwd,config:e.config??{},plugins:t,check:e.check});if(!e.silent)for(let e of n)console.log(` ${e.id}: ${e.status}`);return n}catch(t){if(!e.silent){let e=t instanceof Error?t.message:String(t);console.warn(` kick typegen plugins: skipped (${e})`)}return[]}}async function Xr(e,t){let{cwd:n,silent:r=!1}=t,i=t.distDir??e?.build?.outDir??`dist`,a=e?.assetMap;if(!a||Object.keys(a).length===0)return null;let o=r?()=>{}:console.log,s=w(n,i);_(s,{recursive:!0});let c=[],l={};for(let[e,t]of Object.entries(a)){let r=await Zr(e,t,n,s);c.push(r.entrySummary),Object.assign(l,r.manifestSlice),o(` ✓ ${e}: ${r.entrySummary.filesCopied} file(s) → ${r.entrySummary.dest}`)}let u={version:1,entries:l},d=S(s,`.kickjs-assets.json`);return ne(d,JSON.stringify(u,null,2)+`
3675
+ `,`utf-8`),o(` ✓ wrote manifest → ${C(n,d)} (${Object.keys(l).length} entries)`),{manifestPath:d,entries:c,manifest:u}}async function Zr(e,t,n,r){let i=w(n,t.src),a=t.dest?w(n,t.dest):S(r,e);if($r(a,n))return console.warn(` ⚠ assetMap.${e}.dest ('${t.dest}') resolves outside the project root — skipping copy`),{entrySummary:{namespace:e,src:t.src,dest:C(n,a),filesCopied:0},manifestSlice:{}};if(!g(i)||!ei(i))return{entrySummary:{namespace:e,src:t.src,dest:C(n,a),filesCopied:0},manifestSlice:{}};let o=await ye(t.glob??`**/*`,{cwd:i,nodir:!0,dot:!1,posix:!0});_(a,{recursive:!0});let s={},{pairs:c,collisionGroupsResolved:l}=be(e,[...o].toSorted(),{strategy:t.keys??`auto`});for(let{rel:e,key:t}of c){let n=S(i,e),o=S(a,e);_(x(o),{recursive:!0}),h(n,o),s[t]=Qr(r,o)}return l>0&&console.log(` ℹ assetMap.${e}: auto-resolved ${l} basename collision(s) by keeping extensions (set 'keys: "strip"' to opt back into legacy last-write-wins behaviour, or 'keys: "with-extension"' to keep all keys verbose).`),{entrySummary:{namespace:e,src:t.src,dest:C(n,a),filesCopied:o.length},manifestSlice:s}}function Qr(e,t){return C(e,t).split(/[\\/]/).filter(Boolean).join(`/`)}function $r(e,t){let n=C(t,e);return n===``?!1:n.startsWith(`..`)||ae(n)}function ei(e){try{return te(e).isDirectory()}catch{return!1}}function ti(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function ni(e,t,n={}){t&&(process.env.PORT=t);let i=ti(n.polling),a=process.cwd(),o=await r(a),s=o?.typegen?.schemaValidator??`zod`,c=o?.typegen?.envFile;try{await p({cwd:a,allowDuplicates:!0,schemaValidator:s,envFile:c,srcDir:o?.typegen?.srcDir,outDir:o?.typegen?.outDir,assetMap:o?.assetMap,runPlugins:!1})}catch(e){console.warn(` kick typegen: skipped (${e?.message??e})`)}await Yr({cwd:a,config:o});let{createRequire:l}=await import(`node:module`),{createServer:u}=await import(T(l(w(`package.json`)).resolve(`vite`)).href),d=await u({configFile:w(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...i?{watch:{usePolling:!0,interval:100}}:{}}}),f=o?.assetMap?Object.values(o.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>w(a,e)):[],m=e=>f.some(t=>e===t||e.startsWith(`${t}/`)),h=null,g=e=>{if(e.includes(`.kickjs`)||e.endsWith(`.d.ts`))return;let t=/\.(ts|tsx|mts|cts)$/.test(e),n=m(e);!t&&!n||(h&&clearTimeout(h),h=setTimeout(()=>{p({cwd:a,silent:!0,allowDuplicates:!0,schemaValidator:s,envFile:c,srcDir:o?.typegen?.srcDir,outDir:o?.typegen?.outDir,assetMap:o?.assetMap,runPlugins:!1}).catch(()=>{}),Yr({cwd:a,config:o,silent:!0}).catch(()=>{})},100))};d.watcher.on(`add`,g),d.watcher.on(`unlink`,g),d.watcher.on(`change`,g),f.length>0&&d.watcher.add(f),await d.listen(),d.printUrls(),console.log(`
3676
3676
  KickJS dev server running (Vite + @forinda/kickjs-vite)
3677
- `);let _=async()=>{h&&clearTimeout(h),await d.close(),process.exit(0)};process.on(`SIGINT`,_),process.on(`SIGTERM`,_)}function ni(e){e.command(`dev`).description(`Start development server with Vite HMR (zero-downtime reload)`).option(`-e, --entry <file>`,`Entry file`,`src/index.ts`).option(`-p, --port <port>`,`Port number`).option(`--polling`,`Force chokidar to poll for file changes (Docker / WSL / NFS / older kernels)`).action(async e=>{try{await ti(e.entry,e.port,{polling:e.polling})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
3677
+ `);let _=async()=>{h&&clearTimeout(h),await d.close(),process.exit(0)};process.on(`SIGINT`,_),process.on(`SIGTERM`,_)}function ri(e){e.command(`dev`).description(`Start development server with Vite HMR (zero-downtime reload)`).option(`-e, --entry <file>`,`Entry file`,`src/index.ts`).option(`-p, --port <port>`,`Port number`).option(`--polling`,`Force chokidar to poll for file changes (Docker / WSL / NFS / older kernels)`).action(async e=>{try{await ni(e.entry,e.port,{polling:e.polling})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
3678
3678
  Error: vite is not installed.
3679
3679
  Run: pnpm add -D vite unplugin-swc
3680
3680
  `):console.error(`
@@ -3682,13 +3682,13 @@ describe('${o}', () => {
3682
3682
  Building for production...
3683
3683
  `);let{createRequire:e}=await import(`node:module`),{build:t}=await import(T(e(w(`package.json`)).resolve(`vite`)).href);await t({configFile:w(`vite.config.ts`)});let n=await r(process.cwd()),i=n?.copyDirs??[];if(i.length>0){console.log(`
3684
3684
  Copying directories to dist...`);for(let e of i){let t=typeof e==`string`?e:e.src,n=typeof e==`string`?S(`dist`,e):e.dest??S(`dist`,t),r=w(t),i=w(n);if(!g(r)){console.log(` ⚠ Skipped ${t} (not found)`);continue}_(i,{recursive:!0}),h(r,i,{recursive:!0}),console.log(` ✓ ${t} → ${n}`)}}if(n?.assetMap&&Object.keys(n.assetMap).length>0){console.log(`
3685
- Building asset map...`);try{await Yr(n,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
3685
+ Building asset map...`);try{await Xr(n,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
3686
3686
  Build complete.
3687
3687
  `)}),e.command(`build:assets`).description(`Rebuild the .kickjs-assets.json manifest under the configured outDir (no JS rebuild)`).action(async()=>{let e=await r(process.cwd());if(!e?.assetMap||Object.keys(e.assetMap).length===0){console.log(` No assetMap entries — nothing to build.`);return}console.log(`
3688
- Building asset map...`);try{await Yr(e,{cwd:process.cwd()}),console.log(`
3688
+ Building asset map...`);try{await Xr(e,{cwd:process.cwd()}),console.log(`
3689
3689
  Asset build complete.
3690
- `)}catch(e){console.error(` ✗ ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),e.command(`start`).description(`Start production server`).option(`-e, --entry <file>`,`Entry file`,`dist/index.js`).option(`-p, --port <port>`,`Port number`).action(e=>{let t={NODE_ENV:`production`};e.port&&(t.PORT=String(e.port)),Ne(e.entry,t)}),e.command(`dev:debug`).description(`Start dev server with Node.js inspector attached`).option(`-e, --entry <file>`,`Entry file`,`src/index.ts`).option(`-p, --port <port>`,`Port number`).option(`--inspect-port <port>`,`Inspector port`,`9229`).action(async e=>{let t=e.inspectPort??`9229`;process.env.NODE_OPTIONS=`--inspect=0.0.0.0:${t}`,console.log(` Debugger: ws://0.0.0.0:${t}`);try{await ti(e.entry,e.port)}catch(e){console.error(`
3691
- Dev server (debug) failed:`,e.message??e),process.exit(1)}})}function ri(e){e.command(`info`).description(`Print system and framework info`).action(()=>{console.log(`
3690
+ `)}catch(e){console.error(` ✗ ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),e.command(`start`).description(`Start production server`).option(`-e, --entry <file>`,`Entry file`,`dist/index.js`).option(`-p, --port <port>`,`Port number`).action(e=>{let t={NODE_ENV:`production`};e.port&&(t.PORT=String(e.port)),Pe(e.entry,t)}),e.command(`dev:debug`).description(`Start dev server with Node.js inspector attached`).option(`-e, --entry <file>`,`Entry file`,`src/index.ts`).option(`-p, --port <port>`,`Port number`).option(`--inspect-port <port>`,`Inspector port`,`9229`).action(async e=>{let t=e.inspectPort??`9229`;process.env.NODE_OPTIONS=`--inspect=0.0.0.0:${t}`,console.log(` Debugger: ws://0.0.0.0:${t}`);try{await ni(e.entry,e.port)}catch(e){console.error(`
3691
+ Dev server (debug) failed:`,e.message??e),process.exit(1)}})}function ii(e){e.command(`info`).description(`Print system and framework info`).action(()=>{console.log(`
3692
3692
  KickJS CLI
3693
3693
 
3694
3694
  System:
@@ -3699,7 +3699,7 @@ describe('${o}', () => {
3699
3699
  @forinda/kickjs workspace
3700
3700
  @forinda/kickjs-vite workspace
3701
3701
  @forinda/kickjs-cli workspace
3702
- `)})}const{bold:Y,dim:X,green:ii,red:ai,yellow:oi,blue:si}=A;function ci(e){let t=Math.floor(e/86400),n=Math.floor(e%86400/3600),r=Math.floor(e%3600/60),i=e%60,a=[];return t&&a.push(`${t}d`),n&&a.push(`${n}h`),r&&a.push(`${r}m`),a.push(`${i}s`),a.join(` `)}async function li(e){let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw Error(`${t.status} ${t.statusText}`);return t.json()}async function ui(e,t){try{return await li(`${e}${t}`)}catch{return null}}async function di(e){let[t,n,r,i,a]=await Promise.all([ui(e,`/health`),ui(e,`/metrics`),ui(e,`/routes`),ui(e,`/container`),ui(e,`/ws`)]);return{health:t,metrics:n,routes:r,container:i,ws:a}}function fi(e,t){let{health:n,metrics:r,routes:i,container:a,ws:o}=t,s=X(`─`.repeat(60));if(console.log(),console.log(Y(` KickJS Inspector`)+X(` → ${e}`)),console.log(s),n){let e=n.status===`healthy`?ii(`● healthy`):ai(`● `+n.status);console.log(` ${Y(`Health:`)} ${e}`)}else console.log(` ${Y(`Health:`)} ${ai(`● unreachable`)}`);if(r){let e=((r.errorRate??0)*100).toFixed(1),t=r.errorRate>.1?ai:r.errorRate>0?oi:ii;console.log(` ${Y(`Uptime:`)} ${ci(r.uptimeSeconds)}`),console.log(` ${Y(`Requests:`)} ${r.requests}`),console.log(` ${Y(`Errors:`)} ${r.serverErrors} server, ${r.clientErrors??0} client ${X(`(`)}${t(e+`%`)}${X(`)`)}`)}if(a&&console.log(` ${Y(`DI:`)} ${a.count} bindings`),o&&o.enabled&&console.log(` ${Y(`WS:`)} ${o.connections??0} connections, ${o.namespaces??0} namespaces`),i?.routes?.length){console.log(),console.log(Y(` Routes`)),console.log(s),console.log(` ${X(`METHOD`)} ${X(`PATH`.padEnd(36))} ${X(`CONTROLLER`)}`);for(let e of i.routes){let t=e.path.length>36?e.path.slice(0,33)+`...`:e.path.padEnd(36);console.log(` ${gt(e.method)} ${t} ${si(e.controller)}.${X(e.handler)}`)}}console.log(s),console.log()}function pi(e){e.command(`inspect [url]`).description(`Connect to a running KickJS app and display debug info`).option(`-p, --port <port>`,`Override port`).option(`-w, --watch`,`Poll every 5 seconds`).option(`-j, --json`,`Output raw JSON`).action(async(e,t)=>{let n=e??`http://localhost:3000`;if(t.port)try{let e=new URL(n);e.port=t.port,n=e.origin}catch{n=`http://localhost:${t.port}`}let r=`${n.replace(/\/$/,``)}/_debug`,i=async()=>{try{let e=await di(r);t.json?console.log(JSON.stringify(e,null,2)):fi(n,e)}catch(e){t.json?console.log(JSON.stringify({error:String(e)})):(console.error(ai(` ✖ Could not connect to ${n}`)),console.error(X(` ${e instanceof Error?e.message:String(e)}`))),t.watch||(process.exitCode=1)}};if(t.watch){let e=async()=>{process.stdout.write(`\x1B[2J\x1B[H`),await i()};await e(),setInterval(e,5e3)}else await i()})}function mi(e,t){let n=e.toLowerCase();return t.every(e=>n.includes(e.toLowerCase()))}function Z(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}const hi=[{match(e,t){let n=mi(e,[`config`,`get`])&&Z(e,[`undefined`,`null`]),r=e.includes(`@Value`)&&Z(e,[`undefined`,`is not defined`]);return!n&&!r?null:{confidence:n&&r?90:75,diagnosis:{id:`env-schema-not-registered`,title:`ConfigService.get() returns undefined for user-defined keys`,explanation:`Your src/index.ts is missing \`import "./config"\`. That side-effect import
3702
+ `)})}const{bold:Y,dim:X,green:ai,red:oi,yellow:si,blue:ci}=A;function li(e){let t=Math.floor(e/86400),n=Math.floor(e%86400/3600),r=Math.floor(e%3600/60),i=e%60,a=[];return t&&a.push(`${t}d`),n&&a.push(`${n}h`),r&&a.push(`${r}m`),a.push(`${i}s`),a.join(` `)}async function ui(e){let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw Error(`${t.status} ${t.statusText}`);return t.json()}async function di(e,t){try{return await ui(`${e}${t}`)}catch{return null}}async function fi(e){let[t,n,r,i,a]=await Promise.all([di(e,`/health`),di(e,`/metrics`),di(e,`/routes`),di(e,`/container`),di(e,`/ws`)]);return{health:t,metrics:n,routes:r,container:i,ws:a}}function pi(e,t){let{health:n,metrics:r,routes:i,container:a,ws:o}=t,s=X(`─`.repeat(60));if(console.log(),console.log(Y(` KickJS Inspector`)+X(` → ${e}`)),console.log(s),n){let e=n.status===`healthy`?ai(`● healthy`):oi(`● `+n.status);console.log(` ${Y(`Health:`)} ${e}`)}else console.log(` ${Y(`Health:`)} ${oi(`● unreachable`)}`);if(r){let e=((r.errorRate??0)*100).toFixed(1),t=r.errorRate>.1?oi:r.errorRate>0?si:ai;console.log(` ${Y(`Uptime:`)} ${li(r.uptimeSeconds)}`),console.log(` ${Y(`Requests:`)} ${r.requests}`),console.log(` ${Y(`Errors:`)} ${r.serverErrors} server, ${r.clientErrors??0} client ${X(`(`)}${t(e+`%`)}${X(`)`)}`)}if(a&&console.log(` ${Y(`DI:`)} ${a.count} bindings`),o&&o.enabled&&console.log(` ${Y(`WS:`)} ${o.connections??0} connections, ${o.namespaces??0} namespaces`),i?.routes?.length){console.log(),console.log(Y(` Routes`)),console.log(s),console.log(` ${X(`METHOD`)} ${X(`PATH`.padEnd(36))} ${X(`CONTROLLER`)}`);for(let e of i.routes){let t=e.path.length>36?e.path.slice(0,33)+`...`:e.path.padEnd(36);console.log(` ${_t(e.method)} ${t} ${ci(e.controller)}.${X(e.handler)}`)}}console.log(s),console.log()}function mi(e){e.command(`inspect [url]`).description(`Connect to a running KickJS app and display debug info`).option(`-p, --port <port>`,`Override port`).option(`-w, --watch`,`Poll every 5 seconds`).option(`-j, --json`,`Output raw JSON`).action(async(e,t)=>{let n=e??`http://localhost:3000`;if(t.port)try{let e=new URL(n);e.port=t.port,n=e.origin}catch{n=`http://localhost:${t.port}`}let r=`${n.replace(/\/$/,``)}/_debug`,i=async()=>{try{let e=await fi(r);t.json?console.log(JSON.stringify(e,null,2)):pi(n,e)}catch(e){t.json?console.log(JSON.stringify({error:String(e)})):(console.error(oi(` ✖ Could not connect to ${n}`)),console.error(X(` ${e instanceof Error?e.message:String(e)}`))),t.watch||(process.exitCode=1)}};if(t.watch){let e=async()=>{process.stdout.write(`\x1B[2J\x1B[H`),await i()};await e(),setInterval(e,5e3)}else await i()})}function hi(e,t){let n=e.toLowerCase();return t.every(e=>n.includes(e.toLowerCase()))}function Z(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}const gi=[{match(e,t){let n=hi(e,[`config`,`get`])&&Z(e,[`undefined`,`null`]),r=e.includes(`@Value`)&&Z(e,[`undefined`,`is not defined`]);return!n&&!r?null:{confidence:n&&r?90:75,diagnosis:{id:`env-schema-not-registered`,title:`ConfigService.get() returns undefined for user-defined keys`,explanation:`Your src/index.ts is missing \`import "./config"\`. That side-effect import
3703
3703
  registers the env schema with kickjs at module-load time. Without it,
3704
3704
  ConfigService falls back to the base schema (PORT/NODE_ENV/LOG_LEVEL only)
3705
3705
  and every user-defined key reads as undefined. @Value() may *appear* to
@@ -3721,7 +3721,7 @@ describe('UserController', () => {
3721
3721
  beforeEach(() => Container.reset())
3722
3722
 
3723
3723
  it('does the thing', async () => { /* ... */ })
3724
- })`,docs:`https://forinda.github.io/kick-js/guide/testing.html`}}:null}},{match(e,t){return e.includes(`@Module`)||mi(e,[`Module`,`is not a function`])||mi(e,[`Module`,`no exported member`])?{confidence:80,diagnosis:{id:`module-decorator-not-found`,title:`KickJS does not have a @Module decorator (different pattern from NestJS)`,explanation:`NestJS uses @Module({ controllers, providers }). KickJS uses an interface
3724
+ })`,docs:`https://forinda.github.io/kick-js/guide/testing.html`}}:null}},{match(e,t){return e.includes(`@Module`)||hi(e,[`Module`,`is not a function`])||hi(e,[`Module`,`no exported member`])?{confidence:80,diagnosis:{id:`module-decorator-not-found`,title:`KickJS does not have a @Module decorator (different pattern from NestJS)`,explanation:`NestJS uses @Module({ controllers, providers }). KickJS uses an interface
3725
3725
  pattern instead: a class implements AppModule and exposes routes() that
3726
3726
  returns the controller wiring. This was a deliberate choice — modules
3727
3727
  become explicit values rather than metadata, which makes them easier to
@@ -3773,24 +3773,24 @@ drop the entry.`,fix:`Open src/modules/index.ts and verify the module is in the
3773
3773
  import { UserModule } from './users/user.module'
3774
3774
  import { TaskModule } from './tasks/task.module' // ← was this missing?
3775
3775
 
3776
- export const modules: AppModuleEntry[] = [UserModule(), TaskModule()]`,docs:`https://forinda.github.io/kick-js/guide/project-structure.html`}}:null}}];function gi(e,t){let n=null;for(let r of hi){let i=null;try{i=r.match(e,t)}catch{continue}!i||i.confidence<40||(!n||i.confidence>n.confidence)&&(n=i)}return n}async function _i(e){let t=e.provider??`openai`,n=process.env.OPENAI_API_KEY;if(t===`openai`&&!n)return{kind:`unavailable`,reason:`OPENAI_API_KEY environment variable is not set`,suggestion:`Set OPENAI_API_KEY in your shell, e.g.
3776
+ export const modules: AppModuleEntry[] = [UserModule(), TaskModule()]`,docs:`https://forinda.github.io/kick-js/guide/project-structure.html`}}:null}}];function _i(e,t){let n=null;for(let r of gi){let i=null;try{i=r.match(e,t)}catch{continue}!i||i.confidence<40||(!n||i.confidence>n.confidence)&&(n=i)}return n}async function vi(e){let t=e.provider??`openai`,n=process.env.OPENAI_API_KEY;if(t===`openai`&&!n)return{kind:`unavailable`,reason:`OPENAI_API_KEY environment variable is not set`,suggestion:`Set OPENAI_API_KEY in your shell, e.g.
3777
3777
  export OPENAI_API_KEY="sk-..."
3778
3778
 
3779
3779
  Then re-run \`kick explain --ai "<your error>"\`.`};let r;try{r=await import(`@forinda/kickjs-ai`)}catch{return{kind:`unavailable`,reason:`@forinda/kickjs-ai is not installed`,suggestion:`Install the AI package to enable the LLM fallback:
3780
3780
  kick add ai
3781
3781
 
3782
3782
  Or manually:
3783
- pnpm add @forinda/kickjs-ai`}}let{OpenAIProvider:i}=r,a=new i({apiKey:n,defaultChatModel:e.model??`gpt-4o-mini`}),o=vi(e.cwd),s=`Error or stack trace:\n\n${e.input.trim()}`;try{let e=yi((await a.chat({messages:[{role:`system`,content:o},{role:`user`,content:s}]})).content);return e?{kind:`ok`,diagnosis:e}:{kind:`error`,message:`The LLM responded but the payload was not valid JSON in the expected shape. Try again, or file an issue with the error text.`}}catch(e){return{kind:`error`,message:`LLM request failed: ${e instanceof Error?e.message:String(e)}`}}}function vi(e){return[`You are a diagnostic assistant for KickJS, a decorator-driven Node.js`,`framework built on Express 5 and TypeScript. KickJS projects use:`,` - @Controller, @Get, @Post, @Autowired, @Service, @Value decorators`,` - An AppModule interface with a routes() method (NOT a @Module decorator)`,` - Zod schemas as both runtime validators and OpenAPI sources`,` - Ctx<KickRoutes.ControllerName['method']> for typed request context`,` - src/config/index.ts with defineEnv/loadEnv for env schema`,' - A side-effect `import "./config"` in src/index.ts to register the schema',` - Container.reset() in beforeEach for DI test isolation`,``,`When the user gives you an error message or stack trace, produce a`,`structured diagnosis that helps them fix the bug. You MUST respond`,`with a single JSON object (no surrounding prose, no markdown fences)`,`matching this shape:`,``,`{`,` "id": "<kebab-case-identifier>",`,` "title": "<one-line problem summary>",`,` "explanation": "<multi-line explanation of what is wrong>",`,` "fix": "<multi-line instructions for fixing the problem>",`,` "codeBefore": "<optional: broken code snippet>",`,` "codeAfter": "<optional: corrected code snippet>",`,` "docs": "<optional: KickJS doc URL that discusses this topic>"`,`}`,``,`The KickJS docs live at https://forinda.github.io/kick-js/ — prefer`,`that domain for any doc links you suggest.`,e?`The project is located at ${e}.`:``].filter(e=>e.length>0).join(`
3784
- `)}function yi(e){let t=[e,bi(e),xi(e)].filter(e=>e!==null);for(let e of t)try{let t=JSON.parse(e);if(Si(t))return t}catch{continue}return null}function bi(e){let t=e.match(/```(?:json)?\s*\n([\s\S]*?)```/);return t?t[1]?.trim()??null:null}function xi(e){let t=e.indexOf(`{`);if(t===-1)return null;let n=0,r=!1,i=!1;for(let a=t;a<e.length;a++){let o=e[a];if(i){i=!1;continue}if(o===`\\`&&r){i=!0;continue}if(o===`"`){r=!r;continue}if(!r&&(o===`{`&&n++,o===`}`&&(n--,n===0)))return e.slice(t,a+1)}return null}function Si(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&typeof t.title==`string`&&typeof t.explanation==`string`&&typeof t.fix==`string`}function Ci(e){e.command(`explain [message]`).description(`Explain a KickJS error and suggest a fix`).option(`-m, --message <text>`,`Error message to explain (alternative to positional arg)`).option(`--ai`,`Fall back to LLM if no known-issue matches (requires @forinda/kickjs-ai)`).option(`--model <name>`,`Model name for the --ai fallback`,`gpt-4o-mini`).option(`--json`,`Output the diagnosis as JSON for tooling integration`).action(async(e,t)=>{let n=await Ei(e,t.message);(!n||n.trim().length===0)&&(process.stderr.write(`Error: no input provided.
3783
+ pnpm add @forinda/kickjs-ai`}}let{OpenAIProvider:i}=r,a=new i({apiKey:n,defaultChatModel:e.model??`gpt-4o-mini`}),o=yi(e.cwd),s=`Error or stack trace:\n\n${e.input.trim()}`;try{let e=bi((await a.chat({messages:[{role:`system`,content:o},{role:`user`,content:s}]})).content);return e?{kind:`ok`,diagnosis:e}:{kind:`error`,message:`The LLM responded but the payload was not valid JSON in the expected shape. Try again, or file an issue with the error text.`}}catch(e){return{kind:`error`,message:`LLM request failed: ${e instanceof Error?e.message:String(e)}`}}}function yi(e){return[`You are a diagnostic assistant for KickJS, a decorator-driven Node.js`,`framework built on Express 5 and TypeScript. KickJS projects use:`,` - @Controller, @Get, @Post, @Autowired, @Service, @Value decorators`,` - An AppModule interface with a routes() method (NOT a @Module decorator)`,` - Zod schemas as both runtime validators and OpenAPI sources`,` - Ctx<KickRoutes.ControllerName['method']> for typed request context`,` - src/config/index.ts with defineEnv/loadEnv for env schema`,' - A side-effect `import "./config"` in src/index.ts to register the schema',` - Container.reset() in beforeEach for DI test isolation`,``,`When the user gives you an error message or stack trace, produce a`,`structured diagnosis that helps them fix the bug. You MUST respond`,`with a single JSON object (no surrounding prose, no markdown fences)`,`matching this shape:`,``,`{`,` "id": "<kebab-case-identifier>",`,` "title": "<one-line problem summary>",`,` "explanation": "<multi-line explanation of what is wrong>",`,` "fix": "<multi-line instructions for fixing the problem>",`,` "codeBefore": "<optional: broken code snippet>",`,` "codeAfter": "<optional: corrected code snippet>",`,` "docs": "<optional: KickJS doc URL that discusses this topic>"`,`}`,``,`The KickJS docs live at https://forinda.github.io/kick-js/ — prefer`,`that domain for any doc links you suggest.`,e?`The project is located at ${e}.`:``].filter(e=>e.length>0).join(`
3784
+ `)}function bi(e){let t=[e,xi(e),Si(e)].filter(e=>e!==null);for(let e of t)try{let t=JSON.parse(e);if(Ci(t))return t}catch{continue}return null}function xi(e){let t=e.match(/```(?:json)?\s*\n([\s\S]*?)```/);return t?t[1]?.trim()??null:null}function Si(e){let t=e.indexOf(`{`);if(t===-1)return null;let n=0,r=!1,i=!1;for(let a=t;a<e.length;a++){let o=e[a];if(i){i=!1;continue}if(o===`\\`&&r){i=!0;continue}if(o===`"`){r=!r;continue}if(!r&&(o===`{`&&n++,o===`}`&&(n--,n===0)))return e.slice(t,a+1)}return null}function Ci(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&typeof t.title==`string`&&typeof t.explanation==`string`&&typeof t.fix==`string`}function wi(e){e.command(`explain [message]`).description(`Explain a KickJS error and suggest a fix`).option(`-m, --message <text>`,`Error message to explain (alternative to positional arg)`).option(`--ai`,`Fall back to LLM if no known-issue matches (requires @forinda/kickjs-ai)`).option(`--model <name>`,`Model name for the --ai fallback`,`gpt-4o-mini`).option(`--json`,`Output the diagnosis as JSON for tooling integration`).action(async(e,t)=>{let n=await Di(e,t.message);(!n||n.trim().length===0)&&(process.stderr.write(`Error: no input provided.
3785
3785
 
3786
3786
  Pass a message as a positional arg, --message flag, or pipe via stdin:
3787
3787
  kick explain "config.get returned undefined"
3788
3788
  pnpm test 2>&1 | kick explain
3789
- `),process.exit(1));let r=Oi(),i=gi(n,r);if(t.json&&i){process.stdout.write(JSON.stringify({matched:!0,...i},null,2)+`
3790
- `);return}if(i){ki(n,i.diagnosis,i.confidence);return}t.ai||(t.json&&(process.stdout.write(JSON.stringify({matched:!1},null,2)+`
3791
- `),process.exit(2)),Ai(n,!1),process.exit(2));let a=await _i({input:n,model:t.model,cwd:r.cwd});t.json&&(process.stdout.write(JSON.stringify(wi(a),null,2)+`
3792
- `),process.exit(a.kind===`ok`?0:2)),Ti(n,a),process.exit(a.kind===`ok`?0:2)})}function wi(e){return e.kind===`ok`?{matched:!0,source:`ai`,diagnosis:e.diagnosis}:e.kind===`unavailable`?{matched:!1,aiUnavailable:!0,reason:e.reason}:{matched:!1,aiError:!0,error:e.message}}function Ti(e,t){if(t.kind===`ok`){ki(e,t.diagnosis,-1,!0);return}if(t.kind===`unavailable`){process.stdout.write(`\n Explaining: ${Mi(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback unavailable: ${t.reason}\n\n`),process.stdout.write(`${ji(t.suggestion,` `)}\n\n`);return}process.stdout.write(`\n Explaining: ${Mi(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback error: ${t.message}\n\n`)}async function Ei(e,t){return e&&e.trim().length>0?e:t&&t.trim().length>0?t:process.stdin.isTTY?``:Di()}function Di(){return new Promise((e,t)=>{let n=``;process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{n+=e}),process.stdin.on(`end`,()=>e(n)),process.stdin.on(`error`,t)})}function Oi(){let e=process.cwd();return{cwd:e,hasFile:t=>g(w(e,t))}}function ki(e,t,n,r=!1){let i=Mi(e.trim(),200),a=r?`AI-generated — verify before applying`:Ni(n);process.stdout.write(`\n Explaining: ${i}\n`),process.stdout.write(`\n Match: ${t.id} (${a})\n`),process.stdout.write(` Title: ${t.title}\n`),process.stdout.write(`\n Diagnosis:\n${ji(t.explanation,` `)}\n`),process.stdout.write(`\n Fix:\n${ji(t.fix,` `)}\n`),t.codeBefore&&process.stdout.write(`\n Before:\n${ji(t.codeBefore,` `)}\n`),t.codeAfter&&process.stdout.write(`\n After:\n${ji(t.codeAfter,` `)}\n`),t.docs&&process.stdout.write(`\n Docs: ${t.docs}\n`),process.stdout.write(`
3793
- `)}function Ai(e,t){let n=Mi(e.trim(),200);process.stdout.write(`\n Explaining: ${n}\n\n`),t?process.stdout.write(` No known-issue matched, and --ai fallback is not yet wired.
3789
+ `),process.exit(1));let r=ki(),i=_i(n,r);if(t.json&&i){process.stdout.write(JSON.stringify({matched:!0,...i},null,2)+`
3790
+ `);return}if(i){Ai(n,i.diagnosis,i.confidence);return}t.ai||(t.json&&(process.stdout.write(JSON.stringify({matched:!1},null,2)+`
3791
+ `),process.exit(2)),ji(n,!1),process.exit(2));let a=await vi({input:n,model:t.model,cwd:r.cwd});t.json&&(process.stdout.write(JSON.stringify(Ti(a),null,2)+`
3792
+ `),process.exit(a.kind===`ok`?0:2)),Ei(n,a),process.exit(a.kind===`ok`?0:2)})}function Ti(e){return e.kind===`ok`?{matched:!0,source:`ai`,diagnosis:e.diagnosis}:e.kind===`unavailable`?{matched:!1,aiUnavailable:!0,reason:e.reason}:{matched:!1,aiError:!0,error:e.message}}function Ei(e,t){if(t.kind===`ok`){Ai(e,t.diagnosis,-1,!0);return}if(t.kind===`unavailable`){process.stdout.write(`\n Explaining: ${Ni(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback unavailable: ${t.reason}\n\n`),process.stdout.write(`${Mi(t.suggestion,` `)}\n\n`);return}process.stdout.write(`\n Explaining: ${Ni(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback error: ${t.message}\n\n`)}async function Di(e,t){return e&&e.trim().length>0?e:t&&t.trim().length>0?t:process.stdin.isTTY?``:Oi()}function Oi(){return new Promise((e,t)=>{let n=``;process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{n+=e}),process.stdin.on(`end`,()=>e(n)),process.stdin.on(`error`,t)})}function ki(){let e=process.cwd();return{cwd:e,hasFile:t=>g(w(e,t))}}function Ai(e,t,n,r=!1){let i=Ni(e.trim(),200),a=r?`AI-generated — verify before applying`:Pi(n);process.stdout.write(`\n Explaining: ${i}\n`),process.stdout.write(`\n Match: ${t.id} (${a})\n`),process.stdout.write(` Title: ${t.title}\n`),process.stdout.write(`\n Diagnosis:\n${Mi(t.explanation,` `)}\n`),process.stdout.write(`\n Fix:\n${Mi(t.fix,` `)}\n`),t.codeBefore&&process.stdout.write(`\n Before:\n${Mi(t.codeBefore,` `)}\n`),t.codeAfter&&process.stdout.write(`\n After:\n${Mi(t.codeAfter,` `)}\n`),t.docs&&process.stdout.write(`\n Docs: ${t.docs}\n`),process.stdout.write(`
3793
+ `)}function ji(e,t){let n=Ni(e.trim(),200);process.stdout.write(`\n Explaining: ${n}\n\n`),t?process.stdout.write(` No known-issue matched, and --ai fallback is not yet wired.
3794
3794
  When @forinda/kickjs-ai ships its provider implementations,
3795
3795
  this command will call the configured LLM with the error +
3796
3796
  project context and return a structured fix.
@@ -3807,12 +3807,12 @@ Pass a message as a positional arg, --message flag, or pipe via stdin:
3807
3807
  3. File an issue with the error text:
3808
3808
  https://github.com/forinda/kick-js/issues/new
3809
3809
 
3810
- `)}function ji(e,t){return e.split(`
3810
+ `)}function Mi(e,t){return e.split(`
3811
3811
  `).map(e=>`${t}${e}`).join(`
3812
- `)}function Mi(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function Ni(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function Pi(e){let t=e.command(`mcp`).description(`Model Context Protocol commands (start | init)`);t.command(`start`,{isDefault:!0}).description(`Run the built application as an MCP server over stdio`).option(`-e, --entry <file>`,`Entry file`,`dist/index.js`).option(`--node-arg <arg...>`,`Extra arguments to pass to node`).action(Fi),t.command(`init`).description(`Generate .mcp.json for Claude Code / Cursor / Zed`).option(`-n, --name <name>`,`Server name (defaults to package.json name)`).option(`-o, --out <file>`,`Output file`,`.mcp.json`).option(`-f, --force`,`Overwrite an existing entry without prompting`).option(`--global`,`Write to ~/.mcp.json instead of the project root`).action(Ii)}function Fi(e){let t=w(e.entry);g(t)||(process.stderr.write(`Error: entry file not found: ${t}\n\nBuild the app first with \`kick build\`, or pass a custom entry:\n kick mcp -e dist/server.js\n`),process.exit(1));let n=[...e.nodeArg??[],t],r=ue(process.execPath,n,{stdio:`inherit`,env:{...process.env,KICK_MCP_STDIO:`1`,NODE_ENV:process.env.NODE_ENV??`production`}});r.on(`error`,e=>{process.stderr.write(`Failed to start MCP server: ${e.message}\n`),process.exit(1)}),r.on(`exit`,(e,t)=>{if(t){process.kill(process.pid,t);return}process.exit(e??0)});let i=e=>{r.killed||r.kill(e)};process.on(`SIGINT`,()=>i(`SIGINT`)),process.on(`SIGTERM`,()=>i(`SIGTERM`))}function Ii(e){let t=process.cwd(),n=Li(t)??re(t),r=e.name??n,i=e.global?w(process.env.HOME??`.`,`.mcp.json`):w(t,e.out),a={command:`kick`,args:[`mcp`],cwd:t},o={mcpServers:{}};if(g(i))try{let e=v(i,`utf8`),t=JSON.parse(e);t&&typeof t==`object`&&t.mcpServers&&(o={mcpServers:{...t.mcpServers}})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: existing ${i} is not valid JSON (${t}).\nFix the file or pass --force to overwrite the entry.\n`),process.exit(1)}o.mcpServers[r]&&!e.force&&(process.stderr.write(`Error: an entry for "${r}" already exists in ${i}.\nPass --force to overwrite it, or use --name to pick a different key.\n`),process.exit(1)),o.mcpServers[r]=a,ne(i,JSON.stringify(o,null,2)+`
3813
- `,`utf8`),process.stdout.write(`\n ✓ Wrote MCP server entry "${r}" to ${i}\n\n To activate it:\n 1. Build your app: kick build\n 2. Restart your MCP client (Claude Code, Cursor, Zed)\n 3. The server should appear in the client's tool picker\n\n`)}function Li(e){let t=w(e,`package.json`);if(!g(t))return null;try{let e=v(t,`utf8`),n=JSON.parse(e);return typeof n.name==`string`?n.name:null}catch{return null}}function Ri(e){e.command(`tinker`).description(`Interactive REPL with DI container and services loaded`).option(`-e, --entry <file>`,`Entry file to load`,`src/index.ts`).action(async e=>{let t=process.cwd(),n=w(t,e.entry);g(n)||(console.error(`\n Error: ${e.entry} not found.\n`),process.exit(1));let r=Bi(t,`tsx`);r||(console.error(`
3812
+ `)}function Ni(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function Pi(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function Fi(e){let t=e.command(`mcp`).description(`Model Context Protocol commands (start | init)`);t.command(`start`,{isDefault:!0}).description(`Run the built application as an MCP server over stdio`).option(`-e, --entry <file>`,`Entry file`,`dist/index.js`).option(`--node-arg <arg...>`,`Extra arguments to pass to node`).action(Ii),t.command(`init`).description(`Generate .mcp.json for Claude Code / Cursor / Zed`).option(`-n, --name <name>`,`Server name (defaults to package.json name)`).option(`-o, --out <file>`,`Output file`,`.mcp.json`).option(`-f, --force`,`Overwrite an existing entry without prompting`).option(`--global`,`Write to ~/.mcp.json instead of the project root`).action(Li)}function Ii(e){let t=w(e.entry);g(t)||(process.stderr.write(`Error: entry file not found: ${t}\n\nBuild the app first with \`kick build\`, or pass a custom entry:\n kick mcp -e dist/server.js\n`),process.exit(1));let n=[...e.nodeArg??[],t],r=ue(process.execPath,n,{stdio:`inherit`,env:{...process.env,KICK_MCP_STDIO:`1`,NODE_ENV:process.env.NODE_ENV??`production`}});r.on(`error`,e=>{process.stderr.write(`Failed to start MCP server: ${e.message}\n`),process.exit(1)}),r.on(`exit`,(e,t)=>{if(t){process.kill(process.pid,t);return}process.exit(e??0)});let i=e=>{r.killed||r.kill(e)};process.on(`SIGINT`,()=>i(`SIGINT`)),process.on(`SIGTERM`,()=>i(`SIGTERM`))}function Li(e){let t=process.cwd(),n=Ri(t)??re(t),r=e.name??n,i=e.global?w(process.env.HOME??`.`,`.mcp.json`):w(t,e.out),a={command:`kick`,args:[`mcp`],cwd:t},o={mcpServers:{}};if(g(i))try{let e=v(i,`utf8`),t=JSON.parse(e);t&&typeof t==`object`&&t.mcpServers&&(o={mcpServers:{...t.mcpServers}})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: existing ${i} is not valid JSON (${t}).\nFix the file or pass --force to overwrite the entry.\n`),process.exit(1)}o.mcpServers[r]&&!e.force&&(process.stderr.write(`Error: an entry for "${r}" already exists in ${i}.\nPass --force to overwrite it, or use --name to pick a different key.\n`),process.exit(1)),o.mcpServers[r]=a,ne(i,JSON.stringify(o,null,2)+`
3813
+ `,`utf8`),process.stdout.write(`\n ✓ Wrote MCP server entry "${r}" to ${i}\n\n To activate it:\n 1. Build your app: kick build\n 2. Restart your MCP client (Claude Code, Cursor, Zed)\n 3. The server should appear in the client's tool picker\n\n`)}function Ri(e){let t=w(e,`package.json`);if(!g(t))return null;try{let e=v(t,`utf8`),n=JSON.parse(e);return typeof n.name==`string`?n.name:null}catch{return null}}function zi(e){e.command(`tinker`).description(`Interactive REPL with DI container and services loaded`).option(`-e, --entry <file>`,`Entry file to load`,`src/index.ts`).action(async e=>{let t=process.cwd(),n=w(t,e.entry);g(n)||(console.error(`\n Error: ${e.entry} not found.\n`),process.exit(1));let r=Vi(t,`tsx`);r||(console.error(`
3814
3814
  Error: tsx not found. Install it: pnpm add -D tsx
3815
- `),process.exit(1));let i=zi(n,e.entry),a=S(t,`.kick-tinker.mjs`),{writeFileSync:o,unlinkSync:s}=await import(`node:fs`);o(a,i,`utf-8`);try{let e=le(a,[],{cwd:t,execPath:r,stdio:`inherit`});await new Promise(t=>{e.on(`exit`,()=>t())})}finally{try{s(a)}catch{}}})}function zi(e,t){return`
3815
+ `),process.exit(1));let i=Bi(n,e.entry),a=S(t,`.kick-tinker.mjs`),{writeFileSync:o,unlinkSync:s}=await import(`node:fs`);o(a,i,`utf-8`);try{let e=le(a,[],{cwd:t,execPath:r,stdio:`inherit`});await new Promise(t=>{e.on(`exit`,()=>t())})}finally{try{s(a)}catch{}}})}function Bi(e,t){return`
3816
3816
  import 'reflect-metadata'
3817
3817
 
3818
3818
  // Prevent bootstrap() from starting the HTTP server
@@ -3866,32 +3866,32 @@ server.on('exit', () => {
3866
3866
  console.log('\\n Goodbye!\\n')
3867
3867
  process.exit(0)
3868
3868
  })
3869
- `}function Bi(e,t){let n=e;for(;;){let e=S(n,`node_modules`,`.bin`,t);if(g(e))return e;let r=w(n,`..`);if(r===n)break;n=r}return null}function Vi(e,t){let n=RegExp(`^\\s*${H(t)}Module\\b`),r=!1,i=0,a=e;for(;;){let e=a.indexOf(`.mount(`,i);if(e===-1)break;let t=e+7,o=1,s=t;for(;s<a.length&&o>0;){let e=a.slice(s,s+2);if(e===`//`||e===`/*`){if(e===`//`)for(s+=2;s<a.length&&a[s]!==`
3869
+ `}function Vi(e,t){let n=e;for(;;){let e=S(n,`node_modules`,`.bin`,t);if(g(e))return e;let r=w(n,`..`);if(r===n)break;n=r}return null}function Hi(e,t){let n=RegExp(`^\\s*${H(t)}Module\\b`),r=!1,i=0,a=e;for(;;){let e=a.indexOf(`.mount(`,i);if(e===-1)break;let t=e+7,o=1,s=t;for(;s<a.length&&o>0;){let e=a.slice(s,s+2);if(e===`//`||e===`/*`){if(e===`//`)for(s+=2;s<a.length&&a[s]!==`
3870
3870
  `;)s++;else{for(s+=2;s+1<a.length&&!(a[s]===`*`&&a[s+1]===`/`);)s++;s+=2}continue}let t=a[s]??``;if(t===`'`||t===`"`||t==="`"){let e=t;for(s++;s<a.length&&a[s]!==e;)a[s]===`\\`&&s++,s++}else if(t===`(`)o++;else if(t===`)`&&(o--,o===0))break;s++}if(o!==0)break;let c=a.slice(t,s);if(n.test(c)){let t=e;for(;t>0&&(a[t-1]===` `||a[t-1]===` `||a[t-1]===`
3871
- `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function Hi(e,t){let n=Ln(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=Vi(a,t).content,a=a.replace(RegExp(`\\s*,?\\s*${H(t)}Module\\b(?:\\s*\\(\\s*\\))?\\s*,?`,`g`),e=>{let t=e.trimStart().startsWith(`,`),n=e.trimEnd().endsWith(`,`);return t&&n?`,`:``}),a=a.replace(/,(\s*])/,`$1`),e.slice(0,r)+a+e.slice(i)}async function Ui(e){let{name:t,modulesDir:n,force:r}=e,i=e.pluralize!==!1,a=B(t),o=R(t),s=i?V(a):a,c=S(n,s);if(!await ze(c)){console.log(`\n Module not found: ${c}\n`);return}if(!r&&!await F({message:A.red(`Delete module '${s}' at ${c}? This cannot be undone.`),initialValue:!1})){console.log(`
3871
+ `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function Ui(e,t){let n=Rn(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=Hi(a,t).content,a=a.replace(RegExp(`\\s*,?\\s*${H(t)}Module\\b(?:\\s*\\(\\s*\\))?\\s*,?`,`g`),e=>{let t=e.trimStart().startsWith(`,`),n=e.trimEnd().endsWith(`,`);return t&&n?`,`:``}),a=a.replace(/,(\s*])/,`$1`),e.slice(0,r)+a+e.slice(i)}async function Wi(e){let{name:t,modulesDir:n,force:r}=e,i=e.pluralize!==!1,a=B(t),o=R(t),s=i?V(a):a,c=S(n,s);if(!await Be(c)){console.log(`\n Module not found: ${c}\n`);return}if(!r&&!await F({message:A.red(`Delete module '${s}' at ${c}? This cannot be undone.`),initialValue:!1})){console.log(`
3872
3872
  Cancelled.
3873
- `);return}await ge(c,{recursive:!0,force:!0}),console.log(` Deleted: ${c}`);let l=S(n,`index.ts`);if(await ze(l)){let e=await D(l,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${H(o)}Module\\s*\\}\\s*from\\s*['"][^'"]*${H(s)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=Hi(e,o),e=e.replace(/\n{3,}/g,`
3873
+ `);return}await ge(c,{recursive:!0,force:!0}),console.log(` Deleted: ${c}`);let l=S(n,`index.ts`);if(await Be(l)){let e=await D(l,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${H(o)}Module\\s*\\}\\s*from\\s*['"][^'"]*${H(s)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=Ui(e,o),e=e.replace(/\n{3,}/g,`
3874
3874
 
3875
- `),e!==t&&(await O(l,e,`utf-8`),console.log(` Unregistered: ${o}Module from ${l}`))}console.log(`\n Module '${s}' removed.\n`)}function Wi(e){e.command(`remove`).alias(`rm`).description(`Remove generated code`).command(`module <names...>`).description(`Remove one or more modules (e.g. kick rm module user task)`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular module name`).option(`-f, --force`,`Skip confirmation prompt`).action(async(e,t)=>{let i=n(await r(process.cwd())),a=t.modulesDir??i.dir??`src/modules`,o=t.pluralize===!1?!1:i.pluralize??!0;for(let n of e)await Ui({name:n,modulesDir:w(a),force:t.force,pluralize:o})})}function Gi(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;console.warn(` kick typegen: unknown --schema-validator '${e}' (only 'zod' and 'false' are supported). Falling back to project config.`)}}function Ki(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function qi(e){e.command(`typegen`).description(`Generate type-safe DI registry and module types into .kickjs/types/`).option(`-w, --watch`,`Watch source files and regenerate on change`).option(`-s, --src <dir>`,`Source directory to scan`,`src`).option(`-o, --out <dir>`,`Output directory`,`.kickjs/types`).option(`--silent`,`Suppress output`).option(`--allow-duplicates`,`Auto-namespace duplicate class names instead of failing (use with caution)`).option(`--schema-validator <name>`,`Schema validator for body/query/params typing (currently 'zod' or 'false')`).option(`--env-file <path>`,`Path to env schema file for KickEnv typing (default 'src/env.ts'; pass 'false' to disable)`).option(`--check`,`CI gate: fail on plugin-typegen drift instead of writing`).option(`--list`,"List every registered typegen plugin id (use to populate `typegen.disable`)").action(async e=>{let t=process.cwd(),n=await r(t);if(e.list){let{mergeCliPlugins:e}=await import(`./plugin-Dz0Yu4Ow.mjs`).then(e=>e.t),{builtinCliPlugins:t}=await Promise.resolve().then(()=>ka),r=e([...t,...n?.plugins??[]],n?.commands??[]),i=new Set(n?.typegen?.disable??[]);if(r.typegens.length===0){console.log(` No typegen plugins registered.`);return}let a=Math.max(...r.typegens.map(e=>e.id.length));console.log(`
3875
+ `),e!==t&&(await O(l,e,`utf-8`),console.log(` Unregistered: ${o}Module from ${l}`))}console.log(`\n Module '${s}' removed.\n`)}function Gi(e){e.command(`remove`).alias(`rm`).description(`Remove generated code`).command(`module <names...>`).description(`Remove one or more modules (e.g. kick rm module user task)`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular module name`).option(`-f, --force`,`Skip confirmation prompt`).action(async(e,t)=>{let i=n(await r(process.cwd())),a=t.modulesDir??i.dir??`src/modules`,o=t.pluralize===!1?!1:i.pluralize??!0;for(let n of e)await Wi({name:n,modulesDir:w(a),force:t.force,pluralize:o})})}function Ki(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;console.warn(` kick typegen: unknown --schema-validator '${e}' (only 'zod' and 'false' are supported). Falling back to project config.`)}}function qi(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function Ji(e){e.command(`typegen`).description(`Generate type-safe DI registry and module types into .kickjs/types/`).option(`-w, --watch`,`Watch source files and regenerate on change`).option(`-s, --src <dir>`,`Source directory to scan`,`src`).option(`-o, --out <dir>`,`Output directory`,`.kickjs/types`).option(`--silent`,`Suppress output`).option(`--allow-duplicates`,`Auto-namespace duplicate class names instead of failing (use with caution)`).option(`--schema-validator <name>`,`Schema validator for body/query/params typing (currently 'zod' or 'false')`).option(`--env-file <path>`,`Path to env schema file for KickEnv typing (default 'src/env.ts'; pass 'false' to disable)`).option(`--check`,`CI gate: fail on plugin-typegen drift instead of writing`).option(`--list`,"List every registered typegen plugin id (use to populate `typegen.disable`)").action(async e=>{let t=process.cwd(),n=await r(t);if(e.list){let{mergeCliPlugins:e}=await import(`./plugin-DLnoaSX8.mjs`).then(e=>e.t),{builtinCliPlugins:t}=await Promise.resolve().then(()=>ja),r=e([...t,...n?.plugins??[]],n?.commands??[]),i=new Set(n?.typegen?.disable??[]);if(r.typegens.length===0){console.log(` No typegen plugins registered.`);return}let a=Math.max(...r.typegens.map(e=>e.id.length));console.log(`
3876
3876
  Registered typegen plugins:
3877
- `);for(let e of r.typegens){let t=i.has(e.id)?` (disabled)`:``;console.log(` ${e.id.padEnd(a+2)}inputs: ${e.inputs.join(`, `)||`(none)`}${t}`)}console.log();return}let i=Gi(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,a=Ki(e.envFile)??n?.typegen?.envFile,o={cwd:t,srcDir:e.src??n?.typegen?.srcDir,outDir:e.out??n?.typegen?.outDir,silent:e.silent,allowDuplicates:e.allowDuplicates,schemaValidator:i,envFile:a,assetMap:n?.assetMap,runPlugins:!1};try{if(e.watch){let t=await l(o);e.silent||console.log(` kick typegen: watching for changes (Ctrl-C to exit)`);let n=()=>{t(),process.exit(0)};process.on(`SIGINT`,n),process.on(`SIGTERM`,n),await new Promise(()=>{})}else{let{result:r}=await p(o),i=await Jr({cwd:t,config:n??null,silent:e.silent,check:e.check});e.check&&i.some(e=>e.status===`written`)&&process.exit(1),e.check||await u(w(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r.written,i,e.silent??!1)}}catch(e){e instanceof f?console.error(`
3877
+ `);for(let e of r.typegens){let t=i.has(e.id)?` (disabled)`:``;console.log(` ${e.id.padEnd(a+2)}inputs: ${e.inputs.join(`, `)||`(none)`}${t}`)}console.log();return}let i=Ki(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,a=qi(e.envFile)??n?.typegen?.envFile,o={cwd:t,srcDir:e.src??n?.typegen?.srcDir,outDir:e.out??n?.typegen?.outDir,silent:e.silent,allowDuplicates:e.allowDuplicates,schemaValidator:i,envFile:a,assetMap:n?.assetMap,runPlugins:!1};try{if(e.watch){let t=await l(o);e.silent||console.log(` kick typegen: watching for changes (Ctrl-C to exit)`);let n=()=>{t(),process.exit(0)};process.on(`SIGINT`,n),process.on(`SIGTERM`,n),await new Promise(()=>{})}else{let{result:r}=await p(o),i=await Yr({cwd:t,config:n??null,silent:e.silent,check:e.check});e.check&&i.some(e=>e.status===`written`)&&process.exit(1),e.check||await u(w(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r.written,i,e.silent??!1)}}catch(e){e instanceof f?console.error(`
3878
3878
  `+e.message+`
3879
- `):e instanceof Error?console.error(`\n kick typegen failed: ${e.message}`):console.error(`\n kick typegen failed: ${JSON.stringify(e)}`),process.exit(1)}})}function Ji(e){let t=[];if(!g(e))return t;let n=y(e,{withFileTypes:!0});for(let r of n){let n=S(e,r.name);if(r.isDirectory()){if([`node_modules`,`dist`,`.kickjs`,`.git`].includes(r.name))continue;t.push(...Ji(n))}else r.isFile()&&/\.tsx?$/.test(r.name)&&!r.name.endsWith(`.d.ts`)&&t.push(n)}return t}function Yi(e){try{return v(e,`utf-8`)}catch{return``}}const Xi=new Set([`secret`,`changeme`,`password`,`test`,`default`,``]);function Zi(e,t){let n=Yi(S(e,`.env`));if(n){let e=n.match(/^JWT_SECRET\s*=\s*['"]?([^'"\n]*)['"]?/m);if(e){let t=e[1].trim();if(Xi.has(t.toLowerCase())||t.length<32)return{severity:`CRITICAL`,message:`JWT_SECRET appears to be a default value or too short (< 32 chars) — change it`}}}for(let e of t)for(let t of[/JWT_SECRET['"]?\s*[:=]\s*['"]?(secret|changeme|password|test|default)['"]?/i,/secret\s*[:=]\s*['"]?(secret|changeme|password|test|default)['"]?/i])if(t.test(e))return{severity:`CRITICAL`,message:`JWT_SECRET appears to be a default value in source code — use an environment variable`};return null}function Qi(e){for(let t of e)if(/cors\s*\(/.test(t)&&/origin\s*:\s*['"]\*['"]/.test(t))return{severity:`CRITICAL`,message:`CORS origin is '*' — restrict to your domains`};return null}function $i(e){for(let t of e)if(/rateLimit/i.test(t)||/@RateLimit/i.test(t))return null;return{severity:`WARNING`,message:`No rate limiting detected — add rateLimit() middleware or @RateLimit decorator`}}function ea(){return process.env.NODE_ENV===`production`?null:{severity:`WARNING`,message:`NODE_ENV is '${process.env.NODE_ENV??`undefined`}', not 'production'`}}function ta(e){let t=!1,n=!1;for(let r of e)/tokenStore/i.test(r)&&(t=!0),/MemoryTokenStore/i.test(r)&&(n=!0);return n?{severity:`WARNING`,message:`MemoryTokenStore detected — use a persistent store (Redis, DB) for production deployments`}:t?null:{severity:`WARNING`,message:`No token revocation store detected — consider adding one for auth token management`}}function na(e){for(let t of e)if(/helmet\s*\(/.test(t))return/security\s*\.\s*helmet\s*.*false/.test(t)?{severity:`WARNING`,message:`Helmet security headers are disabled — enable them for production`}:{severity:`INFO`,message:`Helmet security headers active`};return{severity:`WARNING`,message:`Helmet not detected — add helmet() middleware for security headers`}}function ra(e){for(let t of e)if(/AuthAdapter/i.test(t))return{severity:`INFO`,message:`AuthAdapter configured`};return{severity:`INFO`,message:`No AuthAdapter detected — add one if your app requires authentication`}}function ia(e){let t=Ji(S(e,`src`)).map(e=>Yi(e)),n=[],r=Zi(e,t);r&&n.push(r);let i=Qi(t);i&&n.push(i);let a=$i(t);a&&n.push(a);let o=ea();o&&n.push(o);let s=ta(t);return s&&n.push(s),n.push(na(t)),n.push(ra(t)),n}function aa(e){e.command(`check`).description(`Audit project for common issues`).option(`--deploy`,`Run production readiness checks`).action(e=>{if(!e.deploy){console.log(`
3879
+ `):e instanceof Error?console.error(`\n kick typegen failed: ${e.message}`):console.error(`\n kick typegen failed: ${JSON.stringify(e)}`),process.exit(1)}})}function Yi(e){let t=[];if(!g(e))return t;let n=y(e,{withFileTypes:!0});for(let r of n){let n=S(e,r.name);if(r.isDirectory()){if([`node_modules`,`dist`,`.kickjs`,`.git`].includes(r.name))continue;t.push(...Yi(n))}else r.isFile()&&/\.tsx?$/.test(r.name)&&!r.name.endsWith(`.d.ts`)&&t.push(n)}return t}function Xi(e){try{return v(e,`utf-8`)}catch{return``}}const Zi=new Set([`secret`,`changeme`,`password`,`test`,`default`,``]);function Qi(e,t){let n=Xi(S(e,`.env`));if(n){let e=n.match(/^JWT_SECRET\s*=\s*['"]?([^'"\n]*)['"]?/m);if(e){let t=e[1].trim();if(Zi.has(t.toLowerCase())||t.length<32)return{severity:`CRITICAL`,message:`JWT_SECRET appears to be a default value or too short (< 32 chars) — change it`}}}for(let e of t)for(let t of[/JWT_SECRET['"]?\s*[:=]\s*['"]?(secret|changeme|password|test|default)['"]?/i,/secret\s*[:=]\s*['"]?(secret|changeme|password|test|default)['"]?/i])if(t.test(e))return{severity:`CRITICAL`,message:`JWT_SECRET appears to be a default value in source code — use an environment variable`};return null}function $i(e){for(let t of e)if(/cors\s*\(/.test(t)&&/origin\s*:\s*['"]\*['"]/.test(t))return{severity:`CRITICAL`,message:`CORS origin is '*' — restrict to your domains`};return null}function ea(e){for(let t of e)if(/rateLimit/i.test(t)||/@RateLimit/i.test(t))return null;return{severity:`WARNING`,message:`No rate limiting detected — add rateLimit() middleware or @RateLimit decorator`}}function ta(){return process.env.NODE_ENV===`production`?null:{severity:`WARNING`,message:`NODE_ENV is '${process.env.NODE_ENV??`undefined`}', not 'production'`}}function na(e){let t=!1,n=!1;for(let r of e)/tokenStore/i.test(r)&&(t=!0),/MemoryTokenStore/i.test(r)&&(n=!0);return n?{severity:`WARNING`,message:`MemoryTokenStore detected — use a persistent store (Redis, DB) for production deployments`}:t?null:{severity:`WARNING`,message:`No token revocation store detected — consider adding one for auth token management`}}function ra(e){for(let t of e)if(/helmet\s*\(/.test(t))return/security\s*\.\s*helmet\s*.*false/.test(t)?{severity:`WARNING`,message:`Helmet security headers are disabled — enable them for production`}:{severity:`INFO`,message:`Helmet security headers active`};return{severity:`WARNING`,message:`Helmet not detected — add helmet() middleware for security headers`}}function ia(e){for(let t of e)if(/AuthAdapter/i.test(t))return{severity:`INFO`,message:`AuthAdapter configured`};return{severity:`INFO`,message:`No AuthAdapter detected — add one if your app requires authentication`}}function aa(e){let t=Yi(S(e,`src`)).map(e=>Xi(e)),n=[],r=Qi(e,t);r&&n.push(r);let i=$i(t);i&&n.push(i);let a=ea(t);a&&n.push(a);let o=ta();o&&n.push(o);let s=na(t);return s&&n.push(s),n.push(ra(t)),n.push(ia(t)),n}function oa(e){e.command(`check`).description(`Audit project for common issues`).option(`--deploy`,`Run production readiness checks`).action(e=>{if(!e.deploy){console.log(`
3880
3880
  Usage: kick check --deploy
3881
3881
 
3882
3882
  Available checks:
3883
3883
  --deploy Audit for production readiness (security, config, best practices)
3884
- `);return}let t=process.cwd();vt(`KickJS Deploy Check`);let n=wt();n.start(`Scanning project...`);let r=ia(t);n.stop(`Scan complete`);let i={CRITICAL:0,WARNING:1,INFO:2};r.sort((e,t)=>i[e.severity]-i[t.severity]);for(let e of r)I.message(`${_t(e.severity)} ${e.message}`);let a=r.filter(e=>e.severity===`CRITICAL`).length,o=r.filter(e=>e.severity===`WARNING`).length,s=r.filter(e=>e.severity===`INFO`).length,c=o===1?`warning`:`warnings`,l=[a>0?A.red(`${a} critical`):`${a} critical`,o>0?A.yellow(`${o} ${c}`):`${o} ${c}`,`${s} info`].join(`, `);a>0?(yt(A.red(`${l} — fix critical issues before deploying`)),process.exit(1)):yt(A.green(`${l} — looking good!`))})}async function Q(e){return je({configPath:b.resolve(process.cwd(),e.config)})}async function $(e){if(e.adapter){let t=await e.adapter();return{adapter:t,cleanup:async()=>t.close()}}if(!e.connectionString)throw Error(`kickjs-db: no adapter resolved — set db.connectionString (or DATABASE_URL) in kick.config.ts, or supply db.adapter() factory`);let t=e.dialect??`postgres`;if(t!==`postgres`)throw Error(`kickjs-db: built-in CLI adapter only supports postgres in M1 (dialect=${t}); use db.adapter() factory for other dialects`);let[{pgAdapter:n},r]=await Promise.all([import(`@forinda/kickjs-db-pg`),import(`pg`)]),i=new r.default.Pool({connectionString:e.connectionString}),a=n({pool:i});return{adapter:a,cleanup:async()=>{await a.close(),await i.end()}}}function oa(e){if(e.length===0){console.log(`No migrations.`);return}console.table(e.map(e=>({id:e.id,state:e.state,batch:e.batch??`-`,reviewed:e.reviewed,applied:e.appliedAt??`-`})))}function sa(e){let t=e.command(`db`).description(`Database commands (kickjs-db)`);t.command(`generate <name>`).description(`Generate a new migration from schema diff`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).option(`-e, --empty`,`Skip schema diff and create an empty migration shell (data migration, seed, freeform SQL)`).action(async(e,t)=>{let n=process.cwd(),r=await we({name:e,config:await Q(t),cwd:n,empty:t.empty});if(r.status===`no-changes`){console.log(`No schema changes detected.`);return}if(r.empty){console.log(`Created empty migration ${r.migrationDir} (author up.sql + down.sql).`);return}let i=r.changeCount===1?``:`s`;console.log(`Created migration ${r.migrationDir} (${r.changeCount} change${i}).`)});let n=t.command(`migrate`).description(`Migration runner subcommands`);n.command(`latest`).description(`Apply all pending migrations in a new batch`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).option(`--confirm-enum-drop`,"Allow migrations carrying the `-- KICK ENUM REMOVE` header to apply",!1).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let r=await Ee({adapter:n,migrationsDir:t.migrationsDir,confirmEnumDrop:e.confirmEnumDrop});r.applied.length===0?console.log(`No pending migrations.`):console.log(`Applied batch ${r.batch}: ${r.applied.join(`, `)}`)}finally{await r()}}),n.command(`up`).description(`Apply the next single pending migration`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).option(`--confirm-enum-drop`,"Allow migrations carrying the `-- KICK ENUM REMOVE` header to apply",!1).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let r=await ke({adapter:n,migrationsDir:t.migrationsDir,confirmEnumDrop:e.confirmEnumDrop});r.applied.length===0?console.log(`No pending migrations.`):console.log(`Applied ${r.applied[0]} (batch ${r.batch})`)}finally{await r()}}),n.command(`down`).description(`Reverse the most recent applied migration`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let e=await Te({adapter:n,migrationsDir:t.migrationsDir});e.reversed?console.log(`Reversed ${e.reversed}.`):console.log(`Nothing to reverse.`)}finally{await r()}}),n.command(`rollback`).description(`Reverse the entire last batch as a single unit`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let e=await De({adapter:n,migrationsDir:t.migrationsDir});e.reversed.length===0?console.log(`Nothing to roll back.`):console.log(`Rolled back batch ${e.batch}: ${e.reversed.join(`, `)}`)}finally{await r()}}),n.command(`status`).description(`Print applied + pending migrations`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{oa(await Oe({adapter:n,migrationsDir:t.migrationsDir}))}finally{await r()}}),t.command(`introspect`).description(`Generate a TypeScript schema file from a live database`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).option(`--out <path>`,`Output file (defaults to db.schemaPath from config)`).option(`--json`,`Print the raw SchemaSnapshot JSON to stdout instead of writing TS source`).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let r=await n.introspect();if(e.json){console.log(JSON.stringify(r,null,2));return}let i=e.out??t.schemaPath;await O(i,Ae(r),`utf8`);let a=Object.keys(r.tables).length;console.log(`Wrote ${i} (${a} table${a===1?``:`s`}).`)}finally{await r()}})}function ca(e){return e.optsWithGlobals().dryRun??!1}function la(e){e.command(`codemod`).description(`Codebase migration commands (AST-style rewrites — distinct from db migrate)`).command(`modules`).description(`Rewrite module declarations between class form and the defineModule factory.
3884
+ `);return}let t=process.cwd();yt(`KickJS Deploy Check`);let n=Tt();n.start(`Scanning project...`);let r=aa(t);n.stop(`Scan complete`);let i={CRITICAL:0,WARNING:1,INFO:2};r.sort((e,t)=>i[e.severity]-i[t.severity]);for(let e of r)I.message(`${vt(e.severity)} ${e.message}`);let a=r.filter(e=>e.severity===`CRITICAL`).length,o=r.filter(e=>e.severity===`WARNING`).length,s=r.filter(e=>e.severity===`INFO`).length,c=o===1?`warning`:`warnings`,l=[a>0?A.red(`${a} critical`):`${a} critical`,o>0?A.yellow(`${o} ${c}`):`${o} ${c}`,`${s} info`].join(`, `);a>0?(bt(A.red(`${l} — fix critical issues before deploying`)),process.exit(1)):bt(A.green(`${l} — looking good!`))})}async function Q(e){return Me({configPath:b.resolve(process.cwd(),e.config)})}async function $(e){if(e.adapter){let t=await e.adapter();return{adapter:t,cleanup:async()=>t.close()}}if(!e.connectionString)throw Error(`kickjs-db: no adapter resolved — set db.connectionString (or DATABASE_URL) in kick.config.ts, or supply db.adapter() factory`);let t=e.dialect??`postgres`;if(t!==`postgres`)throw Error(`kickjs-db: built-in CLI adapter only supports postgres in M1 (dialect=${t}); use db.adapter() factory for other dialects`);let[{pgAdapter:n},r]=await Promise.all([import(`@forinda/kickjs-db-pg`),import(`pg`)]),i=new r.default.Pool({connectionString:e.connectionString}),a=n({pool:i});return{adapter:a,cleanup:async()=>{await a.close(),await i.end()}}}async function sa(e){if(e.adapter||(e.dialect??`postgres`)!==`postgres`||!e.connectionString)return null;let t=new(await(import(`pg`))).default.Pool({connectionString:e.connectionString});return{runner:t,cleanup:async()=>{await t.end()}}}function ca(e){if(e.length===0){console.log(`No migrations.`);return}console.table(e.map(e=>({id:e.id,state:e.state,batch:e.batch??`-`,reviewed:e.reviewed,applied:e.appliedAt??`-`})))}function la(e){let t=e.command(`db`).description(`Database commands (kickjs-db)`);t.command(`generate <name>`).description(`Generate a new migration from schema diff`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).option(`-e, --empty`,`Skip schema diff and create an empty migration shell (data migration, seed, freeform SQL)`).action(async(e,t)=>{let n=process.cwd(),r=await Q(t),i=await sa(r),a=i?e=>we(i.runner,e):void 0;try{let i=await Te({name:e,config:r,cwd:n,empty:t.empty,detectCompositeRefs:a});if(i.status===`no-changes`){console.log(`No schema changes detected.`);return}if(i.empty){console.log(`Created empty migration ${i.migrationDir} (author up.sql + down.sql).`);return}let o=i.changeCount===1?``:`s`;console.log(`Created migration ${i.migrationDir} (${i.changeCount} change${o}).`)}finally{await i?.cleanup()}});let n=t.command(`migrate`).description(`Migration runner subcommands`);n.command(`latest`).description(`Apply all pending migrations in a new batch`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).option(`--confirm-enum-drop`,"Allow migrations carrying the `-- KICK ENUM REMOVE` header to apply",!1).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let r=await De({adapter:n,migrationsDir:t.migrationsDir,confirmEnumDrop:e.confirmEnumDrop});r.applied.length===0?console.log(`No pending migrations.`):console.log(`Applied batch ${r.batch}: ${r.applied.join(`, `)}`)}finally{await r()}}),n.command(`up`).description(`Apply the next single pending migration`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).option(`--confirm-enum-drop`,"Allow migrations carrying the `-- KICK ENUM REMOVE` header to apply",!1).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let r=await Ae({adapter:n,migrationsDir:t.migrationsDir,confirmEnumDrop:e.confirmEnumDrop});r.applied.length===0?console.log(`No pending migrations.`):console.log(`Applied ${r.applied[0]} (batch ${r.batch})`)}finally{await r()}}),n.command(`down`).description(`Reverse the most recent applied migration`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let e=await Ee({adapter:n,migrationsDir:t.migrationsDir});e.reversed?console.log(`Reversed ${e.reversed}.`):console.log(`Nothing to reverse.`)}finally{await r()}}),n.command(`rollback`).description(`Reverse the entire last batch as a single unit`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let e=await Oe({adapter:n,migrationsDir:t.migrationsDir});e.reversed.length===0?console.log(`Nothing to roll back.`):console.log(`Rolled back batch ${e.batch}: ${e.reversed.join(`, `)}`)}finally{await r()}}),n.command(`status`).description(`Print applied + pending migrations`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{ca(await ke({adapter:n,migrationsDir:t.migrationsDir}))}finally{await r()}}),t.command(`introspect`).description(`Generate a TypeScript schema file from a live database`).option(`-c, --config <path>`,`Path to kick.config.ts`,`kick.config.ts`).option(`--out <path>`,`Output file (defaults to db.schemaPath from config)`).option(`--json`,`Print the raw SchemaSnapshot JSON to stdout instead of writing TS source`).action(async e=>{let t=await Q(e),{adapter:n,cleanup:r}=await $(t);try{let r=await n.introspect();if(e.json){console.log(JSON.stringify(r,null,2));return}let i=e.out??t.schemaPath;await O(i,je(r),`utf8`);let a=Object.keys(r.tables).length;console.log(`Wrote ${i} (${a} table${a===1?``:`s`}).`)}finally{await r()}})}function ua(e){return e.optsWithGlobals().dryRun??!1}function da(e){e.command(`codemod`).description(`Codebase migration commands (AST-style rewrites — distinct from db migrate)`).command(`modules`).description(`Rewrite module declarations between class form and the defineModule factory.
3885
3885
  Direction defaults to \`modules.style\` from kick.config (or "define").
3886
3886
  --target define|class Override the migration direction.
3887
3887
  --apply Apply the changes (default: dry-run preview).
3888
- --experimental Acknowledge that AST migration is experimental.`).option(`--modules-dir <dir>`,`Modules directory (default: src/modules from kick.config)`).option(`--apply`,`Apply the migration to disk (default: dry-run)`).option(`--experimental`,`Acknowledge that this command is experimental`).option(`--target <style>`,`Migration direction — 'define' or 'class'`).option(`--no-backup`,`Skip the .kickjs/codemod-backups/ snapshot (default: backup on)`).action(async(e,t)=>{let i=ca(t)||!e.apply;j(i),e.experimental||(console.error(`
3888
+ --experimental Acknowledge that AST migration is experimental.`).option(`--modules-dir <dir>`,`Modules directory (default: src/modules from kick.config)`).option(`--apply`,`Apply the migration to disk (default: dry-run)`).option(`--experimental`,`Acknowledge that this command is experimental`).option(`--target <style>`,`Migration direction — 'define' or 'class'`).option(`--no-backup`,`Skip the .kickjs/codemod-backups/ snapshot (default: backup on)`).action(async(e,t)=>{let i=ua(t)||!e.apply;j(i),e.experimental||(console.error(`
3889
3889
  `+A.red(`Error:`)+` kick codemod modules is experimental — pass --experimental to acknowledge.
3890
3890
  The regex-based rewrite handles the shapes our templates produce.
3891
3891
  Hand-rolled modules with non-standard structures may be skipped.
3892
3892
  Always commit before running with --apply.
3893
- `),process.exit(1));let a=n(await r(process.cwd())),o=w(e.modulesDir??a.dir??`src/modules`),s;e.target===`define`||e.target===`class`?s=e.target:e.target===void 0?s=a.style??`define`:(console.error(`\n ${A.red(`Error:`)} --target must be 'define' or 'class' (got '${e.target}').\n`),process.exit(1));let c=A.dim(`→ ${s}`),l=i?A.dim(`(dry-run)`):A.bold(`(applying)`);console.log(`\n ${A.bold(`kick codemod modules`)} ${c} ${l}`),console.log(` modulesDir: ${A.dim(o)}\n`);let u=e.backup!==!1&&!i,d=await mr(o,{dryRun:i,target:s,backup:u});if(d.backupDir){let e=d.backupDir;console.log(` ${A.green(`✓`)} backup: ${A.dim(e)}\n ${A.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else !i&&e.backup===!1&&console.log(` ${A.dim(`(--no-backup — skipping snapshot)`)}\n`);let f=0,p=0;for(let e of d.files)if(e.status===`migrated`)f++,console.log(` ${A.green(`✓`)} ${e.path}`);else{p++;let t=A.dim(`(${e.reason??`skipped`})`);console.log(` ${A.dim(`-`)} ${e.path} ${t}`)}if(console.log(),d.indexStatus===`migrated`)console.log(` ${A.green(`✓`)} ${d.indexPath}`);else if(d.indexStatus===`skipped`){let e=A.dim(`(${d.indexReason??`skipped`})`);console.log(` ${A.dim(`-`)} ${d.indexPath} ${e}`)}else console.log(` ${A.dim(`-`)} ${d.indexPath} ${A.dim(`(not found)`)}`);let m=i?A.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${A.bold(String(f))} migrated, ${A.bold(String(p))} skipped${m}\n`)})}const ua=[`src/db/schema.ts`,`src/db/schema/index.ts`,`src/db/schema`],da=()=>({id:`kick/db`,inputs:[`src/db/schema.ts`,`src/db/schema/**/*.ts`],async generate(e){let t=fa(e.cwd);if(!t)return null;let n=b.resolve(e.cwd,`.kickjs/types`);return[`import type { SchemaToTypes, SchemaToRelationsRegister, KickDbClient } from '@forinda/kickjs-db'`,`import type * as appSchema from '${pa(b.relative(n,t)).replace(/\.ts$/,``).replace(/\/index$/,``)}'`,``,`declare global {`,` interface KickDbSchema extends SchemaToTypes<typeof appSchema> {}`,`}`,``,`declare module '@forinda/kickjs-db' {`,` interface KickDbRegister {`,` db: KickDbClient<KickDbSchema>`,` }`,``,` interface KickDbRelationsRegister {`,` db: SchemaToRelationsRegister<typeof appSchema>`,` }`,`}`].join(`
3894
- `)}});function fa(e){for(let t of ua){let n=b.resolve(e,t);if(t.endsWith(`.ts`)){if(g(n))return n}else{let e=b.join(n,`index.ts`);if(g(e))return e}}return null}function pa(e){return e.replace(/\\/g,`/`)}const ma=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){if(!g(b.resolve(e.cwd,`kick.config.ts`)))return null;let t=await r(e.cwd);if(!t?.assetMap)return null;let n=s(t.assetMap,e.cwd);return n.count===0?null:d(n)}}),ha="/* eslint-disable */\n// AUTO-GENERATED by `kick typegen`. DO NOT EDIT.\n// Re-run with `kick typegen` or rely on `kick dev` to refresh.\n";function ga(e,t,n){if(e.length===0)return`${ha}
3893
+ `),process.exit(1));let a=n(await r(process.cwd())),o=w(e.modulesDir??a.dir??`src/modules`),s;e.target===`define`||e.target===`class`?s=e.target:e.target===void 0?s=a.style??`define`:(console.error(`\n ${A.red(`Error:`)} --target must be 'define' or 'class' (got '${e.target}').\n`),process.exit(1));let c=A.dim(`→ ${s}`),l=i?A.dim(`(dry-run)`):A.bold(`(applying)`);console.log(`\n ${A.bold(`kick codemod modules`)} ${c} ${l}`),console.log(` modulesDir: ${A.dim(o)}\n`);let u=e.backup!==!1&&!i,d=await hr(o,{dryRun:i,target:s,backup:u});if(d.backupDir){let e=d.backupDir;console.log(` ${A.green(`✓`)} backup: ${A.dim(e)}\n ${A.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else !i&&e.backup===!1&&console.log(` ${A.dim(`(--no-backup — skipping snapshot)`)}\n`);let f=0,p=0;for(let e of d.files)if(e.status===`migrated`)f++,console.log(` ${A.green(`✓`)} ${e.path}`);else{p++;let t=A.dim(`(${e.reason??`skipped`})`);console.log(` ${A.dim(`-`)} ${e.path} ${t}`)}if(console.log(),d.indexStatus===`migrated`)console.log(` ${A.green(`✓`)} ${d.indexPath}`);else if(d.indexStatus===`skipped`){let e=A.dim(`(${d.indexReason??`skipped`})`);console.log(` ${A.dim(`-`)} ${d.indexPath} ${e}`)}else console.log(` ${A.dim(`-`)} ${d.indexPath} ${A.dim(`(not found)`)}`);let m=i?A.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${A.bold(String(f))} migrated, ${A.bold(String(p))} skipped${m}\n`)})}const fa=[`src/db/schema.ts`,`src/db/schema/index.ts`,`src/db/schema`],pa=()=>({id:`kick/db`,inputs:[`src/db/schema.ts`,`src/db/schema/**/*.ts`],async generate(e){let t=ma(e.cwd);if(!t)return null;let n=b.resolve(e.cwd,`.kickjs/types`);return[`import type { SchemaToTypes, SchemaToRelationsRegister, KickDbClient } from '@forinda/kickjs-db'`,`import type * as appSchema from '${ha(b.relative(n,t)).replace(/\.ts$/,``).replace(/\/index$/,``)}'`,``,`declare global {`,` interface KickDbSchema extends SchemaToTypes<typeof appSchema> {}`,`}`,``,`declare module '@forinda/kickjs-db' {`,` interface KickDbRegister {`,` db: KickDbClient<KickDbSchema>`,` }`,``,` interface KickDbRelationsRegister {`,` db: SchemaToRelationsRegister<typeof appSchema>`,` }`,`}`].join(`
3894
+ `)}});function ma(e){for(let t of fa){let n=b.resolve(e,t);if(t.endsWith(`.ts`)){if(g(n))return n}else{let e=b.join(n,`index.ts`);if(g(e))return e}}return null}function ha(e){return e.replace(/\\/g,`/`)}const ga=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){if(!g(b.resolve(e.cwd,`kick.config.ts`)))return null;let t=await r(e.cwd);if(!t?.assetMap)return null;let n=s(t.assetMap,e.cwd);return n.count===0?null:d(n)}}),_a="/* eslint-disable */\n// AUTO-GENERATED by `kick typegen`. DO NOT EDIT.\n// Re-run with `kick typegen` or rely on `kick dev` to refresh.\n";function va(e,t,n){if(e.length===0)return`${_a}
3895
3895
  // (no routes discovered yet — annotate a controller method with
3896
3896
  // @Get/@Post/@Put/@Delete/@Patch and re-run \`kick typegen\`)
3897
3897
  declare global {
@@ -3900,8 +3900,8 @@ declare global {
3900
3900
  }
3901
3901
 
3902
3902
  export {}
3903
- `;let r=new Map;for(let t of e){let e=r.get(t.controller)??[];e.push(t),r.set(t.controller,e)}let i=new Map,a=(e,r)=>{let a=ya(e,r,t,n,i);return a?`import('zod').infer<typeof ${a}>`:null},o=[];for(let[e,t]of r){let n=[` interface ${e} {`];for(let e of t){let t=e.pathParams.length>0?`{ ${e.pathParams.map(e=>`${e}: string`).join(`; `)} }`:`{}`,r=a(e.bodySchema,e.filePath),i=a(e.querySchema,e.filePath),o=a(e.paramsSchema,e.filePath)??t,s=r??`unknown`,c=i??_a(e),l=va(e);n.push(` /**`,` * ${e.httpMethod} ${e.path}`,...l.map(e=>` * ${e}`),` */`,` ${e.method}: {`,` params: ${o}`,` body: ${s}`,` query: ${c}`,` response: unknown`,` }`)}n.push(` }`),o.push(n.join(`
3904
- `))}return`${ha}${ba(i)}
3903
+ `;let r=new Map;for(let t of e){let e=r.get(t.controller)??[];e.push(t),r.set(t.controller,e)}let i=new Map,a=(e,r)=>{let a=xa(e,r,t,n,i);return a?`import('zod').infer<typeof ${a}>`:null},o=[];for(let[e,t]of r){let n=[` interface ${e} {`];for(let e of t){let t=e.pathParams.length>0?`{ ${e.pathParams.map(e=>`${e}: string`).join(`; `)} }`:`{}`,r=a(e.bodySchema,e.filePath),i=a(e.querySchema,e.filePath),o=a(e.paramsSchema,e.filePath)??t,s=r??`unknown`,c=i??ya(e),l=ba(e);n.push(` /**`,` * ${e.httpMethod} ${e.path}`,...l.map(e=>` * ${e}`),` */`,` ${e.method}: {`,` params: ${o}`,` body: ${s}`,` query: ${c}`,` response: unknown`,` }`)}n.push(` }`),o.push(n.join(`
3904
+ `))}return`${_a}${Sa(i)}
3905
3905
  declare global {
3906
3906
  // eslint-disable-next-line @typescript-eslint/no-namespace
3907
3907
  namespace KickRoutes {
@@ -3911,9 +3911,9 @@ ${o.join(`
3911
3911
  }
3912
3912
 
3913
3913
  export {}
3914
- `}function _a(e){if(e.queryFilterable===null)return`unknown`;let t=e.querySortable??[];return`{ filter?: string | string[]; sort?: ${t.length>0?t.flatMap(e=>[`'${e}'`,`'-${e}'`]).join(` | `):`string`}; q?: string; page?: string; limit?: string }`}function va(e){let t=[];return e.queryFilterable&&e.queryFilterable.length>0&&t.push(`Filterable: ${e.queryFilterable.join(`, `)}`),e.querySortable&&e.querySortable.length>0&&t.push(`Sortable: ${e.querySortable.join(`, `)}`),e.querySearchable&&e.querySearchable.length>0&&t.push(`Searchable: ${e.querySearchable.join(`, `)}`),t}function ya(e,t,n,r,i){if(!e||r!==`zod`||e.source===null)return null;let a=xa(e.source,t,n);if(a===`unknown`)return null;let o=`${a}::${e.identifier}`,s=i.get(o)?.specifier;return s?s=i.get(o).specifier:(s=`_S${i.size}`,i.set(o,{identifier:e.identifier,specifier:s})),s}function ba(e){if(e.size===0)return``;let t=[];for(let[n,r]of e){let[e]=n.split(`::`);t.push(`import type { ${r.identifier} as ${r.specifier} } from '${e}'`)}return t.join(`
3914
+ `}function ya(e){if(e.queryFilterable===null)return`unknown`;let t=e.querySortable??[];return`{ filter?: string | string[]; sort?: ${t.length>0?t.flatMap(e=>[`'${e}'`,`'-${e}'`]).join(` | `):`string`}; q?: string; page?: string; limit?: string }`}function ba(e){let t=[];return e.queryFilterable&&e.queryFilterable.length>0&&t.push(`Filterable: ${e.queryFilterable.join(`, `)}`),e.querySortable&&e.querySortable.length>0&&t.push(`Sortable: ${e.querySortable.join(`, `)}`),e.querySearchable&&e.querySearchable.length>0&&t.push(`Searchable: ${e.querySearchable.join(`, `)}`),t}function xa(e,t,n,r,i){if(!e||r!==`zod`||e.source===null)return null;let a=Ca(e.source,t,n);if(a===`unknown`)return null;let o=`${a}::${e.identifier}`,s=i.get(o)?.specifier;return s?s=i.get(o).specifier:(s=`_S${i.size}`,i.set(o,{identifier:e.identifier,specifier:s})),s}function Sa(e){if(e.size===0)return``;let t=[];for(let[n,r]of e){let[e]=n.split(`::`);t.push(`import type { ${r.identifier} as ${r.specifier} } from '${e}'`)}return t.join(`
3915
3915
  `)+`
3916
- `}function xa(e,t,n){if(e===null)return`unknown`;let r=x(n);if(e===``){let e=C(r,t).split(oe).join(`/`);return e=e.replace(/\.(ts|tsx|mts|cts)$/i,``),e.startsWith(`.`)||(e=`./`+e),e}if(!e.startsWith(`.`)&&!e.startsWith(`/`))return e;let i=C(r,w(x(t),e)).split(oe).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),i}const Sa=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:Ca(e),cwd:e.cwd,envFile:wa(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=b.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return ga(t.routes,r,n)}});function Ca(e){return b.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function wa(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function Ta(e,t){if(!e)return null;let n=C(x(t),e.filePath).split(oe).join(`/`);return n=n.replace(/\.(ts|tsx|mts|cts)$/i,``),n.startsWith(`.`)||(n=`./`+n),`/* eslint-disable */
3916
+ `}function Ca(e,t,n){if(e===null)return`unknown`;let r=x(n);if(e===``){let e=C(r,t).split(oe).join(`/`);return e=e.replace(/\.(ts|tsx|mts|cts)$/i,``),e.startsWith(`.`)||(e=`./`+e),e}if(!e.startsWith(`.`)&&!e.startsWith(`/`))return e;let i=C(r,w(x(t),e)).split(oe).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),i}const wa=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:Ta(e),cwd:e.cwd,envFile:Ea(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=b.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return va(t.routes,r,n)}});function Ta(e){return b.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Ea(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function Da(e,t){if(!e)return null;let n=C(x(t),e.filePath).split(oe).join(`/`);return n=n.replace(/\.(ts|tsx|mts|cts)$/i,``),n.startsWith(`.`)||(n=`./`+n),`/* eslint-disable */
3917
3917
  // AUTO-GENERATED by \`kick typegen\`. DO NOT EDIT.
3918
3918
  // Re-run with \`kick typegen\` or rely on \`kick dev\` to refresh.
3919
3919
 
@@ -3949,4 +3949,4 @@ declare global {
3949
3949
  }
3950
3950
 
3951
3951
  export {}
3952
- `}const Ea=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=Oa(e);if(t===!1)return null;let n=await e.getScanResult({root:Da(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=b.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return Ta(n.env,r)}});function Da(e){return b.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Oa(e){return e.config?.typegen?.envFile}var ka=e({builtinCliPlugins:()=>Aa});const Aa=[o({name:`kick/init`,register:Pt}),o({name:`kick/generate`,register:Ur}),o({name:`kick/run`,register:ni}),o({name:`kick/info`,register:ri}),o({name:`kick/inspect`,register:pi}),o({name:`kick/add`,register:Mt}),o({name:`kick/list`,register:jt}),o({name:`kick/explain`,register:Ci}),o({name:`kick/mcp`,register:Pi}),o({name:`kick/tinker`,register:Ri}),o({name:`kick/remove`,register:Wi}),o({name:`kick/typegen`,register:qi}),o({name:`kick/check`,register:aa}),o({name:`kick/db`,register:sa,typegens:[da()]}),o({name:`kick/codemod`,register:la}),o({name:`kick/assets`,typegens:[ma()]}),o({name:`kick/routes`,typegens:[Sa()]}),o({name:`kick/env`,typegens:[Ea()]})];export{Me as i,ka as n,qr as r,Aa as t};
3952
+ `}const Oa=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=Aa(e);if(t===!1)return null;let n=await e.getScanResult({root:ka(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=b.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return Da(n.env,r)}});function ka(e){return b.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Aa(e){return e.config?.typegen?.envFile}var ja=e({builtinCliPlugins:()=>Ma});const Ma=[o({name:`kick/init`,register:Ft}),o({name:`kick/generate`,register:Wr}),o({name:`kick/run`,register:ri}),o({name:`kick/info`,register:ii}),o({name:`kick/inspect`,register:mi}),o({name:`kick/add`,register:Nt}),o({name:`kick/list`,register:Mt}),o({name:`kick/explain`,register:wi}),o({name:`kick/mcp`,register:Fi}),o({name:`kick/tinker`,register:zi}),o({name:`kick/remove`,register:Gi}),o({name:`kick/typegen`,register:Ji}),o({name:`kick/check`,register:oa}),o({name:`kick/db`,register:la,typegens:[pa()]}),o({name:`kick/codemod`,register:da}),o({name:`kick/assets`,typegens:[ga()]}),o({name:`kick/routes`,typegens:[wa()]}),o({name:`kick/env`,typegens:[Oa()]})];export{Ne as i,ja as n,Jr as r,Ma as t};