@forinda/kickjs-cli 5.9.1 → 5.10.1

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 (29) hide show
  1. package/dist/{agent-docs-CxuUgXF_.mjs → agent-docs-D1k73ywL.mjs} +3 -3
  2. package/dist/{agent-docs-CxuUgXF_.mjs.map → agent-docs-D1k73ywL.mjs.map} +1 -1
  3. package/dist/{builtins-yDCsD2ae.mjs → builtins-DsO7X7g9.mjs} +2 -2
  4. package/dist/cli.mjs +262 -164
  5. package/dist/{config-icjz-b4f.mjs → config-BnCPYsQu.mjs} +3 -3
  6. package/dist/config-BnCPYsQu.mjs.map +1 -0
  7. package/dist/{doctor-BrkA44Gz.mjs → doctor-Brw2ruus.mjs} +126 -30
  8. package/dist/doctor-Brw2ruus.mjs.map +1 -0
  9. package/dist/index.d.mts +11 -5
  10. package/dist/index.d.mts.map +1 -1
  11. package/dist/index.mjs +2 -2
  12. package/dist/{plugin-CdC5d4kw.mjs → plugin-0_cDz8hu.mjs} +3 -3
  13. package/dist/{plugin-CdC5d4kw.mjs.map → plugin-0_cDz8hu.mjs.map} +1 -1
  14. package/dist/{project-docs-LqGoslXZ.mjs → project-docs-Bh20nvAP.mjs} +2 -2
  15. package/dist/{project-docs-LqGoslXZ.mjs.map → project-docs-Bh20nvAP.mjs.map} +1 -1
  16. package/dist/{project-root-CM9jhMiW.mjs → project-root-B7_vpWeX.mjs} +3 -3
  17. package/dist/{project-root-CM9jhMiW.mjs.map → project-root-B7_vpWeX.mjs.map} +1 -1
  18. package/dist/{rolldown-runtime-My-8F9u3.mjs → rolldown-runtime-C3T7GIRR.mjs} +1 -1
  19. package/dist/{run-plugins-B3Ooiczg.mjs → run-plugins-w_kqfVLL.mjs} +14 -12
  20. package/dist/run-plugins-w_kqfVLL.mjs.map +1 -0
  21. package/dist/{typegen-Cd0w7Al-.mjs → typegen-CFtS0A1P.mjs} +5 -5
  22. package/dist/typegen-CFtS0A1P.mjs.map +1 -0
  23. package/dist/{types-Dry-y2AZ.mjs → types-CkZ7XoFJ.mjs} +2 -2
  24. package/dist/{types-Dry-y2AZ.mjs.map → types-CkZ7XoFJ.mjs.map} +1 -1
  25. package/package.json +10 -10
  26. package/dist/config-icjz-b4f.mjs.map +0 -1
  27. package/dist/doctor-BrkA44Gz.mjs.map +0 -1
  28. package/dist/run-plugins-B3Ooiczg.mjs.map +0 -1
  29. package/dist/typegen-Cd0w7Al-.mjs.map +0 -1
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v5.9.1
2
+ * @forinda/kickjs-cli v5.10.1
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{createRequire as e}from"node:module";import{Command as t}from"commander";import{cpSync as n,existsSync as r,mkdirSync as i,readFileSync as a,readdirSync as o,rmSync as s,statSync as c,writeFileSync as l}from"node:fs";import u,{basename as d,dirname as f,extname as p,isAbsolute as m,join as h,parse as g,relative as _,resolve as v,sep as y}from"node:path";import{fileURLToPath as b,pathToFileURL as x}from"node:url";import{execFileSync as ee,execSync as S,fork as te,spawn as ne,spawnSync as re}from"node:child_process";import{access as ie,copyFile as ae,mkdir as oe,readFile as C,readdir as se,rm as ce,stat as le,unlink as ue,writeFile as w}from"node:fs/promises";import*as T from"@clack/prompts";import E from"picocolors";import de from"pluralize";import{glob as fe,globSync as pe}from"glob";import{groupAssetKeys as me}from"@forinda/kickjs";import{arch as he,platform as ge,release as _e}from"node:os";import{detectCompositeReferences as ve,generate as ye,migrateDown as be,migrateLatest as xe,migrateRollback as Se,migrateStatus as Ce,migrateUp as we,renderSchemaSource as Te,resolveDbConfig as Ee}from"@forinda/kickjs-db";var De=Object.defineProperty,D=(e,t)=>{let n={};for(var r in e)De(n,r,{get:e[r],enumerable:!0});return t||De(n,Symbol.toStringTag,{value:`Module`}),n};function Oe(e,t,n){S(e,{cwd:t,stdio:`inherit`,env:n?{...process.env,...n}:process.env})}function ke(e,t,n){let r=re(process.execPath,[e],{cwd:n,stdio:`inherit`,env:{...process.env,...t}});r.status!==0&&process.exit(r.status??1)}function Ae(e,t){if(!t?.commands?.length)return;let n=new Set(e.commands.map(e=>e.name()));for(let r of t.commands){if(n.has(r.name)){console.warn(` Warning: custom command '${r.name}' skipped — conflicts with a built-in command`);continue}je(e,r)}}function je(e,t){let n=e.command(t.name).description(t.description);if(t.aliases)for(let e of t.aliases)n.alias(e);n.allowUnknownOption(!0),n.argument(`[args...]`,`Additional arguments passed to the command`),n.action(e=>{let n=e.join(` `),r=Array.isArray(t.steps)?t.steps:[t.steps];for(let e of r){let r=n?`${e} ${n}`:e;console.log(` $ ${r}`);try{Oe(r)}catch{console.error(` Command failed: ${t.name}`),process.exitCode=1;return}}})}var Me=D({BUILTIN_REPO_TYPES:()=>Pe,PACKAGE_MANAGERS:()=>Ne,defineConfig:()=>Fe,loadKickConfig:()=>k,resolveModuleConfig:()=>O,resolveTokenScope:()=>Ie,validateAssetMap:()=>ze});const Ne=[`pnpm`,`npm`,`yarn`,`bun`],Pe=[`drizzle`,`inmemory`,`prisma`];function Fe(e){return e}function Ie(e,t){if(e?.tokenScope&&typeof e.tokenScope==`string`&&e.tokenScope.length>0){let t=Le(e.tokenScope);if(t.length>0)return t}try{let e=h(t,`package.json`);if(r(e)){let t=JSON.parse(a(e,`utf-8`));if(typeof t.name==`string`&&t.name.length>0){let e=t.name.match(/^@([^/]+)\//),n=Le(e?e[1]:t.name);if(n.length>0)return n}}}catch{}return`app`}function Le(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,`-`).replace(/^-+|-+$/g,``).replace(/-{2,}/g,`-`)}function O(e){if(!e)return{};let t={dir:e.modules?.dir,repo:e.modules?.repo,schemaDir:e.modules?.schemaDir,pluralize:e.modules?.pluralize,prismaClientPath:e.modules?.prismaClientPath,style:e.modules?.style};return t.style!==void 0&&t.style!==`define`&&t.style!==`class`&&(console.warn(` Warning: modules.style '${t.style}' is not a valid value (expected 'define' or 'class'). Falling back to 'define'.`),t.style=`define`),t.repo&&typeof t.repo==`string`&&!Pe.includes(t.repo)&&console.warn(` Warning: modules.repo '${t.repo}' is not a built-in type (${Pe.join(`, `)}). It will generate a stub repository. Use { name: '${t.repo}' } to silence this warning.`),t}const Re=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];async function k(e){let{findProjectRoot:t}=await Promise.resolve().then(()=>Xt),n=t(e);for(let e of Re){let t=h(n,e);try{await ie(t)}catch{continue}if(e.endsWith(`.json`)){let e=await C(t,`utf-8`);return JSON.parse(e)}if(e.endsWith(`.ts`)){let r;try{r=await import(`jiti`)}catch(t){let n=t instanceof Error?t.message:String(t);n.includes(`Cannot find package 'jiti'`)||n.includes(`ERR_MODULE_NOT_FOUND`)?console.warn(`Warning: Failed to load ${e} — 'jiti' is required for TypeScript configs. Run \`pnpm add -D jiti\` (or your package manager's equivalent), or rename the file to kick.config.js / kick.config.mjs / kick.config.json.`):console.warn(`Warning: Failed to initialize jiti for ${e}: ${n}`);continue}try{let e=await r.createJiti(n,{interopDefault:!0,fsCache:!1}).import(t,{default:!0}),i=ze(e,n);for(let e of i)console.warn(` Warning: ${e}`);return e}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Warning: Failed to load ${e}: ${n}`);continue}}try{let{pathToFileURL:e}=await import(`node:url`),r=await import(e(t).href),i=r.default??r,a=ze(i,n);for(let e of a)console.warn(` Warning: ${e}`);return i}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Warning: Failed to load ${e}: ${n}`);continue}}return null}function ze(e,t){let n=[];if(!e?.assetMap)return n;let i=v(t);for(let[a,o]of Object.entries(e.assetMap)){if(!a||a.includes(`/`)){n.push(`assetMap key '${a}' is invalid — must be a non-empty string without '/'`);continue}if(typeof o?.src!=`string`||o.src.length===0){n.push(`assetMap.${a} is missing a non-empty 'src' field`);continue}r(v(t,o.src))||n.push(`assetMap.${a}.src ('${o.src}') does not exist — typegen + build will fail`),o.dest&&Be(v(t,o.dest),i)&&n.push(`assetMap.${a}.dest ('${o.dest}') resolves outside the project root — refusing to copy`)}return n}function Be(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function A(e){return e}var Ve=class extends Error{constructor(e,t,n){super(`Two plugins registered the same ${e} '${t}': ${n.join(`, `)}. Plugins must use unique ${e} names.`),this.name=`KickPluginConflictError`}};function He(e,t=[]){let n=new Map;for(let t of e){let e=(n.get(t.name)??0)+1;if(n.set(t.name,e),e===2)throw new Ve(`plugin`,t.name,[t.name,t.name])}let r=new Map,i=[];for(let t of e)for(let e of t.commands??[]){let n=r.get(e.name);if(n)throw new Ve(`command`,e.name,[n,t.name]);r.set(e.name,t.name),i.push(e)}let a=new Set(t.map(e=>e.name)),o=[...i.filter(e=>!a.has(e.name)),...t],s=new Map,c=[];for(let t of e)for(let e of t.typegens??[]){let n=s.get(e.id);if(n)throw new Ve(`typegen`,e.id,[n,t.name]);s.set(e.id,t.name),c.push(e)}let l=new Map,u=[];for(let t of e)for(let e of t.generators??[]){let n=l.get(e.name);if(n)throw new Ve(`generator`,e.name,[n,t.name]);l.set(e.name,t.name),u.push({source:t.name,spec:e})}return{commands:o,typegens:c,generators:u,register:async(t,n)=>{let r;if(n)r={generators:u,...n};else{let{findProjectRoot:e}=await Promise.resolve().then(()=>Xt),t=process.cwd();r={cwd:t,projectRoot:e(t),config:null,log:()=>{},generators:u}}for(let n of e)n.register&&await n.register(t,r)}}}var Ue=D({mergeCliPlugins:()=>He});let We=!1;function j(e){We=e}const Ge=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`,`.md`]);async function M(e,t){We||(await oe(f(e),{recursive:!0}),await w(e,t,`utf-8`),Ge.has(p(e))&&await Je(e,t).catch(()=>{}))}let Ke;async function qe(t){if(Ke!==void 0)return Ke;try{Ke=await import(e(h(t,`package.json`)).resolve(`oxfmt`))}catch{Ke=null}return Ke}async function Je(e,t){let n=await qe(process.cwd());if(!n)return;let r=await Xe(e);if(r===null)return;let i=await n.format(e,t,r);i.code!==t&&await w(e,i.code,`utf-8`)}const Ye=new Map;async function Xe(e){let t=f(e),n=t;if(Ye.has(n))return Ye.get(n);for(;;){let e=h(t,`.oxfmtrc.json`);if(r(e))try{let t=await C(e,`utf-8`),r=JSON.parse(t);return delete r.$schema,delete r.ignorePatterns,Ye.set(n,r),r}catch{return Ye.set(n,null),null}let i=f(t);if(i===t)return Ye.set(n,null),null;t=i}}async function Ze(e){try{return await ie(e),!0}catch{return!1}}const Qe={swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`};function $e(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 et(e,t,n,r=[]){let i={"@forinda/kickjs":$e(n,`@forinda/kickjs`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,zod:`^4.3.6`};for(let e of r){let t=Qe[e];t&&!i[t]&&(i[t]=$e(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":$e(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":$e(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 tt(){return`import { defineConfig } from 'vite'
11
+ import{createRequire as e}from"node:module";import{Command as t}from"commander";import{cpSync as n,existsSync as r,mkdirSync as i,readFileSync as a,readdirSync as o,rmSync as s,statSync as c,writeFileSync as l}from"node:fs";import u,{basename as d,dirname as f,extname as p,isAbsolute as m,join as h,parse as g,relative as _,resolve as v,sep as y}from"node:path";import{fileURLToPath as b,pathToFileURL as x}from"node:url";import{execFileSync as ee,execSync as S,fork as te,spawn as ne,spawnSync as re}from"node:child_process";import{access as ie,copyFile as ae,mkdir as oe,readFile as C,readdir as se,rm as ce,stat as le,unlink as ue,writeFile as w}from"node:fs/promises";import*as T from"@clack/prompts";import E from"picocolors";import de from"pluralize";import{glob as fe,globSync as pe}from"glob";import{groupAssetKeys as me}from"@forinda/kickjs";import{arch as he,platform as ge,release as _e}from"node:os";import{detectCompositeReferences as ve,generate as ye,migrateDown as be,migrateLatest as xe,migrateRollback as Se,migrateStatus as Ce,migrateUp as we,renderSchemaSource as Te,resolveDbConfig as Ee}from"@forinda/kickjs-db";var De=Object.defineProperty,D=(e,t)=>{let n={};for(var r in e)De(n,r,{get:e[r],enumerable:!0});return t||De(n,Symbol.toStringTag,{value:`Module`}),n};function Oe(e,t,n){S(e,{cwd:t,stdio:`inherit`,env:n?{...process.env,...n}:process.env})}function ke(e,t,n){let r=re(process.execPath,[e],{cwd:n,stdio:`inherit`,env:{...process.env,...t}});r.status!==0&&process.exit(r.status??1)}function Ae(e,t){if(!t?.commands?.length)return;let n=new Set(e.commands.map(e=>e.name()));for(let r of t.commands){if(n.has(r.name)){console.warn(` Warning: custom command '${r.name}' skipped — conflicts with a built-in command`);continue}je(e,r)}}function je(e,t){let n=e.command(t.name).description(t.description);if(t.aliases)for(let e of t.aliases)n.alias(e);n.allowUnknownOption(!0),n.argument(`[args...]`,`Additional arguments passed to the command`),n.action(e=>{let n=e.join(` `),r=Array.isArray(t.steps)?t.steps:[t.steps];for(let e of r){let r=n?`${e} ${n}`:e;console.log(` $ ${r}`);try{Oe(r)}catch{console.error(` Command failed: ${t.name}`),process.exitCode=1;return}}})}var Me=D({BUILTIN_REPO_TYPES:()=>Pe,PACKAGE_MANAGERS:()=>Ne,defineConfig:()=>Fe,loadKickConfig:()=>k,resolveModuleConfig:()=>O,resolveTokenScope:()=>Ie,validateAssetMap:()=>ze});const Ne=[`pnpm`,`npm`,`yarn`,`bun`],Pe=[`drizzle`,`inmemory`,`prisma`];function Fe(e){return e}function Ie(e,t){if(e?.tokenScope&&typeof e.tokenScope==`string`&&e.tokenScope.length>0){let t=Le(e.tokenScope);if(t.length>0)return t}try{let e=h(t,`package.json`);if(r(e)){let t=JSON.parse(a(e,`utf-8`));if(typeof t.name==`string`&&t.name.length>0){let e=t.name.match(/^@([^/]+)\//),n=Le(e?e[1]:t.name);if(n.length>0)return n}}}catch{}return`app`}function Le(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,`-`).replace(/^-+|-+$/g,``).replace(/-{2,}/g,`-`)}function O(e){if(!e)return{};let t={dir:e.modules?.dir,repo:e.modules?.repo,schemaDir:e.modules?.schemaDir,pluralize:e.modules?.pluralize,prismaClientPath:e.modules?.prismaClientPath,style:e.modules?.style};return t.style!==void 0&&t.style!==`define`&&t.style!==`class`&&(console.warn(` Warning: modules.style '${t.style}' is not a valid value (expected 'define' or 'class'). Falling back to 'define'.`),t.style=`define`),t.repo&&typeof t.repo==`string`&&!Pe.includes(t.repo)&&console.warn(` Warning: modules.repo '${t.repo}' is not a built-in type (${Pe.join(`, `)}). It will generate a stub repository. Use { name: '${t.repo}' } to silence this warning.`),t}const Re=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];async function k(e){let{findProjectRoot:t}=await Promise.resolve().then(()=>Zt),n=t(e);for(let e of Re){let t=h(n,e);try{await ie(t)}catch{continue}if(e.endsWith(`.json`)){let e=await C(t,`utf-8`);return JSON.parse(e)}if(e.endsWith(`.ts`)){let r;try{r=await import(`jiti`)}catch(t){let n=t instanceof Error?t.message:String(t);n.includes(`Cannot find package 'jiti'`)||n.includes(`ERR_MODULE_NOT_FOUND`)?console.warn(`Warning: Failed to load ${e} — 'jiti' is required for TypeScript configs. Run \`pnpm add -D jiti\` (or your package manager's equivalent), or rename the file to kick.config.js / kick.config.mjs / kick.config.json.`):console.warn(`Warning: Failed to initialize jiti for ${e}: ${n}`);continue}try{let e=await r.createJiti(n,{interopDefault:!0,fsCache:!1}).import(t,{default:!0}),i=ze(e,n);for(let e of i)console.warn(` Warning: ${e}`);return e}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Warning: Failed to load ${e}: ${n}`);continue}}try{let{pathToFileURL:e}=await import(`node:url`),r=await import(e(t).href),i=r.default??r,a=ze(i,n);for(let e of a)console.warn(` Warning: ${e}`);return i}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Warning: Failed to load ${e}: ${n}`);continue}}return null}function ze(e,t){let n=[];if(!e?.assetMap)return n;let i=v(t);for(let[a,o]of Object.entries(e.assetMap)){if(!a||a.includes(`/`)){n.push(`assetMap key '${a}' is invalid — must be a non-empty string without '/'`);continue}if(typeof o?.src!=`string`||o.src.length===0){n.push(`assetMap.${a} is missing a non-empty 'src' field`);continue}r(v(t,o.src))||n.push(`assetMap.${a}.src ('${o.src}') does not exist — typegen + build will fail`),o.dest&&Be(v(t,o.dest),i)&&n.push(`assetMap.${a}.dest ('${o.dest}') resolves outside the project root — refusing to copy`)}return n}function Be(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function A(e){return e}var Ve=class extends Error{constructor(e,t,n){super(`Two plugins registered the same ${e} '${t}': ${n.join(`, `)}. Plugins must use unique ${e} names.`),this.name=`KickPluginConflictError`}};function He(e,t=[]){let n=new Map;for(let t of e){let e=(n.get(t.name)??0)+1;if(n.set(t.name,e),e===2)throw new Ve(`plugin`,t.name,[t.name,t.name])}let r=new Map,i=[];for(let t of e)for(let e of t.commands??[]){let n=r.get(e.name);if(n)throw new Ve(`command`,e.name,[n,t.name]);r.set(e.name,t.name),i.push(e)}let a=new Set(t.map(e=>e.name)),o=[...i.filter(e=>!a.has(e.name)),...t],s=new Map,c=[];for(let t of e)for(let e of t.typegens??[]){let n=s.get(e.id);if(n)throw new Ve(`typegen`,e.id,[n,t.name]);s.set(e.id,t.name),c.push(e)}let l=new Map,u=[];for(let t of e)for(let e of t.generators??[]){let n=l.get(e.name);if(n)throw new Ve(`generator`,e.name,[n,t.name]);l.set(e.name,t.name),u.push({source:t.name,spec:e})}return{commands:o,typegens:c,generators:u,register:async(t,n)=>{let r;if(n)r={generators:u,...n};else{let{findProjectRoot:e}=await Promise.resolve().then(()=>Zt),t=process.cwd();r={cwd:t,projectRoot:e(t),config:null,log:()=>{},generators:u}}for(let n of e)n.register&&await n.register(t,r)}}}var Ue=D({mergeCliPlugins:()=>He});let We=!1;function j(e){We=e}const Ge=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`,`.md`]);async function M(e,t){We||(await oe(f(e),{recursive:!0}),await w(e,t,`utf-8`),Ge.has(p(e))&&await Je(e,t).catch(()=>{}))}let Ke;async function qe(t){if(Ke!==void 0)return Ke;try{Ke=await import(e(h(t,`package.json`)).resolve(`oxfmt`))}catch{Ke=null}return Ke}async function Je(e,t){let n=await qe(process.cwd());if(!n)return;let r=await Xe(e);if(r===null)return;let i=await n.format(e,t,r);i.code!==t&&await w(e,i.code,`utf-8`)}const Ye=new Map;async function Xe(e){let t=f(e),n=t;if(Ye.has(n))return Ye.get(n);for(;;){let e=h(t,`.oxfmtrc.json`);if(r(e))try{let t=await C(e,`utf-8`),r=JSON.parse(t);return delete r.$schema,delete r.ignorePatterns,Ye.set(n,r),r}catch{return Ye.set(n,null),null}let i=f(t);if(i===t)return Ye.set(n,null),null;t=i}}async function Ze(e){try{return await ie(e),!0}catch{return!1}}const Qe={swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`},$e={zod:{name:`zod`,range:`^4.3.6`},valibot:{name:`valibot`,range:`^1.4.1`},yup:{name:`yup`,range:`^1.7.1`}};function et(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 tt(e,t,n,r=[],i=`zod`){let a=$e[i],o={"@forinda/kickjs":et(n,`@forinda/kickjs`),"@forinda/kickjs-schema":et(n,`@forinda/kickjs-schema`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,[a.name]:a.range};for(let e of r){let t=Qe[e];t&&!o[t]&&(o[t]=et(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:o,devDependencies:{"@forinda/kickjs-cli":et(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":et(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 nt(){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'
@@ -38,7 +38,7 @@ export default defineConfig({
38
38
  },
39
39
  },
40
40
  })
41
- `}function nt(){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 rt(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function it(){return`# https://editorconfig.org
41
+ `}function rt(){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 it(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function at(){return`# https://editorconfig.org
42
42
  root = true
43
43
 
44
44
  [*]
@@ -51,14 +51,14 @@ insert_final_newline = true
51
51
 
52
52
  [*.md]
53
53
  trim_trailing_whitespace = false
54
- `}function at(){return`node_modules/
54
+ `}function ot(){return`node_modules/
55
55
  dist/
56
56
  .env
57
57
  coverage/
58
58
  .DS_Store
59
59
  *.tsbuildinfo
60
60
  .kickjs/
61
- `}function ot(){return`# Auto-detect text files and normalise line endings to LF
61
+ `}function st(){return`# Auto-detect text files and normalise line endings to LF
62
62
  * text=auto eol=lf
63
63
 
64
64
  # Explicitly mark generated / binary files
@@ -76,11 +76,11 @@ coverage/
76
76
  pnpm-lock.yaml -diff linguist-generated
77
77
  yarn.lock -diff linguist-generated
78
78
  package-lock.json -diff linguist-generated
79
- `}function st(){return`PORT=3000
80
- NODE_ENV=development
81
79
  `}function ct(){return`PORT=3000
82
80
  NODE_ENV=development
83
- `}function lt(){return`import { defineConfig } from 'vitest/config'
81
+ `}function lt(){return`PORT=3000
82
+ NODE_ENV=development
83
+ `}function ut(){return`import { defineConfig } from 'vitest/config'
84
84
  import swc from 'unplugin-swc'
85
85
 
86
86
  export default defineConfig({
@@ -91,7 +91,7 @@ export default defineConfig({
91
91
  include: ['src/**/*.test.ts'],
92
92
  },
93
93
  })
94
- `}function ut(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'
94
+ `}function dt(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'
95
95
  // Side-effect import — registers the extended env schema with kickjs
96
96
  // **before** any controller / service / @Value gets resolved. Without
97
97
  // this line ConfigService.get('YOUR_KEY') returns undefined because the
@@ -161,31 +161,124 @@ export const app = await bootstrap({
161
161
  express.json(),
162
162
  ],
163
163
  })
164
- `}}}function dt(){return`import { defineModules } from '@forinda/kickjs'
164
+ `}}}function ft(){return`import { defineModules } from '@forinda/kickjs'
165
165
  import { HelloModule } from './hello/hello.module'
166
166
 
167
167
  // Remove HelloModule and run: kick g module <name>
168
168
  // \`defineModules()\` returns a chainable list — \`kick g module\` appends
169
169
  // \`.mount(NewModule())\` to the chain on every generation.
170
170
  export const modules = defineModules().mount(HelloModule())
171
- `}function ft(){return`import { defineEnv, loadEnv } from '@forinda/kickjs/config'
171
+ `}function pt(e=`zod`){return e===`valibot`?`import { loadEnvFromSchema } from '@forinda/kickjs/config'
172
+ import { fromValibot } from '@forinda/kickjs-schema/valibot'
173
+ import * as v from 'valibot'
174
+
175
+ /**
176
+ * Project environment schema (Valibot).
177
+ *
178
+ * \`fromValibot\` wraps the Valibot schema as a \`KickSchema\` so the
179
+ * env loader, validate middleware, and swagger spec generator all see
180
+ * the same shape. The default export is the contract \`kick typegen\`
181
+ * reads to populate \`KickEnv\` via \`InferSchemaOutput<typeof _envSchema>\`
182
+ * — that's what makes \`@Value('FOO')\` autocomplete and
183
+ * \`process.env.FOO\` typed.
184
+ *
185
+ * @example
186
+ * DATABASE_URL: v.pipe(v.string(), v.url()),
187
+ * JWT_SECRET: v.pipe(v.string(), v.minLength(32)),
188
+ * REDIS_URL: v.optional(v.pipe(v.string(), v.url())),
189
+ */
190
+ const envSchema = fromValibot(
191
+ v.object({
192
+ PORT: v.optional(v.pipe(v.string(), v.transform(Number)), '3000'),
193
+ NODE_ENV: v.optional(v.picklist(['development', 'production', 'test']), 'development'),
194
+ LOG_LEVEL: v.optional(v.string(), 'info'),
195
+ // DATABASE_URL: v.pipe(v.string(), v.url()),
196
+ }),
197
+ )
198
+
199
+ /**
200
+ * IMPORTANT — side effect: register the schema with kickjs's env cache
201
+ * **at module-load time**. \`ConfigService\` and \`@Value()\` both consume
202
+ * this cache, and they will fall back to the base schema (or undefined)
203
+ * if no extended schema has been registered before they're resolved.
204
+ *
205
+ * As long as \`src/index.ts\` imports this file (\`import './config'\`) at
206
+ * the top — before \`bootstrap()\` runs — every controller and service
207
+ * in the app sees the typed extended values.
208
+ */
209
+ export const env = loadEnvFromSchema(envSchema)
210
+
211
+ export default envSchema
212
+ `:e===`yup`?`import { loadEnvFromSchema } from '@forinda/kickjs/config'
213
+ import { fromYup } from '@forinda/kickjs-schema/yup'
214
+ import * as yup from 'yup'
215
+
216
+ /**
217
+ * Project environment schema (Yup).
218
+ *
219
+ * \`fromYup\` wraps the Yup schema as a \`KickSchema\` so the env loader,
220
+ * validate middleware, and swagger spec generator all see the same
221
+ * shape. The default export is the contract \`kick typegen\` reads to
222
+ * populate \`KickEnv\` via \`InferSchemaOutput<typeof _envSchema>\`.
223
+ *
224
+ * Note: Yup's \`.url()\` defaults to http/https; database connection
225
+ * strings like \`postgres://\` use \`.matches(/^[a-z]+:\\/\\/.+/i)\` or
226
+ * a plain \`.string().required()\`.
227
+ *
228
+ * @example
229
+ * DATABASE_URL: yup.string().required(),
230
+ * JWT_SECRET: yup.string().min(32).required(),
231
+ * REDIS_URL: yup.string().url().optional(),
232
+ */
233
+ const envSchema = fromYup(
234
+ yup.object({
235
+ PORT: yup.number().default(3000),
236
+ NODE_ENV: yup
237
+ .string()
238
+ .oneOf(['development', 'production', 'test'])
239
+ .default('development'),
240
+ LOG_LEVEL: yup.string().default('info'),
241
+ // DATABASE_URL: yup.string().required(),
242
+ }),
243
+ )
244
+
245
+ /**
246
+ * IMPORTANT — side effect: register the schema with kickjs's env cache
247
+ * **at module-load time**. \`ConfigService\` and \`@Value()\` both consume
248
+ * this cache, and they will fall back to the base schema (or undefined)
249
+ * if no extended schema has been registered before they're resolved.
250
+ *
251
+ * As long as \`src/index.ts\` imports this file (\`import './config'\`) at
252
+ * the top — before \`bootstrap()\` runs — every controller and service
253
+ * in the app sees the typed extended values.
254
+ */
255
+ export const env = loadEnvFromSchema(envSchema)
256
+
257
+ export default envSchema
258
+ `:`import { loadEnvFromSchema } from '@forinda/kickjs/config'
259
+ import { fromZod } from '@forinda/kickjs-schema/zod'
172
260
  import { z } from 'zod'
173
261
 
174
262
  /**
175
- * Project environment schema.
263
+ * Project environment schema (Zod).
176
264
  *
177
- * Extend the base schema with your application's variables. The
178
- * default export is the contract \`kick typegen\` reads to populate
179
- * the global \`KickEnv\` registry that's what makes \`@Value('FOO')\`
180
- * autocomplete and \`process.env.FOO\` typed.
265
+ * \`fromZod\` wraps the Zod schema as a \`KickSchema\` so the env loader,
266
+ * validate middleware, and swagger spec generator all see the same
267
+ * shape. The default export is the contract \`kick typegen\` reads to
268
+ * populate \`KickEnv\` via \`InferSchemaOutput<typeof _envSchema>\` —
269
+ * that's what makes \`@Value('FOO')\` autocomplete and
270
+ * \`process.env.FOO\` typed.
181
271
  *
182
272
  * @example
183
273
  * DATABASE_URL: z.string().url(),
184
274
  * JWT_SECRET: z.string().min(32),
185
275
  * REDIS_URL: z.string().url().optional(),
186
276
  */
187
- const envSchema = defineEnv((base) =>
188
- base.extend({
277
+ const envSchema = fromZod(
278
+ z.object({
279
+ PORT: z.coerce.number().default(3000),
280
+ NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
281
+ LOG_LEVEL: z.string().default('info'),
189
282
  // DATABASE_URL: z.string().url(),
190
283
  }),
191
284
  )
@@ -196,14 +289,14 @@ const envSchema = defineEnv((base) =>
196
289
  * this cache, and they will fall back to the base schema (or undefined)
197
290
  * if no extended schema has been registered before they're resolved.
198
291
  *
199
- * As long as \`src/index.ts\` imports this file (\`import './env'\`) at the
200
- * top — before \`bootstrap()\` runs — every controller and service in the
201
- * app sees the typed extended values.
292
+ * As long as \`src/index.ts\` imports this file (\`import './config'\`) at
293
+ * the top — before \`bootstrap()\` runs — every controller and service
294
+ * in the app sees the typed extended values.
202
295
  */
203
- export const env = loadEnv(envSchema)
296
+ export const env = loadEnvFromSchema(envSchema)
204
297
 
205
298
  export default envSchema
206
- `}function pt(){return`import { Service } from '@forinda/kickjs'
299
+ `}function mt(){return`import { Service } from '@forinda/kickjs'
207
300
 
208
301
  @Service()
209
302
  export class HelloService {
@@ -215,7 +308,7 @@ export class HelloService {
215
308
  return { status: 'ok', uptime: process.uptime() }
216
309
  }
217
310
  }
218
- `}function mt(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
311
+ `}function ht(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
219
312
  import { HelloService } from './hello.service'
220
313
 
221
314
  // \`Ctx<KickRoutes.HelloController['<method>']>\` is generated by
@@ -237,7 +330,7 @@ export class HelloController {
237
330
  ctx.json(this.helloService.healthCheck())
238
331
  }
239
332
  }
240
- `}function ht(){return`import { defineModule } from '@forinda/kickjs'
333
+ `}function gt(){return`import { defineModule } from '@forinda/kickjs'
241
334
  import { HelloController } from './hello.controller'
242
335
 
243
336
  export const HelloModule = defineModule({
@@ -258,7 +351,7 @@ export const HelloModule = defineModule({
258
351
  },
259
352
  }),
260
353
  })
261
- `}function gt(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
354
+ `}function _t(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
262
355
 
263
356
  export default defineConfig({
264
357
  pattern: '${e}',
@@ -273,9 +366,12 @@ export default defineConfig({
273
366
 
274
367
  // \`kick typegen\` populates \`.kickjs/types/\` so \`Ctx<KickRoutes.X['method']>\`
275
368
  // resolves to fully-typed params/body/query. Auto-runs on \`kick dev\`.
276
- // Set \`schemaValidator: false\` to skip schema-driven body typing entirely.
369
+ // \`'kickjs-schema'\` routes inference through \`InferSchemaOutput\` so the
370
+ // typegen works for any wrapped schema (Zod / Valibot / Yup). Switch
371
+ // to \`'zod'\` if you ship Zod schemas without \`fromZod()\` wrapping, or
372
+ // set \`schemaValidator: false\` to skip schema-driven body typing.
277
373
  typegen: {
278
- schemaValidator: 'zod',
374
+ schemaValidator: 'kickjs-schema',
279
375
  },
280
376
 
281
377
  commands: [
@@ -302,7 +398,7 @@ export default defineConfig({
302
398
  },
303
399
  ],
304
400
  })
305
- `}function _t(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}
401
+ `}function vt(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}
306
402
 
307
403
  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.
308
404
 
@@ -365,7 +461,7 @@ Copy \`.env.example\` to \`.env\` and configure:
365
461
 
366
462
  - [KickJS Documentation](https://forinda.github.io/kick-js/)
367
463
  - [CLI Reference](https://forinda.github.io/kick-js/api/cli.html)
368
- `}function vt(e,t,n){return`# CLAUDE.md — ${e}
464
+ `}function yt(e,t,n){return`# CLAUDE.md — ${e}
369
465
 
370
466
  **Read \`./.agents/AGENTS.md\` first.** It is the canonical, multi-agent
371
467
  reference for this project (Claude, Copilot, Codex, Gemini, etc.) —
@@ -439,7 +535,7 @@ When generating or modifying code in this project, stay aligned with the v4 conv
439
535
  - **Refresh these files**: \`kick g agents -f\` regenerates \`CLAUDE.md\` at the project root and \`.agents/AGENTS.md\` + \`.agents/GEMINI.md\` + \`.agents/COPILOT.md\` + every \`.agents/skills/<name>/SKILL.md\` from the latest CLI templates. Hand-edited content is overwritten — keep customisation in \`.agents/AGENTS.local.md\` or per-skill \`SKILL.local.md\` files alongside.
440
536
 
441
537
  For everything else (controllers, services, modules, RequestContext API, generators, CLI commands, package additions, env wiring, troubleshooting) → \`.agents/AGENTS.md\`.
442
- `}function yt(e,t,n){return`# AGENTS.md — AI Agent Guide for ${e}
538
+ `}function bt(e,t,n){return`# AGENTS.md — AI Agent Guide for ${e}
443
539
 
444
540
  This guide is the **canonical, multi-agent reference** for this KickJS
445
541
  application — Claude, Copilot, Codex, Gemini, etc. all read it first.
@@ -946,7 +1042,7 @@ ${t===`cqrs`?`### Background Jobs
946
1042
  - [Decorators Guide](https://forinda.github.io/kick-js/guide/decorators.html)
947
1043
  - [DI System](https://forinda.github.io/kick-js/guide/dependency-injection.html)
948
1044
  - [Testing](https://forinda.github.io/kick-js/api/testing.html)
949
- `}function bt(e,t,n){let r=`<!-- Generated by \`kick g agents\` for ${e}. Edits are overwritten on the next refresh; keep customisation in a SKILL.local.md alongside. -->`;return[{slug:`add-module`,frontmatterName:`kickjs-add-module`,description:`Use when the user asks to add a new feature module (controller + service + repo + DTOs).`,body:`**Trigger phrases**: "add a users module", "scaffold tasks", "new feature for X".
1045
+ `}function xt(e,t,n){let r=`<!-- Generated by \`kick g agents\` for ${e}. Edits are overwritten on the next refresh; keep customisation in a SKILL.local.md alongside. -->`;return[{slug:`add-module`,frontmatterName:`kickjs-add-module`,description:`Use when the user asks to add a new feature module (controller + service + repo + DTOs).`,body:`**Trigger phrases**: "add a users module", "scaffold tasks", "new feature for X".
950
1046
 
951
1047
  **Steps**:
952
1048
  1. Run \`kick g module <name>\` (use plural form if the project pluralizes — check \`kick.config.ts\`).
@@ -1081,7 +1177,7 @@ description: ${e.description}
1081
1177
  ${r}
1082
1178
 
1083
1179
  ${e.body}
1084
- `}))}function xt(e,t,n){return`# GEMINI.md — ${e}
1180
+ `}))}function St(e,t,n){return`# GEMINI.md — ${e}
1085
1181
 
1086
1182
  **Read \`./AGENTS.md\` first.** It is the canonical, multi-agent
1087
1183
  reference for this project — every convention, structure, decorator
@@ -1115,7 +1211,7 @@ without us copy-pasting.
1115
1211
  \`kick g agents --only gemini -f\` regenerates this file from the
1116
1212
  CLI template. Hand-edited content is overwritten — keep customisation
1117
1213
  in \`.agents/GEMINI.local.md\`.
1118
- `}function St(e,t,n){return`# COPILOT.md — ${e}
1214
+ `}function Ct(e,t,n){return`# COPILOT.md — ${e}
1119
1215
 
1120
1216
  **Read \`./AGENTS.md\` first.** It is the canonical, multi-agent
1121
1217
  reference for this project — every convention, structure, decorator
@@ -1148,16 +1244,16 @@ Codex / Cursor / Gemini / Claude Code without copy-pasting.
1148
1244
  \`kick g agents --only copilot -f\` regenerates this file from the
1149
1245
  CLI template. Hand-edited content is overwritten — keep customisation
1150
1246
  in \`.agents/COPILOT.local.md\`.
1151
- `}const Ct=f(b(import.meta.url)),wt=JSON.parse(a(h(Ct,`..`,`package.json`),`utf-8`)),Tt=`^${wt.version}`,Et=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-vite`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function Dt(){let e=await Promise.all(Et.map(async e=>{try{let t=ee(`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,Tt]}));return Object.fromEntries(e)}async function Ot(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 Dt();await M(h(s,`package.json`),et(t,i,l,o)),await M(h(s,`vite.config.ts`),tt()),await M(h(s,`tsconfig.json`),nt()),await M(h(s,`.prettierrc`),rt()),await M(h(s,`.editorconfig`),it()),await M(h(s,`.gitignore`),at()),await M(h(s,`.gitattributes`),ot()),await M(h(s,`.env`),st()),await M(h(s,`.env.example`),ct()),await M(h(s,`src/config/index.ts`),ft()),await M(h(s,`src/index.ts`),ut(t,i,wt.version,o)),await M(h(s,`src/modules/index.ts`),dt()),await M(h(s,`src/modules/hello/hello.service.ts`),pt()),await M(h(s,`src/modules/hello/hello.controller.ts`),mt()),await M(h(s,`src/modules/hello/hello.module.ts`),ht()),await M(h(s,`kick.config.ts`),gt(i,a,r)),await M(h(s,`vitest.config.ts`),lt()),await M(h(s,`README.md`),_t(t,i,r));let{generateAgentDocs:u}=await Promise.resolve().then(()=>_r);if(await u({outDir:s,name:t,pm:r,template:i,only:`all`,force:!0}),e.installDeps){console.log(`\n Installing dependencies with ${r}...\n`);try{S(`${r} install`,{cwd:s,stdio:`inherit`}),console.log(`
1152
- Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${r} install failed. Run it manually.`)}}try{let{runTypegen:e}=await Promise.resolve().then(()=>la);await e({cwd:s,allowDuplicates:!0,silent:!0})}catch{}if(e.initGit)try{S(`git init`,{cwd:s,stdio:`pipe`}),S(`git branch -M main`,{cwd:s,stdio:`pipe`}),S(`git add -A`,{cwd:s,stdio:`pipe`}),S(`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(`
1153
- Project scaffolded successfully!`),console.log();let d=s!==process.cwd();c(`Next steps:`),d&&c(` cd ${t}`),e.installDeps||c(` ${r} install`);let f={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(` ${f[i]??f.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 kt={GET:E.green,POST:E.cyan,PUT:E.yellow,PATCH:E.magenta,DELETE:E.red};function At(e){return(kt[e]??E.dim)(e.padEnd(7))}function jt(e){let t=`[${e}]`.padEnd(10);switch(e){case`CRITICAL`:return E.red(t);case`WARNING`:return E.yellow(t);case`INFO`:return E.blue(E.dim(t));default:return t}}E.green(`✓`),E.red(`✖`),E.yellow(`⚠`),E.blue(`ℹ`);function Mt(e){T.intro(E.bgCyan(E.black(` ${e} `)))}function N(e){T.outro(e)}function Nt(e){T.isCancel(e)&&(T.cancel(`Operation cancelled.`),process.exit(0))}async function Pt(e){let t=await T.text(e);return Nt(t),t}async function Ft(e){let t=await T.select(e);return Nt(t),t}async function It(e){let t=await T.multiselect(e);return Nt(t),t}async function P(e){let t=await T.confirm(e);return Nt(t),t}function Lt(){return T.spinner()}const F=T.log,Rt={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},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`},"queue:redis-pubsub":{pkg:`@forinda/kickjs-queue`,peers:[`ioredis`],description:`Lightweight pub/sub via Redis (no persistence)`},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 zt(e,t=process.cwd()){let n=t;for(;;){if(r(v(n,e)))return n;let t=f(n);if(t===n)return null;n=t}}function Bt(){return zt(`pnpm-lock.yaml`)?`pnpm`:zt(`yarn.lock`)?`yarn`:zt(`bun.lockb`)||zt(`bun.lock`)?`bun`:zt(`package-lock.json`)?`npm`:null}function Vt(){let e=process.cwd();for(;e;){let t=v(e,`package.json`);if(r(t))try{let e=JSON.parse(a(t,`utf-8`)).packageManager;if(typeof e==`string`){let t=e.split(`@`)[0];if(Ne.includes(t))return t}}catch{}let n=f(e);if(n===e)return null;e=n}return null}async function Ht(e){if(e&&Ne.includes(e))return{pm:e,source:`flag`};let t=await k(process.cwd());if(t?.packageManager&&Ne.includes(t.packageManager))return{pm:t.packageManager,source:`config`};let n=Vt();if(n)return{pm:n,source:`package.json`};let r=Bt();return r?{pm:r,source:`lockfile`}:{pm:`npm`,source:`default`}}async function Ut(e){let{pm:t}=await Ht(e);return t}function Wt(e=!1){let t=Object.entries(Rt),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(`
1247
+ `}const wt=f(b(import.meta.url)),Tt=JSON.parse(a(h(wt,`..`,`package.json`),`utf-8`)),Et=`^${Tt.version}`,Dt=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-schema`,`@forinda/kickjs-vite`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function Ot(){let e=await Promise.all(Dt.map(async e=>{try{let t=ee(`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,Et]}));return Object.fromEntries(e)}async function kt(e){let{name:t,directory:n,packageManager:r=`pnpm`,template:i=`rest`,defaultRepo:a=`inmemory`,packages:o=[],schemaLib:s=`zod`}=e,c=n,l=e=>console.log(` ${e}`);console.log(`\n Creating KickJS project: ${t}\n`),l(`Resolving package versions...`);let u=await Ot();await M(h(c,`package.json`),tt(t,i,u,o,s)),await M(h(c,`vite.config.ts`),nt()),await M(h(c,`tsconfig.json`),rt()),await M(h(c,`.prettierrc`),it()),await M(h(c,`.editorconfig`),at()),await M(h(c,`.gitignore`),ot()),await M(h(c,`.gitattributes`),st()),await M(h(c,`.env`),ct()),await M(h(c,`.env.example`),lt()),await M(h(c,`src/config/index.ts`),pt(s)),await M(h(c,`src/index.ts`),dt(t,i,Tt.version,o)),await M(h(c,`src/modules/index.ts`),ft()),await M(h(c,`src/modules/hello/hello.service.ts`),mt()),await M(h(c,`src/modules/hello/hello.controller.ts`),ht()),await M(h(c,`src/modules/hello/hello.module.ts`),gt()),await M(h(c,`kick.config.ts`),_t(i,a,r)),await M(h(c,`vitest.config.ts`),ut()),await M(h(c,`README.md`),vt(t,i,r));let{generateAgentDocs:d}=await Promise.resolve().then(()=>vr);if(await d({outDir:c,name:t,pm:r,template:i,only:`all`,force:!0}),e.installDeps){console.log(`\n Installing dependencies with ${r}...\n`);try{S(`${r} install`,{cwd:c,stdio:`inherit`}),console.log(`
1248
+ Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${r} install failed. Run it manually.`)}}try{let{runTypegen:e}=await Promise.resolve().then(()=>ua);await e({cwd:c,allowDuplicates:!0,silent:!0})}catch{}if(e.initGit)try{S(`git init`,{cwd:c,stdio:`pipe`}),S(`git branch -M main`,{cwd:c,stdio:`pipe`}),S(`git add -A`,{cwd:c,stdio:`pipe`}),S(`git commit -m "chore: initial commit from kick new"`,{cwd:c,stdio:`pipe`}),l(`Git repository initialized`)}catch{l(`Warning: git init failed (git may not be installed)`)}console.log(`
1249
+ Project scaffolded successfully!`),console.log();let f=c!==process.cwd();l(`Next steps:`),f&&l(` cd ${t}`),e.installDeps||l(` ${r} install`);let p={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`};l(` ${p[i]??p.rest}`),l(` kick dev`),l(``),l(`Commands:`),l(` kick dev Start dev server with Vite HMR`),l(` kick build Production build via Vite`),l(` kick start Run production build`),l(``),l(`Generators:`),l(` kick g module <name> Full DDD module (controller, DTOs, use-cases, repo)`),l(` kick g scaffold <n> <f..> CRUD module from field definitions`),l(` kick g controller <name> Standalone controller`),l(` kick g service <name> @Service() class`),l(` kick g middleware <name> Express middleware`),l(` kick g guard <name> Route guard (auth, roles, etc.)`),l(` kick g adapter <name> AppAdapter with lifecycle hooks`),l(` kick g dto <name> Zod DTO schema`),i===`cqrs`&&l(` kick g job <name> Queue job processor`),l(` kick g config Generate kick.config.ts`),l(``),l(`Add packages:`),l(` kick add <pkg> Install a KickJS package + peers`),l(` kick add --list Show all available packages`),l(``),l(`Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing`),l(``)}const At={GET:E.green,POST:E.cyan,PUT:E.yellow,PATCH:E.magenta,DELETE:E.red};function jt(e){return(At[e]??E.dim)(e.padEnd(7))}function Mt(e){let t=`[${e}]`.padEnd(10);switch(e){case`CRITICAL`:return E.red(t);case`WARNING`:return E.yellow(t);case`INFO`:return E.blue(E.dim(t));default:return t}}E.green(`✓`),E.red(`✖`),E.yellow(`⚠`),E.blue(`ℹ`);function Nt(e){T.intro(E.bgCyan(E.black(` ${e} `)))}function N(e){T.outro(e)}function Pt(e){T.isCancel(e)&&(T.cancel(`Operation cancelled.`),process.exit(0))}async function Ft(e){let t=await T.text(e);return Pt(t),t}async function It(e){let t=await T.select(e);return Pt(t),t}async function Lt(e){let t=await T.multiselect(e);return Pt(t),t}async function P(e){let t=await T.confirm(e);return Pt(t),t}function Rt(){return T.spinner()}const F=T.log,zt={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},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`},"queue:redis-pubsub":{pkg:`@forinda/kickjs-queue`,peers:[`ioredis`],description:`Lightweight pub/sub via Redis (no persistence)`},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 Bt(e,t=process.cwd()){let n=t;for(;;){if(r(v(n,e)))return n;let t=f(n);if(t===n)return null;n=t}}function Vt(){return Bt(`pnpm-lock.yaml`)?`pnpm`:Bt(`yarn.lock`)?`yarn`:Bt(`bun.lockb`)||Bt(`bun.lock`)?`bun`:Bt(`package-lock.json`)?`npm`:null}function Ht(){let e=process.cwd();for(;e;){let t=v(e,`package.json`);if(r(t))try{let e=JSON.parse(a(t,`utf-8`)).packageManager;if(typeof e==`string`){let t=e.split(`@`)[0];if(Ne.includes(t))return t}}catch{}let n=f(e);if(n===e)return null;e=n}return null}async function Ut(e){if(e&&Ne.includes(e))return{pm:e,source:`flag`};let t=await k(process.cwd());if(t?.packageManager&&Ne.includes(t.packageManager))return{pm:t.packageManager,source:`config`};let n=Ht();if(n)return{pm:n,source:`package.json`};let r=Vt();return r?{pm:r,source:`lockfile`}:{pm:`npm`,source:`default`}}async function Wt(e){let{pm:t}=await Ut(e);return t}function Gt(e=!1){let t=Object.entries(zt),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(`
1154
1250
  Core packages (always installed by \`kick new\`):
1155
1251
  `);for(let e of r)console.log(a(e));if(e){console.log(`
1156
1252
  Optional packages (add as needed):
1157
1253
  `);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(`
1158
- Usage: kick add auth drizzle swagger`),console.log(` kick add queue:bullmq`),console.log()}function Gt(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=>{Wt(!!e.all)})}function Kt(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){Wt(!!t.all);return}let{pm:n,source:r}=await Ht(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=Rt[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.
1254
+ Usage: kick add auth drizzle swagger`),console.log(` kick add queue:bullmq`),console.log()}function Kt(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=>{Gt(!!e.all)})}function qt(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){Gt(!!t.all);return}let{pm:n,source:r}=await Ut(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=zt[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.
1159
1255
  `),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{S(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{S(t,{stdio:`inherit`})}catch{console.log(`\n Installation failed. Run manually:\n ${t}\n`)}}console.log(` Done!
1160
- `)}})}const qt=[{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 Jt(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)=>{Mt(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await Pt({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let i;if(e===`.`?(i=v(`.`),e=d(i)):i=v(t.directory||e),r(i)){let r=o(i);if(r.length>0){if(t.force)F.warn(`Clearing existing files in ${i}`);else if(n){F.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),N(`Aborted.`);return}else{F.warn(`Directory "${e}" is not empty:`);let t=r.slice(0,5);for(let e of t)F.message(` - ${e}`);if(r.length>5&&F.message(` ... and ${r.length-5} more`),!await P({message:E.red(`Remove all existing files and proceed?`),initialValue:!1})){N(`Aborted.`);return}}for(let e of r)s(v(i,e),{recursive:!0,force:!0})}}let a=t.template;a||=n?`minimal`:await Ft({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 c=t.pm;c||=n?await Ut(void 0):await Ft({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let l=t.repo;l||(n?l=`inmemory`:(l=await Ft({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`}]}),l===`custom`&&(l=await Pt({message:`Custom repository name`,defaultValue:`custom`}))));let u;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();u=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else u=n?[]:await It({message:`Select packages to include`,options:[...qt],required:!1});let f;f=t.git===void 0?n?!0:await P({message:`Initialize git repository?`,initialValue:!0}):t.git;let p;p=t.install===void 0?n?!0:await P({message:`Install dependencies?`,initialValue:!0}):t.install,await Ot({name:e,directory:i,packageManager:c,initGit:f,installDeps:p,template:a,defaultRepo:l,packages:u}),N(`Done! Next steps: ${E.cyan(`cd ${e} && ${c} dev`)}`)})}function I(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function L(e){let t=I(e);return t.charAt(0).toLowerCase()+t.slice(1)}function R(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function z(e){return de.plural(e)}function Yt(e){return de.plural(e)}var Xt=D({findProjectRoot:()=>Qt});const Zt=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];function Qt(e=process.cwd()){let t=v(e),{root:n}=g(t),i=null,a=t;for(;;){for(let e of Zt)if(r(v(a,e)))return a;if(i===null&&r(v(a,`package.json`))&&(i=a),a===n)break;let e=f(a);if(e===a)break;a=e}return i??t}function $t(e){return R(e).replace(/-/g,`_`)}function en(e){let t=e.cwd??process.cwd(),n=e.projectRoot??Qt(t),r=e.pluralize??!0,i=I(e.name),a=L(e.name),o=R(e.name),s=$t(e.name),c={name:e.name,pascal:i,camel:a,kebab:o,snake:s,modulesDir:e.modulesDir??`src/modules`,cwd:t,projectRoot:n,args:e.args??[],flags:e.flags??{}};if(r){let e=z(o);c.pluralKebab=e,c.pluralPascal=I(e),c.pluralCamel=L(e)}return c}function tn(e,t){return v(e.cwd,t)}async function nn(e){return import(x(e).href)}const rn=new Map;async function an(e){let t=rn.get(e);if(t)return t;let n=on(e);return rn.set(e,n),n}async function on(t){let n=v(t,`package.json`);if(!r(n))return{generators:[],loaded:[],failed:[]};let i=sn(JSON.parse(await C(n,`utf-8`))),a=e(v(t,`package.json`)),o=[],s=[],c=[];for(let e of i){let t;try{t=a.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await C(t,`utf-8`))}catch(t){c.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let i=n.kickjs.generators,l=v(f(t),i);if(!r(l)){c.push({source:e,reason:`kickjs.generators points to missing file: ${i}`});continue}let u;try{u=await nn(l)}catch(t){c.push({source:e,reason:`failed to import manifest: ${t}`});continue}let d=u.default;if(!Array.isArray(d)){c.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of d){if(!cn(t)){c.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}o.push({source:e,spec:t})}s.push(e)}return{generators:o,loaded:s,failed:c}}function sn(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 cn(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function ln(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return fn(r.spec,r.source,e,n);let i=dn(await an(n),e.generatorName);return i?fn(i.spec,i.source,e,n):null}async function un(e,t=[]){let n=await an(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 dn(e,t){return e.generators.find(e=>e.spec.name===t)}async function fn(e,t,n,r){let i=en({name:n.itemName,args:n.args,flags:n.flags,modulesDir:n.modulesDir,pluralize:n.pluralize,cwd:r,projectRoot:n.projectRoot}),a=await e.files(i),o=[];for(let e of a){let t=tn(i,e.path);await M(t,e.content),o.push(t)}return{files:o,source:t}}function B(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const pn={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function mn(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function hn(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function gn(e){return pn[e]??mn(e)}function _n(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]??`${mn(n)}${e}Repository`,repoFile:i[n]??`${hn(n)}-${t}`}}function vn(e){return e??`define`}function yn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=_n(t,n,i),c=vn(a),l=`/**
1256
+ `)}})}const Jt=[{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 Yt(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(`-s, --schema <lib>`,`Schema library for env / DTOs: zod | valibot | yup (default: zod)`).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)=>{Nt(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await Ft({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let i;if(e===`.`?(i=v(`.`),e=d(i)):i=v(t.directory||e),r(i)){let r=o(i);if(r.length>0){if(t.force)F.warn(`Clearing existing files in ${i}`);else if(n){F.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),N(`Aborted.`);return}else{F.warn(`Directory "${e}" is not empty:`);let t=r.slice(0,5);for(let e of t)F.message(` - ${e}`);if(r.length>5&&F.message(` ... and ${r.length-5} more`),!await P({message:E.red(`Remove all existing files and proceed?`),initialValue:!1})){N(`Aborted.`);return}}for(let e of r)s(v(i,e),{recursive:!0,force:!0})}}let a=t.template;a||=n?`minimal`:await It({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 c=t.pm;c||=n?await Wt(void 0):await It({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let l=t.repo;l||(n?l=`inmemory`:(l=await It({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`}]}),l===`custom`&&(l=await Ft({message:`Custom repository name`,defaultValue:`custom`}))));let u=t.schema;u||=n?`zod`:await It({message:`Schema library (env + DTO validation)`,options:[{value:`zod`,label:`Zod`,hint:`default — broad ecosystem`},{value:`valibot`,label:`Valibot`,hint:`smaller bundle`},{value:`yup`,label:`Yup`,hint:`classic API`}]}),[`zod`,`valibot`,`yup`].includes(u)||(F.warn(`Unknown --schema "${u}", falling back to zod.`),u=`zod`);let f;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();f=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else f=n?[]:await Lt({message:`Select packages to include`,options:[...Jt],required:!1});let p;p=t.git===void 0?n?!0:await P({message:`Initialize git repository?`,initialValue:!0}):t.git;let m;m=t.install===void 0?n?!0:await P({message:`Install dependencies?`,initialValue:!0}):t.install,await kt({name:e,directory:i,packageManager:c,initGit:p,installDeps:m,template:a,defaultRepo:l,packages:f,schemaLib:u}),N(`Done! Next steps: ${E.cyan(`cd ${e} && ${c} dev`)}`)})}function I(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function L(e){let t=I(e);return t.charAt(0).toLowerCase()+t.slice(1)}function R(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function z(e){return de.plural(e)}function Xt(e){return de.plural(e)}var Zt=D({findProjectRoot:()=>$t});const Qt=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];function $t(e=process.cwd()){let t=v(e),{root:n}=g(t),i=null,a=t;for(;;){for(let e of Qt)if(r(v(a,e)))return a;if(i===null&&r(v(a,`package.json`))&&(i=a),a===n)break;let e=f(a);if(e===a)break;a=e}return i??t}function en(e){return R(e).replace(/-/g,`_`)}function tn(e){let t=e.cwd??process.cwd(),n=e.projectRoot??$t(t),r=e.pluralize??!0,i=I(e.name),a=L(e.name),o=R(e.name),s=en(e.name),c={name:e.name,pascal:i,camel:a,kebab:o,snake:s,modulesDir:e.modulesDir??`src/modules`,cwd:t,projectRoot:n,args:e.args??[],flags:e.flags??{}};if(r){let e=z(o);c.pluralKebab=e,c.pluralPascal=I(e),c.pluralCamel=L(e)}return c}function nn(e,t){return v(e.cwd,t)}async function rn(e){return import(x(e).href)}const an=new Map;async function on(e){let t=an.get(e);if(t)return t;let n=sn(e);return an.set(e,n),n}async function sn(t){let n=v(t,`package.json`);if(!r(n))return{generators:[],loaded:[],failed:[]};let i=cn(JSON.parse(await C(n,`utf-8`))),a=e(v(t,`package.json`)),o=[],s=[],c=[];for(let e of i){let t;try{t=a.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await C(t,`utf-8`))}catch(t){c.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let i=n.kickjs.generators,l=v(f(t),i);if(!r(l)){c.push({source:e,reason:`kickjs.generators points to missing file: ${i}`});continue}let u;try{u=await rn(l)}catch(t){c.push({source:e,reason:`failed to import manifest: ${t}`});continue}let d=u.default;if(!Array.isArray(d)){c.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of d){if(!ln(t)){c.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}o.push({source:e,spec:t})}s.push(e)}return{generators:o,loaded:s,failed:c}}function cn(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 ln(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function un(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return pn(r.spec,r.source,e,n);let i=fn(await on(n),e.generatorName);return i?pn(i.spec,i.source,e,n):null}async function dn(e,t=[]){let n=await on(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 fn(e,t){return e.generators.find(e=>e.spec.name===t)}async function pn(e,t,n,r){let i=tn({name:n.itemName,args:n.args,flags:n.flags,modulesDir:n.modulesDir,pluralize:n.pluralize,cwd:r,projectRoot:n.projectRoot}),a=await e.files(i),o=[];for(let e of a){let t=nn(i,e.path);await M(t,e.content),o.push(t)}return{files:o,source:t}}function B(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const mn={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function hn(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function gn(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function _n(e){return mn[e]??hn(e)}function vn(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]??`${hn(n)}${e}Repository`,repoFile:i[n]??`${gn(n)}-${t}`}}function yn(e){return e??`define`}function bn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=vn(t,n,i),c=yn(a),l=`/**
1161
1257
  * ${t} Module
1162
1258
  *
1163
1259
  * Self-contained feature module following Domain-Driven Design (DDD).
@@ -1167,7 +1263,7 @@ in \`.agents/COPILOT.local.md\`.
1167
1263
  * presentation/ — HTTP controllers (entry points)
1168
1264
  * application/ — Use cases (orchestration) and DTOs (validation)
1169
1265
  * domain/ — Entities, value objects, repository interfaces, domain services
1170
- * infrastructure/ — Repository implementations (currently ${gn(i)})
1266
+ * infrastructure/ — Repository implementations (currently ${_n(i)})
1171
1267
  */`,u=`import { ${t.toUpperCase()}_REPOSITORY } from './domain/repositories/${n}.repository'
1172
1268
  import { ${o} } from './infrastructure/repositories/${s}.repository'
1173
1269
  import { ${t}Controller } from './presentation/${n}.controller'
@@ -1201,7 +1297,7 @@ export class ${t}Module implements AppModule {
1201
1297
  /**
1202
1298
  * Register module dependencies in the DI container.
1203
1299
  * Bind repository interface tokens to their implementations here.
1204
- * Currently wired to ${gn(i)}. To swap implementations, change the factory target.
1300
+ * Currently wired to ${_n(i)}. To swap implementations, change the factory target.
1205
1301
  */
1206
1302
  register(container: Container): void {
1207
1303
  container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
@@ -1227,7 +1323,7 @@ export const ${t}Module = defineModule({
1227
1323
  /**
1228
1324
  * Register module dependencies in the DI container.
1229
1325
  * Bind repository interface tokens to their implementations here.
1230
- * Currently wired to ${gn(i)}. To swap implementations, change the factory target.
1326
+ * Currently wired to ${_n(i)}. To swap implementations, change the factory target.
1231
1327
  */
1232
1328
  register(container) {
1233
1329
  container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
@@ -1244,7 +1340,7 @@ ${d}
1244
1340
  },
1245
1341
  }),
1246
1342
  })
1247
- `}function bn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=_n(t,n,i),c=vn(a),l=`/**
1343
+ `}function xn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=vn(t,n,i),c=yn(a),l=`/**
1248
1344
  * ${t} Module
1249
1345
  *
1250
1346
  * REST module with a flat folder structure.
@@ -1316,7 +1412,7 @@ ${d}
1316
1412
  },
1317
1413
  }),
1318
1414
  })
1319
- `}function xn(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=vn(i),o=` /**
1415
+ `}function Sn(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=yn(i),o=` /**
1320
1416
  * Declare HTTP routes. Return value shape:
1321
1417
  *
1322
1418
  * - \`path\` — URL prefix for this route set.
@@ -1356,7 +1452,7 @@ ${o}
1356
1452
  },
1357
1453
  }),
1358
1454
  })
1359
- `}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'
1455
+ `}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'
1360
1456
  import { ApiTags } from '@forinda/kickjs-swagger'
1361
1457
  import { Create${t}UseCase } from '../application/use-cases/create-${n}.use-case'
1362
1458
  import { Get${t}UseCase } from '../application/use-cases/get-${n}.use-case'
@@ -1419,7 +1515,7 @@ export class ${t}Controller {
1419
1515
  ctx.noContent()
1420
1516
  }
1421
1517
  }
1422
- `}function Cn(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'
1518
+ `}function wn(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'
1423
1519
  import { ApiTags } from '@forinda/kickjs-swagger'
1424
1520
  import { ${t}Service } from './${n}.service'
1425
1521
  import { create${t}Schema } from './dtos/create-${n}.dto'
@@ -1474,14 +1570,14 @@ export class ${t}Controller {
1474
1570
  ctx.noContent()
1475
1571
  }
1476
1572
  }
1477
- `}function wn(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
1573
+ `}function Tn(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
1478
1574
 
1479
1575
  export const ${t.toUpperCase()}_QUERY_CONFIG: QueryParamsConfig = {
1480
1576
  filterable: ['name'],
1481
1577
  sortable: ['name', 'createdAt'],
1482
1578
  searchable: ['name'],
1483
1579
  }
1484
- `}function Tn(e){let{pascal:t}=e;return`import { z } from 'zod'
1580
+ `}function En(e){let{pascal:t}=e;return`import { z } from 'zod'
1485
1581
 
1486
1582
  /**
1487
1583
  * Create ${t} DTO — Zod schema for validating POST request bodies.
@@ -1497,20 +1593,20 @@ export const create${t}Schema = z.object({
1497
1593
  })
1498
1594
 
1499
1595
  export type Create${t}DTO = z.infer<typeof create${t}Schema>
1500
- `}function En(e){let{pascal:t}=e;return`import { z } from 'zod'
1596
+ `}function Dn(e){let{pascal:t}=e;return`import { z } from 'zod'
1501
1597
 
1502
1598
  export const update${t}Schema = z.object({
1503
1599
  name: z.string().min(1).max(200).optional(),
1504
1600
  })
1505
1601
 
1506
1602
  export type Update${t}DTO = z.infer<typeof update${t}Schema>
1507
- `}function Dn(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
1603
+ `}function On(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
1508
1604
  id: string
1509
1605
  name: string
1510
1606
  createdAt: string
1511
1607
  updatedAt: string
1512
1608
  }
1513
- `}function On(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
1609
+ `}function kn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
1514
1610
  * Create ${t} Use Case
1515
1611
  *
1516
1612
  * Application layer — orchestrates a single business operation.
@@ -1588,7 +1684,7 @@ export class Delete${t}UseCase {
1588
1684
  await this.repo.delete(id)
1589
1685
  }
1590
1686
  }
1591
- `}]}function kn(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
1687
+ `}]}function An(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
1592
1688
  * ${t} Repository Interface
1593
1689
  *
1594
1690
  * Defines the contract for data access.
@@ -1683,7 +1779,7 @@ export class InMemory${t}Repository implements I${t}Repository {
1683
1779
  this.store.delete(id)
1684
1780
  }
1685
1781
  }
1686
- `}function An(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`/**
1782
+ `}function jn(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`/**
1687
1783
  * ${o} ${t} Repository
1688
1784
  *
1689
1785
  * Stub implementation for a custom '${r}' repository.
@@ -1752,7 +1848,7 @@ export class ${o}${t}Repository implements I${t}Repository {
1752
1848
  this.store.delete(id)
1753
1849
  }
1754
1850
  }
1755
- `}function jn(e){let{pascal:t,kebab:n}=e;return`/**
1851
+ `}function Mn(e){let{pascal:t,kebab:n}=e;return`/**
1756
1852
  * ${t} Domain Service
1757
1853
  *
1758
1854
  * Domain layer — contains business rules that don't belong to a single entity.
@@ -1775,7 +1871,7 @@ export class ${t}DomainService {
1775
1871
  }
1776
1872
  }
1777
1873
  }
1778
- `}function Mn(e){let{pascal:t,kebab:n}=e;return`/**
1874
+ `}function Nn(e){let{pascal:t,kebab:n}=e;return`/**
1779
1875
  * ${t} Entity
1780
1876
  *
1781
1877
  * Domain layer — the core business object.
@@ -1844,7 +1940,7 @@ export class ${t} {
1844
1940
  }
1845
1941
  }
1846
1942
  }
1847
- `}function Nn(e){let{pascal:t}=e;return`/**
1943
+ `}function Pn(e){let{pascal:t}=e;return`/**
1848
1944
  * ${t} ID Value Object
1849
1945
  *
1850
1946
  * Domain layer — wraps a primitive ID with type safety and validation.
@@ -1878,7 +1974,7 @@ export class ${t}Id {
1878
1974
  return this.value === other.value
1879
1975
  }
1880
1976
  }
1881
- `}function Pn(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
1977
+ `}function Fn(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
1882
1978
  import { Container } from '@forinda/kickjs'
1883
1979
 
1884
1980
  describe('${t}Controller', () => {
@@ -1930,7 +2026,7 @@ describe('${t}Controller', () => {
1930
2026
  })
1931
2027
  })
1932
2028
  })
1933
- `}function Fn(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'
2029
+ `}function In(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'
1934
2030
  import { InMemory${t}Repository } from '${i}'
1935
2031
 
1936
2032
  describe('InMemory${t}Repository', () => {
@@ -1992,7 +2088,7 @@ describe('InMemory${t}Repository', () => {
1992
2088
  expect(found).toBeNull()
1993
2089
  })
1994
2090
  })
1995
- `}function In(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
2091
+ `}function Ln(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
1996
2092
  import type { ParsedQuery } from '@forinda/kickjs'
1997
2093
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from './${n}.repository'
1998
2094
  import type { ${t}ResponseDTO } from './dtos/${n}-response.dto'
@@ -2029,14 +2125,14 @@ export class ${t}Service {
2029
2125
  await this.repo.delete(id)
2030
2126
  }
2031
2127
  }
2032
- `}function Ln(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
2128
+ `}function Rn(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
2033
2129
 
2034
2130
  export const ${t.toUpperCase()}_QUERY_CONFIG: QueryFieldConfig = {
2035
2131
  filterable: ['name'],
2036
2132
  sortable: ['name', 'createdAt'],
2037
2133
  searchable: ['name'],
2038
2134
  }
2039
- `}function Rn(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=`/**
2135
+ `}function zn(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=`/**
2040
2136
  * ${t} Module — CQRS Pattern
2041
2137
  *
2042
2138
  * Separates read (queries) and write (commands) operations.
@@ -2115,7 +2211,7 @@ ${p}
2115
2211
  },
2116
2212
  }),
2117
2213
  })
2118
- `}function zn(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'
2214
+ `}function Bn(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'
2119
2215
  import { ApiTags } from '@forinda/kickjs-swagger'
2120
2216
  import { Create${t}Command } from './commands/create-${n}.command'
2121
2217
  import { Update${t}Command } from './commands/update-${n}.command'
@@ -2178,7 +2274,7 @@ export class ${t}Controller {
2178
2274
  ctx.noContent()
2179
2275
  }
2180
2276
  }
2181
- `}function Bn(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2277
+ `}function Vn(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2182
2278
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
2183
2279
  import type { Create${t}DTO } from '../dtos/create-${n}.dto'
2184
2280
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
@@ -2232,7 +2328,7 @@ export class Delete${t}Command {
2232
2328
  this.events.emit('${n}.deleted', { id })
2233
2329
  }
2234
2330
  }
2235
- `}]}function Vn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2331
+ `}]}function Hn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2236
2332
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
2237
2333
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
2238
2334
 
@@ -2260,7 +2356,7 @@ export class List${i}Query {
2260
2356
  return this.repo.findPaginated(parsed)
2261
2357
  }
2262
2358
  }
2263
- `}]}function Hn(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
2359
+ `}]}function Un(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
2264
2360
  import { EventEmitter } from 'node:events'
2265
2361
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
2266
2362
 
@@ -2346,7 +2442,7 @@ export class On${t}ChangeHandler {
2346
2442
  })
2347
2443
  }
2348
2444
  }
2349
- `}]}function Un(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
2445
+ `}]}function Wn(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
2350
2446
  * Drizzle ${t} Repository
2351
2447
  *
2352
2448
  * Implements the repository interface using Drizzle ORM.
@@ -2428,7 +2524,7 @@ export class Drizzle${t}Repository implements I${t}Repository {
2428
2524
  throw new Error('Drizzle ${t} repository not yet implemented')
2429
2525
  }
2430
2526
  }
2431
- `}function Wn(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
2527
+ `}function Gn(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
2432
2528
  // TODO: Import your schema table and reference actual columns for type safety
2433
2529
  // import { ${n}s } from '@/db/schema'
2434
2530
 
@@ -2446,7 +2542,7 @@ export const ${t.toUpperCase()}_QUERY_CONFIG: DrizzleQueryParamsConfig = {
2446
2542
  // ${n}s.name,
2447
2543
  ],
2448
2544
  }
2449
- `}function Gn(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`/**
2545
+ `}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`/**
2450
2546
  * Prisma ${t} Repository
2451
2547
  *
2452
2548
  * Implements the repository interface using Prisma Client.
@@ -2504,7 +2600,7 @@ export class Prisma${t}Repository implements I${t}Repository {
2504
2600
  await this.prisma.${a}.deleteMany({ where: { id } })
2505
2601
  }
2506
2602
  }
2507
- `}async function Kn(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,xn({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
2603
+ `}async function qn(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,Sn({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
2508
2604
 
2509
2605
  // \`Ctx<KickRoutes.${t}Controller['<method>']>\` is generated by
2510
2606
  // \`kick typegen\` (auto-run on \`kick dev\`).
@@ -2516,7 +2612,7 @@ export class ${t}Controller {
2516
2612
  ctx.json({ message: '${t} list' })
2517
2613
  }
2518
2614
  }
2519
- `)}async function qn(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`,bn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,Ln({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Cn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,In({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,Tn({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,En({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,Dn({pascal:t,kebab:n})),await u(`${n}.repository.ts`,kn({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let d={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},f={inmemory:()=>V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Un({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>Gn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${R(a)}-${n}`,m=f[a]??(()=>An({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`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,Pn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,Fn({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`,Rn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,Ln({pascal:t,kebab:n})),await u(`${n}.controller.ts`,zn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,Tn({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,En({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,Dn({pascal:t,kebab:n}));let d=Bn({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=Vn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=Hn({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,kn({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let m={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},h={inmemory:()=>V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Un({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>Gn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${R(a)}-${n}`,_=h[a]??(()=>An({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,Pn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,Fn({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function Yn(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`,yn({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?Wn({pascal:t,kebab:n}):wn({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,Sn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,Tn({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,En({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,Dn({pascal:t,kebab:n}));let f=On({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`,kn({pascal:t,kebab:n,tokenScope:l})),await d(`domain/services/${n}-domain.service.ts`,jn({pascal:t,kebab:n}));let p={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},m={inmemory:()=>V({pascal:t,kebab:n}),drizzle:()=>Un({pascal:t,kebab:n}),prisma:()=>Gn({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${R(a)}-${n}`,g=m[a]??(()=>An({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,Mn({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,Nn({pascal:t,kebab:n}))),s||(a!==`inmemory`&&await d(`infrastructure/repositories/in-memory-${n}.repository.ts`,V({pascal:t,kebab:n})),await d(`__tests__/${n}.controller.test.ts`,Pn({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,Fn({pascal:t,kebab:n,plural:r})))}function Xn(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Zn(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=R(t),d=I(t),f=c?z(u):u,p=c?Yt(d):d,m=h(n,f),g=[],_=o??!1,v={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=h(m,e);if(s){g.push(n);return}if(!_&&await Ze(n)&&!await P({message:`File exists: ${E.dim(e)}. Overwrite?`,initialValue:!1})){F.warn(`Skipped: ${e}`);return}await M(n,t),g.push(n)},files:g};switch(l){case`minimal`:await Kn(v);break;case`rest`:await qn(v);break;case`cqrs`:await Jn(v);break;default:await Yn(v);break}return s||await Qn(n,d,f,u,v.style),g}async function Qn(e,t,n,r,i=`define`){let a=h(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'
2615
+ `)}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`,Rn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,wn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,Ln({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,En({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,On({pascal:t,kebab:n})),await u(`${n}.repository.ts`,An({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let d={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},f={inmemory:()=>V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Wn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>Kn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${R(a)}-${n}`,m=f[a]??(()=>jn({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`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,Fn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,In({pascal:t,kebab:n,plural:r,repoPrefix:`../${d.inmemory??`in-memory-${n}`}.repository`})))}async function Yn(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`,zn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,Rn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Bn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,En({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,On({pascal:t,kebab:n}));let d=Vn({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=Hn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=Un({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,An({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let m={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},h={inmemory:()=>V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Wn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>Kn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${R(a)}-${n}`,_=h[a]??(()=>jn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,Fn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,In({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function Xn(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`,bn({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?Gn({pascal:t,kebab:n}):Tn({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,Cn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,En({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,On({pascal:t,kebab:n}));let f=kn({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`,An({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:()=>V({pascal:t,kebab:n}),drizzle:()=>Wn({pascal:t,kebab:n}),prisma:()=>Kn({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${R(a)}-${n}`,g=m[a]??(()=>jn({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,Nn({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,Pn({pascal:t,kebab:n}))),s||(a!==`inmemory`&&await d(`infrastructure/repositories/in-memory-${n}.repository.ts`,V({pascal:t,kebab:n})),await d(`__tests__/${n}.controller.test.ts`,Fn({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,In({pascal:t,kebab:n,plural:r})))}function Zn(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Qn(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=R(t),d=I(t),f=c?z(u):u,p=c?Xt(d):d,m=h(n,f),g=[],_=o??!1,v={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=h(m,e);if(s){g.push(n);return}if(!_&&await Ze(n)&&!await P({message:`File exists: ${E.dim(e)}. Overwrite?`,initialValue:!1})){F.warn(`Skipped: ${e}`);return}await M(n,t),g.push(n)},files:g};switch(l){case`minimal`:await qn(v);break;case`rest`:await Jn(v);break;case`cqrs`:await Yn(v);break;default:await Xn(v);break}return s||await $n(n,d,f,u,v.style),g}async function $n(e,t,n,r,i=`define`){let a=h(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'
2520
2616
  import { ${t}Module } from '${s}'
2521
2617
 
2522
2618
  export const modules: AppModuleEntry[] = [${c}]
@@ -2527,8 +2623,8 @@ export const modules = defineModules().mount(${c})
2527
2623
  `);return}let l=await C(a,`utf-8`),u=`import { ${t}Module } from '${s}'`,d=B(s);if(!RegExp(`^import\\s*\\{[^}]*\\b${B(t)}Module\\b[^}]*\\}\\s*from\\s*['"]${d}['"]`,`m`).test(l)){let e=l.lastIndexOf(`import `);if(e!==-1){let t=l.indexOf(`
2528
2624
  `,e);l=l.slice(0,t+1)+u+`
2529
2625
  `+l.slice(t+1)}else l=u+`
2530
- `+l}let f=er(l);if(f){let e=l.slice(f.rhsStart,f.rhsEnd+1);RegExp(`\\b${B(t)}Module\\b`).test(e)||(l=$n(l,c))}else l=$n(l,c);await w(a,l,`utf-8`)}function $n(e,t){let n=er(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 er(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=rr(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=tr(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function tr(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=ir(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=ir(e,t);if(n===-1)break;i=n+1}return i}function nr(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
2531
- `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function rr(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=nr(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 ir(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=nr(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 ar(e){let{name:t,outDir:n}=e,r=R(t),i=I(t),a=[],o=h(n,`${r}.adapter.ts`);return await M(o,`import {
2626
+ `+l}let f=tr(l);if(f){let e=l.slice(f.rhsStart,f.rhsEnd+1);RegExp(`\\b${B(t)}Module\\b`).test(e)||(l=er(l,c))}else l=er(l,c);await w(a,l,`utf-8`)}function er(e,t){let n=tr(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 tr(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=ir(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=nr(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function nr(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=ar(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=ar(e,t);if(n===-1)break;i=n+1}return i}function rr(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
2627
+ `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function ir(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=rr(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 ar(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=rr(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 or(e){let{name:t,outDir:n}=e,r=R(t),i=I(t),a=[],o=h(n,`${r}.adapter.ts`);return await M(o,`import {
2532
2628
  defineAdapter,
2533
2629
  type AdapterContext,
2534
2630
  type AdapterMiddleware,
@@ -2697,7 +2793,7 @@ export const ${i}Adapter = defineAdapter<${i}AdapterConfig>({
2697
2793
  }
2698
2794
  },
2699
2795
  })
2700
- `),a.push(o),a}async function or(e){let{name:t,outDir:n}=e,r=R(t),i=I(t),a=[],o=h(n,`${r}.plugin.ts`);return await M(o,`import {
2796
+ `),a.push(o),a}async function sr(e){let{name:t,outDir:n}=e,r=R(t),i=I(t),a=[],o=h(n,`${r}.plugin.ts`);return await M(o,`import {
2701
2797
  definePlugin,
2702
2798
  type AppAdapter,
2703
2799
  type AppModuleEntry,
@@ -2841,7 +2937,7 @@ export const ${i}Plugin = definePlugin<${i}PluginConfig>({
2841
2937
  },
2842
2938
  }),
2843
2939
  })
2844
- `),a.push(o),a}const sr={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`},cr={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`},lr={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,command:`commands`,query:`queries`,event:`events`};function ur(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,pattern:o=`ddd`,shouldPluralize:s=!0}=e;if(n)return v(n);if(r){let e=o===`ddd`?sr:o===`cqrs`?lr:cr,n=R(r),a=s?z(n):n,c=e[t]??``,l=h(i,a);return v(c?h(l,c):l)}return v(a)}async function dr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=ur({type:`middleware`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/middleware`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=L(t),c=[],l=h(a,`${o}.middleware.ts`);return await M(l,`import type { Request, Response, NextFunction } from 'express'
2940
+ `),a.push(o),a}const cr={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`},lr={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`},ur={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,command:`commands`,query:`queries`,event:`events`};function dr(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,pattern:o=`ddd`,shouldPluralize:s=!0}=e;if(n)return v(n);if(r){let e=o===`ddd`?cr:o===`cqrs`?ur:lr,n=R(r),a=s?z(n):n,c=e[t]??``,l=h(i,a);return v(c?h(l,c):l)}return v(a)}async function fr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`middleware`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/middleware`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=L(t),c=[],l=h(a,`${o}.middleware.ts`);return await M(l,`import type { Request, Response, NextFunction } from 'express'
2845
2941
 
2846
2942
  export interface ${I(t)}Options {
2847
2943
  // Add configuration options here. The factory below closes over the
@@ -2891,7 +2987,7 @@ export function ${s}(options: ${I(t)}Options = {}) {
2891
2987
  next()
2892
2988
  }
2893
2989
  }
2894
- `),c.push(l),c}async function fr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=ur({type:`guard`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/guards`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=L(t),c=I(t),l=[],u=h(a,`${o}.guard.ts`);return await M(u,`import { Container, HttpException } from '@forinda/kickjs'
2990
+ `),c.push(l),c}async function pr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`guard`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/guards`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=L(t),c=I(t),l=[],u=h(a,`${o}.guard.ts`);return await M(u,`import { Container, HttpException } from '@forinda/kickjs'
2895
2991
  import type { RequestContext } from '@forinda/kickjs'
2896
2992
 
2897
2993
  /**
@@ -2927,7 +3023,7 @@ export async function ${s}Guard(ctx: RequestContext, next: () => void): Promise<
2927
3023
  ctx.res.status(401).json({ message: 'Invalid or expired token' })
2928
3024
  }
2929
3025
  }
2930
- `),l.push(u),l}async function pr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=ur({type:`service`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/services`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=[],l=h(a,`${o}.service.ts`);return await M(l,`import { Service } from '@forinda/kickjs'
3026
+ `),l.push(u),l}async function mr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`service`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/services`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=[],l=h(a,`${o}.service.ts`);return await M(l,`import { Service } from '@forinda/kickjs'
2931
3027
 
2932
3028
  @Service()
2933
3029
  export class ${s}Service {
@@ -2936,7 +3032,7 @@ export class ${s}Service {
2936
3032
  // @Inject(MY_REPO) private readonly repo: IMyRepository,
2937
3033
  // ) {}
2938
3034
  }
2939
- `),c.push(l),c}async function mr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=ur({type:`controller`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/controllers`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=[],l=h(a,`${o}.controller.ts`);return await M(l,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
3035
+ `),c.push(l),c}async function hr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`controller`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/controllers`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=[],l=h(a,`${o}.controller.ts`);return await M(l,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
2940
3036
 
2941
3037
  // \`Ctx<KickRoutes.${s}Controller['<method>']>\` is generated by
2942
3038
  // \`kick typegen\` (auto-run on \`kick dev\`). After the first run, your IDE
@@ -2957,7 +3053,7 @@ export class ${s}Controller {
2957
3053
  ctx.created({ message: '${s} created', data: ctx.body })
2958
3054
  }
2959
3055
  }
2960
- `),c.push(l),c}async function hr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=ur({type:`dto`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/dtos`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=L(t),l=[],u=h(a,`${o}.dto.ts`);return await M(u,`import { z } from 'zod'
3056
+ `),c.push(l),c}async function gr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`dto`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/dtos`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=L(t),l=[],u=h(a,`${o}.dto.ts`);return await M(u,`import { z } from 'zod'
2961
3057
 
2962
3058
  export const ${c}Schema = z.object({
2963
3059
  // Define your schema fields here
@@ -2965,7 +3061,7 @@ export const ${c}Schema = z.object({
2965
3061
  })
2966
3062
 
2967
3063
  export type ${s}DTO = z.infer<typeof ${c}Schema>
2968
- `),l.push(u),l}async function gr(e){let t=h(e.outDir,`kick.config.ts`),n=e.modulesDir??`src/modules`,i=e.defaultRepo??`inmemory`;return r(t)&&!e.force&&!await P({message:`kick.config.ts already exists. Overwrite?`,initialValue:!1})?(console.log(`
3064
+ `),l.push(u),l}async function _r(e){let t=h(e.outDir,`kick.config.ts`),n=e.modulesDir??`src/modules`,i=e.defaultRepo??`inmemory`;return r(t)&&!e.force&&!await P({message:`kick.config.ts already exists. Overwrite?`,initialValue:!1})?(console.log(`
2969
3065
  Skipped — existing kick.config.ts preserved.`),[]):(await M(t,`import { defineConfig } from '@forinda/kickjs-cli'
2970
3066
 
2971
3067
  export default defineConfig({
@@ -3003,18 +3099,18 @@ export default defineConfig({
3003
3099
  },
3004
3100
  ],
3005
3101
  })
3006
- `),[t])}var _r=D({generateAgentDocs:()=>Cr});const vr=`.agents`,yr=new Set([`rest`,`ddd`,`cqrs`,`minimal`]);function br(e,t){if(t)return t;try{let t=JSON.parse(a(h(e,`package.json`),`utf-8`));if(t.name)return t.name.replace(/^@[^/]+\//,``)}catch{}return e.split(`/`).findLast(Boolean)??`app`}function xr(e,t){if(t)return t;try{let t=JSON.parse(a(h(e,`package.json`),`utf-8`));if(t.packageManager)return t.packageManager.split(`@`)[0]}catch{}return`pnpm`}async function Sr(e,t){if(t)return t;try{let t=(await k(e))?.pattern;if(t&&yr.has(t))return t}catch{}return`ddd`}async function Cr(e){let t=e.only??`all`,n=br(e.outDir,e.name),i=xr(e.outDir,e.pm),a=await Sr(e.outDir,e.template),o=t===`agents`||t===`both`||t===`all`,s=t===`claude`||t===`both`||t===`all`,c=t===`skills`||t===`all`,l=t===`gemini`||t===`all`,u=t===`copilot`||t===`all`,d=[];if(o&&d.push({file:h(e.outDir,vr,`AGENTS.md`),render:()=>yt(n,a,i)}),s&&d.push({file:h(e.outDir,`CLAUDE.md`),render:()=>vt(n,a,i)}),c)for(let t of bt(n,a,i))d.push({file:h(e.outDir,vr,`skills`,t.slug,`SKILL.md`),render:()=>t.content});l&&d.push({file:h(e.outDir,vr,`GEMINI.md`),render:()=>xt(n,a,i)}),u&&d.push({file:h(e.outDir,vr,`COPILOT.md`),render:()=>St(n,a,i)});let f=[];for(let{file:t,render:n}of d){if(r(t)&&!e.force&&!await P({message:`${t.replace(e.outDir+`/`,``)} already exists. Overwrite?`,initialValue:!1})){console.log(` Skipped — existing ${t.replace(e.outDir+`/`,``)} preserved.`);continue}await M(t,n()),f.push(t)}return f}function wr(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 H(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=wr(e,r);return i===-1?null:e.slice(r+1,i)}function U(e,t,n){let r=` `.repeat(n);return e.split(`
3102
+ `),[t])}var vr=D({generateAgentDocs:()=>wr});const yr=`.agents`,br=new Set([`rest`,`ddd`,`cqrs`,`minimal`]);function xr(e,t){if(t)return t;try{let t=JSON.parse(a(h(e,`package.json`),`utf-8`));if(t.name)return t.name.replace(/^@[^/]+\//,``)}catch{}return e.split(`/`).findLast(Boolean)??`app`}function Sr(e,t){if(t)return t;try{let t=JSON.parse(a(h(e,`package.json`),`utf-8`));if(t.packageManager)return t.packageManager.split(`@`)[0]}catch{}return`pnpm`}async function Cr(e,t){if(t)return t;try{let t=(await k(e))?.pattern;if(t&&br.has(t))return t}catch{}return`ddd`}async function wr(e){let t=e.only??`all`,n=xr(e.outDir,e.name),i=Sr(e.outDir,e.pm),a=await Cr(e.outDir,e.template),o=t===`agents`||t===`both`||t===`all`,s=t===`claude`||t===`both`||t===`all`,c=t===`skills`||t===`all`,l=t===`gemini`||t===`all`,u=t===`copilot`||t===`all`,d=[];if(o&&d.push({file:h(e.outDir,yr,`AGENTS.md`),render:()=>bt(n,a,i)}),s&&d.push({file:h(e.outDir,`CLAUDE.md`),render:()=>yt(n,a,i)}),c)for(let t of xt(n,a,i))d.push({file:h(e.outDir,yr,`skills`,t.slug,`SKILL.md`),render:()=>t.content});l&&d.push({file:h(e.outDir,yr,`GEMINI.md`),render:()=>St(n,a,i)}),u&&d.push({file:h(e.outDir,yr,`COPILOT.md`),render:()=>Ct(n,a,i)});let f=[];for(let{file:t,render:n}of d){if(r(t)&&!e.force&&!await P({message:`${t.replace(e.outDir+`/`,``)} already exists. Overwrite?`,initialValue:!1})){console.log(` Skipped — existing ${t.replace(e.outDir+`/`,``)} preserved.`);continue}await M(t,n()),f.push(t)}return f}function Tr(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 H(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=Tr(e,r);return i===-1?null:e.slice(r+1,i)}function U(e,t,n){let r=` `.repeat(n);return e.split(`
3007
3103
  `).map(e=>{if(e.trim()===``)return e;let n=RegExp(`^ {0,${t}}`);return r+e.replace(n,``)}).join(`
3008
- `)}function Tr(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 Er(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 Dr(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=wr(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=H(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=H(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=H(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=Tr(s),p=``;return l&&(p+=` register(container) {${U(l,4,6)} },\n\n`),u&&(p+=` contributors() {${U(u,4,6)} },\n\n`),p+=` routes() {${U(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
3104
+ `)}function Er(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 Dr(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 Or(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=Tr(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=H(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=H(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=H(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=Er(s),p=``;return l&&(p+=` register(container) {${U(l,4,6)} },\n\n`),u&&(p+=` contributors() {${U(u,4,6)} },\n\n`),p+=` routes() {${U(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
3009
3105
  name: '${r}',
3010
3106
  build: () => ({
3011
3107
  ${p}
3012
3108
  }),
3013
- })`}${c}`}}function Or(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=wr(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]===`
3014
- `||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=wr(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=H(m,/register\s*\(([^)]*)\)\s*\{/),g=H(m,/contributors\s*\(\s*\)\s*\{/),_=H(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=Er(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${U(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${U(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${U(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
3109
+ })`}${c}`}}function kr(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=Tr(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]===`
3110
+ `||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=Tr(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=H(m,/register\s*\(([^)]*)\)\s*\{/),g=H(m,/contributors\s*\(\s*\)\s*\{/),_=H(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=Dr(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${U(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${U(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${U(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
3015
3111
  ${y}
3016
3112
  }
3017
- `}${u}`}}function kr(e,t){return t===`class`?Or(e):Dr(e)}function Ar(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 jr(e){let t=[];return await n(v(e),0),t;async function n(e,r){let i;try{i=await se(e)}catch{return}for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=h(e,a),o;try{o=await le(i)}catch{continue}o.isDirectory()?await n(i,r+1):(a.endsWith(`.module.ts`)||a===`index.ts`&&r===1)&&t.push(i)}}}async function Mr(e,t){let n=0;return await r(e,t),n;async function r(e,t){let i;try{i=await se(e)}catch{return}await oe(t,{recursive:!0});for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=h(e,a),o=h(t,a),s;try{s=await le(i)}catch{continue}s.isDirectory()?await r(i,o):(await ae(i,o),n++)}}}function Nr(e){return h(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function Pr(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await jr(e),s=await C(h(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=Nr(r),await Mr(e,c));let l=[];for(let e of o){let t=kr(await C(e,`utf-8`),i);if(t.migrated==null){l.push({path:e,status:`skipped`,reason:t.reason});continue}n||await w(e,t.migrated,`utf-8`),l.push({path:e,status:`migrated`})}let u=h(e,`index.ts`),d=null;try{d=await C(u,`utf-8`)}catch{return{target:i,files:l,indexStatus:`not-found`,indexPath:u,backupDir:c}}let f=Ar(d,i);return f.migrated==null?{target:i,files:l,indexStatus:`skipped`,indexPath:u,indexReason:f.reason,backupDir:c}:(n||await w(u,f.migrated,`utf-8`),{target:i,files:l,indexStatus:`migrated`,indexPath:u,backupDir:c})}async function Fr(e,t){let n=await jr(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 C(e,`utf-8`);i.test(t)&&r.push(e)}return r}async function Ir(e){let{name:t,outDir:n}=e,r=I(t),i=R(t),a=L(t),o=e.queue??`${i}-queue`,s=[];return await(async(e,t)=>{let r=h(n,e);await M(r,t),s.push(r)})(`${i}.job.ts`,`import { Inject } from '@forinda/kickjs'
3113
+ `}${u}`}}function Ar(e,t){return t===`class`?kr(e):Or(e)}function jr(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 Mr(e){let t=[];return await n(v(e),0),t;async function n(e,r){let i;try{i=await se(e)}catch{return}for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=h(e,a),o;try{o=await le(i)}catch{continue}o.isDirectory()?await n(i,r+1):(a.endsWith(`.module.ts`)||a===`index.ts`&&r===1)&&t.push(i)}}}async function Nr(e,t){let n=0;return await r(e,t),n;async function r(e,t){let i;try{i=await se(e)}catch{return}await oe(t,{recursive:!0});for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=h(e,a),o=h(t,a),s;try{s=await le(i)}catch{continue}s.isDirectory()?await r(i,o):(await ae(i,o),n++)}}}function Pr(e){return h(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function Fr(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await Mr(e),s=await C(h(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=Pr(r),await Nr(e,c));let l=[];for(let e of o){let t=Ar(await C(e,`utf-8`),i);if(t.migrated==null){l.push({path:e,status:`skipped`,reason:t.reason});continue}n||await w(e,t.migrated,`utf-8`),l.push({path:e,status:`migrated`})}let u=h(e,`index.ts`),d=null;try{d=await C(u,`utf-8`)}catch{return{target:i,files:l,indexStatus:`not-found`,indexPath:u,backupDir:c}}let f=jr(d,i);return f.migrated==null?{target:i,files:l,indexStatus:`skipped`,indexPath:u,indexReason:f.reason,backupDir:c}:(n||await w(u,f.migrated,`utf-8`),{target:i,files:l,indexStatus:`migrated`,indexPath:u,backupDir:c})}async function Ir(e,t){let n=await Mr(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 C(e,`utf-8`);i.test(t)&&r.push(e)}return r}async function Lr(e){let{name:t,outDir:n}=e,r=I(t),i=R(t),a=L(t),o=e.queue??`${i}-queue`,s=[];return await(async(e,t)=>{let r=h(n,e);await M(r,t),s.push(r)})(`${i}.job.ts`,`import { Inject } from '@forinda/kickjs'
3018
3114
  import { Job, Process, QUEUE_MANAGER, type QueueService } from '@forinda/kickjs-queue'
3019
3115
 
3020
3116
  /**
@@ -3047,7 +3143,7 @@ export class ${r}Job {
3047
3143
  // Handle high-priority variant of this job
3048
3144
  }
3049
3145
  }
3050
- `),s}const Lr={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 Rr(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=Lr[a];if(!o){let e=[...Object.keys(Lr),`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 zr(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=R(t),d=I(t);L(t);let f=l?z(u):u,p=l?Yt(d):d,m=h(r,f),g=[],_=async(e,t)=>{let n=h(m,e);await M(n,t),g.push(n)};await _(`${u}.module.ts`,qr(d,u,f,c)),await _(`constants.ts`,Ur(d,n)),await _(`presentation/${u}.controller.ts`,Jr(d,u,f,p)),await _(`application/dtos/create-${u}.dto.ts`,Br(d,n)),await _(`application/dtos/update-${u}.dto.ts`,Vr(d,n)),await _(`application/dtos/${u}-response.dto.ts`,Hr(d,n));let v=Zr(d,u,f,p);for(let e of v)await _(`application/use-cases/${e.file}`,e.content);return await _(`domain/repositories/${u}.repository.ts`,Yr(d,u,s)),await _(`domain/services/${u}-domain.service.ts`,Xr(d,u)),o===`inmemory`&&await _(`infrastructure/repositories/in-memory-${u}.repository.ts`,Wr(d,u,n)),i||(await _(`domain/entities/${u}.entity.ts`,Gr(d,u,n)),await _(`domain/value-objects/${u}-id.vo.ts`,Kr(d))),await Qn(r,d,f,u,c),g}function Br(e,t){return`import { z } from 'zod'
3146
+ `),s}const Rr={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 zr(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=Rr[a];if(!o){let e=[...Object.keys(Rr),`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 Br(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=R(t),d=I(t);L(t);let f=l?z(u):u,p=l?Xt(d):d,m=h(r,f),g=[],_=async(e,t)=>{let n=h(m,e);await M(n,t),g.push(n)};await _(`${u}.module.ts`,Jr(d,u,f,c)),await _(`constants.ts`,Wr(d,n)),await _(`presentation/${u}.controller.ts`,Yr(d,u,f,p)),await _(`application/dtos/create-${u}.dto.ts`,Vr(d,n)),await _(`application/dtos/update-${u}.dto.ts`,Hr(d,n)),await _(`application/dtos/${u}-response.dto.ts`,Ur(d,n));let v=Qr(d,u,f,p);for(let e of v)await _(`application/use-cases/${e.file}`,e.content);return await _(`domain/repositories/${u}.repository.ts`,Xr(d,u,s)),await _(`domain/services/${u}-domain.service.ts`,Zr(d,u)),o===`inmemory`&&await _(`infrastructure/repositories/in-memory-${u}.repository.ts`,Gr(d,u,n)),i||(await _(`domain/entities/${u}.entity.ts`,Kr(d,u,n)),await _(`domain/value-objects/${u}-id.vo.ts`,qr(d))),await $n(r,d,f,u,c),g}function Vr(e,t){return`import { z } from 'zod'
3051
3147
 
3052
3148
  export const create${e}Schema = z.object({
3053
3149
  ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:``},`}).join(`
@@ -3055,7 +3151,7 @@ ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:`
3055
3151
  })
3056
3152
 
3057
3153
  export type Create${e}DTO = z.infer<typeof create${e}Schema>
3058
- `}function Vr(e,t){return`import { z } from 'zod'
3154
+ `}function Hr(e,t){return`import { z } from 'zod'
3059
3155
 
3060
3156
  export const update${e}Schema = z.object({
3061
3157
  ${t.map(e=>` ${e.name}: ${e.zodType}.optional(),`).join(`
@@ -3063,21 +3159,21 @@ ${t.map(e=>` ${e.name}: ${e.zodType}.optional(),`).join(`
3063
3159
  })
3064
3160
 
3065
3161
  export type Update${e}DTO = z.infer<typeof update${e}Schema>
3066
- `}function Hr(e,t){return`export interface ${e}ResponseDTO {
3162
+ `}function Ur(e,t){return`export interface ${e}ResponseDTO {
3067
3163
  id: string
3068
3164
  ${t.map(e=>` ${e.name}${e.optional?`?`:``}: ${e.tsType}`).join(`
3069
3165
  `)}
3070
3166
  createdAt: string
3071
3167
  updatedAt: string
3072
3168
  }
3073
- `}function Ur(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'
3169
+ `}function Wr(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'
3074
3170
 
3075
3171
  export const ${e.toUpperCase()}_QUERY_CONFIG: ApiQueryParamsConfig = {
3076
3172
  filterable: [${i}],
3077
3173
  sortable: [${a}],
3078
3174
  searchable: [${o}],
3079
3175
  }
3080
- `}function Wr(e,t,n){return`import { randomUUID } from 'node:crypto'
3176
+ `}function Gr(e,t,n){return`import { randomUUID } from 'node:crypto'
3081
3177
  import { Repository, HttpException } from '@forinda/kickjs'
3082
3178
  import type { ParsedQuery } from '@forinda/kickjs'
3083
3179
  import type { I${e}Repository } from '../../domain/repositories/${t}.repository'
@@ -3129,7 +3225,7 @@ ${n.map(e=>` ${e.name}: dto.${e.name},`).join(`
3129
3225
  this.store.delete(id)
3130
3226
  }
3131
3227
  }
3132
- `}function Gr(e,t,n){return`import { ${e}Id } from '../value-objects/${t}-id.vo'
3228
+ `}function Kr(e,t,n){return`import { ${e}Id } from '../value-objects/${t}-id.vo'
3133
3229
 
3134
3230
  interface ${e}Props {
3135
3231
  id: ${e}Id
@@ -3175,7 +3271,7 @@ ${n.map(e=>` ${e.name}: this.props.${e.name},`).join(`
3175
3271
  }
3176
3272
  }
3177
3273
  }
3178
- `}function Kr(e){return`import { randomUUID } from 'node:crypto'
3274
+ `}function qr(e){return`import { randomUUID } from 'node:crypto'
3179
3275
 
3180
3276
  export class ${e}Id {
3181
3277
  private constructor(private readonly value: string) {}
@@ -3190,7 +3286,7 @@ export class ${e}Id {
3190
3286
  toString(): string { return this.value }
3191
3287
  equals(other: ${e}Id): boolean { return this.value === other.value }
3192
3288
  }
3193
- `}function qr(e,t,n,r=`define`){let i=`import { ${e}Controller } from './presentation/${t}.controller'
3289
+ `}function Jr(e,t,n,r=`define`){let i=`import { ${e}Controller } from './presentation/${t}.controller'
3194
3290
  import { ${e.toUpperCase()}_REPOSITORY } from './domain/repositories/${t}.repository'
3195
3291
  import { InMemory${e}Repository } from './infrastructure/repositories/in-memory-${t}.repository'
3196
3292
 
@@ -3263,7 +3359,7 @@ ${a}
3263
3359
  },
3264
3360
  }),
3265
3361
  })
3266
- `}function Jr(e,t,n,r){return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
3362
+ `}function Yr(e,t,n,r){return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
3267
3363
  import { ApiTags } from '@forinda/kickjs-swagger'
3268
3364
  import { Create${e}UseCase } from '../application/use-cases/create-${t}.use-case'
3269
3365
  import { Get${e}UseCase } from '../application/use-cases/get-${t}.use-case'
@@ -3326,7 +3422,7 @@ export class ${e}Controller {
3326
3422
  ctx.noContent()
3327
3423
  }
3328
3424
  }
3329
- `}function Yr(e,t,n){return`import { createToken } from '@forinda/kickjs'
3425
+ `}function Xr(e,t,n){return`import { createToken } from '@forinda/kickjs'
3330
3426
  import type { ${e}ResponseDTO } from '../../application/dtos/${t}-response.dto'
3331
3427
  import type { Create${e}DTO } from '../../application/dtos/create-${t}.dto'
3332
3428
  import type { Update${e}DTO } from '../../application/dtos/update-${t}.dto'
@@ -3352,7 +3448,7 @@ export interface I${e}Repository {
3352
3448
  * adopters must NOT use the reserved \`'kick/'\` namespace.
3353
3449
  */
3354
3450
  export const ${e.toUpperCase()}_REPOSITORY = createToken<I${e}Repository>('${n}/${e}/repository')
3355
- `}function Xr(e,t){return`import { Service, Inject, HttpException } from '@forinda/kickjs'
3451
+ `}function Zr(e,t){return`import { Service, Inject, HttpException } from '@forinda/kickjs'
3356
3452
  import { ${e.toUpperCase()}_REPOSITORY, type I${e}Repository } from '../repositories/${t}.repository'
3357
3453
 
3358
3454
  @Service()
@@ -3366,7 +3462,7 @@ export class ${e}DomainService {
3366
3462
  if (!entity) throw HttpException.notFound('${e} not found')
3367
3463
  }
3368
3464
  }
3369
- `}function Zr(e,t,n,r){return[{file:`create-${t}.use-case.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
3465
+ `}function Qr(e,t,n,r){return[{file:`create-${t}.use-case.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
3370
3466
  import { ${e.toUpperCase()}_REPOSITORY, type I${e}Repository } from '../../domain/repositories/${t}.repository'
3371
3467
  import type { Create${e}DTO } from '../dtos/create-${t}.dto'
3372
3468
 
@@ -3409,7 +3505,7 @@ export class Delete${e}UseCase {
3409
3505
  constructor(@Inject(${e.toUpperCase()}_REPOSITORY) private repo: I${e}Repository) {}
3410
3506
  async execute(id: string) { return this.repo.delete(id) }
3411
3507
  }
3412
- `}]}async function Qr(e){let{name:t,moduleName:n,modulesDir:r}=e,i=e.pluralize??!0,a=R(t),o=I(t),s=[],c;if(e.outDir)c=v(e.outDir);else if(n){let e=R(n),t=i?z(e):e;c=v(h(r??`src/modules`,t,`__tests__`))}else c=v(`src/__tests__`);let l=h(c,`${a}.test.ts`);return await M(l,`import { describe, it, expect, beforeEach } from 'vitest'
3508
+ `}]}async function $r(e){let{name:t,moduleName:n,modulesDir:r}=e,i=e.pluralize??!0,a=R(t),o=I(t),s=[],c;if(e.outDir)c=v(e.outDir);else if(n){let e=R(n),t=i?z(e):e;c=v(h(r??`src/modules`,t,`__tests__`))}else c=v(`src/__tests__`);let l=h(c,`${a}.test.ts`);return await M(l,`import { describe, it, expect, beforeEach } from 'vitest'
3413
3509
  import { Container } from '@forinda/kickjs'
3414
3510
 
3415
3511
  describe('${o}', () => {
@@ -3432,9 +3528,9 @@ describe('${o}', () => {
3432
3528
  expect(true).toBe(true)
3433
3529
  })
3434
3530
  })
3435
- `),s.push(l),s}const $r=[`Service`,`Controller`,`Repository`,`Injectable`,`Component`,`Module`],ei=[`.ts`,`.tsx`,`.mts`,`.cts`],ti=[`node_modules`,`.kickjs`,`dist`,`build`,`.test.`,`.spec.`,`.d.ts`],ni=new RegExp(String.raw`@(${$r.join(`|`)})\s*\([^)]*\)`+String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*`+String.raw`\s*export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`,`g`),ri=new RegExp(String.raw`export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppModule\b`,`g`),ii=/(?:export\s+)?const\s+(\w+)\s*(?::\s*[^=]+)?=\s*createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,ai=/createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,oi=/@Inject\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,si=/\b(defineAdapter|definePlugin)\s*(?:<[^>]*>)?\s*\(/g,ci=new RegExp(String.raw`export\s+(?:default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppAdapter\b`,`g`),li=/\bname\s*(?::\s*[^=]+)?=\s*['"`]([^'"`]+)['"`]/,ui=/\bdefineAugmentation\s*\(\s*['"`]([^'"`]+)['"`]\s*(,\s*\{)?/g,di=new RegExp(String.raw`@(${[`Get`,`Post`,`Put`,`Delete`,`Patch`].join(`|`)})\s*\(`,`g`);function fi(e,t){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 pi(e,t){let n=t;for(;n<e.length;){for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==`@`)break;let t=e.slice(n).match(/^@([A-Z]\w*)/);if(!t)break;for(n+=t[0].length;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]===`(`){let t=fi(e,n);if(t<0)return null;n=t+1}}for(;n<e.length&&/\s/.test(e[n]);)n++;for(let t of[`public`,`private`,`protected`])if(e.slice(n,n+t.length)===t&&/\s/.test(e.charAt(n+t.length))){for(n+=t.length;n<e.length&&/\s/.test(e[n]);)n++;break}if(e.slice(n,n+5)===`async`&&/\s/.test(e.charAt(n+5)))for(n+=5;n<e.length&&/\s/.test(e[n]);)n++;let r=e.slice(n).match(/^([a-zA-Z_]\w*)\s*\(/);return r?{methodName:r[1],endPos:n+r[0].length}:null}function mi(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function hi(e,t){let n=e.endsWith(`/`)?e.slice(0,-1):e;return!t||t===`/`?n||`/`:n+(t.startsWith(`/`)?t:`/`+t)||`/`}const gi=/\b(?:public\s+|private\s+|protected\s+)?routes\s*\([^)]*\)\s*(?::\s*[A-Za-z_][\w<>[\]\s,|]*\s*)?\{/g,_i=/\bpath\s*:\s*['"`]([^'"`]*)['"`]/g,vi=/\bcontroller\s*:\s*([A-Z]\w*)\b/g,yi=/\bimport\.meta\.glob\s*\(/g;function bi(e){let t=[];for(yi.lastIndex=0;yi.exec(e)!==null;){let n=yi.lastIndex-1,r=fi(e,n);if(r<0)continue;let i=e.slice(n+1,r),a=/['"`]([^'"`]+)['"`]/g,o;for(;(o=a.exec(i))!==null;)t.push(o[1])}return t}function xi(e){let t=e.replace(/[.+^$()|[\]\\]/g,`\\$&`).replace(/\?/g,`.`).replace(/\*\*\//g,`___DOUBLESTAR_SLASH___`).replace(/\*\*/g,`___DOUBLESTAR___`).replace(/\*/g,`[^/]*`).replace(/___DOUBLESTAR_SLASH___/g,`(?:.+/)?`).replace(/___DOUBLESTAR___/g,`.*`);return RegExp(`^`+t+`$`)}function Si(e,t){let n=e.startsWith(`./`)?e:`./`+e,r=!1;for(let e of t){let t=e.startsWith(`!`);xi(t?e.slice(1):e).test(n)&&(r=!t)}return r}function Ci(e){let t=[];gi.lastIndex=0;let n;for(;(n=gi.exec(e))!==null;){let r=e.indexOf(`{`,n.index+n[0].length-1);if(r<0)continue;let i=Fi(e,r);if(i<0)continue;let a=e.slice(r+1,i),o=[];_i.lastIndex=0;let s;for(;(s=_i.exec(a))!==null;)o.push(s[1]??``);let c=[];vi.lastIndex=0;let l;for(;(l=vi.exec(a))!==null;)c.push(l[1]);let u=Math.min(o.length,c.length);for(let e=0;e<u;e++)t.push({controller:c[e],mountPath:o[e]})}return t}function wi(e,t){let n=new RegExp(String.raw`\b${t}\s*:\s*([A-Za-z_$][\w$]*)`,`g`).exec(e);return n?n[1]:null}function Ti(e,t){let n=new RegExp(String.raw`import\s*(?:type\s+)?\{[^}]*\b${t}\b[^}]*\}\s*from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(n)return n[1];let r=new RegExp(String.raw`import\s+(?:type\s+)?${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(r)return r[1];let i=new RegExp(String.raw`import\s*\*\s*as\s+${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);return i?i[1]:new RegExp(String.raw`(?:^|\n)\s*(?:export\s+)?const\s+${t}\b`).test(e)?``:null}function Ei(e,t){let n=/@ApiQueryParams\s*\(\s*([\s\S]*?)\s*\)\s*$/.exec(e);if(!n){let n=/@ApiQueryParams\s*\(([\s\S]*?)\)/.exec(e);return n?Di(n[1].trim(),t):null}return Di(n[1].trim(),t)}function Di(e,t){if(e.startsWith(`{`))return ki(e);let n=/^([A-Za-z_]\w*)/.exec(e);if(n){let e=n[1],r=new RegExp(String.raw`const\s+${e}\s*(?::\s*[^=]+)?=\s*(\{[\s\S]*?\n\})`,`m`).exec(t);if(r)return ki(r[1])}return{filterable:[],sortable:[],searchable:[]}}function Oi(e,t){let n=new RegExp(String.raw`${t}\s*:\s*\[([\s\S]*?)\]`).exec(e);return n?Array.from(n[1].matchAll(/['"`]([^'"`]+)['"`]/g)).map(e=>e[1]):[]}function ki(e){return{filterable:Oi(e,`filterable`),sortable:Oi(e,`sortable`),searchable:Oi(e,`searchable`)}}async function Ai(e,t){let n=t.extensions??ei,r=t.exclude??ti,i=[],a;try{a=await se(e,{withFileTypes:!0,encoding:`utf-8`})}catch{return i}for(let o of a){let a=h(e,o.name),s=_(t.cwd,a);r.some(e=>s.includes(e))||(o.isDirectory()?i.push(...await Ai(a,t)):o.isFile()&&n.some(e=>o.name.endsWith(e))&&i.push(a))}return i}function W(e,t){return _(t,e).split(y).join(`/`)}function ji(e,t,n){let r=[],i=W(t,n);ni.lastIndex=0;let a;for(;(a=ni.exec(e))!==null;){let[,e,n,o]=a;r.push({className:o,decorator:e,filePath:t,relativePath:i,isDefault:!!n})}ri.lastIndex=0;let o;for(;(o=ri.exec(e))!==null;){let[,e,n]=o;r.some(e=>e.className===n&&e.filePath===t)||r.push({className:n,decorator:`Module`,filePath:t,relativePath:i,isDefault:!!e})}return r}function Mi(e,t,n){let r=[],i=W(t,n),a=new Set;ii.lastIndex=0;let o;for(;(o=ii.exec(e))!==null;){let[e,n,s]=o;a.add(e),r.push({name:s,variable:n,filePath:t,relativePath:i})}for(ai.lastIndex=0;(o=ai.exec(e))!==null;)a.has(o[0])||r.push({name:o[1],variable:null,filePath:t,relativePath:i});return r}function Ni(e,t,n,r,i=new Map){let a=[];if(r.length===0)return a;let o=W(t,n),s=[];for(let t of r){let n=new RegExp(String.raw`class\s+${t.className}\b`).exec(e);n?.index!==void 0&&s.push({cls:t,start:n.index})}s.sort((e,t)=>e.start-t.start);for(let n=0;n<s.length;n++){let{cls:r,start:c}=s[n],l=n+1<s.length?s[n+1].start:e.length,u=e.slice(c,l);di.lastIndex=0;let d;for(;(d=di.exec(u))!==null;){let n=d[1],s=d.index,c=di.lastIndex-1,l=fi(u,c);if(l<0)continue;let f=u.slice(c+1,l),p=f.match(/^\s*['"`]([^'"`]*)['"`]/),m=p&&p[1].length>0?p[1]:`/`,h=pi(u,l+1);if(!h)continue;let{methodName:g,endPos:_}=h;di.lastIndex=_;let v=Ei(u.slice(s,_),e),y=wi(f,`body`),b=wi(f,`query`),x=wi(f,`params`),ee=i.get(r.className)??``,S=ee?hi(ee,m):m;a.push({controller:r.className,method:g,httpMethod:n.toUpperCase(),path:m,pathParams:mi(S),queryFilterable:v?.filterable??null,querySortable:v?.sortable??null,querySearchable:v?.searchable??null,bodySchema:y?{identifier:y,source:Ti(e,y)}:null,querySchema:b?{identifier:b,source:Ti(e,b)}:null,paramsSchema:x?{identifier:x,source:Ti(e,x)}:null,filePath:t,relativePath:o})}}return a}function Pi(e,t,n){let r=[],i=W(t,n);oi.lastIndex=0;let a;for(;(a=oi.exec(e))!==null;)r.push({name:a[1],filePath:t,relativePath:i});return r}function Fi(e,t){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 Ii(e,t,n){let r=[],i=W(t,n),a=new Set;si.lastIndex=0;let o;for(;(o=si.exec(e))!==null;){let n=o[1],s=si.lastIndex-1,c=fi(e,s);if(c<0)continue;let l=e.slice(s+1,c),u=/\bname\s*:\s*['"`]([^'"`]+)['"`]/.exec(l);if(!u)continue;let d=u[1],f=`${n}::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:n===`definePlugin`?`plugin`:`adapter`,name:d,filePath:t,relativePath:i}))}ci.lastIndex=0;let s;for(;(s=ci.exec(e))!==null;){let n=s.index,o=e.indexOf(`{`,n);if(o<0)continue;let c=Fi(e,o);if(c<0)continue;let l=e.slice(o+1,c),u=li.exec(l);if(!u)continue;let d=u[1],f=`class::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:`adapter`,name:d,filePath:t,relativePath:i}))}return r}function Li(e,t,n){let r=[],i=W(t,n);ui.lastIndex=0;let a;for(;(a=ui.exec(e))!==null;){let n=a[1],o=null,s=null;if(a[2]){let t=e.indexOf(`{`,a.index+a[0].length-1);if(t>=0){let n=Fi(e,t);if(n>=0){let r=e.slice(t+1,n);o=Ri(r,`description`),s=Ri(r,`example`)}}}r.push({name:n,description:o,example:s,filePath:t,relativePath:i})}return r}function Ri(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(['"\`])`,`g`).exec(e);if(!n)return null;let r=n[1],i=n.index+n[0].length,a=i,o=null;for(;a<e.length;){let t=e[a];if(t===`\\`){a+=2;continue}if(t===r){o=e.slice(i,a);break}a++}return o===null?null:o.replace(/\\(.)/g,(e,t)=>t===`n`?`
3436
- `:t===`t`?` `:t===`r`?`\r`:t)}const zi=[`src/config/index.ts`,`src/config/env.ts`,`src/config.ts`,`src/env.ts`];async function Bi(e,t){let n=t===`src/env.ts`?zi:[t];for(let t of n){let n=v(e,t),r;try{r=await C(n,`utf-8`)}catch{continue}if(/\bdefineEnv\s*\(/.test(r)&&/export\s+default\b/.test(r))return{filePath:n,relativePath:W(n,e)}}return null}function Vi(e){let t=new Map;for(let n of e){let e=t.get(n.className)??[];e.push(n),t.set(n.className,e)}let n=[];for(let[e,r]of t)new Set(r.map(e=>e.filePath)).size>1&&n.push({className:e,classes:r});return n.sort((e,t)=>e.className.localeCompare(t.className)),n}async function Hi(e){let t=await Ai(v(e.root),e),n=[],r=[],i=[],a=[],o=[],s=[],c=new Map;for(let r of t){let t;try{t=await C(r,`utf-8`)}catch{continue}c.set(r,t),n.push(...ji(t,r,e.cwd)),i.push(...Mi(t,r,e.cwd)),a.push(...Pi(t,r,e.cwd)),o.push(...Ii(t,r,e.cwd)),s.push(...Li(t,r,e.cwd))}let l=new Map;for(let[,e]of c)for(let{controller:t,mountPath:n}of Ci(e))l.has(t)||l.set(t,n);for(let[t,i]of c){let a=n.filter(e=>e.filePath===t);r.push(...Ni(i,t,e.cwd,a,l))}let u=[];for(let[e,t]of c){if(!/\.module\.[mc]?[tj]sx?$/.test(e))continue;let r=bi(t);if(r.length===0)continue;let i=e.replaceAll(y,`/`),a=i.slice(0,i.lastIndexOf(`/`));for(let t of n){if(t.decorator===`Module`)continue;let n=t.filePath.replaceAll(y,`/`);n.startsWith(a+`/`)&&n!==i&&(Si(n.slice(a.length+1),r)||u.push({className:t.className,filePath:t.filePath,relativePath:t.relativePath,moduleFilePath:e,decorator:t.decorator}))}}n.sort((e,t)=>e.className===t.className?e.relativePath.localeCompare(t.relativePath):e.className.localeCompare(t.className)),i.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),a.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),r.sort((e,t)=>e.controller.localeCompare(t.controller)||e.method.localeCompare(t.method)),o.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),s.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath));let d=Vi(n),f=await Bi(e.cwd,e.envFile??`src/env.ts`);return u.sort((e,t)=>e.relativePath.localeCompare(t.relativePath)||e.className.localeCompare(t.className)),{classes:n,routes:r,tokens:i,injects:a,collisions:d,env:f,pluginsAndAdapters:o,augmentations:s,orphanedClasses:u}}const G="/* 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",Ui=new Set([`Service`,`Repository`,`Injectable`,`Component`]);var Wi=class extends Error{collisions;constructor(e){super(Gi(e)),this.name=`TokenCollisionError`,this.collisions=e}};function Gi(e){let t=[`kick typegen: token collision detected`];for(let n of e){t.push(``),t.push(` ${n.classes.length} classes named '${n.className}':`);for(let e of n.classes)t.push(` - ${e.relativePath}`)}return t.push(``),t.push(`Resolutions:`),t.push(` (a) Rename one of the classes`),t.push(` (b) Use createToken<T>('namespaced/Name') and import the token explicitly — see @forinda/kickjs`),t.push(` (c) Pass --allow-duplicates to namespace the registry keys automatically`),t.push(` (e.g. 'modules/users/UserService' instead of 'UserService')`),t.join(`
3437
- `)}function Ki(e,t){let n=_(f(t),e).split(y).join(`/`);return n=n.replace(/\.(ts|tsx|mts|cts)$/i,``),n.startsWith(`.`)||(n=`./`+n),n}function qi(e){let t=e.relativePath.replace(/^src\//,``).replace(/\.(ts|tsx|mts|cts)$/i,``).split(`/`);t.pop();let n=t.join(`/`);return n?`${n}/${e.className}`:e.className}function Ji(e,t,n){let r=new Set,i=[];for(let a of e){if(!Ui.has(a.decorator))continue;let e=n.has(a.className)?qi(a):a.className;if(r.has(e))continue;r.add(e);let o=Ki(a.filePath,t),s=a.isDefault?`import('${o}').default`:`import('${o}').${a.className}`;i.push(` '${e}': ${s}`)}return`${G}
3531
+ `),s.push(l),s}const ei=[`Service`,`Controller`,`Repository`,`Injectable`,`Component`,`Module`],ti=[`.ts`,`.tsx`,`.mts`,`.cts`],ni=[`node_modules`,`.kickjs`,`dist`,`build`,`.test.`,`.spec.`,`.d.ts`],ri=new RegExp(String.raw`@(${ei.join(`|`)})\s*\([^)]*\)`+String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*`+String.raw`\s*export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`,`g`),ii=new RegExp(String.raw`export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppModule\b`,`g`),ai=/(?:export\s+)?const\s+(\w+)\s*(?::\s*[^=]+)?=\s*createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,oi=/createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,si=/@Inject\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,ci=/\b(defineAdapter|definePlugin)\s*(?:<[^>]*>)?\s*\(/g,li=new RegExp(String.raw`export\s+(?:default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppAdapter\b`,`g`),ui=/\bname\s*(?::\s*[^=]+)?=\s*['"`]([^'"`]+)['"`]/,di=/\bdefineAugmentation\s*\(\s*['"`]([^'"`]+)['"`]\s*(,\s*\{)?/g,fi=new RegExp(String.raw`@(${[`Get`,`Post`,`Put`,`Delete`,`Patch`].join(`|`)})\s*\(`,`g`);function pi(e,t){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 mi(e,t){let n=t;for(;n<e.length;){for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==`@`)break;let t=e.slice(n).match(/^@([A-Z]\w*)/);if(!t)break;for(n+=t[0].length;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]===`(`){let t=pi(e,n);if(t<0)return null;n=t+1}}for(;n<e.length&&/\s/.test(e[n]);)n++;for(let t of[`public`,`private`,`protected`])if(e.slice(n,n+t.length)===t&&/\s/.test(e.charAt(n+t.length))){for(n+=t.length;n<e.length&&/\s/.test(e[n]);)n++;break}if(e.slice(n,n+5)===`async`&&/\s/.test(e.charAt(n+5)))for(n+=5;n<e.length&&/\s/.test(e[n]);)n++;let r=e.slice(n).match(/^([a-zA-Z_]\w*)\s*\(/);return r?{methodName:r[1],endPos:n+r[0].length}:null}function hi(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function gi(e,t){let n=e.endsWith(`/`)?e.slice(0,-1):e;return!t||t===`/`?n||`/`:n+(t.startsWith(`/`)?t:`/`+t)||`/`}const _i=/\b(?:public\s+|private\s+|protected\s+)?routes\s*\([^)]*\)\s*(?::\s*[A-Za-z_][\w<>[\]\s,|]*\s*)?\{/g,vi=/\bpath\s*:\s*['"`]([^'"`]*)['"`]/g,yi=/\bcontroller\s*:\s*([A-Z]\w*)\b/g,bi=/\bimport\.meta\.glob\s*\(/g;function xi(e){let t=[];for(bi.lastIndex=0;bi.exec(e)!==null;){let n=bi.lastIndex-1,r=pi(e,n);if(r<0)continue;let i=e.slice(n+1,r),a=/['"`]([^'"`]+)['"`]/g,o;for(;(o=a.exec(i))!==null;)t.push(o[1])}return t}function Si(e){let t=e.replace(/[.+^$()|[\]\\]/g,`\\$&`).replace(/\?/g,`.`).replace(/\*\*\//g,`___DOUBLESTAR_SLASH___`).replace(/\*\*/g,`___DOUBLESTAR___`).replace(/\*/g,`[^/]*`).replace(/___DOUBLESTAR_SLASH___/g,`(?:.+/)?`).replace(/___DOUBLESTAR___/g,`.*`);return RegExp(`^`+t+`$`)}function Ci(e,t){let n=e.startsWith(`./`)?e:`./`+e,r=!1;for(let e of t){let t=e.startsWith(`!`);Si(t?e.slice(1):e).test(n)&&(r=!t)}return r}function wi(e){let t=[];_i.lastIndex=0;let n;for(;(n=_i.exec(e))!==null;){let r=e.indexOf(`{`,n.index+n[0].length-1);if(r<0)continue;let i=Ii(e,r);if(i<0)continue;let a=e.slice(r+1,i),o=[];vi.lastIndex=0;let s;for(;(s=vi.exec(a))!==null;)o.push(s[1]??``);let c=[];yi.lastIndex=0;let l;for(;(l=yi.exec(a))!==null;)c.push(l[1]);let u=Math.min(o.length,c.length);for(let e=0;e<u;e++)t.push({controller:c[e],mountPath:o[e]})}return t}function Ti(e,t){let n=new RegExp(String.raw`\b${t}\s*:\s*([A-Za-z_$][\w$]*)`,`g`).exec(e);return n?n[1]:null}function Ei(e,t){let n=new RegExp(String.raw`import\s*(?:type\s+)?\{[^}]*\b${t}\b[^}]*\}\s*from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(n)return n[1];let r=new RegExp(String.raw`import\s+(?:type\s+)?${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(r)return r[1];let i=new RegExp(String.raw`import\s*\*\s*as\s+${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);return i?i[1]:new RegExp(String.raw`(?:^|\n)\s*(?:export\s+)?const\s+${t}\b`).test(e)?``:null}function Di(e,t){let n=/@ApiQueryParams\s*\(\s*([\s\S]*?)\s*\)\s*$/.exec(e);if(!n){let n=/@ApiQueryParams\s*\(([\s\S]*?)\)/.exec(e);return n?Oi(n[1].trim(),t):null}return Oi(n[1].trim(),t)}function Oi(e,t){if(e.startsWith(`{`))return Ai(e);let n=/^([A-Za-z_]\w*)/.exec(e);if(n){let e=n[1],r=new RegExp(String.raw`const\s+${e}\s*(?::\s*[^=]+)?=\s*(\{[\s\S]*?\n\})`,`m`).exec(t);if(r)return Ai(r[1])}return{filterable:[],sortable:[],searchable:[]}}function ki(e,t){let n=new RegExp(String.raw`${t}\s*:\s*\[([\s\S]*?)\]`).exec(e);return n?Array.from(n[1].matchAll(/['"`]([^'"`]+)['"`]/g)).map(e=>e[1]):[]}function Ai(e){return{filterable:ki(e,`filterable`),sortable:ki(e,`sortable`),searchable:ki(e,`searchable`)}}async function ji(e,t){let n=t.extensions??ti,r=t.exclude??ni,i=[],a;try{a=await se(e,{withFileTypes:!0,encoding:`utf-8`})}catch{return i}for(let o of a){let a=h(e,o.name),s=_(t.cwd,a);r.some(e=>s.includes(e))||(o.isDirectory()?i.push(...await ji(a,t)):o.isFile()&&n.some(e=>o.name.endsWith(e))&&i.push(a))}return i}function W(e,t){return _(t,e).split(y).join(`/`)}function Mi(e,t,n){let r=[],i=W(t,n);ri.lastIndex=0;let a;for(;(a=ri.exec(e))!==null;){let[,e,n,o]=a;r.push({className:o,decorator:e,filePath:t,relativePath:i,isDefault:!!n})}ii.lastIndex=0;let o;for(;(o=ii.exec(e))!==null;){let[,e,n]=o;r.some(e=>e.className===n&&e.filePath===t)||r.push({className:n,decorator:`Module`,filePath:t,relativePath:i,isDefault:!!e})}return r}function Ni(e,t,n){let r=[],i=W(t,n),a=new Set;ai.lastIndex=0;let o;for(;(o=ai.exec(e))!==null;){let[e,n,s]=o;a.add(e),r.push({name:s,variable:n,filePath:t,relativePath:i})}for(oi.lastIndex=0;(o=oi.exec(e))!==null;)a.has(o[0])||r.push({name:o[1],variable:null,filePath:t,relativePath:i});return r}function Pi(e,t,n,r,i=new Map){let a=[];if(r.length===0)return a;let o=W(t,n),s=[];for(let t of r){let n=new RegExp(String.raw`class\s+${t.className}\b`).exec(e);n?.index!==void 0&&s.push({cls:t,start:n.index})}s.sort((e,t)=>e.start-t.start);for(let n=0;n<s.length;n++){let{cls:r,start:c}=s[n],l=n+1<s.length?s[n+1].start:e.length,u=e.slice(c,l);fi.lastIndex=0;let d;for(;(d=fi.exec(u))!==null;){let n=d[1],s=d.index,c=fi.lastIndex-1,l=pi(u,c);if(l<0)continue;let f=u.slice(c+1,l),p=f.match(/^\s*['"`]([^'"`]*)['"`]/),m=p&&p[1].length>0?p[1]:`/`,h=mi(u,l+1);if(!h)continue;let{methodName:g,endPos:_}=h;fi.lastIndex=_;let v=Di(u.slice(s,_),e),y=Ti(f,`body`),b=Ti(f,`query`),x=Ti(f,`params`),ee=i.get(r.className)??``,S=ee?gi(ee,m):m;a.push({controller:r.className,method:g,httpMethod:n.toUpperCase(),path:m,pathParams:hi(S),queryFilterable:v?.filterable??null,querySortable:v?.sortable??null,querySearchable:v?.searchable??null,bodySchema:y?{identifier:y,source:Ei(e,y)}:null,querySchema:b?{identifier:b,source:Ei(e,b)}:null,paramsSchema:x?{identifier:x,source:Ei(e,x)}:null,filePath:t,relativePath:o})}}return a}function Fi(e,t,n){let r=[],i=W(t,n);si.lastIndex=0;let a;for(;(a=si.exec(e))!==null;)r.push({name:a[1],filePath:t,relativePath:i});return r}function Ii(e,t){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 Li(e,t,n){let r=[],i=W(t,n),a=new Set;ci.lastIndex=0;let o;for(;(o=ci.exec(e))!==null;){let n=o[1],s=ci.lastIndex-1,c=pi(e,s);if(c<0)continue;let l=e.slice(s+1,c),u=/\bname\s*:\s*['"`]([^'"`]+)['"`]/.exec(l);if(!u)continue;let d=u[1],f=`${n}::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:n===`definePlugin`?`plugin`:`adapter`,name:d,filePath:t,relativePath:i}))}li.lastIndex=0;let s;for(;(s=li.exec(e))!==null;){let n=s.index,o=e.indexOf(`{`,n);if(o<0)continue;let c=Ii(e,o);if(c<0)continue;let l=e.slice(o+1,c),u=ui.exec(l);if(!u)continue;let d=u[1],f=`class::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:`adapter`,name:d,filePath:t,relativePath:i}))}return r}function Ri(e,t,n){let r=[],i=W(t,n);di.lastIndex=0;let a;for(;(a=di.exec(e))!==null;){let n=a[1],o=null,s=null;if(a[2]){let t=e.indexOf(`{`,a.index+a[0].length-1);if(t>=0){let n=Ii(e,t);if(n>=0){let r=e.slice(t+1,n);o=zi(r,`description`),s=zi(r,`example`)}}}r.push({name:n,description:o,example:s,filePath:t,relativePath:i})}return r}function zi(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(['"\`])`,`g`).exec(e);if(!n)return null;let r=n[1],i=n.index+n[0].length,a=i,o=null;for(;a<e.length;){let t=e[a];if(t===`\\`){a+=2;continue}if(t===r){o=e.slice(i,a);break}a++}return o===null?null:o.replace(/\\(.)/g,(e,t)=>t===`n`?`
3532
+ `:t===`t`?` `:t===`r`?`\r`:t)}const Bi=[`src/config/index.ts`,`src/config/env.ts`,`src/config.ts`,`src/env.ts`];async function Vi(e,t){let n=t===`src/env.ts`?Bi:[t];for(let t of n){let n=v(e,t),r;try{r=await C(n,`utf-8`)}catch{continue}if(!(!/\bdefineEnv\s*\(/.test(r)&&!/\bfrom(Zod|Valibot|Yup)\s*\(/.test(r))&&/export\s+default\b/.test(r)&&!/export\s+default\s+loadEnvFromSchema\s*\(/.test(r))return{filePath:n,relativePath:W(n,e)}}return null}function Hi(e){let t=new Map;for(let n of e){let e=t.get(n.className)??[];e.push(n),t.set(n.className,e)}let n=[];for(let[e,r]of t)new Set(r.map(e=>e.filePath)).size>1&&n.push({className:e,classes:r});return n.sort((e,t)=>e.className.localeCompare(t.className)),n}async function Ui(e){let t=await ji(v(e.root),e),n=[],r=[],i=[],a=[],o=[],s=[],c=new Map;for(let r of t){let t;try{t=await C(r,`utf-8`)}catch{continue}c.set(r,t),n.push(...Mi(t,r,e.cwd)),i.push(...Ni(t,r,e.cwd)),a.push(...Fi(t,r,e.cwd)),o.push(...Li(t,r,e.cwd)),s.push(...Ri(t,r,e.cwd))}let l=new Map;for(let[,e]of c)for(let{controller:t,mountPath:n}of wi(e))l.has(t)||l.set(t,n);for(let[t,i]of c){let a=n.filter(e=>e.filePath===t);r.push(...Pi(i,t,e.cwd,a,l))}let u=[];for(let[e,t]of c){if(!/\.module\.[mc]?[tj]sx?$/.test(e))continue;let r=xi(t);if(r.length===0)continue;let i=e.replaceAll(y,`/`),a=i.slice(0,i.lastIndexOf(`/`));for(let t of n){if(t.decorator===`Module`)continue;let n=t.filePath.replaceAll(y,`/`);n.startsWith(a+`/`)&&n!==i&&(Ci(n.slice(a.length+1),r)||u.push({className:t.className,filePath:t.filePath,relativePath:t.relativePath,moduleFilePath:e,decorator:t.decorator}))}}n.sort((e,t)=>e.className===t.className?e.relativePath.localeCompare(t.relativePath):e.className.localeCompare(t.className)),i.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),a.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),r.sort((e,t)=>e.controller.localeCompare(t.controller)||e.method.localeCompare(t.method)),o.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),s.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath));let d=Hi(n),f=await Vi(e.cwd,e.envFile??`src/env.ts`);return u.sort((e,t)=>e.relativePath.localeCompare(t.relativePath)||e.className.localeCompare(t.className)),{classes:n,routes:r,tokens:i,injects:a,collisions:d,env:f,pluginsAndAdapters:o,augmentations:s,orphanedClasses:u}}const G="/* 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",Wi=new Set([`Service`,`Repository`,`Injectable`,`Component`]);var Gi=class extends Error{collisions;constructor(e){super(Ki(e)),this.name=`TokenCollisionError`,this.collisions=e}};function Ki(e){let t=[`kick typegen: token collision detected`];for(let n of e){t.push(``),t.push(` ${n.classes.length} classes named '${n.className}':`);for(let e of n.classes)t.push(` - ${e.relativePath}`)}return t.push(``),t.push(`Resolutions:`),t.push(` (a) Rename one of the classes`),t.push(` (b) Use createToken<T>('namespaced/Name') and import the token explicitly — see @forinda/kickjs`),t.push(` (c) Pass --allow-duplicates to namespace the registry keys automatically`),t.push(` (e.g. 'modules/users/UserService' instead of 'UserService')`),t.join(`
3533
+ `)}function qi(e,t){let n=_(f(t),e).split(y).join(`/`);return n=n.replace(/\.(ts|tsx|mts|cts)$/i,``),n.startsWith(`.`)||(n=`./`+n),n}function Ji(e){let t=e.relativePath.replace(/^src\//,``).replace(/\.(ts|tsx|mts|cts)$/i,``).split(`/`);t.pop();let n=t.join(`/`);return n?`${n}/${e.className}`:e.className}function Yi(e,t,n){let r=new Set,i=[];for(let a of e){if(!Wi.has(a.decorator))continue;let e=n.has(a.className)?Ji(a):a.className;if(r.has(e))continue;r.add(e);let o=qi(a.filePath,t),s=a.isDefault?`import('${o}').default`:`import('${o}').${a.className}`;i.push(` '${e}': ${s}`)}return`${G}
3438
3534
  declare module '@forinda/kickjs' {
3439
3535
  interface KickJsRegistry {
3440
3536
  ${i.length?i.join(`
@@ -3443,14 +3539,14 @@ ${i.length?i.join(`
3443
3539
  }
3444
3540
 
3445
3541
  export {}
3446
- `}function Yi(e,t,n){return t.length===0?`${G}
3542
+ `}function Xi(e,t,n){return t.length===0?`${G}
3447
3543
  // ${n}
3448
3544
  export type ${e} = never
3449
3545
  `:`${G}
3450
3546
  export type ${e} =
3451
3547
  ${[...new Set(t)].toSorted().map(e=>` | '${e}'`).join(`
3452
3548
  `)}
3453
- `}function Xi(e,t){return`${G}
3549
+ `}function Zi(e,t){return`${G}
3454
3550
  export type { ServiceToken } from './services'
3455
3551
  export type { ModuleToken } from './modules'
3456
3552
 
@@ -3466,7 +3562,7 @@ import './plugins'
3466
3562
  import './augmentations'
3467
3563
  ${t?`import './kick__assets'
3468
3564
  `:``}${e?`import './kick__env'
3469
- `:``}`}function Zi(e){let t=new Map;for(let n of e)t.has(n.name)||t.set(n.name,n);return`${G}
3565
+ `:``}`}function Qi(e){let t=new Map;for(let n of e)t.has(n.name)||t.set(n.name,n);return`${G}
3470
3566
  declare module '@forinda/kickjs' {
3471
3567
  /**
3472
3568
  * Map of every plugin/adapter \`name\` discovered in the project. The
@@ -3481,7 +3577,7 @@ ${[...t.values()].toSorted((e,t)=>e.name.localeCompare(t.name)).map(e=>` '${e
3481
3577
  }
3482
3578
 
3483
3579
  export {}
3484
- `}function Qi(e){if(e.length===0)return`${G}
3580
+ `}function $i(e){if(e.length===0)return`${G}
3485
3581
  // No augmentations discovered.
3486
3582
  //
3487
3583
  // Plugins advertise augmentable interfaces via:
@@ -3505,9 +3601,9 @@ export {}
3505
3601
  ${n.join(`
3506
3602
 
3507
3603
  `)}
3508
- `}async function $i(e){let{classes:t,routes:n=[],tokens:r=[],injects:i=[],collisions:a=[],env:o=null,pluginsAndAdapters:s=[],augmentations:c=[],assets:l={entries:[],count:0},outDir:u,allowDuplicates:d=!1,schemaValidator:p=!1}=e;if(a.length>0&&!d)throw new Wi(a);await oe(u,{recursive:!0});let m=h(u,`registry.d.ts`),g=h(u,`services.d.ts`),_=h(u,`modules.d.ts`),v=h(u,`plugins.d.ts`),y=h(u,`augmentations.d.ts`),b=h(u,`index.d.ts`),x=new Set(a.map(e=>e.className)),ee=Ji(t,m,x),S=t.filter(e=>Ui.has(e.decorator)).map(e=>x.has(e.className)?qi(e):e.className),te=r.map(e=>e.name),ne=i.map(e=>e.name),re=[...S,...te,...ne],ie=t.filter(e=>e.decorator===`Module`).map(e=>e.className),ae=Yi(`ServiceToken`,re,"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)"),C=Yi(`ModuleToken`,ie,"(no @Module classes discovered — `kick g module <name>` to add one)"),se=Zi(s),ce=Qi(c),le=Xi(o!==null,l.count>0);await w(m,ee,`utf-8`),await w(g,ae,`utf-8`),await w(_,C,`utf-8`),await w(v,se,`utf-8`),await w(y,ce,`utf-8`),await w(b,le,`utf-8`);let ue=[m,g,_,v,y,b];await w(h(f(u),`.gitignore`),`# Auto-generated by kick typegen
3604
+ `}async function ea(e){let{classes:t,routes:n=[],tokens:r=[],injects:i=[],collisions:a=[],env:o=null,pluginsAndAdapters:s=[],augmentations:c=[],assets:l={entries:[],count:0},outDir:u,allowDuplicates:d=!1,schemaValidator:p=!1}=e;if(a.length>0&&!d)throw new Gi(a);await oe(u,{recursive:!0});let m=h(u,`registry.d.ts`),g=h(u,`services.d.ts`),_=h(u,`modules.d.ts`),v=h(u,`plugins.d.ts`),y=h(u,`augmentations.d.ts`),b=h(u,`index.d.ts`),x=new Set(a.map(e=>e.className)),ee=Yi(t,m,x),S=t.filter(e=>Wi.has(e.decorator)).map(e=>x.has(e.className)?Ji(e):e.className),te=r.map(e=>e.name),ne=i.map(e=>e.name),re=[...S,...te,...ne],ie=t.filter(e=>e.decorator===`Module`).map(e=>e.className),ae=Xi(`ServiceToken`,re,"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)"),C=Xi(`ModuleToken`,ie,"(no @Module classes discovered — `kick g module <name>` to add one)"),se=Qi(s),ce=$i(c),le=Zi(o!==null,l.count>0);await w(m,ee,`utf-8`),await w(g,ae,`utf-8`),await w(_,C,`utf-8`),await w(v,se,`utf-8`),await w(y,ce,`utf-8`),await w(b,le,`utf-8`);let ue=[m,g,_,v,y,b];await w(h(f(u),`.gitignore`),`# Auto-generated by kick typegen
3509
3605
  *
3510
- `,`utf-8`);let T=new Set(s.map(e=>e.name)).size,E=new Set(c.map(e=>e.name)).size;return{registryEntries:S.length,serviceTokens:new Set(re).size,moduleTokens:ie.length,routeEntries:n.length,pluginEntries:T,augmentationEntries:E,assetEntries:l.count,envWritten:o!==null,written:ue,resolvedCollisions:a.length}}const ea=/^(kick\/)?([a-z][\w-]*\/[A-Z]\w*)(\/.+)?(:[a-z][\w-]+(:[a-z][\w-]+)*)?$/;function ta(e){let t=[];for(let n of e){let e=n.name;e.startsWith(`kickjs.`)||ea.test(e)||t.push({token:e,variable:n.variable,filePath:n.relativePath,reason:"does not match `<scope>/<PascalKey>[/<suffix>][:<instance>]`",suggestion:na(e)})}return t}function na(e){if(/^[A-Z]\w*$/.test(e))return`'<scope>/${e}' (e.g. 'mycorp/${e}')`;if(e.includes(`.`))return`consider '<scope>/PascalKey' instead of dotted form`;let t=/^([a-z][\w-]*)\/([a-z]\w*)$/.exec(e);if(t){let[,e,n]=t;return`'${e}/${n.charAt(0).toUpperCase()}${n.slice(1)}'`}}function ra(e,t){if(!e)return{entries:[],count:0};let n=new Map;for(let[r,i]of Object.entries(e)){if(!i||typeof i.src!=`string`)continue;let e=v(t,i.src);if(!ca(e))continue;let a=pe(i.glob??`**/*`,{cwd:e,nodir:!0,dot:!1,posix:!0});a.sort();let{pairs:o}=me(r,a,{strategy:i.keys??`auto`});for(let{key:e}of o){let t=e.slice(r.length+1);n.set(e,{namespace:r,key:t})}}return{entries:[...n.values()],count:n.size}}function ia(e){let t="/* 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";if(e.entries.length===0)return`${t}
3606
+ `,`utf-8`);let T=new Set(s.map(e=>e.name)).size,E=new Set(c.map(e=>e.name)).size;return{registryEntries:S.length,serviceTokens:new Set(re).size,moduleTokens:ie.length,routeEntries:n.length,pluginEntries:T,augmentationEntries:E,assetEntries:l.count,envWritten:o!==null,written:ue,resolvedCollisions:a.length}}const ta=/^(kick\/)?([a-z][\w-]*\/[A-Z]\w*)(\/.+)?(:[a-z][\w-]+(:[a-z][\w-]+)*)?$/;function na(e){let t=[];for(let n of e){let e=n.name;e.startsWith(`kickjs.`)||ta.test(e)||t.push({token:e,variable:n.variable,filePath:n.relativePath,reason:"does not match `<scope>/<PascalKey>[/<suffix>][:<instance>]`",suggestion:ra(e)})}return t}function ra(e){if(/^[A-Z]\w*$/.test(e))return`'<scope>/${e}' (e.g. 'mycorp/${e}')`;if(e.includes(`.`))return`consider '<scope>/PascalKey' instead of dotted form`;let t=/^([a-z][\w-]*)\/([a-z]\w*)$/.exec(e);if(t){let[,e,n]=t;return`'${e}/${n.charAt(0).toUpperCase()}${n.slice(1)}'`}}function ia(e,t){if(!e)return{entries:[],count:0};let n=new Map;for(let[r,i]of Object.entries(e)){if(!i||typeof i.src!=`string`)continue;let e=v(t,i.src);if(!la(e))continue;let a=pe(i.glob??`**/*`,{cwd:e,nodir:!0,dot:!1,posix:!0});a.sort();let{pairs:o}=me(r,a,{strategy:i.keys??`auto`});for(let{key:e}of o){let t=e.slice(r.length+1);n.set(e,{namespace:r,key:t})}}return{entries:[...n.values()],count:n.size}}function aa(e){let t="/* 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";if(e.entries.length===0)return`${t}
3511
3607
  declare module '@forinda/kickjs' {
3512
3608
  /**
3513
3609
  * Map of every typed asset discovered in the project's assetMap.
@@ -3518,7 +3614,7 @@ declare module '@forinda/kickjs' {
3518
3614
  }
3519
3615
 
3520
3616
  export {}
3521
- `;let n={};for(let t of e.entries){let e=`${t.namespace}/${t.key}`.split(`/`),r=n;for(let t=0;t<e.length-1;t++){let n=e[t],i=r[n];if(i===aa){let e={};r[n]=e,r=e}else i||(r[n]={}),r=r[n]}let i=e[e.length-1];typeof r[i]!=`object`&&(r[i]=aa)}return`${t}
3617
+ `;let n={};for(let t of e.entries){let e=`${t.namespace}/${t.key}`.split(`/`),r=n;for(let t=0;t<e.length-1;t++){let n=e[t],i=r[n];if(i===oa){let e={};r[n]=e,r=e}else i||(r[n]={}),r=r[n]}let i=e[e.length-1];typeof r[i]!=`object`&&(r[i]=oa)}return`${t}
3522
3618
  declare module '@forinda/kickjs' {
3523
3619
  /**
3524
3620
  * Map of every typed asset discovered in the project's assetMap.
@@ -3527,30 +3623,30 @@ declare module '@forinda/kickjs' {
3527
3623
  * prod → dist).
3528
3624
  */
3529
3625
  interface KickAssets {
3530
- ${oa(n,` `)}
3626
+ ${sa(n,` `)}
3531
3627
  }
3532
3628
  }
3533
3629
 
3534
3630
  export {}
3535
- `}const aa=Symbol(`asset-leaf`);function oa(e,t){let n=Object.keys(e).toSorted(),r=[];for(let i of n){let n=e[i],a=sa(i)?i:JSON.stringify(i);n===aa?r.push(`${t}${a}: () => string`):(r.push(`${t}${a}: {`),r.push(oa(n,`${t} `)),r.push(`${t}}`))}return r.join(`
3536
- `)}function sa(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function ca(e){try{return c(e).isDirectory()}catch{return!1}}var la=D({runTypegen:()=>K,sweepStaleTypegen:()=>pa,watchTypegen:()=>da});function ua(e){let t=e.cwd??process.cwd();return{cwd:t,srcDir:v(t,e.srcDir??`src`),outDir:v(t,e.outDir??`.kickjs/types`),silent:e.silent??!1,allowDuplicates:e.allowDuplicates??!1,schemaValidator:e.schemaValidator??!1,envFile:e.envFile??`src/env.ts`}}async function K(e={}){let{cwd:t,srcDir:n,outDir:r,silent:i,allowDuplicates:a,schemaValidator:o,envFile:s}=ua(e),c=Date.now(),l=await Hi({root:n,cwd:t,envFile:s===!1?void 0:s}),u=ra(e.assetMap,t),d=await $i({classes:l.classes,routes:l.routes,tokens:l.tokens,injects:l.injects,collisions:l.collisions,env:s===!1?null:l.env,pluginsAndAdapters:l.pluginsAndAdapters,augmentations:l.augmentations,assets:u,outDir:r,allowDuplicates:a,schemaValidator:o}),f=[];if(e.runPlugins!==!1)try{let{runAllPluginTypegens:e}=await Promise.resolve().then(()=>wa),{loadKickConfig:n}=await Promise.resolve().then(()=>Me);f=await e({cwd:t,config:await n(t),silent:!0})}catch(e){if(!i){let t=e instanceof Error?e.message:String(e);console.warn(` kick typegen: plugin pipeline failed (${t}) — continuing`)}}e.runPlugins!==!1&&await pa(r,d.written,f,i);let p=ta(l.tokens),m=Date.now()-c;if(!i){let e=r.replace(t+`/`,``),n=d.resolvedCollisions>0?`, ${d.resolvedCollisions} collisions namespaced`:``,i=d.envWritten?`, env typed`:``,a=d.pluginEntries>0?`, ${d.pluginEntries} plugins/adapters`:``,o=d.augmentationEntries>0?`, ${d.augmentationEntries} augmentations`:``,s=d.assetEntries>0?`, ${d.assetEntries} assets`:``;if(console.log(` kick typegen → ${d.serviceTokens} services, ${d.routeEntries} routes, ${d.moduleTokens} modules${a}${o}${s}${i}${n} → ${e} (${m}ms)`),p.length>0){console.warn(` kick typegen: ${p.length} token(s) don't match the §22.2 convention:`);for(let e of p){let t=e.variable?` [${e.variable}]`:``;console.warn(` '${e.token}' (${e.filePath})${t} — ${e.reason}`),e.suggestion&&console.warn(` → suggestion: ${e.suggestion}`)}}if(l.orphanedClasses.length>0){console.warn(` kick typegen: ${l.orphanedClasses.length} decorated class(es) not matched by any module's import.meta.glob():`);for(let e of l.orphanedClasses)console.warn(` @${e.decorator} ${e.className} (${e.relativePath})`),console.warn(` → not picked up by any glob in ${e.moduleFilePath}`)}}return{scan:l,result:d,tokenWarnings:p}}async function da(e={}){let t=ua(e),{srcDir:n,silent:r,cwd:i}=t,a={...t,allowDuplicates:!0,runPlugins:!1},o=process.env.KICKJS_WATCH_POLLING===`1`||process.env.KICKJS_WATCH_POLLING===`true`,[{runAllPluginTypegens:s},{loadKickConfig:c}]=await Promise.all([Promise.resolve().then(()=>wa),Promise.resolve().then(()=>Me)]),l=await c(i),u=[],d=async()=>{try{u=(await K({...a})).result.written}catch(e){if(r)return;if(e instanceof Wi)console.error(`
3631
+ `}const oa=Symbol(`asset-leaf`);function sa(e,t){let n=Object.keys(e).toSorted(),r=[];for(let i of n){let n=e[i],a=ca(i)?i:JSON.stringify(i);n===oa?r.push(`${t}${a}: () => string`):(r.push(`${t}${a}: {`),r.push(sa(n,`${t} `)),r.push(`${t}}`))}return r.join(`
3632
+ `)}function ca(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function la(e){try{return c(e).isDirectory()}catch{return!1}}var ua=D({runTypegen:()=>K,sweepStaleTypegen:()=>ma,watchTypegen:()=>fa});function da(e){let t=e.cwd??process.cwd();return{cwd:t,srcDir:v(t,e.srcDir??`src`),outDir:v(t,e.outDir??`.kickjs/types`),silent:e.silent??!1,allowDuplicates:e.allowDuplicates??!1,schemaValidator:e.schemaValidator??!1,envFile:e.envFile??`src/env.ts`}}async function K(e={}){let{cwd:t,srcDir:n,outDir:r,silent:i,allowDuplicates:a,schemaValidator:o,envFile:s}=da(e),c=Date.now(),l=await Ui({root:n,cwd:t,envFile:s===!1?void 0:s}),u=ia(e.assetMap,t),d=await ea({classes:l.classes,routes:l.routes,tokens:l.tokens,injects:l.injects,collisions:l.collisions,env:s===!1?null:l.env,pluginsAndAdapters:l.pluginsAndAdapters,augmentations:l.augmentations,assets:u,outDir:r,allowDuplicates:a,schemaValidator:o}),f=[];if(e.runPlugins!==!1)try{let{runAllPluginTypegens:e}=await Promise.resolve().then(()=>Ta),{loadKickConfig:n}=await Promise.resolve().then(()=>Me);f=await e({cwd:t,config:await n(t),silent:!0})}catch(e){if(!i){let t=e instanceof Error?e.message:String(e);console.warn(` kick typegen: plugin pipeline failed (${t}) — continuing`)}}e.runPlugins!==!1&&await ma(r,d.written,f,i);let p=na(l.tokens),m=Date.now()-c;if(!i){let e=r.replace(t+`/`,``),n=d.resolvedCollisions>0?`, ${d.resolvedCollisions} collisions namespaced`:``,i=d.envWritten?`, env typed`:``,a=d.pluginEntries>0?`, ${d.pluginEntries} plugins/adapters`:``,o=d.augmentationEntries>0?`, ${d.augmentationEntries} augmentations`:``,s=d.assetEntries>0?`, ${d.assetEntries} assets`:``;if(console.log(` kick typegen → ${d.serviceTokens} services, ${d.routeEntries} routes, ${d.moduleTokens} modules${a}${o}${s}${i}${n} → ${e} (${m}ms)`),p.length>0){console.warn(` kick typegen: ${p.length} token(s) don't match the §22.2 convention:`);for(let e of p){let t=e.variable?` [${e.variable}]`:``;console.warn(` '${e.token}' (${e.filePath})${t} — ${e.reason}`),e.suggestion&&console.warn(` → suggestion: ${e.suggestion}`)}}if(l.orphanedClasses.length>0){console.warn(` kick typegen: ${l.orphanedClasses.length} decorated class(es) not matched by any module's import.meta.glob():`);for(let e of l.orphanedClasses)console.warn(` @${e.decorator} ${e.className} (${e.relativePath})`),console.warn(` → not picked up by any glob in ${e.moduleFilePath}`)}}return{scan:l,result:d,tokenWarnings:p}}async function fa(e={}){let t=da(e),{srcDir:n,silent:r,cwd:i}=t,a={...t,allowDuplicates:!0,runPlugins:!1},o=process.env.KICKJS_WATCH_POLLING===`1`||process.env.KICKJS_WATCH_POLLING===`true`,[{runAllPluginTypegens:s},{loadKickConfig:c}]=await Promise.all([Promise.resolve().then(()=>Ta),Promise.resolve().then(()=>Me)]),l=await c(i),u=[],d=async()=>{try{u=(await K({...a})).result.written}catch(e){if(r)return;if(e instanceof Gi)console.error(`
3537
3633
  `+e.message+`
3538
- `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}},f=async()=>{try{let e=await s({cwd:i,config:l,silent:!0});await pa(t.outDir,u,e,!0)}catch{}};await d(),await f();let{watch:p}=await import(`node:fs`),m=null,h=e=>{e&&/\.(ts|tsx|mts|cts)$/.test(e)&&(e.includes(`.kickjs`)||e.endsWith(`.d.ts`)||(m&&clearTimeout(m),m=setTimeout(()=>{d().then(f)},100)))};if(o){r||console.log(` kick typegen: polling mode (KICKJS_WATCH_POLLING)`);let e=setInterval(()=>{fa({...a,silent:!0},!0)},2e3);return()=>clearInterval(e)}let g;try{g=p(n,{recursive:!0},(e,t)=>{h(t)})}catch(e){r||console.warn(` kick typegen: watch mode unavailable (${e?.message??e}). Falling back to polling.`);let t=setInterval(()=>{fa({...a,silent:!0},!0)},2e3);return()=>clearInterval(t)}return()=>{m&&clearTimeout(m),g.close()}}async function fa(e,t){try{await K(e)}catch(e){if(t)return;if(e instanceof Wi)console.error(`
3634
+ `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}},f=async()=>{try{let e=await s({cwd:i,config:l,silent:!0});await ma(t.outDir,u,e,!0)}catch{}};await d(),await f();let{watch:p}=await import(`node:fs`),m=null,h=e=>{e&&/\.(ts|tsx|mts|cts)$/.test(e)&&(e.includes(`.kickjs`)||e.endsWith(`.d.ts`)||(m&&clearTimeout(m),m=setTimeout(()=>{d().then(f)},100)))};if(o){r||console.log(` kick typegen: polling mode (KICKJS_WATCH_POLLING)`);let e=setInterval(()=>{pa({...a,silent:!0},!0)},2e3);return()=>clearInterval(e)}let g;try{g=p(n,{recursive:!0},(e,t)=>{h(t)})}catch(e){r||console.warn(` kick typegen: watch mode unavailable (${e?.message??e}). Falling back to polling.`);let t=setInterval(()=>{pa({...a,silent:!0},!0)},2e3);return()=>clearInterval(t)}return()=>{m&&clearTimeout(m),g.close()}}async function pa(e,t){try{await K(e)}catch(e){if(t)return;if(e instanceof Gi)console.error(`
3539
3635
  `+e.message+`
3540
- `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}}async function pa(e,t,n,r){let i=new Set;for(let e of t)i.add(d(e));for(let e of n)e.outFile&&i.add(d(e.outFile));let a;try{a=await se(e)}catch{return[]}let o=[];for(let t of a){if(i.has(t))continue;let n=v(e,t);try{if(!(await le(n)).isFile())continue;await ue(n),o.push(t)}catch{}}return o.length>0&&!r&&console.log(` kick typegen: swept ${o.length} stale file(s): ${o.join(`, `)}`),o}const ma=[`agents`,`claude`,`skills`,`gemini`,`copilot`,`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(`
3541
- (dry run — no files were written)`),console.log()}async function ha(e){if(!e)try{let e=await k(process.cwd());await K({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 ga=[{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 _a(){console.log(`
3636
+ `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}}async function ma(e,t,n,r){let i=new Set;for(let e of t)i.add(d(e));for(let e of n)e.outFile&&i.add(d(e.outFile));let a;try{a=await se(e)}catch{return[]}let o=[];for(let t of a){if(i.has(t))continue;let n=v(e,t);try{if(!(await le(n)).isFile())continue;await ue(n),o.push(t)}catch{}}return o.length>0&&!r&&console.log(` kick typegen: swept ${o.length} stale file(s): ${o.join(`, `)}`),o}const ha=[`agents`,`claude`,`skills`,`gemini`,`copilot`,`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(`
3637
+ (dry run — no files were written)`),console.log()}async function ga(e){if(!e)try{let e=await k(process.cwd());await K({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 _a=[{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 va(){console.log(`
3542
3638
  Built-in generators:
3543
- `);let e=Math.max(...ga.map(e=>e.name.length));for(let t of ga)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await k(process.cwd()),n=He(t?.plugins??[],t?.commands??[]),r=await un(process.cwd(),n.generators);if(r.generators.length>0){console.log(`
3639
+ `);let e=Math.max(..._a.map(e=>e.name.length));for(let t of _a)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await k(process.cwd()),n=He(t?.plugins??[],t?.commands??[]),r=await dn(process.cwd(),n.generators);if(r.generators.length>0){console.log(`
3544
3640
  Plugin generators:
3545
3641
  `);let e=Math.max(...r.generators.map(e=>`${e.spec.name} <name>`.length));for(let{source:t,spec:n}of r.generators){let r=`${n.name} <name>`;console.log(` kick g ${r.padEnd(e+2)} ${n.description} [${t}]`)}}if(r.failed.length>0){console.log(`
3546
3642
  Failed to load:
3547
- `);for(let{source:e,reason:t}of r.failed)console.log(` ${e} — ${t}`)}console.log()}async function va(e,t,n){let r=await k(process.cwd()),i=O(r),a=t.modulesDir??i.dir??`src/modules`,o=t.repo??Xn(i.repo),s=t.pattern??r?.pattern??`ddd`,c=t.pluralize===!1?!1:i.pluralize??!0,l=Ie(r,process.cwd()),u=i.style??`define`;if(!n&&u===`define`){let e=await Fr(v(a),`define`);if(e.length>0){console.error(`\n ${E.red(`Error:`)} ${e.length} module file(s) still use the legacy \`class … implements AppModule\` shape.\n ${E.dim(`Project setting:`)} modules.style: 'define' (default)\n\n ${E.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 ${E.bold(`Pick one:`)}\n 1. Migrate everything to defineModule:\n ${E.dim(`$`)} kick codemod modules --experimental --apply\n 2. Keep the class form — pin it in kick.config.ts:\n ${E.dim(`// kick.config.ts`)}\n ${E.dim(`export default defineConfig({ modules: { style: 'class' } })`)}\n`),process.exit(1)}}let d=[];for(let r of e){let e=await Zn({name:r,modulesDir:v(a),noEntity:t.entity===!1,noTests:t.tests===!1,repo:o,minimal:t.minimal,force:t.force,pattern:s,dryRun:n,pluralize:c,prismaClientPath:i.prismaClientPath,tokenScope:l,style:i.style});d.push(...e)}J(d,n),await ha(n)}function ya(e,t){let n=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,r,i)=>{if(r.list){await _a();return}if(!e||e.length===0){n.help();return}let a=q(i);j(a);let[o,s,...c]=e;if(o){let e=await k(process.cwd()),n=He(e?.plugins??[],e?.commands??[]),i=await ln({generatorName:o,itemName:s??``,args:c,flags:r,cwd:process.cwd(),projectRoot:t?.projectRoot},n.generators);if(i){J(i.files,a);return}}await va(e,r,a)});n.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 va(e,{...n.optsWithGlobals(),...t},r)}),n.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 ar({name:e,outDir:v(t.out)}),r)}),n.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 or({name:e,outDir:v(t.out)}),r)}),n.command(`middleware <name>`).description(`Generate an Express middleware function
3548
- 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await dr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`guard <name>`).description(`Generate a route guard (auth, roles, etc.)
3549
- 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await fr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`service <name>`).description(`Generate a @Service() class
3550
- 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await pr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`controller <name>`).description(`Generate a @Controller() class with basic routes
3551
- 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await mr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r),await ha(r)}),n.command(`dto <name>`).description(`Generate a Zod DTO schema
3552
- 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await hr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`test <name>`).description(`Generate a Vitest test scaffold
3553
- 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,n)=>{let r=q(n);j(r);let i=O(await k(process.cwd())),a=i.dir??`src/modules`;J(await Qr({name:e,outDir:t.out,moduleName:t.module,modulesDir:a,pluralize:i.pluralize??!0}),r)}),n.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 Ir({name:e,outDir:v(t.out),queue:t.queue}),r)}),n.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
3643
+ `);for(let{source:e,reason:t}of r.failed)console.log(` ${e} — ${t}`)}console.log()}async function ya(e,t,n){let r=await k(process.cwd()),i=O(r),a=t.modulesDir??i.dir??`src/modules`,o=t.repo??Zn(i.repo),s=t.pattern??r?.pattern??`ddd`,c=t.pluralize===!1?!1:i.pluralize??!0,l=Ie(r,process.cwd()),u=i.style??`define`;if(!n&&u===`define`){let e=await Ir(v(a),`define`);if(e.length>0){console.error(`\n ${E.red(`Error:`)} ${e.length} module file(s) still use the legacy \`class … implements AppModule\` shape.\n ${E.dim(`Project setting:`)} modules.style: 'define' (default)\n\n ${E.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 ${E.bold(`Pick one:`)}\n 1. Migrate everything to defineModule:\n ${E.dim(`$`)} kick codemod modules --experimental --apply\n 2. Keep the class form — pin it in kick.config.ts:\n ${E.dim(`// kick.config.ts`)}\n ${E.dim(`export default defineConfig({ modules: { style: 'class' } })`)}\n`),process.exit(1)}}let d=[];for(let r of e){let e=await Qn({name:r,modulesDir:v(a),noEntity:t.entity===!1,noTests:t.tests===!1,repo:o,minimal:t.minimal,force:t.force,pattern:s,dryRun:n,pluralize:c,prismaClientPath:i.prismaClientPath,tokenScope:l,style:i.style});d.push(...e)}J(d,n),await ga(n)}function ba(e,t){let n=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,r,i)=>{if(r.list){await va();return}if(!e||e.length===0){n.help();return}let a=q(i);j(a);let[o,s,...c]=e;if(o){let e=await k(process.cwd()),n=He(e?.plugins??[],e?.commands??[]),i=await un({generatorName:o,itemName:s??``,args:c,flags:r,cwd:process.cwd(),projectRoot:t?.projectRoot},n.generators);if(i){J(i.files,a);return}}await ya(e,r,a)});n.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 ya(e,{...n.optsWithGlobals(),...t},r)}),n.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 or({name:e,outDir:v(t.out)}),r)}),n.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 sr({name:e,outDir:v(t.out)}),r)}),n.command(`middleware <name>`).description(`Generate an Express middleware function
3644
+ 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await fr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`guard <name>`).description(`Generate a route guard (auth, roles, etc.)
3645
+ 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await pr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`service <name>`).description(`Generate a @Service() class
3646
+ 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await mr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`controller <name>`).description(`Generate a @Controller() class with basic routes
3647
+ 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await hr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r),await ga(r)}),n.command(`dto <name>`).description(`Generate a Zod DTO schema
3648
+ 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,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await gr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`test <name>`).description(`Generate a Vitest test scaffold
3649
+ 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,n)=>{let r=q(n);j(r);let i=O(await k(process.cwd())),a=i.dir??`src/modules`;J(await $r({name:e,outDir:t.out,moduleName:t.module,modulesDir:a,pluralize:i.pluralize??!0}),r)}),n.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 Lr({name:e,outDir:v(t.out),queue:t.queue}),r)}),n.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
3554
3650
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
3555
3651
  Types: string, text, number, int, float, boolean, date, email, url, uuid, json, enum:a,b,c
3556
3652
  Optional: append :optional (shell-safe): description:text:optional
@@ -3559,11 +3655,11 @@ export {}
3559
3655
  Usage: kick g scaffold <name> <field:type> [field:type...]
3560
3656
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
3561
3657
  Optional: append :optional (shell-safe, no quoting needed)
3562
- `),process.exit(1));let a=await k(process.cwd()),o=O(a),s=n.modulesDir??o.dir??`src/modules`,c=Rr(t),l=Ie(a,process.cwd()),u=a?.pattern??`ddd`;u!==`ddd`&&(console.error(`\n Error: 'kick g scaffold' currently only supports the DDD pattern.\n Detected project pattern: '${u}'.\n Workarounds:\n - Run 'kick g module ${e}' for the ${u} 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 d=await zr({name:e,fields:c,modulesDir:v(s),noEntity:n.entity===!1,noTests:n.tests===!1,pluralize:n.pluralize===!1?!1:o.pluralize??!0,tokenScope:l,style:o.style});console.log(`\n Scaffolded ${e} with ${c.length} field(s):`);for(let e of c)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);J(d,i),await ha(i)}),n.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 gr({outDir:v(`.`),modulesDir:e.modulesDir,defaultRepo:e.repo,force:e.force}),n)}),n.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(!ma.includes(r)){console.error(` Invalid --only value: ${r}. Expected: ${ma.join(` | `)}`),process.exitCode=1;return}J(await Cr({outDir:v(`.`),only:r,name:e.name,pm:e.pm,template:e.template,force:e.force}),n)});for(let e of t?.generators??[])ba(n,e,t?.projectRoot)}function ba(e,t,n){let{source:r,spec:i}=t,a=i.args?.[0],o=a?.name??`itemName`,s=a?.required?`<${o}>`:`[${o}]`,c=`${i.name} ${s} [extraArgs...]`,l=e.command(c).description(`${i.description} [${r}]`);for(let e of i.flags??[]){let t=e.takesValue?`--${e.name} <value>`:`--${e.name}`,n=e.alias?`-${e.alias}, ${t}`:t;l.option(n,e.description??``)}l.action(async(e,r,a,o)=>{let s=q(o);j(s);let c=await ln({generatorName:i.name,itemName:e??``,args:r??[],flags:a,cwd:process.cwd(),projectRoot:n},[t]);c&&J(c.files,s)})}async function xa(e){let t=u.resolve(e.cwd,`.kickjs/types`);await oe(t,{recursive:!0});let n=new Map,i=e.scan??Hi,a={cwd:e.cwd,config:e.config,async importTs(e){return await import(x(e).href)},async writeFile(t,n){let r=u.resolve(e.cwd,t);await oe(u.dirname(r),{recursive:!0}),await w(r,n,`utf8`)},getScanResult:e=>{let t=Sa(e),r=n.get(t);return r||(r=i(e),n.set(t,r)),r},log:console},o=[];for(let n of e.plugins){let i=await n.generate(a);if(i===null){o.push({id:n.id,status:`skipped`});continue}let s=n.outExtension??`.d.ts`,c=u.join(t,`${n.id.replace(/\//g,`__`)}${s}`),l=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: ${n.id} */\n\n`+i+`
3563
- `,d=``;if(r(c)&&(d=await C(c,`utf8`)),d===l){o.push({id:n.id,status:`unchanged`,outFile:c});continue}if(e.check)throw Error(`kick typegen --check: drift detected for ${n.id} (${c})`);await w(c,l,`utf8`),o.push({id:n.id,status:`written`,outFile:c})}return o}function Sa(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 Ca(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 wa=D({applyDisableFilter:()=>Ca,runAllPluginTypegens:()=>Ta});async function Ta(e){let{enabled:t,skipped:n,unknown:r}=Ca(He([...As,...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 xa({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 Ea(e,t){let{cwd:n,silent:r=!1}=t,a=t.distDir??e?.build?.outDir??`dist`,o=e?.assetMap;if(!o||Object.keys(o).length===0)return null;let s=r?()=>{}:console.log,c=v(n,a);i(c,{recursive:!0});let u=[],d={};for(let[e,t]of Object.entries(o)){let r=await Da(e,t,n,c);u.push(r.entrySummary),Object.assign(d,r.manifestSlice),s(` ✓ ${e}: ${r.entrySummary.filesCopied} file(s) → ${r.entrySummary.dest}`)}let f={version:1,entries:d},p=h(c,`.kickjs-assets.json`);return l(p,JSON.stringify(f,null,2)+`
3564
- `,`utf-8`),s(` ✓ wrote manifest → ${_(n,p)} (${Object.keys(d).length} entries)`),{manifestPath:p,entries:u,manifest:f}}async function Da(e,t,a,o){let s=v(a,t.src),c=t.dest?v(a,t.dest):h(o,e);if(ka(c,a))return console.warn(` ⚠ assetMap.${e}.dest ('${t.dest}') resolves outside the project root — skipping copy`),{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:0},manifestSlice:{}};if(!r(s)||!Aa(s))return{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:0},manifestSlice:{}};let l=await fe(t.glob??`**/*`,{cwd:s,nodir:!0,dot:!1,posix:!0});i(c,{recursive:!0});let u={},{pairs:d,collisionGroupsResolved:p}=me(e,[...l].toSorted(),{strategy:t.keys??`auto`});for(let{rel:e,key:t}of d){let r=h(s,e),a=h(c,e);i(f(a),{recursive:!0}),n(r,a),u[t]=Oa(o,a)}return p>0&&console.log(` ℹ assetMap.${e}: auto-resolved ${p} 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:_(a,c),filesCopied:l.length},manifestSlice:u}}function Oa(e,t){return _(e,t).split(/[\\/]/).filter(Boolean).join(`/`)}function ka(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function Aa(e){try{return c(e).isDirectory()}catch{return!1}}function ja(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function Ma(e,t,n={}){t&&(process.env.PORT=t);let r=ja(n.polling),i=process.cwd(),a=await k(i),o=a?.typegen?.schemaValidator??`zod`,s=a?.typegen?.envFile;try{await K({cwd:i,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1})}catch(e){console.warn(` kick typegen: skipped (${e?.message??e})`)}await Ta({cwd:i,config:a});let{createRequire:c}=await import(`node:module`),{createServer:l}=await import(x(c(v(`package.json`)).resolve(`vite`)).href),u=await l({configFile:v(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...r?{watch:{usePolling:!0,interval:100}}:{}}}),d=a?.assetMap?Object.values(a.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>v(i,e)):[],f=e=>d.some(t=>e===t||e.startsWith(`${t}/`)),p=null,m=e=>{if(e.includes(`.kickjs`)||e.endsWith(`.d.ts`))return;let t=/\.(ts|tsx|mts|cts)$/.test(e),n=f(e);!t&&!n||(p&&clearTimeout(p),p=setTimeout(()=>{K({cwd:i,silent:!0,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1}).catch(()=>{}),Ta({cwd:i,config:a,silent:!0}).catch(()=>{})},100))};u.watcher.on(`add`,m),u.watcher.on(`unlink`,m),u.watcher.on(`change`,m),d.length>0&&u.watcher.add(d),await u.listen(),u.printUrls(),console.log(`
3658
+ `),process.exit(1));let a=await k(process.cwd()),o=O(a),s=n.modulesDir??o.dir??`src/modules`,c=zr(t),l=Ie(a,process.cwd()),u=a?.pattern??`ddd`;u!==`ddd`&&(console.error(`\n Error: 'kick g scaffold' currently only supports the DDD pattern.\n Detected project pattern: '${u}'.\n Workarounds:\n - Run 'kick g module ${e}' for the ${u} 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 d=await Br({name:e,fields:c,modulesDir:v(s),noEntity:n.entity===!1,noTests:n.tests===!1,pluralize:n.pluralize===!1?!1:o.pluralize??!0,tokenScope:l,style:o.style});console.log(`\n Scaffolded ${e} with ${c.length} field(s):`);for(let e of c)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);J(d,i),await ga(i)}),n.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 _r({outDir:v(`.`),modulesDir:e.modulesDir,defaultRepo:e.repo,force:e.force}),n)}),n.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(!ha.includes(r)){console.error(` Invalid --only value: ${r}. Expected: ${ha.join(` | `)}`),process.exitCode=1;return}J(await wr({outDir:v(`.`),only:r,name:e.name,pm:e.pm,template:e.template,force:e.force}),n)});for(let e of t?.generators??[])xa(n,e,t?.projectRoot)}function xa(e,t,n){let{source:r,spec:i}=t,a=i.args?.[0],o=a?.name??`itemName`,s=a?.required?`<${o}>`:`[${o}]`,c=`${i.name} ${s} [extraArgs...]`,l=e.command(c).description(`${i.description} [${r}]`);for(let e of i.flags??[]){let t=e.takesValue?`--${e.name} <value>`:`--${e.name}`,n=e.alias?`-${e.alias}, ${t}`:t;l.option(n,e.description??``)}l.action(async(e,r,a,o)=>{let s=q(o);j(s);let c=await un({generatorName:i.name,itemName:e??``,args:r??[],flags:a,cwd:process.cwd(),projectRoot:n},[t]);c&&J(c.files,s)})}async function Sa(e){let t=u.resolve(e.cwd,`.kickjs/types`);await oe(t,{recursive:!0});let n=new Map,i=e.scan??Ui,a={cwd:e.cwd,config:e.config,async importTs(e){return await import(x(e).href)},async writeFile(t,n){let r=u.resolve(e.cwd,t);await oe(u.dirname(r),{recursive:!0}),await w(r,n,`utf8`)},getScanResult:e=>{let t=Ca(e),r=n.get(t);return r||(r=i(e),n.set(t,r)),r},log:console},o=[];for(let n of e.plugins){let i=await n.generate(a);if(i===null){o.push({id:n.id,status:`skipped`});continue}let s=n.outExtension??`.d.ts`,c=u.join(t,`${n.id.replace(/\//g,`__`)}${s}`),l=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: ${n.id} */\n\n`+i+`
3659
+ `,d=``;if(r(c)&&(d=await C(c,`utf8`)),d===l){o.push({id:n.id,status:`unchanged`,outFile:c});continue}if(e.check)throw Error(`kick typegen --check: drift detected for ${n.id} (${c})`);await w(c,l,`utf8`),o.push({id:n.id,status:`written`,outFile:c})}return o}function Ca(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 wa(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 Ta=D({applyDisableFilter:()=>wa,runAllPluginTypegens:()=>Ea});async function Ea(e){let{enabled:t,skipped:n,unknown:r}=wa(He([...js,...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 Sa({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 Da(e,t){let{cwd:n,silent:r=!1}=t,a=t.distDir??e?.build?.outDir??`dist`,o=e?.assetMap;if(!o||Object.keys(o).length===0)return null;let s=r?()=>{}:console.log,c=v(n,a);i(c,{recursive:!0});let u=[],d={};for(let[e,t]of Object.entries(o)){let r=await Oa(e,t,n,c);u.push(r.entrySummary),Object.assign(d,r.manifestSlice),s(` ✓ ${e}: ${r.entrySummary.filesCopied} file(s) → ${r.entrySummary.dest}`)}let f={version:1,entries:d},p=h(c,`.kickjs-assets.json`);return l(p,JSON.stringify(f,null,2)+`
3660
+ `,`utf-8`),s(` ✓ wrote manifest → ${_(n,p)} (${Object.keys(d).length} entries)`),{manifestPath:p,entries:u,manifest:f}}async function Oa(e,t,a,o){let s=v(a,t.src),c=t.dest?v(a,t.dest):h(o,e);if(Aa(c,a))return console.warn(` ⚠ assetMap.${e}.dest ('${t.dest}') resolves outside the project root — skipping copy`),{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:0},manifestSlice:{}};if(!r(s)||!ja(s))return{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:0},manifestSlice:{}};let l=await fe(t.glob??`**/*`,{cwd:s,nodir:!0,dot:!1,posix:!0});i(c,{recursive:!0});let u={},{pairs:d,collisionGroupsResolved:p}=me(e,[...l].toSorted(),{strategy:t.keys??`auto`});for(let{rel:e,key:t}of d){let r=h(s,e),a=h(c,e);i(f(a),{recursive:!0}),n(r,a),u[t]=ka(o,a)}return p>0&&console.log(` ℹ assetMap.${e}: auto-resolved ${p} 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:_(a,c),filesCopied:l.length},manifestSlice:u}}function ka(e,t){return _(e,t).split(/[\\/]/).filter(Boolean).join(`/`)}function Aa(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function ja(e){try{return c(e).isDirectory()}catch{return!1}}function Ma(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function Na(e,t,n={}){t&&(process.env.PORT=t);let r=Ma(n.polling),i=process.cwd(),a=await k(i),o=a?.typegen?.schemaValidator??`zod`,s=a?.typegen?.envFile;try{await K({cwd:i,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1})}catch(e){console.warn(` kick typegen: skipped (${e?.message??e})`)}await Ea({cwd:i,config:a});let{createRequire:c}=await import(`node:module`),{createServer:l}=await import(x(c(v(`package.json`)).resolve(`vite`)).href),u=await l({configFile:v(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...r?{watch:{usePolling:!0,interval:100}}:{}}}),d=a?.assetMap?Object.values(a.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>v(i,e)):[],f=e=>d.some(t=>e===t||e.startsWith(`${t}/`)),p=null,m=e=>{if(e.includes(`.kickjs`)||e.endsWith(`.d.ts`))return;let t=/\.(ts|tsx|mts|cts)$/.test(e),n=f(e);!t&&!n||(p&&clearTimeout(p),p=setTimeout(()=>{K({cwd:i,silent:!0,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1}).catch(()=>{}),Ea({cwd:i,config:a,silent:!0}).catch(()=>{})},100))};u.watcher.on(`add`,m),u.watcher.on(`unlink`,m),u.watcher.on(`change`,m),d.length>0&&u.watcher.add(d),await u.listen(),u.printUrls(),console.log(`
3565
3661
  KickJS dev server running (Vite + @forinda/kickjs-vite)
3566
- `);let h=async()=>{p&&clearTimeout(p),await u.close(),process.exit(0)};process.on(`SIGINT`,h),process.on(`SIGTERM`,h)}function Na(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 Ma(e.entry,e.port,{polling:e.polling})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
3662
+ `);let h=async()=>{p&&clearTimeout(p),await u.close(),process.exit(0)};process.on(`SIGINT`,h),process.on(`SIGTERM`,h)}function Pa(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 Na(e.entry,e.port,{polling:e.polling})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
3567
3663
  Error: vite is not installed.
3568
3664
  Run: pnpm add -D vite unplugin-swc
3569
3665
  `):console.error(`
@@ -3571,13 +3667,13 @@ export {}
3571
3667
  Building for production...
3572
3668
  `);let{createRequire:e}=await import(`node:module`),{build:t}=await import(x(e(v(`package.json`)).resolve(`vite`)).href);await t({configFile:v(`vite.config.ts`)});let a=await k(process.cwd()),o=a?.copyDirs??[];if(o.length>0){console.log(`
3573
3669
  Copying directories to dist...`);for(let e of o){let t=typeof e==`string`?e:e.src,a=typeof e==`string`?h(`dist`,e):e.dest??h(`dist`,t),o=v(t),s=v(a);if(!r(o)){console.log(` ⚠ Skipped ${t} (not found)`);continue}i(s,{recursive:!0}),n(o,s,{recursive:!0}),console.log(` ✓ ${t} → ${a}`)}}if(a?.assetMap&&Object.keys(a.assetMap).length>0){console.log(`
3574
- Building asset map...`);try{await Ea(a,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
3670
+ Building asset map...`);try{await Da(a,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
3575
3671
  Build complete.
3576
3672
  `)}),e.command(`build:assets`).description(`Rebuild the .kickjs-assets.json manifest under the configured outDir (no JS rebuild)`).action(async()=>{let e=await k(process.cwd());if(!e?.assetMap||Object.keys(e.assetMap).length===0){console.log(` No assetMap entries — nothing to build.`);return}console.log(`
3577
- Building asset map...`);try{await Ea(e,{cwd:process.cwd()}),console.log(`
3673
+ Building asset map...`);try{await Da(e,{cwd:process.cwd()}),console.log(`
3578
3674
  Asset build complete.
3579
- `)}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)),ke(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 Ma(e.entry,e.port)}catch(e){console.error(`
3580
- Dev server (debug) failed:`,e.message??e),process.exit(1)}})}function Pa(e){e.command(`info`).description(`Print system and framework info`).action(()=>{console.log(`
3675
+ `)}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)),ke(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 Na(e.entry,e.port)}catch(e){console.error(`
3676
+ Dev server (debug) failed:`,e.message??e),process.exit(1)}})}function Fa(e){e.command(`info`).description(`Print system and framework info`).action(()=>{console.log(`
3581
3677
  KickJS CLI
3582
3678
 
3583
3679
  System:
@@ -3588,7 +3684,7 @@ export {}
3588
3684
  @forinda/kickjs workspace
3589
3685
  @forinda/kickjs-vite workspace
3590
3686
  @forinda/kickjs-cli workspace
3591
- `)})}const{bold:Y,dim:X,green:Fa,red:Ia,yellow:La,blue:Ra}=E;function za(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 Ba(e){let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw Error(`${t.status} ${t.statusText}`);return t.json()}async function Va(e,t){try{return await Ba(`${e}${t}`)}catch{return null}}async function Ha(e){let[t,n,r,i,a]=await Promise.all([Va(e,`/health`),Va(e,`/metrics`),Va(e,`/routes`),Va(e,`/container`),Va(e,`/ws`)]);return{health:t,metrics:n,routes:r,container:i,ws:a}}function Ua(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`?Fa(`● healthy`):Ia(`● `+n.status);console.log(` ${Y(`Health:`)} ${e}`)}else console.log(` ${Y(`Health:`)} ${Ia(`● unreachable`)}`);if(r){let e=((r.errorRate??0)*100).toFixed(1),t=r.errorRate>.1?Ia:r.errorRate>0?La:Fa;console.log(` ${Y(`Uptime:`)} ${za(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(` ${At(e.method)} ${t} ${Ra(e.controller)}.${X(e.handler)}`)}}console.log(s),console.log()}function Wa(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 Ha(r);t.json?console.log(JSON.stringify(e,null,2)):Ua(n,e)}catch(e){t.json?console.log(JSON.stringify({error:String(e)})):(console.error(Ia(` ✖ 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 Ga(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 Ka=[{match(e,t){let n=Ga(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
3687
+ `)})}const{bold:Y,dim:X,green:Ia,red:La,yellow:Ra,blue:za}=E;function Ba(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 Va(e){let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw Error(`${t.status} ${t.statusText}`);return t.json()}async function Ha(e,t){try{return await Va(`${e}${t}`)}catch{return null}}async function Ua(e){let[t,n,r,i,a]=await Promise.all([Ha(e,`/health`),Ha(e,`/metrics`),Ha(e,`/routes`),Ha(e,`/container`),Ha(e,`/ws`)]);return{health:t,metrics:n,routes:r,container:i,ws:a}}function Wa(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`?Ia(`● healthy`):La(`● `+n.status);console.log(` ${Y(`Health:`)} ${e}`)}else console.log(` ${Y(`Health:`)} ${La(`● unreachable`)}`);if(r){let e=((r.errorRate??0)*100).toFixed(1),t=r.errorRate>.1?La:r.errorRate>0?Ra:Ia;console.log(` ${Y(`Uptime:`)} ${Ba(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(` ${jt(e.method)} ${t} ${za(e.controller)}.${X(e.handler)}`)}}console.log(s),console.log()}function Ga(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 Ua(r);t.json?console.log(JSON.stringify(e,null,2)):Wa(n,e)}catch(e){t.json?console.log(JSON.stringify({error:String(e)})):(console.error(La(` ✖ 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 Ka(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 qa=[{match(e,t){let n=Ka(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
3592
3688
  registers the env schema with kickjs at module-load time. Without it,
3593
3689
  ConfigService falls back to the base schema (PORT/NODE_ENV/LOG_LEVEL only)
3594
3690
  and every user-defined key reads as undefined. @Value() may *appear* to
@@ -3610,7 +3706,7 @@ describe('UserController', () => {
3610
3706
  beforeEach(() => Container.reset())
3611
3707
 
3612
3708
  it('does the thing', async () => { /* ... */ })
3613
- })`,docs:`https://forinda.github.io/kick-js/guide/testing.html`}}:null}},{match(e,t){return e.includes(`@Module`)||Ga(e,[`Module`,`is not a function`])||Ga(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
3709
+ })`,docs:`https://forinda.github.io/kick-js/guide/testing.html`}}:null}},{match(e,t){return e.includes(`@Module`)||Ka(e,[`Module`,`is not a function`])||Ka(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
3614
3710
  pattern instead: a class implements AppModule and exposes routes() that
3615
3711
  returns the controller wiring. This was a deliberate choice — modules
3616
3712
  become explicit values rather than metadata, which makes them easier to
@@ -3662,24 +3758,24 @@ drop the entry.`,fix:`Open src/modules/index.ts and verify the module is in the
3662
3758
  import { UserModule } from './users/user.module'
3663
3759
  import { TaskModule } from './tasks/task.module' // ← was this missing?
3664
3760
 
3665
- export const modules: AppModuleEntry[] = [UserModule(), TaskModule()]`,docs:`https://forinda.github.io/kick-js/guide/project-structure.html`}}:null}}];function qa(e,t){let n=null;for(let r of Ka){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 Ja(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.
3761
+ export const modules: AppModuleEntry[] = [UserModule(), TaskModule()]`,docs:`https://forinda.github.io/kick-js/guide/project-structure.html`}}:null}}];function Ja(e,t){let n=null;for(let r of qa){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 Ya(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.
3666
3762
  export OPENAI_API_KEY="sk-..."
3667
3763
 
3668
3764
  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:
3669
3765
  kick add ai
3670
3766
 
3671
3767
  Or manually:
3672
- pnpm add @forinda/kickjs-ai`}}let{OpenAIProvider:i}=r,a=new i({apiKey:n,defaultChatModel:e.model??`gpt-4o-mini`}),o=Ya(e.cwd),s=`Error or stack trace:\n\n${e.input.trim()}`;try{let e=Xa((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 Ya(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(`
3673
- `)}function Xa(e){let t=[e,Za(e),Qa(e)].filter(e=>e!==null);for(let e of t)try{let t=JSON.parse(e);if($a(t))return t}catch{continue}return null}function Za(e){let t=e.match(/```(?:json)?\s*\n([\s\S]*?)```/);return t?t[1]?.trim()??null:null}function Qa(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 $a(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 eo(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 ro(e,t.message);(!n||n.trim().length===0)&&(process.stderr.write(`Error: no input provided.
3768
+ pnpm add @forinda/kickjs-ai`}}let{OpenAIProvider:i}=r,a=new i({apiKey:n,defaultChatModel:e.model??`gpt-4o-mini`}),o=Xa(e.cwd),s=`Error or stack trace:\n\n${e.input.trim()}`;try{let e=Za((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 Xa(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(`
3769
+ `)}function Za(e){let t=[e,Qa(e),$a(e)].filter(e=>e!==null);for(let e of t)try{let t=JSON.parse(e);if(eo(t))return t}catch{continue}return null}function Qa(e){let t=e.match(/```(?:json)?\s*\n([\s\S]*?)```/);return t?t[1]?.trim()??null:null}function $a(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 eo(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 to(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 io(e,t.message);(!n||n.trim().length===0)&&(process.stderr.write(`Error: no input provided.
3674
3770
 
3675
3771
  Pass a message as a positional arg, --message flag, or pipe via stdin:
3676
3772
  kick explain "config.get returned undefined"
3677
3773
  pnpm test 2>&1 | kick explain
3678
- `),process.exit(1));let r=ao(),i=qa(n,r);if(t.json&&i){process.stdout.write(JSON.stringify({matched:!0,...i},null,2)+`
3679
- `);return}if(i){oo(n,i.diagnosis,i.confidence);return}t.ai||(t.json&&(process.stdout.write(JSON.stringify({matched:!1},null,2)+`
3680
- `),process.exit(2)),so(n,!1),process.exit(2));let a=await Ja({input:n,model:t.model,cwd:r.cwd});t.json&&(process.stdout.write(JSON.stringify(to(a),null,2)+`
3681
- `),process.exit(a.kind===`ok`?0:2)),no(n,a),process.exit(a.kind===`ok`?0:2)})}function to(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 no(e,t){if(t.kind===`ok`){oo(e,t.diagnosis,-1,!0);return}if(t.kind===`unavailable`){process.stdout.write(`\n Explaining: ${lo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback unavailable: ${t.reason}\n\n`),process.stdout.write(`${co(t.suggestion,` `)}\n\n`);return}process.stdout.write(`\n Explaining: ${lo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback error: ${t.message}\n\n`)}async function ro(e,t){return e&&e.trim().length>0?e:t&&t.trim().length>0?t:process.stdin.isTTY?``:io()}function io(){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 ao(){let e=process.cwd();return{cwd:e,hasFile:t=>r(v(e,t))}}function oo(e,t,n,r=!1){let i=lo(e.trim(),200),a=r?`AI-generated — verify before applying`:uo(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${co(t.explanation,` `)}\n`),process.stdout.write(`\n Fix:\n${co(t.fix,` `)}\n`),t.codeBefore&&process.stdout.write(`\n Before:\n${co(t.codeBefore,` `)}\n`),t.codeAfter&&process.stdout.write(`\n After:\n${co(t.codeAfter,` `)}\n`),t.docs&&process.stdout.write(`\n Docs: ${t.docs}\n`),process.stdout.write(`
3682
- `)}function so(e,t){let n=lo(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.
3774
+ `),process.exit(1));let r=oo(),i=Ja(n,r);if(t.json&&i){process.stdout.write(JSON.stringify({matched:!0,...i},null,2)+`
3775
+ `);return}if(i){so(n,i.diagnosis,i.confidence);return}t.ai||(t.json&&(process.stdout.write(JSON.stringify({matched:!1},null,2)+`
3776
+ `),process.exit(2)),co(n,!1),process.exit(2));let a=await Ya({input:n,model:t.model,cwd:r.cwd});t.json&&(process.stdout.write(JSON.stringify(no(a),null,2)+`
3777
+ `),process.exit(a.kind===`ok`?0:2)),ro(n,a),process.exit(a.kind===`ok`?0:2)})}function no(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 ro(e,t){if(t.kind===`ok`){so(e,t.diagnosis,-1,!0);return}if(t.kind===`unavailable`){process.stdout.write(`\n Explaining: ${uo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback unavailable: ${t.reason}\n\n`),process.stdout.write(`${lo(t.suggestion,` `)}\n\n`);return}process.stdout.write(`\n Explaining: ${uo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback error: ${t.message}\n\n`)}async function io(e,t){return e&&e.trim().length>0?e:t&&t.trim().length>0?t:process.stdin.isTTY?``:ao()}function ao(){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 oo(){let e=process.cwd();return{cwd:e,hasFile:t=>r(v(e,t))}}function so(e,t,n,r=!1){let i=uo(e.trim(),200),a=r?`AI-generated — verify before applying`:fo(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${lo(t.explanation,` `)}\n`),process.stdout.write(`\n Fix:\n${lo(t.fix,` `)}\n`),t.codeBefore&&process.stdout.write(`\n Before:\n${lo(t.codeBefore,` `)}\n`),t.codeAfter&&process.stdout.write(`\n After:\n${lo(t.codeAfter,` `)}\n`),t.docs&&process.stdout.write(`\n Docs: ${t.docs}\n`),process.stdout.write(`
3778
+ `)}function co(e,t){let n=uo(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.
3683
3779
  When @forinda/kickjs-ai ships its provider implementations,
3684
3780
  this command will call the configured LLM with the error +
3685
3781
  project context and return a structured fix.
@@ -3696,12 +3792,12 @@ Pass a message as a positional arg, --message flag, or pipe via stdin:
3696
3792
  3. File an issue with the error text:
3697
3793
  https://github.com/forinda/kick-js/issues/new
3698
3794
 
3699
- `)}function co(e,t){return e.split(`
3795
+ `)}function lo(e,t){return e.split(`
3700
3796
  `).map(e=>`${t}${e}`).join(`
3701
- `)}function lo(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function uo(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function fo(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(po),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(mo)}function po(e){let t=v(e.entry);r(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],i=ne(process.execPath,n,{stdio:`inherit`,env:{...process.env,KICK_MCP_STDIO:`1`,NODE_ENV:process.env.NODE_ENV??`production`}});i.on(`error`,e=>{process.stderr.write(`Failed to start MCP server: ${e.message}\n`),process.exit(1)}),i.on(`exit`,(e,t)=>{if(t){process.kill(process.pid,t);return}process.exit(e??0)});let a=e=>{i.killed||i.kill(e)};process.on(`SIGINT`,()=>a(`SIGINT`)),process.on(`SIGTERM`,()=>a(`SIGTERM`))}function mo(e){let t=process.cwd(),n=ho(t)??d(t),i=e.name??n,o=e.global?v(process.env.HOME??`.`,`.mcp.json`):v(t,e.out),s={command:`kick`,args:[`mcp`],cwd:t},c={mcpServers:{}};if(r(o))try{let e=a(o,`utf8`),t=JSON.parse(e);t&&typeof t==`object`&&t.mcpServers&&(c={mcpServers:{...t.mcpServers}})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: existing ${o} is not valid JSON (${t}).\nFix the file or pass --force to overwrite the entry.\n`),process.exit(1)}c.mcpServers[i]&&!e.force&&(process.stderr.write(`Error: an entry for "${i}" already exists in ${o}.\nPass --force to overwrite it, or use --name to pick a different key.\n`),process.exit(1)),c.mcpServers[i]=s,l(o,JSON.stringify(c,null,2)+`
3702
- `,`utf8`),process.stdout.write(`\n ✓ Wrote MCP server entry "${i}" to ${o}\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 ho(e){let t=v(e,`package.json`);if(!r(t))return null;try{let e=a(t,`utf8`),n=JSON.parse(e);return typeof n.name==`string`?n.name:null}catch{return null}}function go(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=v(t,e.entry);r(n)||(console.error(`\n Error: ${e.entry} not found.\n`),process.exit(1));let i=vo(t,`tsx`);i||(console.error(`
3797
+ `)}function uo(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function fo(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function po(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(mo),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(ho)}function mo(e){let t=v(e.entry);r(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],i=ne(process.execPath,n,{stdio:`inherit`,env:{...process.env,KICK_MCP_STDIO:`1`,NODE_ENV:process.env.NODE_ENV??`production`}});i.on(`error`,e=>{process.stderr.write(`Failed to start MCP server: ${e.message}\n`),process.exit(1)}),i.on(`exit`,(e,t)=>{if(t){process.kill(process.pid,t);return}process.exit(e??0)});let a=e=>{i.killed||i.kill(e)};process.on(`SIGINT`,()=>a(`SIGINT`)),process.on(`SIGTERM`,()=>a(`SIGTERM`))}function ho(e){let t=process.cwd(),n=go(t)??d(t),i=e.name??n,o=e.global?v(process.env.HOME??`.`,`.mcp.json`):v(t,e.out),s={command:`kick`,args:[`mcp`],cwd:t},c={mcpServers:{}};if(r(o))try{let e=a(o,`utf8`),t=JSON.parse(e);t&&typeof t==`object`&&t.mcpServers&&(c={mcpServers:{...t.mcpServers}})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: existing ${o} is not valid JSON (${t}).\nFix the file or pass --force to overwrite the entry.\n`),process.exit(1)}c.mcpServers[i]&&!e.force&&(process.stderr.write(`Error: an entry for "${i}" already exists in ${o}.\nPass --force to overwrite it, or use --name to pick a different key.\n`),process.exit(1)),c.mcpServers[i]=s,l(o,JSON.stringify(c,null,2)+`
3798
+ `,`utf8`),process.stdout.write(`\n ✓ Wrote MCP server entry "${i}" to ${o}\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 go(e){let t=v(e,`package.json`);if(!r(t))return null;try{let e=a(t,`utf8`),n=JSON.parse(e);return typeof n.name==`string`?n.name:null}catch{return null}}function _o(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=v(t,e.entry);r(n)||(console.error(`\n Error: ${e.entry} not found.\n`),process.exit(1));let i=yo(t,`tsx`);i||(console.error(`
3703
3799
  Error: tsx not found. Install it: pnpm add -D tsx
3704
- `),process.exit(1));let a=_o(n,e.entry),o=h(t,`.kick-tinker.mjs`),{writeFileSync:s,unlinkSync:c}=await import(`node:fs`);s(o,a,`utf-8`);try{let e=te(o,[],{cwd:t,execPath:i,stdio:`inherit`});await new Promise(t=>{e.on(`exit`,()=>t())})}finally{try{c(o)}catch{}}})}function _o(e,t){return`
3800
+ `),process.exit(1));let a=vo(n,e.entry),o=h(t,`.kick-tinker.mjs`),{writeFileSync:s,unlinkSync:c}=await import(`node:fs`);s(o,a,`utf-8`);try{let e=te(o,[],{cwd:t,execPath:i,stdio:`inherit`});await new Promise(t=>{e.on(`exit`,()=>t())})}finally{try{c(o)}catch{}}})}function vo(e,t){return`
3705
3801
  import 'reflect-metadata'
3706
3802
 
3707
3803
  // Prevent bootstrap() from starting the HTTP server
@@ -3755,40 +3851,40 @@ server.on('exit', () => {
3755
3851
  console.log('\\n Goodbye!\\n')
3756
3852
  process.exit(0)
3757
3853
  })
3758
- `}function vo(e,t){let n=e;for(;;){let e=h(n,`node_modules`,`.bin`,t);if(r(e))return e;let i=v(n,`..`);if(i===n)break;n=i}return null}function yo(e,t){let n=RegExp(`^\\s*${B(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]!==`
3854
+ `}function yo(e,t){let n=e;for(;;){let e=h(n,`node_modules`,`.bin`,t);if(r(e))return e;let i=v(n,`..`);if(i===n)break;n=i}return null}function bo(e,t){let n=RegExp(`^\\s*${B(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]!==`
3759
3855
  `;)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]===`
3760
- `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function bo(e,t){let n=er(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=yo(a,t).content,a=a.replace(RegExp(`\\s*,?\\s*${B(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 xo(e){let{name:t,modulesDir:n,force:r}=e,i=e.pluralize!==!1,a=R(t),o=I(t),s=i?z(a):a,c=h(n,s);if(!await Ze(c)){console.log(`\n Module not found: ${c}\n`);return}if(!r&&!await P({message:E.red(`Delete module '${s}' at ${c}? This cannot be undone.`),initialValue:!1})){console.log(`
3856
+ `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function xo(e,t){let n=tr(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=bo(a,t).content,a=a.replace(RegExp(`\\s*,?\\s*${B(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 So(e){let{name:t,modulesDir:n,force:r}=e,i=e.pluralize!==!1,a=R(t),o=I(t),s=i?z(a):a,c=h(n,s);if(!await Ze(c)){console.log(`\n Module not found: ${c}\n`);return}if(!r&&!await P({message:E.red(`Delete module '${s}' at ${c}? This cannot be undone.`),initialValue:!1})){console.log(`
3761
3857
  Cancelled.
3762
- `);return}await ce(c,{recursive:!0,force:!0}),console.log(` Deleted: ${c}`);let l=h(n,`index.ts`);if(await Ze(l)){let e=await C(l,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${B(o)}Module\\s*\\}\\s*from\\s*['"][^'"]*${B(s)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=bo(e,o),e=e.replace(/\n{3,}/g,`
3858
+ `);return}await ce(c,{recursive:!0,force:!0}),console.log(` Deleted: ${c}`);let l=h(n,`index.ts`);if(await Ze(l)){let e=await C(l,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${B(o)}Module\\s*\\}\\s*from\\s*['"][^'"]*${B(s)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=xo(e,o),e=e.replace(/\n{3,}/g,`
3763
3859
 
3764
- `),e!==t&&(await w(l,e,`utf-8`),console.log(` Unregistered: ${o}Module from ${l}`))}console.log(`\n Module '${s}' removed.\n`)}function So(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 n=O(await k(process.cwd())),r=t.modulesDir??n.dir??`src/modules`,i=t.pluralize===!1?!1:n.pluralize??!0;for(let n of e)await xo({name:n,modulesDir:v(r),force:t.force,pluralize:i})})}function Co(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 wo(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function To(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=Qt(process.cwd()),n=await k(t);if(e.list){let{mergeCliPlugins:e}=await Promise.resolve().then(()=>Ue),{builtinCliPlugins:t}=await Promise.resolve().then(()=>ks),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(`
3860
+ `),e!==t&&(await w(l,e,`utf-8`),console.log(` Unregistered: ${o}Module from ${l}`))}console.log(`\n Module '${s}' removed.\n`)}function Co(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 n=O(await k(process.cwd())),r=t.modulesDir??n.dir??`src/modules`,i=t.pluralize===!1?!1:n.pluralize??!0;for(let n of e)await So({name:n,modulesDir:v(r),force:t.force,pluralize:i})})}function wo(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;if(e===`kickjs-schema`||e===`schema`)return`kickjs-schema`;console.warn(` kick typegen: unknown --schema-validator '${e}' (supported: 'zod', 'kickjs-schema', 'false'). Falling back to project config.`)}}function To(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function Eo(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=$t(process.cwd()),n=await k(t);if(e.list){let{mergeCliPlugins:e}=await Promise.resolve().then(()=>Ue),{builtinCliPlugins:t}=await Promise.resolve().then(()=>As),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(`
3765
3861
  Registered typegen plugins:
3766
- `);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 r=Co(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,i=wo(e.envFile)??n?.typegen?.envFile,a={cwd:t,srcDir:e.src??n?.typegen?.srcDir,outDir:e.out??n?.typegen?.outDir,silent:e.silent,allowDuplicates:e.allowDuplicates,schemaValidator:r,envFile:i,assetMap:n?.assetMap,runPlugins:!1};try{if(e.watch){let t=await da(a);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 K(a),i=await Ta({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 pa(v(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r.written,i,e.silent??!1)}}catch(e){e instanceof Wi?console.error(`
3862
+ `);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 r=wo(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,i=To(e.envFile)??n?.typegen?.envFile,a={cwd:t,srcDir:e.src??n?.typegen?.srcDir,outDir:e.out??n?.typegen?.outDir,silent:e.silent,allowDuplicates:e.allowDuplicates,schemaValidator:r,envFile:i,assetMap:n?.assetMap,runPlugins:!1};try{if(e.watch){let t=await fa(a);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 K(a),i=await Ea({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 ma(v(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r.written,i,e.silent??!1)}}catch(e){e instanceof Gi?console.error(`
3767
3863
  `+e.message+`
3768
- `):e instanceof Error?console.error(`\n kick typegen failed: ${e.message}`):console.error(`\n kick typegen failed: ${JSON.stringify(e)}`),process.exit(1)}})}function Eo(e){let t=[];if(!r(e))return t;let n=o(e,{withFileTypes:!0});for(let r of n){let n=h(e,r.name);if(r.isDirectory()){if([`node_modules`,`dist`,`.kickjs`,`.git`].includes(r.name))continue;t.push(...Eo(n))}else r.isFile()&&/\.tsx?$/.test(r.name)&&!r.name.endsWith(`.d.ts`)&&t.push(n)}return t}function Do(e){try{return a(e,`utf-8`)}catch{return``}}const Oo=new Set([`secret`,`changeme`,`password`,`test`,`default`,``]);function ko(e,t){let n=Do(h(e,`.env`));if(n){let e=n.match(/^JWT_SECRET\s*=\s*['"]?([^'"\n]*)['"]?/m);if(e){let t=e[1].trim();if(Oo.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 Ao(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 jo(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 Mo(){return process.env.NODE_ENV===`production`?null:{severity:`WARNING`,message:`NODE_ENV is '${process.env.NODE_ENV??`undefined`}', not 'production'`}}function No(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 Po(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 Fo(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 Io(e){let t=Eo(h(e,`src`)).map(e=>Do(e)),n=[],r=ko(e,t);r&&n.push(r);let i=Ao(t);i&&n.push(i);let a=jo(t);a&&n.push(a);let o=Mo();o&&n.push(o);let s=No(t);return s&&n.push(s),n.push(Po(t)),n.push(Fo(t)),n}function Lo(e){e.command(`check`).description(`Audit project for common issues`).option(`--deploy`,`Run production readiness checks`).action(e=>{if(!e.deploy){console.log(`
3864
+ `):e instanceof Error?console.error(`\n kick typegen failed: ${e.message}`):console.error(`\n kick typegen failed: ${JSON.stringify(e)}`),process.exit(1)}})}function Do(e){let t=[];if(!r(e))return t;let n=o(e,{withFileTypes:!0});for(let r of n){let n=h(e,r.name);if(r.isDirectory()){if([`node_modules`,`dist`,`.kickjs`,`.git`].includes(r.name))continue;t.push(...Do(n))}else r.isFile()&&/\.tsx?$/.test(r.name)&&!r.name.endsWith(`.d.ts`)&&t.push(n)}return t}function Oo(e){try{return a(e,`utf-8`)}catch{return``}}const ko=new Set([`secret`,`changeme`,`password`,`test`,`default`,``]);function Ao(e,t){let n=Oo(h(e,`.env`));if(n){let e=n.match(/^JWT_SECRET\s*=\s*['"]?([^'"\n]*)['"]?/m);if(e){let t=e[1].trim();if(ko.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 jo(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 Mo(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 No(){return process.env.NODE_ENV===`production`?null:{severity:`WARNING`,message:`NODE_ENV is '${process.env.NODE_ENV??`undefined`}', not 'production'`}}function Po(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 Fo(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 Io(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 Lo(e){let t=Do(h(e,`src`)).map(e=>Oo(e)),n=[],r=Ao(e,t);r&&n.push(r);let i=jo(t);i&&n.push(i);let a=Mo(t);a&&n.push(a);let o=No();o&&n.push(o);let s=Po(t);return s&&n.push(s),n.push(Fo(t)),n.push(Io(t)),n}function Ro(e){e.command(`check`).description(`Audit project for common issues`).option(`--deploy`,`Run production readiness checks`).action(e=>{if(!e.deploy){console.log(`
3769
3865
  Usage: kick check --deploy
3770
3866
 
3771
3867
  Available checks:
3772
3868
  --deploy Audit for production readiness (security, config, best practices)
3773
- `);return}let t=process.cwd();Mt(`KickJS Deploy Check`);let n=Lt();n.start(`Scanning project...`);let r=Io(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)F.message(`${jt(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?E.red(`${a} critical`):`${a} critical`,o>0?E.yellow(`${o} ${c}`):`${o} ${c}`,`${s} info`].join(`, `);a>0?(N(E.red(`${l} — fix critical issues before deploying`)),process.exit(1)):N(E.green(`${l} — looking good!`))})}function Ro(e){try{return JSON.parse(a(e,`utf-8`))}catch{return null}}function zo(e){try{return a(e,`utf-8`)}catch{return null}}function Bo(e){let t=zo(h(e,`tsconfig.json`));if(!t)return null;let n=t.replace(/\/\*[\s\S]*?\*\//g,``).replace(/\/\/.*$/gm,``),r;try{r=JSON.parse(n)}catch{return null}if(typeof r?.extends==`string`){let t=Vo(e,r.extends);if(t){let e=Ro(t)??{};r.compilerOptions={...e.compilerOptions,...r.compilerOptions}}}return r}function Vo(e,t){if(t.startsWith(`.`)){let n=v(e,t);return r(n)?n:null}let n=h(e,`node_modules`,t);return r(n)?n:null}function Ho(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function Uo(){let e=process.version,t=Number.parseInt(e.replace(/^v/,``).split(`.`)[0],10);return Number.isNaN(t)||t<20?{name:`Node version`,status:`fail`,message:e,fix:`KickJS requires Node 20 or newer.
3774
- Install a supported version via nvm / fnm / volta.`}:{name:`Node version`,status:`pass`,message:e}}function Wo(e){if(!e.pkg)return{name:`@forinda/kickjs installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]?{name:`@forinda/kickjs installed`,status:`pass`,message:t[`@forinda/kickjs`]}:{name:`@forinda/kickjs installed`,status:`fail`,fix:"This directory does not look like a KickJS project — `@forinda/kickjs` is not in your package.json. Run `kick doctor` from the project root, or scaffold a fresh project with `kick new <name>`."}}function Go(e){if(!e.pkg)return null;let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]&&!t.express?{name:`express installed`,status:`fail`,fix:"`@forinda/kickjs` declares `express` as a required peer dependency, but your package.json does not include it. Install: pnpm add express"}:t.express?{name:`express installed`,status:`pass`,message:t.express}:null}function Ko(e){if(!e.pkg)return{name:`reflect-metadata installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies,...e.pkg.devDependencies};return t[`reflect-metadata`]?{name:`reflect-metadata installed`,status:`pass`,message:t[`reflect-metadata`]}:{name:`reflect-metadata installed`,status:`fail`,fix:`KickJS decorators require the reflect-metadata polyfill.
3869
+ `);return}let t=process.cwd();Nt(`KickJS Deploy Check`);let n=Rt();n.start(`Scanning project...`);let r=Lo(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)F.message(`${Mt(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?E.red(`${a} critical`):`${a} critical`,o>0?E.yellow(`${o} ${c}`):`${o} ${c}`,`${s} info`].join(`, `);a>0?(N(E.red(`${l} — fix critical issues before deploying`)),process.exit(1)):N(E.green(`${l} — looking good!`))})}function zo(e){try{return JSON.parse(a(e,`utf-8`))}catch{return null}}function Bo(e){try{return a(e,`utf-8`)}catch{return null}}function Vo(e){let t=Bo(h(e,`tsconfig.json`));if(!t)return null;let n=t.replace(/\/\*[\s\S]*?\*\//g,``).replace(/\/\/.*$/gm,``),r;try{r=JSON.parse(n)}catch{return null}if(typeof r?.extends==`string`){let t=Ho(e,r.extends);if(t){let e=zo(t)??{};r.compilerOptions={...e.compilerOptions,...r.compilerOptions}}}return r}function Ho(e,t){if(t.startsWith(`.`)){let n=v(e,t);return r(n)?n:null}let n=h(e,`node_modules`,t);return r(n)?n:null}function Uo(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function Wo(){let e=process.version,t=Number.parseInt(e.replace(/^v/,``).split(`.`)[0],10);return Number.isNaN(t)||t<20?{name:`Node version`,status:`fail`,message:e,fix:`KickJS requires Node 20 or newer.
3870
+ Install a supported version via nvm / fnm / volta.`}:{name:`Node version`,status:`pass`,message:e}}function Go(e){if(!e.pkg)return{name:`@forinda/kickjs installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]?{name:`@forinda/kickjs installed`,status:`pass`,message:t[`@forinda/kickjs`]}:{name:`@forinda/kickjs installed`,status:`fail`,fix:"This directory does not look like a KickJS project — `@forinda/kickjs` is not in your package.json. Run `kick doctor` from the project root, or scaffold a fresh project with `kick new <name>`."}}function Ko(e){if(!e.pkg)return null;let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]&&!t.express?{name:`express installed`,status:`fail`,fix:"`@forinda/kickjs` declares `express` as a required peer dependency, but your package.json does not include it. Install: pnpm add express"}:t.express?{name:`express installed`,status:`pass`,message:t.express}:null}function qo(e){if(!e.pkg)return{name:`reflect-metadata installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies,...e.pkg.devDependencies};return t[`reflect-metadata`]?{name:`reflect-metadata installed`,status:`pass`,message:t[`reflect-metadata`]}:{name:`reflect-metadata installed`,status:`fail`,fix:`KickJS decorators require the reflect-metadata polyfill.
3775
3871
  Install it: pnpm add reflect-metadata
3776
3872
  Then import it at the top of src/index.ts:
3777
3873
 
3778
3874
  import 'reflect-metadata'
3779
- // ... rest of bootstrap`}}function qo(e){if(!e.tsconfig)return[{name:`tsconfig.json present`,status:`fail`,fix:"Create a tsconfig.json with `experimentalDecorators: true` and `emitDecoratorMetadata: true`. `kick new` scaffolds one automatically."}];let t=e.tsconfig.compilerOptions??{},n=[];return n.push(t.experimentalDecorators===!0?{name:`tsconfig: experimentalDecorators`,status:`pass`}:{name:`tsconfig: experimentalDecorators`,status:`fail`,fix:'Add `"experimentalDecorators": true` to compilerOptions in tsconfig.json. Without it, @Service / @Controller / @Get etc. don\'t register any metadata at compile time.'}),n.push(t.emitDecoratorMetadata===!0?{name:`tsconfig: emitDecoratorMetadata`,status:`pass`}:{name:`tsconfig: emitDecoratorMetadata`,status:`fail`,fix:'Add `"emitDecoratorMetadata": true` to compilerOptions in tsconfig.json. The DI container uses this metadata for constructor-parameter injection.'}),n}function Jo(e){let t=[`src/env.ts`,`src/env/index.ts`,`src/config/env.ts`,`src/config/index.ts`].map(t=>h(e.cwd,t)).filter(e=>r(e)).filter(e=>/\bloadEnv\s*\(/.test(zo(e)??``));if(t.length===0)return null;let n=[`src/index.ts`,`src/main.ts`].map(t=>h(e.cwd,t)).find(e=>r(e));if(!n)return{name:`env wiring`,status:`warn`,message:`env-init file exists but no src/index.ts or src/main.ts found`};let i=zo(n)??``,a=f(n),o=[];for(let e of t){let t=_(a,e).replace(/\\/g,`/`).replace(/\.ts$/,``),n=t.startsWith(`.`)?t:`./`+t,r=n.replace(/\/index$/,``);o.push(n,r);let i=e.replace(/\\/g,`/`).match(/\/src\/(.+?)(?:\.ts)?$/);if(i){let e=`@/`+i[1],t=e.replace(/\/index$/,``);o.push(e,t)}}let s=-1;for(let e of new Set(o)){let t=RegExp(`^import\\s+(?:.*?from\\s+)?['"]${Ho(e)}['"]`,`m`),n=i.match(t);n&&n.index!==void 0&&(s===-1||n.index<s)&&(s=n.index)}let c=i.search(/\bbootstrap\s*\(/),l=t.map(t=>_(e.cwd,t).replace(/\\/g,`/`)).join(`, `);return s===-1?{name:`env wiring`,status:`fail`,message:l,fix:`An env-init file (${l}) calls \`loadEnv(...)\` but \`${_(e.cwd,n).replace(/\\/g,`/`)}\` doesn't import it.\nWithout this, ConfigService.get('X') returns undefined while @Value('X') works via process.env fallback — a half-broken config you won't notice until something is missing.\n\nFix: add a side-effect import at the top of ${_(e.cwd,n).replace(/\\/g,`/`)} (above bootstrap()), pointing at one of the detected files. For example:\n\n import './env'\n // or\n import './config'\n // or, with the @/ alias:\n import '@/config/env'`}:c!==-1&&s>c?{name:`env wiring`,status:`warn`,message:`env-init imported AFTER bootstrap() — should be before`,fix:`Move the env import above the bootstrap() call so the schema runs before any service reads from ConfigService.`}:{name:`env wiring`,status:`pass`}}function Yo(e,t=Xo){let n=0,r=0,i=[e];for(;i.length>0&&r<t;){let e=i.pop(),a;try{a=o(e,{withFileTypes:!0})}catch{continue}for(let o of a){if(r>=t)break;r++;let a=h(e,o.name);if(o.isDirectory()){i.push(a);continue}try{let e=c(a).mtimeMs;e>n&&(n=e)}catch{}}}return n}const Xo=2e3;function Zo(e){let t=h(e.cwd,`.kickjs`,`types`);if(!r(t))return null;let n=Yo(t);if(n===0)return null;let i=Date.now()-n,a=Math.floor(i/6e4);return a>60?{name:`typegen freshness`,status:`warn`,message:`last updated ${a} minutes ago`,fix:"Re-run `kick typegen` (or `kick dev`, which runs it on every reload) so generated types match the current code."}:{name:`typegen freshness`,status:`pass`,message:a===0?`just now`:`${a}m ago`}}const Qo=[()=>Uo(),Wo,Go,Ko,qo,Jo,Zo];async function $o(e,t={}){let n={cwd:e,pkg:Ro(h(e,`package.json`)),tsconfig:Bo(e)},r=[...Qo,...t.extraChecks??[]],i=[];for(let e of r){let t;try{t=await e(n)}catch(t){i.push({name:e.name||`doctor check`,status:`fail`,message:t instanceof Error?t.message:String(t)});continue}t!=null&&(Array.isArray(t)?i.push(...t):i.push(t))}return i}function es(e){switch(e){case`pass`:return E.green(`✔`);case`warn`:return E.yellow(`⚠`);case`fail`:return E.red(`✖`)}}function ts(e){let t=es(e.status),n=e.message?` ${E.dim(`(${e.message})`)}`:``;return`${t} ${e.name}${n}`}function ns(e){return e.split(`
3875
+ // ... rest of bootstrap`}}function Jo(e){if(!e.tsconfig)return[{name:`tsconfig.json present`,status:`fail`,fix:"Create a tsconfig.json with `experimentalDecorators: true` and `emitDecoratorMetadata: true`. `kick new` scaffolds one automatically."}];let t=e.tsconfig.compilerOptions??{},n=[];return n.push(t.experimentalDecorators===!0?{name:`tsconfig: experimentalDecorators`,status:`pass`}:{name:`tsconfig: experimentalDecorators`,status:`fail`,fix:'Add `"experimentalDecorators": true` to compilerOptions in tsconfig.json. Without it, @Service / @Controller / @Get etc. don\'t register any metadata at compile time.'}),n.push(t.emitDecoratorMetadata===!0?{name:`tsconfig: emitDecoratorMetadata`,status:`pass`}:{name:`tsconfig: emitDecoratorMetadata`,status:`fail`,fix:'Add `"emitDecoratorMetadata": true` to compilerOptions in tsconfig.json. The DI container uses this metadata for constructor-parameter injection.'}),n}function Yo(e){let t=[`src/env.ts`,`src/env/index.ts`,`src/config/env.ts`,`src/config/index.ts`].map(t=>h(e.cwd,t)).filter(e=>r(e)).filter(e=>/\bloadEnv\s*\(/.test(Bo(e)??``));if(t.length===0)return null;let n=[`src/index.ts`,`src/main.ts`].map(t=>h(e.cwd,t)).find(e=>r(e));if(!n)return{name:`env wiring`,status:`warn`,message:`env-init file exists but no src/index.ts or src/main.ts found`};let i=Bo(n)??``,a=f(n),o=[];for(let e of t){let t=_(a,e).replace(/\\/g,`/`).replace(/\.ts$/,``),n=t.startsWith(`.`)?t:`./`+t,r=n.replace(/\/index$/,``);o.push(n,r);let i=e.replace(/\\/g,`/`).match(/\/src\/(.+?)(?:\.ts)?$/);if(i){let e=`@/`+i[1],t=e.replace(/\/index$/,``);o.push(e,t)}}let s=-1;for(let e of new Set(o)){let t=RegExp(`^import\\s+(?:.*?from\\s+)?['"]${Uo(e)}['"]`,`m`),n=i.match(t);n&&n.index!==void 0&&(s===-1||n.index<s)&&(s=n.index)}let c=i.search(/\bbootstrap\s*\(/),l=t.map(t=>_(e.cwd,t).replace(/\\/g,`/`)).join(`, `);return s===-1?{name:`env wiring`,status:`fail`,message:l,fix:`An env-init file (${l}) calls \`loadEnv(...)\` but \`${_(e.cwd,n).replace(/\\/g,`/`)}\` doesn't import it.\nWithout this, ConfigService.get('X') returns undefined while @Value('X') works via process.env fallback — a half-broken config you won't notice until something is missing.\n\nFix: add a side-effect import at the top of ${_(e.cwd,n).replace(/\\/g,`/`)} (above bootstrap()), pointing at one of the detected files. For example:\n\n import './env'\n // or\n import './config'\n // or, with the @/ alias:\n import '@/config/env'`}:c!==-1&&s>c?{name:`env wiring`,status:`warn`,message:`env-init imported AFTER bootstrap() — should be before`,fix:`Move the env import above the bootstrap() call so the schema runs before any service reads from ConfigService.`}:{name:`env wiring`,status:`pass`}}function Xo(e,t=Zo){let n=0,r=0,i=[e];for(;i.length>0&&r<t;){let e=i.pop(),a;try{a=o(e,{withFileTypes:!0})}catch{continue}for(let o of a){if(r>=t)break;r++;let a=h(e,o.name);if(o.isDirectory()){i.push(a);continue}try{let e=c(a).mtimeMs;e>n&&(n=e)}catch{}}}return n}const Zo=2e3;function Qo(e){let t=h(e.cwd,`.kickjs`,`types`);if(!r(t))return null;let n=Xo(t);if(n===0)return null;let i=Date.now()-n,a=Math.floor(i/6e4);return a>60?{name:`typegen freshness`,status:`warn`,message:`last updated ${a} minutes ago`,fix:"Re-run `kick typegen` (or `kick dev`, which runs it on every reload) so generated types match the current code."}:{name:`typegen freshness`,status:`pass`,message:a===0?`just now`:`${a}m ago`}}const $o=[()=>Wo(),Go,Ko,qo,Jo,Yo,Qo];async function es(e,t={}){let n={cwd:e,pkg:zo(h(e,`package.json`)),tsconfig:Vo(e)},r=[...$o,...t.extraChecks??[]],i=[];for(let e of r){let t;try{t=await e(n)}catch(t){i.push({name:e.name||`doctor check`,status:`fail`,message:t instanceof Error?t.message:String(t)});continue}t!=null&&(Array.isArray(t)?i.push(...t):i.push(t))}return i}function ts(e){switch(e){case`pass`:return E.green(`✔`);case`warn`:return E.yellow(`⚠`);case`fail`:return E.red(`✖`)}}function ns(e){let t=ts(e.status),n=e.message?` ${E.dim(`(${e.message})`)}`:``;return`${t} ${e.name}${n}`}function rs(e){return e.split(`
3780
3876
  `).map(e=>` ${E.dim(`→`)} ${e}`).join(`
3781
- `)}function rs(e){return e?.doctor?.checks??[]}function is(e){e.command(`doctor`).description(`Pre-flight checks for your KickJS project (dev environment health)`).action(async()=>{let e=process.cwd(),t=rs(await k(e));Mt(`KickJS Doctor`);let n=await $o(e,{extraChecks:t});for(let e of n)F.message(ts(e)),e.fix&&e.status!==`pass`&&F.message(ns(e.fix));let r=n.filter(e=>e.status===`pass`).length,i=n.filter(e=>e.status===`warn`).length,a=n.filter(e=>e.status===`fail`).length,o=[E.green(`${r} passed`),i>0?E.yellow(`${i} warning${i===1?``:`s`}`):`${i} warnings`,a>0?E.red(`${a} error${a===1?``:`s`}`):`${a} errors`].join(`, `);a>0?(N(`${o} — fix the errors above before running the app`),process.exit(1)):N(i>0?`${o} — review the warnings`:E.green(`${o} — your environment looks good`))})}async function Q(e){return Ee({configPath:u.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 as(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 os(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 ss(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 as(r),a=i?e=>ve(i.runner,e):void 0;try{let i=await ye({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 xe({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 we({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 be({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 Se({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{os(await Ce({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 w(i,Te(r),`utf8`);let a=Object.keys(r.tables).length;console.log(`Wrote ${i} (${a} table${a===1?``:`s`}).`)}finally{await r()}})}function cs(e){return e.optsWithGlobals().dryRun??!1}function ls(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.
3877
+ `)}function is(e){return e?.doctor?.checks??[]}function as(e){e.command(`doctor`).description(`Pre-flight checks for your KickJS project (dev environment health)`).action(async()=>{let e=process.cwd(),t=is(await k(e));Nt(`KickJS Doctor`);let n=await es(e,{extraChecks:t});for(let e of n)F.message(ns(e)),e.fix&&e.status!==`pass`&&F.message(rs(e.fix));let r=n.filter(e=>e.status===`pass`).length,i=n.filter(e=>e.status===`warn`).length,a=n.filter(e=>e.status===`fail`).length,o=[E.green(`${r} passed`),i>0?E.yellow(`${i} warning${i===1?``:`s`}`):`${i} warnings`,a>0?E.red(`${a} error${a===1?``:`s`}`):`${a} errors`].join(`, `);a>0?(N(`${o} — fix the errors above before running the app`),process.exit(1)):N(i>0?`${o} — review the warnings`:E.green(`${o} — your environment looks good`))})}async function Q(e){return Ee({configPath:u.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 os(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 ss(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 cs(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 os(r),a=i?e=>ve(i.runner,e):void 0;try{let i=await ye({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 xe({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 we({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 be({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 Se({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{ss(await Ce({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 w(i,Te(r),`utf8`);let a=Object.keys(r.tables).length;console.log(`Wrote ${i} (${a} table${a===1?``:`s`}).`)}finally{await r()}})}function ls(e){return e.optsWithGlobals().dryRun??!1}function us(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.
3782
3878
  Direction defaults to \`modules.style\` from kick.config (or "define").
3783
3879
  --target define|class Override the migration direction.
3784
3880
  --apply Apply the changes (default: dry-run preview).
3785
- --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 n=cs(t)||!e.apply;j(n),e.experimental||(console.error(`
3881
+ --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 n=ls(t)||!e.apply;j(n),e.experimental||(console.error(`
3786
3882
  `+E.red(`Error:`)+` kick codemod modules is experimental — pass --experimental to acknowledge.
3787
3883
  The regex-based rewrite handles the shapes our templates produce.
3788
3884
  Hand-rolled modules with non-standard structures may be skipped.
3789
3885
  Always commit before running with --apply.
3790
- `),process.exit(1));let r=O(await k(process.cwd())),i=v(e.modulesDir??r.dir??`src/modules`),a;e.target===`define`||e.target===`class`?a=e.target:e.target===void 0?a=r.style??`define`:(console.error(`\n ${E.red(`Error:`)} --target must be 'define' or 'class' (got '${e.target}').\n`),process.exit(1));let o=E.dim(`→ ${a}`),s=n?E.dim(`(dry-run)`):E.bold(`(applying)`);console.log(`\n ${E.bold(`kick codemod modules`)} ${o} ${s}`),console.log(` modulesDir: ${E.dim(i)}\n`);let c=e.backup!==!1&&!n,l=await Pr(i,{dryRun:n,target:a,backup:c});if(l.backupDir){let e=l.backupDir;console.log(` ${E.green(`✓`)} backup: ${E.dim(e)}\n ${E.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else !n&&e.backup===!1&&console.log(` ${E.dim(`(--no-backup — skipping snapshot)`)}\n`);let u=0,d=0;for(let e of l.files)if(e.status===`migrated`)u++,console.log(` ${E.green(`✓`)} ${e.path}`);else{d++;let t=E.dim(`(${e.reason??`skipped`})`);console.log(` ${E.dim(`-`)} ${e.path} ${t}`)}if(console.log(),l.indexStatus===`migrated`)console.log(` ${E.green(`✓`)} ${l.indexPath}`);else if(l.indexStatus===`skipped`){let e=E.dim(`(${l.indexReason??`skipped`})`);console.log(` ${E.dim(`-`)} ${l.indexPath} ${e}`)}else console.log(` ${E.dim(`-`)} ${l.indexPath} ${E.dim(`(not found)`)}`);let f=n?E.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${E.bold(String(u))} migrated, ${E.bold(String(d))} skipped${f}\n`)})}const us=[`src/db/schema.ts`,`src/db/schema/index.ts`,`src/db/schema`],ds=()=>({id:`kick/db`,inputs:[`src/db/schema.ts`,`src/db/schema/**/*.ts`],async generate(e){let t=fs(e.cwd);if(!t)return null;let n=u.resolve(e.cwd,`.kickjs/types`);return[`import type { SchemaToTypes, SchemaToRelationsRegister, KickDbClient } from '@forinda/kickjs-db'`,`import type * as appSchema from '${ps(u.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(`
3791
- `)}});function fs(e){for(let t of us){let n=u.resolve(e,t);if(t.endsWith(`.ts`)){if(r(n))return n}else{let e=u.join(n,`index.ts`);if(r(e))return e}}return null}function ps(e){return e.replace(/\\/g,`/`)}const ms=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){if(!r(u.resolve(e.cwd,`kick.config.ts`)))return null;let t=await k(e.cwd);if(!t?.assetMap)return null;let n=ra(t.assetMap,e.cwd);return n.count===0?null:ia(n)}}),hs="/* 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 gs(e,t,n){if(e.length===0)return`${hs}
3886
+ `),process.exit(1));let r=O(await k(process.cwd())),i=v(e.modulesDir??r.dir??`src/modules`),a;e.target===`define`||e.target===`class`?a=e.target:e.target===void 0?a=r.style??`define`:(console.error(`\n ${E.red(`Error:`)} --target must be 'define' or 'class' (got '${e.target}').\n`),process.exit(1));let o=E.dim(`→ ${a}`),s=n?E.dim(`(dry-run)`):E.bold(`(applying)`);console.log(`\n ${E.bold(`kick codemod modules`)} ${o} ${s}`),console.log(` modulesDir: ${E.dim(i)}\n`);let c=e.backup!==!1&&!n,l=await Fr(i,{dryRun:n,target:a,backup:c});if(l.backupDir){let e=l.backupDir;console.log(` ${E.green(`✓`)} backup: ${E.dim(e)}\n ${E.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else !n&&e.backup===!1&&console.log(` ${E.dim(`(--no-backup — skipping snapshot)`)}\n`);let u=0,d=0;for(let e of l.files)if(e.status===`migrated`)u++,console.log(` ${E.green(`✓`)} ${e.path}`);else{d++;let t=E.dim(`(${e.reason??`skipped`})`);console.log(` ${E.dim(`-`)} ${e.path} ${t}`)}if(console.log(),l.indexStatus===`migrated`)console.log(` ${E.green(`✓`)} ${l.indexPath}`);else if(l.indexStatus===`skipped`){let e=E.dim(`(${l.indexReason??`skipped`})`);console.log(` ${E.dim(`-`)} ${l.indexPath} ${e}`)}else console.log(` ${E.dim(`-`)} ${l.indexPath} ${E.dim(`(not found)`)}`);let f=n?E.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${E.bold(String(u))} migrated, ${E.bold(String(d))} skipped${f}\n`)})}const ds=[`src/db/schema.ts`,`src/db/schema/index.ts`,`src/db/schema`],fs=()=>({id:`kick/db`,inputs:[`src/db/schema.ts`,`src/db/schema/**/*.ts`],async generate(e){let t=ps(e.cwd);if(!t)return null;let n=u.resolve(e.cwd,`.kickjs/types`);return[`import type { SchemaToTypes, SchemaToRelationsRegister, KickDbClient } from '@forinda/kickjs-db'`,`import type * as appSchema from '${ms(u.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(`
3887
+ `)}});function ps(e){for(let t of ds){let n=u.resolve(e,t);if(t.endsWith(`.ts`)){if(r(n))return n}else{let e=u.join(n,`index.ts`);if(r(e))return e}}return null}function ms(e){return e.replace(/\\/g,`/`)}const hs=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){if(!r(u.resolve(e.cwd,`kick.config.ts`)))return null;let t=await k(e.cwd);if(!t?.assetMap)return null;let n=ia(t.assetMap,e.cwd);return n.count===0?null:aa(n)}}),gs="/* 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 _s(e,t,n){if(e.length===0)return`${gs}
3792
3888
  // (no routes discovered yet — annotate a controller method with
3793
3889
  // @Get/@Post/@Put/@Delete/@Patch and re-run \`kick typegen\`)
3794
3890
  declare global {
@@ -3797,8 +3893,8 @@ declare global {
3797
3893
  }
3798
3894
 
3799
3895
  export {}
3800
- `;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=ys(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??_s(e),l=vs(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(`
3801
- `))}return`${hs}${bs(i)}
3896
+ `;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=bs(e,r,t,n,i);return a?n===`kickjs-schema`?`import('@forinda/kickjs-schema').InferSchemaOutput<typeof ${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??vs(e),l=ys(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(`
3897
+ `))}return`${gs}${xs(i)}
3802
3898
  declare global {
3803
3899
  // eslint-disable-next-line @typescript-eslint/no-namespace
3804
3900
  namespace KickRoutes {
@@ -3808,21 +3904,23 @@ ${o.join(`
3808
3904
  }
3809
3905
 
3810
3906
  export {}
3811
- `}function _s(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 vs(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 ys(e,t,n,r,i){if(!e||r!==`zod`||e.source===null)return null;let a=xs(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 bs(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(`
3907
+ `}function vs(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 ys(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 bs(e,t,n,r,i){if(!e||r===!1||e.source===null)return null;let a=Ss(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 xs(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(`
3812
3908
  `)+`
3813
- `}function xs(e,t,n){if(e===null)return`unknown`;let r=f(n);if(e===``){let e=_(r,t).split(y).join(`/`);return e=e.replace(/\.(ts|tsx|mts|cts)$/i,``),e.startsWith(`.`)||(e=`./`+e),e}if(!e.startsWith(`.`)&&!e.startsWith(`/`))return e;let i=_(r,v(f(t),e)).split(y).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),i}const Ss=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:Cs(e),cwd:e.cwd,envFile:ws(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=u.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return gs(t.routes,r,n)}});function Cs(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ws(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function Ts(e,t){if(!e)return null;let n=_(f(t),e.filePath).split(y).join(`/`);return n=n.replace(/\.(ts|tsx|mts|cts)$/i,``),n.startsWith(`.`)||(n=`./`+n),`/* eslint-disable */
3909
+ `}function Ss(e,t,n){if(e===null)return`unknown`;let r=f(n);if(e===``){let e=_(r,t).split(y).join(`/`);return e=e.replace(/\.(ts|tsx|mts|cts)$/i,``),e.startsWith(`.`)||(e=`./`+e),e}if(!e.startsWith(`.`)&&!e.startsWith(`/`))return e;let i=_(r,v(f(t),e)).split(y).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),i}const Cs=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:ws(e),cwd:e.cwd,envFile:Ts(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=u.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return _s(t.routes,r,n)}});function ws(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Ts(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function Es(e,t,n=`zod`){if(!e)return null;let r=_(f(t),e.filePath).split(y).join(`/`);return r=r.replace(/\.(ts|tsx|mts|cts)$/i,``),r.startsWith(`.`)||(r=`./`+r),`/* eslint-disable */
3814
3910
  // AUTO-GENERATED by \`kick typegen\`. DO NOT EDIT.
3815
3911
  // Re-run with \`kick typegen\` or rely on \`kick dev\` to refresh.
3816
3912
 
3817
3913
  // Importing the schema as a type lets us infer its shape without
3818
3914
  // pulling in any runtime code. \`Awaited<>\` strips an accidental
3819
3915
  // Promise wrap on dynamic-imported defaults.
3820
- import type _envSchema from '${n}'
3916
+ import type _envSchema from '${r}'
3821
3917
 
3822
- // Local type alias interfaces can only \`extend\` an identifier,
3918
+ ${n===`kickjs-schema`?`type _Raw = import('@forinda/kickjs-schema').InferSchemaOutput<typeof _envSchema>
3919
+ type _Resolved = { [K in keyof _Raw]: _Raw[K] }
3920
+ `:``}// Local type alias — interfaces can only \`extend\` an identifier,
3823
3921
  // not an inline import expression, so we resolve the schema's
3824
3922
  // inferred shape into a named type first.
3825
- type _KickEnvShape = import('zod').infer<typeof _envSchema>
3923
+ type _KickEnvShape = ${n===`kickjs-schema`?`_Resolved`:`import('zod').infer<typeof _envSchema>`}
3826
3924
 
3827
3925
  declare global {
3828
3926
  /**
@@ -3846,4 +3944,4 @@ declare global {
3846
3944
  }
3847
3945
 
3848
3946
  export {}
3849
- `}const Es=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=Os(e);if(t===!1)return null;let n=await e.getScanResult({root:Ds(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=u.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return Ts(n.env,r)}});function Ds(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Os(e){return e.config?.typegen?.envFile}var ks=D({builtinCliPlugins:()=>As});const As=[A({name:`kick/init`,register:Jt}),A({name:`kick/generate`,register:ya}),A({name:`kick/run`,register:Na}),A({name:`kick/info`,register:Pa}),A({name:`kick/inspect`,register:Wa}),A({name:`kick/add`,register:Kt}),A({name:`kick/list`,register:Gt}),A({name:`kick/explain`,register:eo}),A({name:`kick/mcp`,register:fo}),A({name:`kick/tinker`,register:go}),A({name:`kick/remove`,register:So}),A({name:`kick/typegen`,register:To}),A({name:`kick/check`,register:Lo}),A({name:`kick/doctor`,register:is}),A({name:`kick/db`,register:ss,typegens:[ds()]}),A({name:`kick/codemod`,register:ls}),A({name:`kick/assets`,typegens:[ms()]}),A({name:`kick/routes`,typegens:[Ss()]}),A({name:`kick/env`,typegens:[Es()]})],js=f(b(import.meta.url)),Ms=JSON.parse(a(h(js,`..`,`package.json`),`utf-8`));async function Ns(){let e=new t;e.name(`kick`).description(`KickJS — A production-grade, decorator-driven Node.js framework`).version(Ms.version);let n=Qt(process.cwd()),r=n,i=await k(r)??{},a=He([...As,...i.plugins??[]],i.commands??[]);await a.register(e,{cwd:r,projectRoot:n,config:i,log:e=>console.log(e)}),Ae(e,{...i,commands:a.commands}),e.showHelpAfterError(),await e.parseAsync(process.argv)}Ns().catch(e=>{console.error(e instanceof Error?e.message:e),process.exitCode=1});export{};
3947
+ `}const Ds=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=ks(e);if(t===!1)return null;let n=await e.getScanResult({root:Os(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=e.config?.typegen?.schemaValidator??`zod`,i=u.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return Es(n.env,i,r)}});function Os(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ks(e){return e.config?.typegen?.envFile}var As=D({builtinCliPlugins:()=>js});const js=[A({name:`kick/init`,register:Yt}),A({name:`kick/generate`,register:ba}),A({name:`kick/run`,register:Pa}),A({name:`kick/info`,register:Fa}),A({name:`kick/inspect`,register:Ga}),A({name:`kick/add`,register:qt}),A({name:`kick/list`,register:Kt}),A({name:`kick/explain`,register:to}),A({name:`kick/mcp`,register:po}),A({name:`kick/tinker`,register:_o}),A({name:`kick/remove`,register:Co}),A({name:`kick/typegen`,register:Eo}),A({name:`kick/check`,register:Ro}),A({name:`kick/doctor`,register:as}),A({name:`kick/db`,register:cs,typegens:[fs()]}),A({name:`kick/codemod`,register:us}),A({name:`kick/assets`,typegens:[hs()]}),A({name:`kick/routes`,typegens:[Cs()]}),A({name:`kick/env`,typegens:[Ds()]})],Ms=f(b(import.meta.url)),Ns=JSON.parse(a(h(Ms,`..`,`package.json`),`utf-8`));async function Ps(){let e=new t;e.name(`kick`).description(`KickJS — A production-grade, decorator-driven Node.js framework`).version(Ns.version);let n=$t(process.cwd()),r=n,i=await k(r)??{},a=He([...js,...i.plugins??[]],i.commands??[]);await a.register(e,{cwd:r,projectRoot:n,config:i,log:e=>console.log(e)}),Ae(e,{...i,commands:a.commands}),e.showHelpAfterError(),await e.parseAsync(process.argv)}Ps().catch(e=>{console.error(e instanceof Error?e.message:e),process.exitCode=1});export{};