@forinda/kickjs-cli 5.10.1 → 5.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/{agent-docs-D1k73ywL.mjs → agent-docs-BuCTT-9g.mjs} +3 -3
  2. package/dist/{agent-docs-D1k73ywL.mjs.map → agent-docs-BuCTT-9g.mjs.map} +1 -1
  3. package/dist/{builtins-DsO7X7g9.mjs → builtins-DOQNq7JT.mjs} +2 -2
  4. package/dist/cli.mjs +213 -172
  5. package/dist/config-DW9HQc2u.mjs +13 -0
  6. package/dist/config-DW9HQc2u.mjs.map +1 -0
  7. package/dist/{doctor-Brw2ruus.mjs → doctor-Cin9GYv9.mjs} +61 -61
  8. package/dist/{doctor-Brw2ruus.mjs.map → doctor-Cin9GYv9.mjs.map} +1 -1
  9. package/dist/index.d.mts +18 -1
  10. package/dist/index.d.mts.map +1 -1
  11. package/dist/index.mjs +2 -2
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/{plugin-0_cDz8hu.mjs → plugin-CcuuVb2P.mjs} +3 -3
  14. package/dist/{plugin-0_cDz8hu.mjs.map → plugin-CcuuVb2P.mjs.map} +1 -1
  15. package/dist/{project-docs-Bh20nvAP.mjs → project-docs-CjnHf0Wd.mjs} +2 -2
  16. package/dist/{project-docs-Bh20nvAP.mjs.map → project-docs-CjnHf0Wd.mjs.map} +1 -1
  17. package/dist/{project-root-B7_vpWeX.mjs → project-root-SRoIXPwv.mjs} +3 -3
  18. package/dist/{project-root-B7_vpWeX.mjs.map → project-root-SRoIXPwv.mjs.map} +1 -1
  19. package/dist/{rolldown-runtime-C3T7GIRR.mjs → rolldown-runtime-BOORVFz_.mjs} +1 -1
  20. package/dist/{run-plugins-w_kqfVLL.mjs → run-plugins-fsoovaEF.mjs} +125 -82
  21. package/dist/run-plugins-fsoovaEF.mjs.map +1 -0
  22. package/dist/typegen-CSLwAvgI.mjs +114 -0
  23. package/dist/typegen-CSLwAvgI.mjs.map +1 -0
  24. package/dist/{types-CkZ7XoFJ.mjs → types-BZ1L4hvm.mjs} +2 -2
  25. package/dist/{types-CkZ7XoFJ.mjs.map → types-BZ1L4hvm.mjs.map} +1 -1
  26. package/package.json +4 -19
  27. package/dist/config-BnCPYsQu.mjs +0 -12
  28. package/dist/config-BnCPYsQu.mjs.map +0 -1
  29. package/dist/run-plugins-w_kqfVLL.mjs.map +0 -1
  30. package/dist/typegen-CFtS0A1P.mjs +0 -117
  31. package/dist/typegen-CFtS0A1P.mjs.map +0 -1
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v5.10.1
2
+ * @forinda/kickjs-cli v5.11.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,7 +8,8 @@
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(()=>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'
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:()=>Be,writeAssetConfigSnapshot:()=>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(()=>Qt),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=Be(e,n);for(let e of i)console.warn(` Warning: ${e}`);return ze(n,e),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=Be(i,n);for(let e of a)console.warn(` Warning: ${e}`);return ze(n,i),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){if(!(!t?.assetMap||Object.keys(t.assetMap).length===0))try{let n=h(e,`.kickjs`);i(n,{recursive:!0});let r={version:1,assetMap:t.assetMap,...t.build?.outDir?{build:{outDir:t.build.outDir}}:{}};l(h(n,`kick.config.json`),JSON.stringify(r,null,2)+`
12
+ `,`utf-8`)}catch{}}function Be(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&&Ve(v(t,o.dest),i)&&n.push(`assetMap.${a}.dest ('${o.dest}') resolves outside the project root — refusing to copy`)}return n}function Ve(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function A(e){return e}var He=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 Ue(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 He(`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 He(`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 He(`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 He(`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(()=>Qt),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 We=D({mergeCliPlugins:()=>Ue});let Ge=!1;function j(e){Ge=e}const Ke=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`,`.md`]);async function M(e,t){Ge||(await oe(f(e),{recursive:!0}),await w(e,t,`utf-8`),Ke.has(p(e))&&await Ye(e,t).catch(()=>{}))}let qe;async function Je(t){if(qe!==void 0)return qe;try{qe=await import(e(h(t,`package.json`)).resolve(`oxfmt`))}catch{qe=null}return qe}async function Ye(e,t){let n=await Je(process.cwd());if(!n)return;let r=await Ze(e);if(r===null)return;let i=await n.format(e,t,r);i.code!==t&&await w(e,i.code,`utf-8`)}const Xe=new Map;async function Ze(e){let t=f(e),n=t;if(Xe.has(n))return Xe.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,Xe.set(n,r),r}catch{return Xe.set(n,null),null}let i=f(t);if(i===t)return Xe.set(n,null),null;t=i}}async function Qe(e){try{return await ie(e),!0}catch{return!1}}const $e={swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`},et={zod:{name:`zod`,range:`^4.3.6`},valibot:{name:`valibot`,range:`^1.4.1`},yup:{name:`yup`,range:`^1.7.1`}};function tt(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 nt(e,t,n,r=[],i=`zod`){let a=et[i],o={"@forinda/kickjs":tt(n,`@forinda/kickjs`),"@forinda/kickjs-schema":tt(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=$e[e];t&&!o[t]&&(o[t]=tt(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":tt(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":tt(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 rt(){return`import { defineConfig } from 'vite'
12
13
  import { resolve } from 'node:path'
13
14
  import swc from 'unplugin-swc'
14
15
  import { kickjsVitePlugin, envWatchPlugin } from '@forinda/kickjs-vite'
@@ -38,7 +39,7 @@ export default defineConfig({
38
39
  },
39
40
  },
40
41
  })
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
+ `}function it(){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 at(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function ot(){return`# https://editorconfig.org
42
43
  root = true
43
44
 
44
45
  [*]
@@ -51,14 +52,14 @@ insert_final_newline = true
51
52
 
52
53
  [*.md]
53
54
  trim_trailing_whitespace = false
54
- `}function ot(){return`node_modules/
55
+ `}function st(){return`node_modules/
55
56
  dist/
56
57
  .env
57
58
  coverage/
58
59
  .DS_Store
59
60
  *.tsbuildinfo
60
61
  .kickjs/
61
- `}function st(){return`# Auto-detect text files and normalise line endings to LF
62
+ `}function ct(){return`# Auto-detect text files and normalise line endings to LF
62
63
  * text=auto eol=lf
63
64
 
64
65
  # Explicitly mark generated / binary files
@@ -76,11 +77,11 @@ coverage/
76
77
  pnpm-lock.yaml -diff linguist-generated
77
78
  yarn.lock -diff linguist-generated
78
79
  package-lock.json -diff linguist-generated
79
- `}function ct(){return`PORT=3000
80
- NODE_ENV=development
81
80
  `}function lt(){return`PORT=3000
82
81
  NODE_ENV=development
83
- `}function ut(){return`import { defineConfig } from 'vitest/config'
82
+ `}function ut(){return`PORT=3000
83
+ NODE_ENV=development
84
+ `}function dt(){return`import { defineConfig } from 'vitest/config'
84
85
  import swc from 'unplugin-swc'
85
86
 
86
87
  export default defineConfig({
@@ -91,7 +92,7 @@ export default defineConfig({
91
92
  include: ['src/**/*.test.ts'],
92
93
  },
93
94
  })
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
+ `}function ft(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
96
  // Side-effect import — registers the extended env schema with kickjs
96
97
  // **before** any controller / service / @Value gets resolved. Without
97
98
  // this line ConfigService.get('YOUR_KEY') returns undefined because the
@@ -161,14 +162,14 @@ export const app = await bootstrap({
161
162
  express.json(),
162
163
  ],
163
164
  })
164
- `}}}function ft(){return`import { defineModules } from '@forinda/kickjs'
165
+ `}}}function pt(){return`import { defineModules } from '@forinda/kickjs'
165
166
  import { HelloModule } from './hello/hello.module'
166
167
 
167
168
  // Remove HelloModule and run: kick g module <name>
168
169
  // \`defineModules()\` returns a chainable list — \`kick g module\` appends
169
170
  // \`.mount(NewModule())\` to the chain on every generation.
170
171
  export const modules = defineModules().mount(HelloModule())
171
- `}function pt(e=`zod`){return e===`valibot`?`import { loadEnvFromSchema } from '@forinda/kickjs/config'
172
+ `}function mt(e=`zod`){return e===`valibot`?`import { loadEnvFromSchema } from '@forinda/kickjs/config'
172
173
  import { fromValibot } from '@forinda/kickjs-schema/valibot'
173
174
  import * as v from 'valibot'
174
175
 
@@ -296,7 +297,7 @@ const envSchema = fromZod(
296
297
  export const env = loadEnvFromSchema(envSchema)
297
298
 
298
299
  export default envSchema
299
- `}function mt(){return`import { Service } from '@forinda/kickjs'
300
+ `}function ht(){return`import { Service } from '@forinda/kickjs'
300
301
 
301
302
  @Service()
302
303
  export class HelloService {
@@ -308,7 +309,7 @@ export class HelloService {
308
309
  return { status: 'ok', uptime: process.uptime() }
309
310
  }
310
311
  }
311
- `}function ht(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
312
+ `}function gt(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
312
313
  import { HelloService } from './hello.service'
313
314
 
314
315
  // \`Ctx<KickRoutes.HelloController['<method>']>\` is generated by
@@ -330,7 +331,7 @@ export class HelloController {
330
331
  ctx.json(this.helloService.healthCheck())
331
332
  }
332
333
  }
333
- `}function gt(){return`import { defineModule } from '@forinda/kickjs'
334
+ `}function _t(){return`import { defineModule } from '@forinda/kickjs'
334
335
  import { HelloController } from './hello.controller'
335
336
 
336
337
  export const HelloModule = defineModule({
@@ -351,7 +352,7 @@ export const HelloModule = defineModule({
351
352
  },
352
353
  }),
353
354
  })
354
- `}function _t(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
355
+ `}function vt(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
355
356
 
356
357
  export default defineConfig({
357
358
  pattern: '${e}',
@@ -398,7 +399,7 @@ export default defineConfig({
398
399
  },
399
400
  ],
400
401
  })
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}
402
+ `}function yt(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}
402
403
 
403
404
  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.
404
405
 
@@ -461,7 +462,7 @@ Copy \`.env.example\` to \`.env\` and configure:
461
462
 
462
463
  - [KickJS Documentation](https://forinda.github.io/kick-js/)
463
464
  - [CLI Reference](https://forinda.github.io/kick-js/api/cli.html)
464
- `}function yt(e,t,n){return`# CLAUDE.md — ${e}
465
+ `}function bt(e,t,n){return`# CLAUDE.md — ${e}
465
466
 
466
467
  **Read \`./.agents/AGENTS.md\` first.** It is the canonical, multi-agent
467
468
  reference for this project (Claude, Copilot, Codex, Gemini, etc.) —
@@ -535,7 +536,7 @@ When generating or modifying code in this project, stay aligned with the v4 conv
535
536
  - **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.
536
537
 
537
538
  For everything else (controllers, services, modules, RequestContext API, generators, CLI commands, package additions, env wiring, troubleshooting) → \`.agents/AGENTS.md\`.
538
- `}function bt(e,t,n){return`# AGENTS.md — AI Agent Guide for ${e}
539
+ `}function xt(e,t,n){return`# AGENTS.md — AI Agent Guide for ${e}
539
540
 
540
541
  This guide is the **canonical, multi-agent reference** for this KickJS
541
542
  application — Claude, Copilot, Codex, Gemini, etc. all read it first.
@@ -1042,7 +1043,7 @@ ${t===`cqrs`?`### Background Jobs
1042
1043
  - [Decorators Guide](https://forinda.github.io/kick-js/guide/decorators.html)
1043
1044
  - [DI System](https://forinda.github.io/kick-js/guide/dependency-injection.html)
1044
1045
  - [Testing](https://forinda.github.io/kick-js/api/testing.html)
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".
1046
+ `}function St(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".
1046
1047
 
1047
1048
  **Steps**:
1048
1049
  1. Run \`kick g module <name>\` (use plural form if the project pluralizes — check \`kick.config.ts\`).
@@ -1177,7 +1178,7 @@ description: ${e.description}
1177
1178
  ${r}
1178
1179
 
1179
1180
  ${e.body}
1180
- `}))}function St(e,t,n){return`# GEMINI.md — ${e}
1181
+ `}))}function Ct(e,t,n){return`# GEMINI.md — ${e}
1181
1182
 
1182
1183
  **Read \`./AGENTS.md\` first.** It is the canonical, multi-agent
1183
1184
  reference for this project — every convention, structure, decorator
@@ -1211,7 +1212,7 @@ without us copy-pasting.
1211
1212
  \`kick g agents --only gemini -f\` regenerates this file from the
1212
1213
  CLI template. Hand-edited content is overwritten — keep customisation
1213
1214
  in \`.agents/GEMINI.local.md\`.
1214
- `}function Ct(e,t,n){return`# COPILOT.md — ${e}
1215
+ `}function wt(e,t,n){return`# COPILOT.md — ${e}
1215
1216
 
1216
1217
  **Read \`./AGENTS.md\` first.** It is the canonical, multi-agent
1217
1218
  reference for this project — every convention, structure, decorator
@@ -1244,16 +1245,16 @@ Codex / Cursor / Gemini / Claude Code without copy-pasting.
1244
1245
  \`kick g agents --only copilot -f\` regenerates this file from the
1245
1246
  CLI template. Hand-edited content is overwritten — keep customisation
1246
1247
  in \`.agents/COPILOT.local.md\`.
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(`
1248
+ `}const Tt=f(b(import.meta.url)),Et=JSON.parse(a(h(Tt,`..`,`package.json`),`utf-8`)),Dt=`^${Et.version}`,Ot=[`@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 kt(){let e=await Promise.all(Ot.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,Dt]}));return Object.fromEntries(e)}async function At(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 kt();await M(h(c,`package.json`),nt(t,i,u,o,s)),await M(h(c,`vite.config.ts`),rt()),await M(h(c,`tsconfig.json`),it()),await M(h(c,`.prettierrc`),at()),await M(h(c,`.editorconfig`),ot()),await M(h(c,`.gitignore`),st()),await M(h(c,`.gitattributes`),ct()),await M(h(c,`.env`),lt()),await M(h(c,`.env.example`),ut()),await M(h(c,`src/config/index.ts`),mt(s)),await M(h(c,`src/index.ts`),ft(t,i,Et.version,o)),await M(h(c,`src/modules/index.ts`),pt()),await M(h(c,`src/modules/hello/hello.service.ts`),ht()),await M(h(c,`src/modules/hello/hello.controller.ts`),gt()),await M(h(c,`src/modules/hello/hello.module.ts`),_t()),await M(h(c,`kick.config.ts`),vt(i,a,r)),await M(h(c,`vitest.config.ts`),dt()),await M(h(c,`README.md`),yt(t,i,r));let{generateAgentDocs:d}=await Promise.resolve().then(()=>xr);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(`
1249
+ Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${r} install failed. Run it manually.`)}}try{let{runTypegen:e}=await Promise.resolve().then(()=>_a);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(`
1250
+ 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 jt={GET:E.green,POST:E.cyan,PUT:E.yellow,PATCH:E.magenta,DELETE:E.red};function Mt(e){return(jt[e]??E.dim)(e.padEnd(7))}function Nt(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 Pt(e){T.intro(E.bgCyan(E.black(` ${e} `)))}function N(e){T.outro(e)}function Ft(e){T.isCancel(e)&&(T.cancel(`Operation cancelled.`),process.exit(0))}async function It(e){let t=await T.text(e);return Ft(t),t}async function Lt(e){let t=await T.select(e);return Ft(t),t}async function Rt(e){let t=await T.multiselect(e);return Ft(t),t}async function P(e){let t=await T.confirm(e);return Ft(t),t}function zt(){return T.spinner()}const F=T.log,Bt={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 Vt(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 Ht(){return Vt(`pnpm-lock.yaml`)?`pnpm`:Vt(`yarn.lock`)?`yarn`:Vt(`bun.lockb`)||Vt(`bun.lock`)?`bun`:Vt(`package-lock.json`)?`npm`:null}function Ut(){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 Wt(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=Ut();if(n)return{pm:n,source:`package.json`};let r=Ht();return r?{pm:r,source:`lockfile`}:{pm:`npm`,source:`default`}}async function Gt(e){let{pm:t}=await Wt(e);return t}function Kt(e=!1){let t=Object.entries(Bt),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(`
1250
1251
  Core packages (always installed by \`kick new\`):
1251
1252
  `);for(let e of r)console.log(a(e));if(e){console.log(`
1252
1253
  Optional packages (add as needed):
1253
1254
  `);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(`
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.
1255
+ Usage: kick add auth drizzle swagger`),console.log(` kick add queue:bullmq`),console.log()}function qt(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=>{Kt(!!e.all)})}function Jt(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){Kt(!!t.all);return}let{pm:n,source:r}=await Wt(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=Bt[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.
1255
1256
  `),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!
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=`/**
1257
+ `)}})}const Yt=[{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 Xt(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)=>{Pt(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await It({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 Lt({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 Gt(void 0):await Lt({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 Lt({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 It({message:`Custom repository name`,defaultValue:`custom`}))));let u=t.schema;u||=n?`zod`:await Lt({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 Rt({message:`Select packages to include`,options:[...Yt],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 At({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 Zt(e){return de.plural(e)}var Qt=D({findProjectRoot:()=>en});const $t=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];function en(e=process.cwd()){let t=v(e),{root:n}=g(t),i=null,a=t;for(;;){for(let e of $t)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 tn(e){return R(e).replace(/-/g,`_`)}function nn(e){let t=e.cwd??process.cwd(),n=e.projectRoot??en(t),r=e.pluralize??!0,i=I(e.name),a=L(e.name),o=R(e.name),s=tn(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 rn(e,t){return v(e.cwd,t)}async function an(e){return import(x(e).href)}const on=new Map;async function sn(e){let t=on.get(e);if(t)return t;let n=cn(e);return on.set(e,n),n}async function cn(t){let n=v(t,`package.json`);if(!r(n))return{generators:[],loaded:[],failed:[]};let i=ln(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 an(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(!un(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 ln(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 un(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function dn(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return mn(r.spec,r.source,e,n);let i=pn(await sn(n),e.generatorName);return i?mn(i.spec,i.source,e,n):null}async function fn(e,t=[]){let n=await sn(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 pn(e,t){return e.generators.find(e=>e.spec.name===t)}async function mn(e,t,n,r){let i=nn({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=rn(i,e.path);await M(t,e.content),o.push(t)}return{files:o,source:t}}function B(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const hn={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function gn(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function _n(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function vn(e){return hn[e]??gn(e)}function yn(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]??`${gn(n)}${e}Repository`,repoFile:i[n]??`${_n(n)}-${t}`}}function bn(e){return e??`define`}function xn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=yn(t,n,i),c=bn(a),l=`/**
1257
1258
  * ${t} Module
1258
1259
  *
1259
1260
  * Self-contained feature module following Domain-Driven Design (DDD).
@@ -1263,7 +1264,7 @@ in \`.agents/COPILOT.local.md\`.
1263
1264
  * presentation/ — HTTP controllers (entry points)
1264
1265
  * application/ — Use cases (orchestration) and DTOs (validation)
1265
1266
  * domain/ — Entities, value objects, repository interfaces, domain services
1266
- * infrastructure/ — Repository implementations (currently ${_n(i)})
1267
+ * infrastructure/ — Repository implementations (currently ${vn(i)})
1267
1268
  */`,u=`import { ${t.toUpperCase()}_REPOSITORY } from './domain/repositories/${n}.repository'
1268
1269
  import { ${o} } from './infrastructure/repositories/${s}.repository'
1269
1270
  import { ${t}Controller } from './presentation/${n}.controller'
@@ -1297,7 +1298,7 @@ export class ${t}Module implements AppModule {
1297
1298
  /**
1298
1299
  * Register module dependencies in the DI container.
1299
1300
  * Bind repository interface tokens to their implementations here.
1300
- * Currently wired to ${_n(i)}. To swap implementations, change the factory target.
1301
+ * Currently wired to ${vn(i)}. To swap implementations, change the factory target.
1301
1302
  */
1302
1303
  register(container: Container): void {
1303
1304
  container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
@@ -1323,7 +1324,7 @@ export const ${t}Module = defineModule({
1323
1324
  /**
1324
1325
  * Register module dependencies in the DI container.
1325
1326
  * Bind repository interface tokens to their implementations here.
1326
- * Currently wired to ${_n(i)}. To swap implementations, change the factory target.
1327
+ * Currently wired to ${vn(i)}. To swap implementations, change the factory target.
1327
1328
  */
1328
1329
  register(container) {
1329
1330
  container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
@@ -1340,7 +1341,7 @@ ${d}
1340
1341
  },
1341
1342
  }),
1342
1343
  })
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=`/**
1344
+ `}function Sn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=yn(t,n,i),c=bn(a),l=`/**
1344
1345
  * ${t} Module
1345
1346
  *
1346
1347
  * REST module with a flat folder structure.
@@ -1412,7 +1413,7 @@ ${d}
1412
1413
  },
1413
1414
  }),
1414
1415
  })
1415
- `}function Sn(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=yn(i),o=` /**
1416
+ `}function Cn(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=bn(i),o=` /**
1416
1417
  * Declare HTTP routes. Return value shape:
1417
1418
  *
1418
1419
  * - \`path\` — URL prefix for this route set.
@@ -1452,7 +1453,7 @@ ${o}
1452
1453
  },
1453
1454
  }),
1454
1455
  })
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'
1456
+ `}function wn(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'
1456
1457
  import { ApiTags } from '@forinda/kickjs-swagger'
1457
1458
  import { Create${t}UseCase } from '../application/use-cases/create-${n}.use-case'
1458
1459
  import { Get${t}UseCase } from '../application/use-cases/get-${n}.use-case'
@@ -1515,7 +1516,7 @@ export class ${t}Controller {
1515
1516
  ctx.noContent()
1516
1517
  }
1517
1518
  }
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'
1519
+ `}function Tn(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'
1519
1520
  import { ApiTags } from '@forinda/kickjs-swagger'
1520
1521
  import { ${t}Service } from './${n}.service'
1521
1522
  import { create${t}Schema } from './dtos/create-${n}.dto'
@@ -1570,14 +1571,14 @@ export class ${t}Controller {
1570
1571
  ctx.noContent()
1571
1572
  }
1572
1573
  }
1573
- `}function Tn(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
1574
+ `}function En(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
1574
1575
 
1575
1576
  export const ${t.toUpperCase()}_QUERY_CONFIG: QueryParamsConfig = {
1576
1577
  filterable: ['name'],
1577
1578
  sortable: ['name', 'createdAt'],
1578
1579
  searchable: ['name'],
1579
1580
  }
1580
- `}function En(e){let{pascal:t}=e;return`import { z } from 'zod'
1581
+ `}function Dn(e){let{pascal:t}=e;return`import { z } from 'zod'
1581
1582
 
1582
1583
  /**
1583
1584
  * Create ${t} DTO — Zod schema for validating POST request bodies.
@@ -1593,20 +1594,20 @@ export const create${t}Schema = z.object({
1593
1594
  })
1594
1595
 
1595
1596
  export type Create${t}DTO = z.infer<typeof create${t}Schema>
1596
- `}function Dn(e){let{pascal:t}=e;return`import { z } from 'zod'
1597
+ `}function On(e){let{pascal:t}=e;return`import { z } from 'zod'
1597
1598
 
1598
1599
  export const update${t}Schema = z.object({
1599
1600
  name: z.string().min(1).max(200).optional(),
1600
1601
  })
1601
1602
 
1602
1603
  export type Update${t}DTO = z.infer<typeof update${t}Schema>
1603
- `}function On(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
1604
+ `}function kn(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
1604
1605
  id: string
1605
1606
  name: string
1606
1607
  createdAt: string
1607
1608
  updatedAt: string
1608
1609
  }
1609
- `}function kn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
1610
+ `}function An(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
1610
1611
  * Create ${t} Use Case
1611
1612
  *
1612
1613
  * Application layer — orchestrates a single business operation.
@@ -1684,7 +1685,7 @@ export class Delete${t}UseCase {
1684
1685
  await this.repo.delete(id)
1685
1686
  }
1686
1687
  }
1687
- `}]}function An(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
1688
+ `}]}function jn(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
1688
1689
  * ${t} Repository Interface
1689
1690
  *
1690
1691
  * Defines the contract for data access.
@@ -1779,7 +1780,7 @@ export class InMemory${t}Repository implements I${t}Repository {
1779
1780
  this.store.delete(id)
1780
1781
  }
1781
1782
  }
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`/**
1783
+ `}function Mn(e){let{pascal:t,kebab:n,repoType:r=``,repoPrefix:i=`../../domain/repositories`,dtoPrefix:a=`../../application/dtos`}=e,o=r.charAt(0).toUpperCase()+r.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
1783
1784
  * ${o} ${t} Repository
1784
1785
  *
1785
1786
  * Stub implementation for a custom '${r}' repository.
@@ -1848,7 +1849,7 @@ export class ${o}${t}Repository implements I${t}Repository {
1848
1849
  this.store.delete(id)
1849
1850
  }
1850
1851
  }
1851
- `}function Mn(e){let{pascal:t,kebab:n}=e;return`/**
1852
+ `}function Nn(e){let{pascal:t,kebab:n}=e;return`/**
1852
1853
  * ${t} Domain Service
1853
1854
  *
1854
1855
  * Domain layer — contains business rules that don't belong to a single entity.
@@ -1871,7 +1872,7 @@ export class ${t}DomainService {
1871
1872
  }
1872
1873
  }
1873
1874
  }
1874
- `}function Nn(e){let{pascal:t,kebab:n}=e;return`/**
1875
+ `}function Pn(e){let{pascal:t,kebab:n}=e;return`/**
1875
1876
  * ${t} Entity
1876
1877
  *
1877
1878
  * Domain layer — the core business object.
@@ -1940,7 +1941,7 @@ export class ${t} {
1940
1941
  }
1941
1942
  }
1942
1943
  }
1943
- `}function Pn(e){let{pascal:t}=e;return`/**
1944
+ `}function Fn(e){let{pascal:t}=e;return`/**
1944
1945
  * ${t} ID Value Object
1945
1946
  *
1946
1947
  * Domain layer — wraps a primitive ID with type safety and validation.
@@ -1974,7 +1975,7 @@ export class ${t}Id {
1974
1975
  return this.value === other.value
1975
1976
  }
1976
1977
  }
1977
- `}function Fn(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
1978
+ `}function In(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
1978
1979
  import { Container } from '@forinda/kickjs'
1979
1980
 
1980
1981
  describe('${t}Controller', () => {
@@ -2026,7 +2027,7 @@ describe('${t}Controller', () => {
2026
2027
  })
2027
2028
  })
2028
2029
  })
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'
2030
+ `}function Ln(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'
2030
2031
  import { InMemory${t}Repository } from '${i}'
2031
2032
 
2032
2033
  describe('InMemory${t}Repository', () => {
@@ -2088,7 +2089,7 @@ describe('InMemory${t}Repository', () => {
2088
2089
  expect(found).toBeNull()
2089
2090
  })
2090
2091
  })
2091
- `}function Ln(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
2092
+ `}function Rn(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
2092
2093
  import type { ParsedQuery } from '@forinda/kickjs'
2093
2094
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from './${n}.repository'
2094
2095
  import type { ${t}ResponseDTO } from './dtos/${n}-response.dto'
@@ -2125,14 +2126,14 @@ export class ${t}Service {
2125
2126
  await this.repo.delete(id)
2126
2127
  }
2127
2128
  }
2128
- `}function Rn(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
2129
+ `}function zn(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
2129
2130
 
2130
2131
  export const ${t.toUpperCase()}_QUERY_CONFIG: QueryFieldConfig = {
2131
2132
  filterable: ['name'],
2132
2133
  sortable: ['name', 'createdAt'],
2133
2134
  searchable: ['name'],
2134
2135
  }
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=`/**
2136
+ `}function Bn(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=`/**
2136
2137
  * ${t} Module — CQRS Pattern
2137
2138
  *
2138
2139
  * Separates read (queries) and write (commands) operations.
@@ -2211,7 +2212,7 @@ ${p}
2211
2212
  },
2212
2213
  }),
2213
2214
  })
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'
2215
+ `}function Vn(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'
2215
2216
  import { ApiTags } from '@forinda/kickjs-swagger'
2216
2217
  import { Create${t}Command } from './commands/create-${n}.command'
2217
2218
  import { Update${t}Command } from './commands/update-${n}.command'
@@ -2274,7 +2275,7 @@ export class ${t}Controller {
2274
2275
  ctx.noContent()
2275
2276
  }
2276
2277
  }
2277
- `}function Vn(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2278
+ `}function Hn(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2278
2279
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
2279
2280
  import type { Create${t}DTO } from '../dtos/create-${n}.dto'
2280
2281
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
@@ -2328,7 +2329,7 @@ export class Delete${t}Command {
2328
2329
  this.events.emit('${n}.deleted', { id })
2329
2330
  }
2330
2331
  }
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'
2332
+ `}]}function Un(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2332
2333
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
2333
2334
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
2334
2335
 
@@ -2356,7 +2357,7 @@ export class List${i}Query {
2356
2357
  return this.repo.findPaginated(parsed)
2357
2358
  }
2358
2359
  }
2359
- `}]}function Un(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
2360
+ `}]}function Wn(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
2360
2361
  import { EventEmitter } from 'node:events'
2361
2362
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
2362
2363
 
@@ -2442,7 +2443,7 @@ export class On${t}ChangeHandler {
2442
2443
  })
2443
2444
  }
2444
2445
  }
2445
- `}]}function Wn(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
2446
+ `}]}function Gn(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
2446
2447
  * Drizzle ${t} Repository
2447
2448
  *
2448
2449
  * Implements the repository interface using Drizzle ORM.
@@ -2524,7 +2525,7 @@ export class Drizzle${t}Repository implements I${t}Repository {
2524
2525
  throw new Error('Drizzle ${t} repository not yet implemented')
2525
2526
  }
2526
2527
  }
2527
- `}function Gn(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
2528
+ `}function Kn(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
2528
2529
  // TODO: Import your schema table and reference actual columns for type safety
2529
2530
  // import { ${n}s } from '@/db/schema'
2530
2531
 
@@ -2542,7 +2543,7 @@ export const ${t.toUpperCase()}_QUERY_CONFIG: DrizzleQueryParamsConfig = {
2542
2543
  // ${n}s.name,
2543
2544
  ],
2544
2545
  }
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`/**
2546
+ `}function qn(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`/**
2546
2547
  * Prisma ${t} Repository
2547
2548
  *
2548
2549
  * Implements the repository interface using Prisma Client.
@@ -2600,7 +2601,7 @@ export class Prisma${t}Repository implements I${t}Repository {
2600
2601
  await this.prisma.${a}.deleteMany({ where: { id } })
2601
2602
  }
2602
2603
  }
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'
2604
+ `}async function Jn(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,Cn({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
2604
2605
 
2605
2606
  // \`Ctx<KickRoutes.${t}Controller['<method>']>\` is generated by
2606
2607
  // \`kick typegen\` (auto-run on \`kick dev\`).
@@ -2612,7 +2613,7 @@ export class ${t}Controller {
2612
2613
  ctx.json({ message: '${t} list' })
2613
2614
  }
2614
2615
  }
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'
2616
+ `)}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`,Sn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,zn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Tn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,Rn({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,On({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,kn({pascal:t,kebab:n})),await u(`${n}.repository.ts`,jn({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:()=>Gn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>qn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${R(a)}-${n}`,m=f[a]??(()=>Mn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${p}.repository.ts`,m()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,In({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,Ln({pascal:t,kebab:n,plural:r,repoPrefix:`../${d.inmemory??`in-memory-${n}`}.repository`})))}async function Xn(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`,zn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Vn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,On({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,kn({pascal:t,kebab:n}));let d=Hn({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=Un({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=Wn({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,jn({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:()=>Gn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>qn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${R(a)}-${n}`,_=h[a]??(()=>Mn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,In({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,Ln({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function Zn(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`,xn({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?Kn({pascal:t,kebab:n}):En({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,wn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,On({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,kn({pascal:t,kebab:n}));let f=An({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`,jn({pascal:t,kebab:n,tokenScope:l})),await d(`domain/services/${n}-domain.service.ts`,Nn({pascal:t,kebab:n}));let p={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},m={inmemory:()=>V({pascal:t,kebab:n}),drizzle:()=>Gn({pascal:t,kebab:n}),prisma:()=>qn({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${R(a)}-${n}`,g=m[a]??(()=>Mn({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,Pn({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,Fn({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`,In({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,Ln({pascal:t,kebab:n,plural:r})))}function Qn(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function $n(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?Zt(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 Qe(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 Jn(v);break;case`rest`:await Yn(v);break;case`cqrs`:await Xn(v);break;default:await Zn(v);break}return s||await er(n,d,f,u,v.style),g}async function er(e,t,n,r,i=`define`){let a=h(e,`index.ts`),o=await Qe(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'
2616
2617
  import { ${t}Module } from '${s}'
2617
2618
 
2618
2619
  export const modules: AppModuleEntry[] = [${c}]
@@ -2623,8 +2624,8 @@ export const modules = defineModules().mount(${c})
2623
2624
  `);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(`
2624
2625
  `,e);l=l.slice(0,t+1)+u+`
2625
2626
  `+l.slice(t+1)}else l=u+`
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 {
2627
+ `+l}let f=nr(l);if(f){let e=l.slice(f.rhsStart,f.rhsEnd+1);RegExp(`\\b${B(t)}Module\\b`).test(e)||(l=tr(l,c))}else l=tr(l,c);await w(a,l,`utf-8`)}function tr(e,t){let n=nr(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 nr(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=ar(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=rr(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function rr(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=or(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=or(e,t);if(n===-1)break;i=n+1}return i}function ir(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
2628
+ `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}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=ir(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 or(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=ir(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 sr(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 {
2628
2629
  defineAdapter,
2629
2630
  type AdapterContext,
2630
2631
  type AdapterMiddleware,
@@ -2793,7 +2794,7 @@ export const ${i}Adapter = defineAdapter<${i}AdapterConfig>({
2793
2794
  }
2794
2795
  },
2795
2796
  })
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 {
2797
+ `),a.push(o),a}async function cr(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 {
2797
2798
  definePlugin,
2798
2799
  type AppAdapter,
2799
2800
  type AppModuleEntry,
@@ -2937,7 +2938,7 @@ export const ${i}Plugin = definePlugin<${i}PluginConfig>({
2937
2938
  },
2938
2939
  }),
2939
2940
  })
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'
2941
+ `),a.push(o),a}const lr={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`,contributor:`presentation/contributors`},ur={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,contributor:`contributors`},dr={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,contributor:`contributors`,command:`commands`,query:`queries`,event:`events`};function H(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`?lr:o===`cqrs`?dr:ur,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=H({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'
2941
2942
 
2942
2943
  export interface ${I(t)}Options {
2943
2944
  // Add configuration options here. The factory below closes over the
@@ -2987,7 +2988,7 @@ export function ${s}(options: ${I(t)}Options = {}) {
2987
2988
  next()
2988
2989
  }
2989
2990
  }
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'
2991
+ `),c.push(l),c}async function pr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=H({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'
2991
2992
  import type { RequestContext } from '@forinda/kickjs'
2992
2993
 
2993
2994
  /**
@@ -3023,7 +3024,47 @@ export async function ${s}Guard(ctx: RequestContext, next: () => void): Promise<
3023
3024
  ctx.res.status(401).json({ message: 'Invalid or expired token' })
3024
3025
  }
3025
3026
  }
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'
3027
+ `),l.push(u),l}function mr(e){return e?e.split(`,`).map(e=>e.trim()).filter(Boolean).map(e=>{let[t,n]=e.split(`:`).map(e=>e.trim());return{name:t,type:n||`string`}}).filter(e=>e.name.length>0):[]}function hr(e){switch(e){case`string`:return`''`;case`number`:return`0`;case`boolean`:return`false`;default:return null}}async function gr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=e.type??`http`,o=R(t),s=I(t),c=e.key??L(t),l=Array.isArray(e.params)?e.params:mr(e.params),u=H({type:`contributor`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/contributors`,pattern:i,shouldPluralize:e.pluralize??!0}),d=a===`http`?`defineHttpContextDecorator`:`defineContextDecorator`,f=a===`http`?`RequestContext`:`ExecutionContext`,p=l.length>0?`\nexport type ${s}Params = {\n${l.map(e=>` ${e.name}: ${e.type}`).join(`
3028
+ `)}\n}\n`:``,m=l.length>0?`${d}.withParams<${s}Params>()({`:`${d}({`,g=l.map(e=>({name:e.name,def:hr(e.type)})).filter(e=>e.def!==null).map(e=>` ${e.name}: ${e.def},`),_=l.length>0?` paramDefaults: {\n${g.join(`
3029
+ `)}\n },\n`:``,v=l.length>0?`(ctx, _deps, params)`:`(ctx)`,y=l.length>0?` // \`params\` is typed as ${s}Params (call-site overrides merged onto paramDefaults).`:` // \`ctx\` is a ${f} — read ctx.req / ctx.headers / ctx.params (http) or ctx.get (bare).`,b=`import { ${d} } from '@forinda/kickjs'
3030
+ import type { ${f} } from '@forinda/kickjs'
3031
+
3032
+ /**
3033
+ * ${s} context contributor (${a}).
3034
+ *
3035
+ * Computes a value and writes it to \`ctx.set('${c}', …)\` before a
3036
+ * matched handler runs — the typed, ordered alternative to
3037
+ * \`@Middleware()\` when the only job is to populate \`ctx\`.
3038
+ *
3039
+ * Apply per method/class, or register globally via
3040
+ * \`bootstrap({ contributors: [${s}] })\`:
3041
+ *
3042
+ * @${s}${l.length>0?`({ ${l[0]?.name}: … })`:``}
3043
+ * @Get('/')
3044
+ * handler(ctx: ${f}) {
3045
+ * return ctx.json(ctx.get('${c}'))
3046
+ * }
3047
+ */
3048
+
3049
+ // Register '${c}' so \`ctx.get('${c}')\` is typed and \`dependsOn: ['${c}']\`
3050
+ // is checked. Replace \`unknown\` with the resolved value's real type.
3051
+ // (For a key you only depend on — no value type needed — declare it in
3052
+ // \`interface ContextKeys\` instead.)
3053
+ declare module '@forinda/kickjs' {
3054
+ interface ContextMeta {
3055
+ '${c}': unknown
3056
+ }
3057
+ }
3058
+ ${p}
3059
+ export const ${s} = ${m}
3060
+ key: '${c}',
3061
+ ${_} resolve: ${v} => {
3062
+ ${y}
3063
+ // TODO: compute and return the value written to ctx.set('${c}', …)
3064
+ throw new Error("${s} contributor: resolve() not implemented")
3065
+ },
3066
+ })
3067
+ `,x=h(u,`${o}.contributor.ts`);return await M(x,b),[x]}async function _r(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=H({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'
3027
3068
 
3028
3069
  @Service()
3029
3070
  export class ${s}Service {
@@ -3032,7 +3073,7 @@ export class ${s}Service {
3032
3073
  // @Inject(MY_REPO) private readonly repo: IMyRepository,
3033
3074
  // ) {}
3034
3075
  }
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'
3076
+ `),c.push(l),c}async function vr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=H({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'
3036
3077
 
3037
3078
  // \`Ctx<KickRoutes.${s}Controller['<method>']>\` is generated by
3038
3079
  // \`kick typegen\` (auto-run on \`kick dev\`). After the first run, your IDE
@@ -3053,7 +3094,7 @@ export class ${s}Controller {
3053
3094
  ctx.created({ message: '${s} created', data: ctx.body })
3054
3095
  }
3055
3096
  }
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'
3097
+ `),c.push(l),c}async function yr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=H({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'
3057
3098
 
3058
3099
  export const ${c}Schema = z.object({
3059
3100
  // Define your schema fields here
@@ -3061,7 +3102,7 @@ export const ${c}Schema = z.object({
3061
3102
  })
3062
3103
 
3063
3104
  export type ${s}DTO = z.infer<typeof ${c}Schema>
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(`
3105
+ `),l.push(u),l}async function br(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(`
3065
3106
  Skipped — existing kick.config.ts preserved.`),[]):(await M(t,`import { defineConfig } from '@forinda/kickjs-cli'
3066
3107
 
3067
3108
  export default defineConfig({
@@ -3099,18 +3140,18 @@ export default defineConfig({
3099
3140
  },
3100
3141
  ],
3101
3142
  })
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(`
3143
+ `),[t])}var xr=D({generateAgentDocs:()=>Dr});const Sr=`.agents`,Cr=new Set([`rest`,`ddd`,`cqrs`,`minimal`]);function wr(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 Tr(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 Er(e,t){if(t)return t;try{let t=(await k(e))?.pattern;if(t&&Cr.has(t))return t}catch{}return`ddd`}async function Dr(e){let t=e.only??`all`,n=wr(e.outDir,e.name),i=Tr(e.outDir,e.pm),a=await Er(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,Sr,`AGENTS.md`),render:()=>xt(n,a,i)}),s&&d.push({file:h(e.outDir,`CLAUDE.md`),render:()=>bt(n,a,i)}),c)for(let t of St(n,a,i))d.push({file:h(e.outDir,Sr,`skills`,t.slug,`SKILL.md`),render:()=>t.content});l&&d.push({file:h(e.outDir,Sr,`GEMINI.md`),render:()=>Ct(n,a,i)}),u&&d.push({file:h(e.outDir,Sr,`COPILOT.md`),render:()=>wt(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 Or(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 U(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=Or(e,r);return i===-1?null:e.slice(r+1,i)}function W(e,t,n){let r=` `.repeat(n);return e.split(`
3103
3144
  `).map(e=>{if(e.trim()===``)return e;let n=RegExp(`^ {0,${t}}`);return r+e.replace(n,``)}).join(`
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({
3145
+ `)}function kr(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 Ar(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 jr(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=Or(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=U(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=U(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=U(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=kr(s),p=``;return l&&(p+=` register(container) {${W(l,4,6)} },\n\n`),u&&(p+=` contributors() {${W(u,4,6)} },\n\n`),p+=` routes() {${W(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
3105
3146
  name: '${r}',
3106
3147
  build: () => ({
3107
3148
  ${p}
3108
3149
  }),
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 {
3150
+ })`}${c}`}}function Mr(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=Or(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]===`
3151
+ `||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=Or(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=U(m,/register\s*\(([^)]*)\)\s*\{/),g=U(m,/contributors\s*\(\s*\)\s*\{/),_=U(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=Ar(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${W(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${W(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${W(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
3111
3152
  ${y}
3112
3153
  }
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'
3154
+ `}${u}`}}function Nr(e,t){return t===`class`?Mr(e):jr(e)}function Pr(e,t){let n=e,r=!1;if(t===`define`){/\bAppModuleClass\b/.test(n)&&(n=n.replaceAll(/\bAppModuleClass\b/g,`AppModuleEntry`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)(?![(.])/g,`$1()`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}else{/\bAppModuleEntry\b/.test(n)&&(n=n.replaceAll(/\bAppModuleEntry\b/g,`AppModuleClass`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)\s*\(\s*\)/g,`$1`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}return r?{migrated:n}:{migrated:null,reason:`no changes needed`}}async function Fr(e){let t=[];return await n(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 Ir(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 Lr(e){return h(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function Rr(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await Fr(e),s=await C(h(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=Lr(r),await Ir(e,c));let l=[];for(let e of o){let t=Nr(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=Pr(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 zr(e,t){let n=await Fr(e),r=[],i=t===`define`?/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/:/export\s+const\s+\w+Module\s*=\s*defineModule\s*\(/;for(let e of n){let t=await C(e,`utf-8`);i.test(t)&&r.push(e)}return r}async function Br(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'
3114
3155
  import { Job, Process, QUEUE_MANAGER, type QueueService } from '@forinda/kickjs-queue'
3115
3156
 
3116
3157
  /**
@@ -3143,7 +3184,7 @@ export class ${r}Job {
3143
3184
  // Handle high-priority variant of this job
3144
3185
  }
3145
3186
  }
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'
3187
+ `),s}const Vr={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 Hr(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=Vr[a];if(!o){let e=[...Object.keys(Vr),`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 Ur(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?Zt(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`,Zr(d,u,f,c)),await _(`constants.ts`,qr(d,n)),await _(`presentation/${u}.controller.ts`,Qr(d,u,f,p)),await _(`application/dtos/create-${u}.dto.ts`,Wr(d,n)),await _(`application/dtos/update-${u}.dto.ts`,Gr(d,n)),await _(`application/dtos/${u}-response.dto.ts`,Kr(d,n));let v=ti(d,u,f,p);for(let e of v)await _(`application/use-cases/${e.file}`,e.content);return await _(`domain/repositories/${u}.repository.ts`,$r(d,u,s)),await _(`domain/services/${u}-domain.service.ts`,ei(d,u)),o===`inmemory`&&await _(`infrastructure/repositories/in-memory-${u}.repository.ts`,Jr(d,u,n)),i||(await _(`domain/entities/${u}.entity.ts`,Yr(d,u,n)),await _(`domain/value-objects/${u}-id.vo.ts`,Xr(d))),await er(r,d,f,u,c),g}function Wr(e,t){return`import { z } from 'zod'
3147
3188
 
3148
3189
  export const create${e}Schema = z.object({
3149
3190
  ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:``},`}).join(`
@@ -3151,7 +3192,7 @@ ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:`
3151
3192
  })
3152
3193
 
3153
3194
  export type Create${e}DTO = z.infer<typeof create${e}Schema>
3154
- `}function Hr(e,t){return`import { z } from 'zod'
3195
+ `}function Gr(e,t){return`import { z } from 'zod'
3155
3196
 
3156
3197
  export const update${e}Schema = z.object({
3157
3198
  ${t.map(e=>` ${e.name}: ${e.zodType}.optional(),`).join(`
@@ -3159,21 +3200,21 @@ ${t.map(e=>` ${e.name}: ${e.zodType}.optional(),`).join(`
3159
3200
  })
3160
3201
 
3161
3202
  export type Update${e}DTO = z.infer<typeof update${e}Schema>
3162
- `}function Ur(e,t){return`export interface ${e}ResponseDTO {
3203
+ `}function Kr(e,t){return`export interface ${e}ResponseDTO {
3163
3204
  id: string
3164
3205
  ${t.map(e=>` ${e.name}${e.optional?`?`:``}: ${e.tsType}`).join(`
3165
3206
  `)}
3166
3207
  createdAt: string
3167
3208
  updatedAt: string
3168
3209
  }
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'
3210
+ `}function qr(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'
3170
3211
 
3171
3212
  export const ${e.toUpperCase()}_QUERY_CONFIG: ApiQueryParamsConfig = {
3172
3213
  filterable: [${i}],
3173
3214
  sortable: [${a}],
3174
3215
  searchable: [${o}],
3175
3216
  }
3176
- `}function Gr(e,t,n){return`import { randomUUID } from 'node:crypto'
3217
+ `}function Jr(e,t,n){return`import { randomUUID } from 'node:crypto'
3177
3218
  import { Repository, HttpException } from '@forinda/kickjs'
3178
3219
  import type { ParsedQuery } from '@forinda/kickjs'
3179
3220
  import type { I${e}Repository } from '../../domain/repositories/${t}.repository'
@@ -3225,7 +3266,7 @@ ${n.map(e=>` ${e.name}: dto.${e.name},`).join(`
3225
3266
  this.store.delete(id)
3226
3267
  }
3227
3268
  }
3228
- `}function Kr(e,t,n){return`import { ${e}Id } from '../value-objects/${t}-id.vo'
3269
+ `}function Yr(e,t,n){return`import { ${e}Id } from '../value-objects/${t}-id.vo'
3229
3270
 
3230
3271
  interface ${e}Props {
3231
3272
  id: ${e}Id
@@ -3271,7 +3312,7 @@ ${n.map(e=>` ${e.name}: this.props.${e.name},`).join(`
3271
3312
  }
3272
3313
  }
3273
3314
  }
3274
- `}function qr(e){return`import { randomUUID } from 'node:crypto'
3315
+ `}function Xr(e){return`import { randomUUID } from 'node:crypto'
3275
3316
 
3276
3317
  export class ${e}Id {
3277
3318
  private constructor(private readonly value: string) {}
@@ -3286,7 +3327,7 @@ export class ${e}Id {
3286
3327
  toString(): string { return this.value }
3287
3328
  equals(other: ${e}Id): boolean { return this.value === other.value }
3288
3329
  }
3289
- `}function Jr(e,t,n,r=`define`){let i=`import { ${e}Controller } from './presentation/${t}.controller'
3330
+ `}function Zr(e,t,n,r=`define`){let i=`import { ${e}Controller } from './presentation/${t}.controller'
3290
3331
  import { ${e.toUpperCase()}_REPOSITORY } from './domain/repositories/${t}.repository'
3291
3332
  import { InMemory${e}Repository } from './infrastructure/repositories/in-memory-${t}.repository'
3292
3333
 
@@ -3359,7 +3400,7 @@ ${a}
3359
3400
  },
3360
3401
  }),
3361
3402
  })
3362
- `}function Yr(e,t,n,r){return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
3403
+ `}function Qr(e,t,n,r){return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
3363
3404
  import { ApiTags } from '@forinda/kickjs-swagger'
3364
3405
  import { Create${e}UseCase } from '../application/use-cases/create-${t}.use-case'
3365
3406
  import { Get${e}UseCase } from '../application/use-cases/get-${t}.use-case'
@@ -3422,7 +3463,7 @@ export class ${e}Controller {
3422
3463
  ctx.noContent()
3423
3464
  }
3424
3465
  }
3425
- `}function Xr(e,t,n){return`import { createToken } from '@forinda/kickjs'
3466
+ `}function $r(e,t,n){return`import { createToken } from '@forinda/kickjs'
3426
3467
  import type { ${e}ResponseDTO } from '../../application/dtos/${t}-response.dto'
3427
3468
  import type { Create${e}DTO } from '../../application/dtos/create-${t}.dto'
3428
3469
  import type { Update${e}DTO } from '../../application/dtos/update-${t}.dto'
@@ -3448,7 +3489,7 @@ export interface I${e}Repository {
3448
3489
  * adopters must NOT use the reserved \`'kick/'\` namespace.
3449
3490
  */
3450
3491
  export const ${e.toUpperCase()}_REPOSITORY = createToken<I${e}Repository>('${n}/${e}/repository')
3451
- `}function Zr(e,t){return`import { Service, Inject, HttpException } from '@forinda/kickjs'
3492
+ `}function ei(e,t){return`import { Service, Inject, HttpException } from '@forinda/kickjs'
3452
3493
  import { ${e.toUpperCase()}_REPOSITORY, type I${e}Repository } from '../repositories/${t}.repository'
3453
3494
 
3454
3495
  @Service()
@@ -3462,7 +3503,7 @@ export class ${e}DomainService {
3462
3503
  if (!entity) throw HttpException.notFound('${e} not found')
3463
3504
  }
3464
3505
  }
3465
- `}function Qr(e,t,n,r){return[{file:`create-${t}.use-case.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
3506
+ `}function ti(e,t,n,r){return[{file:`create-${t}.use-case.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
3466
3507
  import { ${e.toUpperCase()}_REPOSITORY, type I${e}Repository } from '../../domain/repositories/${t}.repository'
3467
3508
  import type { Create${e}DTO } from '../dtos/create-${t}.dto'
3468
3509
 
@@ -3505,7 +3546,7 @@ export class Delete${e}UseCase {
3505
3546
  constructor(@Inject(${e.toUpperCase()}_REPOSITORY) private repo: I${e}Repository) {}
3506
3547
  async execute(id: string) { return this.repo.delete(id) }
3507
3548
  }
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'
3549
+ `}]}async function ni(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'
3509
3550
  import { Container } from '@forinda/kickjs'
3510
3551
 
3511
3552
  describe('${o}', () => {
@@ -3528,9 +3569,9 @@ describe('${o}', () => {
3528
3569
  expect(true).toBe(true)
3529
3570
  })
3530
3571
  })
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}
3572
+ `),s.push(l),s}const ri=[`Service`,`Controller`,`Repository`,`Injectable`,`Component`,`Module`],ii=[`.ts`,`.tsx`,`.mts`,`.cts`],ai=[`node_modules`,`.kickjs`,`dist`,`build`,`.test.`,`.spec.`,`.d.ts`],oi=new RegExp(String.raw`@(${ri.join(`|`)})\s*\([^)]*\)`+String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*`+String.raw`\s*export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`,`g`),si=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`),ci=/(?:export\s+)?const\s+(\w+)\s*(?::\s*[^=]+)?=\s*createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,li=/createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,ui=/@Inject\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,di=/\b(defineAdapter|definePlugin)\s*(?:<[^>]*>)?\s*\(/g,fi=/\b(?:defineContextDecorator|defineHttpContextDecorator)\s*(?:\.withParams\s*<(?:[^<>]|<[^<>]*>)*>\s*\(\s*\))?\s*(?:<(?:[^<>]|<[^<>]*>)*>)?\s*\(/g,pi=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`),mi=/\bname\s*(?::\s*[^=]+)?=\s*['"`]([^'"`]+)['"`]/,hi=/\bdefineAugmentation\s*\(\s*['"`]([^'"`]+)['"`]\s*(,\s*\{)?/g,gi=new RegExp(String.raw`@(${[`Get`,`Post`,`Put`,`Delete`,`Patch`].join(`|`)})\s*\(`,`g`);function _i(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 vi(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=_i(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 yi(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function bi(e,t){let n=e.endsWith(`/`)?e.slice(0,-1):e;return!t||t===`/`?n||`/`:n+(t.startsWith(`/`)?t:`/`+t)||`/`}const xi=/\b(?:public\s+|private\s+|protected\s+)?routes\s*\([^)]*\)\s*(?::\s*[A-Za-z_][\w<>[\]\s,|]*\s*)?\{/g,Si=/\bpath\s*:\s*['"`]([^'"`]*)['"`]/g,Ci=/\bcontroller\s*:\s*([A-Z]\w*)\b/g,wi=/\bimport\.meta\.glob\s*\(/g;function Ti(e){let t=[];for(wi.lastIndex=0;wi.exec(e)!==null;){let n=wi.lastIndex-1,r=_i(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 Ei(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 Di(e,t){let n=e.startsWith(`./`)?e:`./`+e,r=!1;for(let e of t){let t=e.startsWith(`!`);Ei(t?e.slice(1):e).test(n)&&(r=!t)}return r}function Oi(e){let t=[];xi.lastIndex=0;let n;for(;(n=xi.exec(e))!==null;){let r=e.indexOf(`{`,n.index+n[0].length-1);if(r<0)continue;let i=Bi(e,r);if(i<0)continue;let a=e.slice(r+1,i),o=[];Si.lastIndex=0;let s;for(;(s=Si.exec(a))!==null;)o.push(s[1]??``);let c=[];Ci.lastIndex=0;let l;for(;(l=Ci.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 ki(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 Ai(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 ji(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?Mi(n[1].trim(),t):null}return Mi(n[1].trim(),t)}function Mi(e,t){if(e.startsWith(`{`))return Pi(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 Pi(r[1])}return{filterable:[],sortable:[],searchable:[]}}function Ni(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 Pi(e){return{filterable:Ni(e,`filterable`),sortable:Ni(e,`sortable`),searchable:Ni(e,`searchable`)}}async function Fi(e,t){let n=t.extensions??ii,r=t.exclude??ai,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 Fi(a,t)):o.isFile()&&n.some(e=>o.name.endsWith(e))&&i.push(a))}return i}function G(e,t){return _(t,e).split(y).join(`/`)}function Ii(e,t,n){let r=[],i=G(t,n);oi.lastIndex=0;let a;for(;(a=oi.exec(e))!==null;){let[,e,n,o]=a;r.push({className:o,decorator:e,filePath:t,relativePath:i,isDefault:!!n})}si.lastIndex=0;let o;for(;(o=si.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 Li(e,t,n){let r=[],i=G(t,n),a=new Set;ci.lastIndex=0;let o;for(;(o=ci.exec(e))!==null;){let[e,n,s]=o;a.add(e),r.push({name:s,variable:n,filePath:t,relativePath:i})}for(li.lastIndex=0;(o=li.exec(e))!==null;)a.has(o[0])||r.push({name:o[1],variable:null,filePath:t,relativePath:i});return r}function Ri(e,t,n,r,i=new Map){let a=[];if(r.length===0)return a;let o=G(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);gi.lastIndex=0;let d;for(;(d=gi.exec(u))!==null;){let n=d[1],s=d.index,c=gi.lastIndex-1,l=_i(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=vi(u,l+1);if(!h)continue;let{methodName:g,endPos:_}=h;gi.lastIndex=_;let v=ji(u.slice(s,_),e),y=ki(f,`body`),b=ki(f,`query`),x=ki(f,`params`),ee=i.get(r.className)??``,S=ee?bi(ee,m):m;a.push({controller:r.className,method:g,httpMethod:n.toUpperCase(),path:m,pathParams:yi(S),queryFilterable:v?.filterable??null,querySortable:v?.sortable??null,querySearchable:v?.searchable??null,bodySchema:y?{identifier:y,source:Ai(e,y)}:null,querySchema:b?{identifier:b,source:Ai(e,b)}:null,paramsSchema:x?{identifier:x,source:Ai(e,x)}:null,filePath:t,relativePath:o})}}return a}function zi(e,t,n){let r=[],i=G(t,n);ui.lastIndex=0;let a;for(;(a=ui.exec(e))!==null;)r.push({name:a[1],filePath:t,relativePath:i});return r}function Bi(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 Vi(e,t,n){let r=[],i=G(t,n),a=new Set;di.lastIndex=0;let o;for(;(o=di.exec(e))!==null;){let n=o[1],s=di.lastIndex-1,c=_i(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}))}pi.lastIndex=0;let s;for(;(s=pi.exec(e))!==null;){let n=s.index,o=e.indexOf(`{`,n);if(o<0)continue;let c=Bi(e,o);if(c<0)continue;let l=e.slice(o+1,c),u=mi.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 Hi(e,t,n){let r=[],i=G(t,n),a=new Set;for(fi.lastIndex=0;fi.exec(e)!==null;){let n=fi.lastIndex-1,o=_i(e,n);if(o<0)continue;let s=e.slice(n+1,o),c=/\bkey\s*:\s*['"`]([^'"`]+)['"`]/.exec(s);if(!c)continue;let l=c[1];a.has(l)||(a.add(l),r.push({key:l,filePath:t,relativePath:i}))}return r}function Ui(e,t,n){let r=[],i=G(t,n);hi.lastIndex=0;let a;for(;(a=hi.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=Bi(e,t);if(n>=0){let r=e.slice(t+1,n);o=Wi(r,`description`),s=Wi(r,`example`)}}}r.push({name:n,description:o,example:s,filePath:t,relativePath:i})}return r}function Wi(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`?`
3573
+ `:t===`t`?` `:t===`r`?`\r`:t)}const Gi=[`src/config/index.ts`,`src/config/env.ts`,`src/config.ts`,`src/env.ts`];async function Ki(e,t){let n=t===`src/env.ts`?Gi:[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:G(n,e)}}return null}function qi(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 Ji(e){let t=await Fi(v(e.root),e),n=[],r=[],i=[],a=[],o=[],s=[],c=[],l=new Map;for(let r of t){let t;try{t=await C(r,`utf-8`)}catch{continue}l.set(r,t),n.push(...Ii(t,r,e.cwd)),i.push(...Li(t,r,e.cwd)),a.push(...zi(t,r,e.cwd)),o.push(...Vi(t,r,e.cwd)),s.push(...Ui(t,r,e.cwd)),c.push(...Hi(t,r,e.cwd))}let u=new Map;for(let[,e]of l)for(let{controller:t,mountPath:n}of Oi(e))u.has(t)||u.set(t,n);for(let[t,i]of l){let a=n.filter(e=>e.filePath===t);r.push(...Ri(i,t,e.cwd,a,u))}let d=[];for(let[e,t]of l){if(!/\.module\.[mc]?[tj]sx?$/.test(e))continue;let r=Ti(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&&(Di(n.slice(a.length+1),r)||d.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)),c.sort((e,t)=>e.key.localeCompare(t.key)||e.relativePath.localeCompare(t.relativePath));let f=qi(n),p=await Ki(e.cwd,e.envFile??`src/env.ts`);return d.sort((e,t)=>e.relativePath.localeCompare(t.relativePath)||e.className.localeCompare(t.className)),{classes:n,routes:r,tokens:i,injects:a,collisions:f,env:p,pluginsAndAdapters:o,augmentations:s,contextKeys:c,orphanedClasses:d}}const K="/* 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",Yi=new Set([`Service`,`Repository`,`Injectable`,`Component`]);var Xi=class extends Error{collisions;constructor(e){super(Zi(e)),this.name=`TokenCollisionError`,this.collisions=e}};function Zi(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(`
3574
+ `)}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 $i(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 ea(e,t,n){let r=new Set,i=[];for(let a of e){if(!Yi.has(a.decorator))continue;let e=n.has(a.className)?$i(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`${K}
3534
3575
  declare module '@forinda/kickjs' {
3535
3576
  interface KickJsRegistry {
3536
3577
  ${i.length?i.join(`
@@ -3539,30 +3580,29 @@ ${i.length?i.join(`
3539
3580
  }
3540
3581
 
3541
3582
  export {}
3542
- `}function Xi(e,t,n){return t.length===0?`${G}
3583
+ `}function ta(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function na(e){return`${K}
3584
+ declare module '@forinda/kickjs' {
3585
+ /**
3586
+ * Key-only registry of every context key produced by a
3587
+ * \`defineContextDecorator\` / \`defineHttpContextDecorator\` in the
3588
+ * project. Feeds \`dependsOn\` typo-checking. Value types live in
3589
+ * \`ContextMeta\`; this only records that the key exists.
3590
+ */
3591
+ interface ContextKeys {
3592
+ ${[...new Set(e.map(e=>e.key))].toSorted().map(e=>` ${ta(e)?e:JSON.stringify(e)}: true`).join(`
3593
+ `)}
3594
+ }
3595
+ }
3596
+
3597
+ export {}
3598
+ `}function ra(e,t,n){return t.length===0?`${K}
3543
3599
  // ${n}
3544
3600
  export type ${e} = never
3545
- `:`${G}
3601
+ `:`${K}
3546
3602
  export type ${e} =
3547
3603
  ${[...new Set(t)].toSorted().map(e=>` | '${e}'`).join(`
3548
3604
  `)}
3549
- `}function Zi(e,t){return`${G}
3550
- export type { ServiceToken } from './services'
3551
- export type { ModuleToken } from './modules'
3552
-
3553
- // The registry, routes, plugins, assets, and env augmentations are
3554
- // loaded as side-effects — importing this file (or having it on
3555
- // tsconfig include) is enough for \`container.resolve()\`,
3556
- // \`Ctx<KickRoutes.UserController['getUser']>\`,
3557
- // \`dependsOn: ['TenantAdapter']\`, \`assets.mails.welcome()\`, and
3558
- // \`@Value('PORT')\` to resolve.
3559
- import './registry'
3560
- import './kick__routes'
3561
- import './plugins'
3562
- import './augmentations'
3563
- ${t?`import './kick__assets'
3564
- `:``}${e?`import './kick__env'
3565
- `:``}`}function Qi(e){let t=new Map;for(let n of e)t.has(n.name)||t.set(n.name,n);return`${G}
3605
+ `}function ia(e,t,n,r){return[...e.filter(e=>Yi.has(e.decorator)).map(e=>r.has(e.className)?$i(e):e.className),...t.map(e=>e.name),...n.map(e=>e.name)]}function aa(e){return e.filter(e=>e.decorator===`Module`).map(e=>e.className)}function oa(e){let t=new Map;for(let n of e)t.has(n.name)||t.set(n.name,n);return`${K}
3566
3606
  declare module '@forinda/kickjs' {
3567
3607
  /**
3568
3608
  * Map of every plugin/adapter \`name\` discovered in the project. The
@@ -3577,7 +3617,7 @@ ${[...t.values()].toSorted((e,t)=>e.name.localeCompare(t.name)).map(e=>` '${e
3577
3617
  }
3578
3618
 
3579
3619
  export {}
3580
- `}function $i(e){if(e.length===0)return`${G}
3620
+ `}function sa(e){if(e.length===0)return`${K}
3581
3621
  // No augmentations discovered.
3582
3622
  //
3583
3623
  // Plugins advertise augmentable interfaces via:
@@ -3593,7 +3633,7 @@ export {}
3593
3633
  `;let t=new Map;for(let n of e)t.has(n.name)||t.set(n.name,n);let n=[];for(let e of[...t.values()].toSorted((e,t)=>e.name.localeCompare(t.name))){let t=[];if(e.description)for(let n of e.description.split(`
3594
3634
  `))t.push(` * ${n}`);if(e.example){t.push(` * @example`," * ```ts");for(let n of e.example.split(`
3595
3635
  `))t.push(` * ${n}`);t.push(" * ```")}t.push(` * @see ${e.relativePath}`),n.push([`/**`,...t,` */`,`export interface ${e.name}Augmentation {}`].join(`
3596
- `))}return`${G}
3636
+ `))}return`${K}
3597
3637
  // Catalogue of augmentable interfaces in this project. The interfaces
3598
3638
  // below are documentation only — augment the source-of-truth interfaces
3599
3639
  // in your own \`d.ts\` files (the framework declares the actual types).
@@ -3601,9 +3641,7 @@ export {}
3601
3641
  ${n.join(`
3602
3642
 
3603
3643
  `)}
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
3605
- *
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}
3644
+ `}const ca=/^(kick\/)?([a-z][\w-]*\/[A-Z]\w*)(\/.+)?(:[a-z][\w-]+(:[a-z][\w-]+)*)?$/;function la(e){let t=[];for(let n of e){let e=n.name;e.startsWith(`kickjs.`)||ca.test(e)||t.push({token:e,variable:n.variable,filePath:n.relativePath,reason:"does not match `<scope>/<PascalKey>[/<suffix>][:<instance>]`",suggestion:ua(e)})}return t}function ua(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 da(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(!ga(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 fa(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}
3607
3645
  declare module '@forinda/kickjs' {
3608
3646
  /**
3609
3647
  * Map of every typed asset discovered in the project's assetMap.
@@ -3614,7 +3652,7 @@ declare module '@forinda/kickjs' {
3614
3652
  }
3615
3653
 
3616
3654
  export {}
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}
3655
+ `;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===pa){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]=pa)}return`${t}
3618
3656
  declare module '@forinda/kickjs' {
3619
3657
  /**
3620
3658
  * Map of every typed asset discovered in the project's assetMap.
@@ -3623,43 +3661,46 @@ declare module '@forinda/kickjs' {
3623
3661
  * prod → dist).
3624
3662
  */
3625
3663
  interface KickAssets {
3626
- ${sa(n,` `)}
3664
+ ${ma(n,` `)}
3627
3665
  }
3628
3666
  }
3629
3667
 
3630
3668
  export {}
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(`
3633
- `+e.message+`
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(`
3669
+ `}const pa=Symbol(`asset-leaf`);function ma(e,t){let n=Object.keys(e).toSorted(),r=[];for(let i of n){let n=e[i],a=ha(i)?i:JSON.stringify(i);n===pa?r.push(`${t}${a}: () => string`):(r.push(`${t}${a}: {`),r.push(ma(n,`${t} `)),r.push(`${t}}`))}return r.join(`
3670
+ `)}function ha(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function ga(e){try{return c(e).isDirectory()}catch{return!1}}var _a=D({runTypegen:()=>q,sweepStaleTypegen:()=>Sa,watchTypegen:()=>xa,writeTypegenArtifacts:()=>ba});function va(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 q(e={}){let{cwd:t,srcDir:n,outDir:r,silent:i,allowDuplicates:a,envFile:o}=va(e),s=Date.now(),c=await Ji({root:n,cwd:t,envFile:o===!1?void 0:o});if(c.collisions.length>0&&!a)throw new Xi(c.collisions);let l=da(e.assetMap,t),u=[],d=[];if(e.runPlugins!==!1){try{let{runAllPluginTypegens:e}=await Promise.resolve().then(()=>Pa),{loadKickConfig:n}=await Promise.resolve().then(()=>Me);u=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`)}}d.push(...await ba(r,u,i))}let f=la(c.tokens),p=ya(c,l.count,d),m=Date.now()-s;if(!i){let e=r.replace(t+`/`,``),n=p.resolvedCollisions>0?`, ${p.resolvedCollisions} collisions namespaced`:``,i=p.envWritten?`, env typed`:``,a=p.pluginEntries>0?`, ${p.pluginEntries} plugins/adapters`:``,o=p.augmentationEntries>0?`, ${p.augmentationEntries} augmentations`:``,s=p.assetEntries>0?`, ${p.assetEntries} assets`:``;if(console.log(` kick typegen → ${p.serviceTokens} services, ${p.routeEntries} routes, ${p.moduleTokens} modules${a}${o}${s}${i}${n} → ${e} (${m}ms)`),f.length>0){console.warn(` kick typegen: ${f.length} token(s) don't match the §22.2 convention:`);for(let e of f){let t=e.variable?` [${e.variable}]`:``;console.warn(` '${e.token}' (${e.filePath})${t} — ${e.reason}`),e.suggestion&&console.warn(` → suggestion: ${e.suggestion}`)}}if(c.orphanedClasses.length>0){console.warn(` kick typegen: ${c.orphanedClasses.length} decorated class(es) not matched by any module's import.meta.glob():`);for(let e of c.orphanedClasses)console.warn(` @${e.decorator} ${e.className} (${e.relativePath})`),console.warn(` → not picked up by any glob in ${e.moduleFilePath}`)}}return{scan:c,result:p,tokenWarnings:f}}function ya(e,t,n){let r=new Set(e.collisions.map(e=>e.className)),i=e.classes.filter(e=>Yi.has(e.decorator)),a=ia(e.classes,e.tokens,e.injects,r);return{registryEntries:i.length,serviceTokens:new Set(a).size,moduleTokens:aa(e.classes).length,routeEntries:e.routes.length,pluginEntries:new Set(e.pluginsAndAdapters.map(e=>e.name)).size,augmentationEntries:new Set(e.augmentations.map(e=>e.name)).size,assetEntries:t,envWritten:e.env!==null,written:n,resolvedCollisions:e.collisions.length}}async function ba(e,t,n){await oe(e,{recursive:!0}),await w(h(f(e),`.gitignore`),`# Auto-generated by kick typegen
3671
+ *
3672
+ `,`utf-8`);let r=t.filter(e=>e.outFile).map(e=>e.outFile);return await Sa(e,r,t,n),r}async function xa(e={}){let t=va(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(()=>Pa),Promise.resolve().then(()=>Me)]),l=await c(i),u=async()=>{try{await q({...a})}catch(e){if(r)return;if(e instanceof Xi)console.error(`
3635
3673
  `+e.message+`
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(`
3674
+ `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}},d=async()=>{try{let e=await s({cwd:i,config:l,silent:!0});await ba(t.outDir,e,!0)}catch{}};await u(),await d();let{watch:f}=await import(`node:fs`),p=null,m=e=>{e&&/\.(ts|tsx|mts|cts)$/.test(e)&&(e.includes(`.kickjs`)||e.endsWith(`.d.ts`)||(p&&clearTimeout(p),p=setTimeout(()=>{u().then(d)},100)))};if(o){r||console.log(` kick typegen: polling mode (KICKJS_WATCH_POLLING)`);let e=setInterval(()=>{u().then(d)},2e3);return()=>clearInterval(e)}let h;try{h=f(n,{recursive:!0},(e,t)=>{m(t)})}catch(e){r||console.warn(` kick typegen: watch mode unavailable (${e?.message??e}). Falling back to polling.`);let t=setInterval(()=>{u().then(d)},2e3);return()=>clearInterval(t)}return()=>{p&&clearTimeout(p),h.close()}}async function Sa(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(!Ca.has(t)||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 Ca=new Set([`assets.d.ts`,`env.ts`,`routes.ts`,`registry.d.ts`,`services.d.ts`,`modules.d.ts`,`plugins.d.ts`,`augmentations.d.ts`,`index.d.ts`]),wa=[`agents`,`claude`,`skills`,`gemini`,`copilot`,`both`,`all`];function J(e){return e.parent?.opts()?.dryRun??!1}function Y(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(`
3675
+ (dry run — no files were written)`),console.log()}async function Ta(e){if(!e)try{let e=await k(process.cwd());await q({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 Ea=[{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:`contributor <name>`,description:`Context contributor [--type http|bare] [--params a:string] [-m]`},{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 Da(){console.log(`
3638
3676
  Built-in generators:
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(`
3677
+ `);let e=Math.max(...Ea.map(e=>e.name.length));for(let t of Ea)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await k(process.cwd()),n=Ue(t?.plugins??[],t?.commands??[]),r=await fn(process.cwd(),n.generators);if(r.generators.length>0){console.log(`
3640
3678
  Plugin generators:
3641
3679
  `);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(`
3642
3680
  Failed to load:
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
3681
+ `);for(let{source:e,reason:t}of r.failed)console.log(` ${e} — ${t}`)}console.log()}async function Oa(e,t,n){let r=await k(process.cwd()),i=O(r),a=t.modulesDir??i.dir??`src/modules`,o=t.repo??Qn(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 zr(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 $n({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)}Y(d,n),await Ta(n)}function ka(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 Da();return}if(!e||e.length===0){n.help();return}let a=J(i);j(a);let[o,s,...c]=e;if(o){let e=await k(process.cwd()),n=Ue(e?.plugins??[],e?.commands??[]),i=await dn({generatorName:o,itemName:s??``,args:c,flags:r,cwd:process.cwd(),projectRoot:t?.projectRoot},n.generators);if(i){Y(i.files,a);return}}await Oa(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=J(n);j(r),await Oa(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=J(n);j(r),Y(await sr({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=J(n);j(r),Y(await cr({name:e,outDir:v(t.out)}),r)}),n.command(`middleware <name>`).description(`Generate an Express middleware function
3682
+ 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=J(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;Y(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.)
3683
+ 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=J(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;Y(await pr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`contributor <name>`).description(`Generate a Context Contributor (typed alternative to @Middleware for ctx.set)
3684
+ --type http (default, RequestContext) | bare (ExecutionContext)
3685
+ --params "source:string,region:number" emits the withParams<T>() form
3686
+ Use -m to scope it to a module: kick g contributor tenant -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).option(`-t, --type <type>`,`Contributor flavour: http | bare`,`http`).option(`-k, --key <key>`,`Context key it writes (defaults to camelCase of name)`).option(`--params <fields>`,`Per-call params, e.g. "source:string,region:number"`).action(async(e,t,n)=>{let r=J(n);j(r);let i=(t.type??`http`).toLowerCase();i!==`http`&&i!==`bare`&&(console.warn(` kick g contributor: unknown --type '${t.type}', using 'http'.`),i=`http`);let a=await k(process.cwd()),o=O(a),s=o.dir??`src/modules`;Y(await gr({name:e,type:i,key:t.key,params:t.params,outDir:t.out,moduleName:t.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),r)}),n.command(`service <name>`).description(`Generate a @Service() class
3687
+ 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=J(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;Y(await _r({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
3688
+ 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=J(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;Y(await vr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r),await Ta(r)}),n.command(`dto <name>`).description(`Generate a Zod DTO schema
3689
+ 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=J(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;Y(await yr({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
3690
+ 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=J(n);j(r);let i=O(await k(process.cwd())),a=i.dir??`src/modules`;Y(await ni({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=J(n);j(r),Y(await Br({name:e,outDir:v(t.out),queue:t.queue}),r)}),n.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
3650
3691
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
3651
3692
  Types: string, text, number, int, float, boolean, date, email, url, uuid, json, enum:a,b,c
3652
3693
  Optional: append :optional (shell-safe): description:text:optional
3653
- or use ? with quoting: "description:text?" or "description?:text"`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`--modules-dir <dir>`,`Modules directory`).action(async(e,t,n,r)=>{let i=q(r);j(i),t.length===0&&(console.error(`
3694
+ or use ? with quoting: "description:text?" or "description?:text"`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`--modules-dir <dir>`,`Modules directory`).action(async(e,t,n,r)=>{let i=J(r);j(i),t.length===0&&(console.error(`
3654
3695
  Error: At least one field is required.
3655
3696
  Usage: kick g scaffold <name> <field:type> [field:type...]
3656
3697
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
3657
3698
  Optional: append :optional (shell-safe, no quoting needed)
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(`
3699
+ `),process.exit(1));let a=await k(process.cwd()),o=O(a),s=n.modulesDir??o.dir??`src/modules`,c=Hr(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 Ur({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)`:``}`);Y(d,i),await Ta(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=J(t);j(n),Y(await br({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=J(t);j(n);let r=e.only??`all`;if(!wa.includes(r)){console.error(` Invalid --only value: ${r}. Expected: ${wa.join(` | `)}`),process.exitCode=1;return}Y(await Dr({outDir:v(`.`),only:r,name:e.name,pm:e.pm,template:e.template,force:e.force}),n)});for(let e of t?.generators??[])Aa(n,e,t?.projectRoot)}function Aa(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=J(o);j(s);let c=await dn({generatorName:i.name,itemName:e??``,args:r??[],flags:a,cwd:process.cwd(),projectRoot:n},[t]);c&&Y(c.files,s)})}async function ja(e){let t=u.resolve(e.cwd,`.kickjs/types`);await oe(t,{recursive:!0});let n=new Map,i=e.scan??Ji,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=Ma(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=n.outExtension??`.d.ts`,s=u.join(t,`${n.id.replace(/\//g,`__`)}${i}`),c;try{c=await n.generate(a)}catch(e){let t=e instanceof Error?e.message:String(e);a.log.error(` ${n.id}: typegen failed (${t}) — keeping previous output`),o.push({id:n.id,status:`error`,outFile:s});continue}if(c===null){o.push({id:n.id,status:`skipped`});continue}let l=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: ${n.id} */\n\n`+c+`
3700
+ `,d=``;if(r(s)&&(d=await C(s,`utf8`)),d===l){o.push({id:n.id,status:`unchanged`,outFile:s});continue}if(e.check)throw Error(`kick typegen --check: drift detected for ${n.id} (${s})`);await w(s,l,`utf8`),o.push({id:n.id,status:`written`,outFile:s})}return o}function Ma(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 Na(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 Pa=D({applyDisableFilter:()=>Na,runAllPluginTypegens:()=>Fa});async function Fa(e){let{enabled:t,skipped:n,unknown:r}=Na(Ue([...Xs,...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 ja({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 Ia(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 La(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)+`
3701
+ `,`utf-8`),s(` ✓ wrote manifest → ${_(n,p)} (${Object.keys(d).length} entries)`),{manifestPath:p,entries:u,manifest:f}}async function La(e,t,a,o){let s=v(a,t.src),c=t.dest?v(a,t.dest):h(o,e);if(za(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)||!Ba(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]=Ra(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 Ra(e,t){return _(e,t).split(/[\\/]/).filter(Boolean).join(`/`)}function za(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function Ba(e){try{return c(e).isDirectory()}catch{return!1}}function Va(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function Ha(e,t,n={}){t&&(process.env.PORT=t);let r=Va(n.polling),i=process.cwd(),a=await k(i),o=a?.typegen?.schemaValidator??`zod`,s=a?.typegen?.envFile;try{await q({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})`)}let c=v(i,a?.typegen?.outDir??`.kickjs/types`);try{await ba(c,await Fa({cwd:i,config:a}),!1)}catch(e){console.warn(` kick typegen: plugin pass skipped (${e?.message??e})`)}let{createRequire:l}=await import(`node:module`),{createServer:u}=await import(x(l(v(`package.json`)).resolve(`vite`)).href),d=await u({configFile:v(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...r?{watch:{usePolling:!0,interval:100}}:{}}}),f=a?.assetMap?Object.values(a.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>v(i,e)):[],p=e=>f.some(t=>e===t||e.startsWith(`${t}/`)),m=null,h=e=>{if(e.includes(`.kickjs`)||e.endsWith(`.d.ts`))return;let t=/\.(ts|tsx|mts|cts)$/.test(e),n=p(e);!t&&!n||(m&&clearTimeout(m),m=setTimeout(()=>{q({cwd:i,silent:!0,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1}).catch(()=>{}),Fa({cwd:i,config:a,silent:!0}).then(e=>ba(c,e,!0)).catch(()=>{})},100))};d.watcher.on(`add`,h),d.watcher.on(`unlink`,h),d.watcher.on(`change`,h),f.length>0&&d.watcher.add(f),await d.listen(),d.printUrls(),console.log(`
3661
3702
  KickJS dev server running (Vite + @forinda/kickjs-vite)
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(`
3703
+ `);let g=async()=>{m&&clearTimeout(m),await d.close(),process.exit(0)};process.on(`SIGINT`,g),process.on(`SIGTERM`,g)}function Ua(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 Ha(e.entry,e.port,{polling:e.polling})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
3663
3704
  Error: vite is not installed.
3664
3705
  Run: pnpm add -D vite unplugin-swc
3665
3706
  `):console.error(`
@@ -3667,13 +3708,13 @@ export {}
3667
3708
  Building for production...
3668
3709
  `);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(`
3669
3710
  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(`
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(`
3711
+ Building asset map...`);try{await Ia(a,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
3671
3712
  Build complete.
3672
3713
  `)}),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(`
3673
- Building asset map...`);try{await Da(e,{cwd:process.cwd()}),console.log(`
3714
+ Building asset map...`);try{await Ia(e,{cwd:process.cwd()}),console.log(`
3674
3715
  Asset build complete.
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(`
3716
+ `)}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 Ha(e.entry,e.port)}catch(e){console.error(`
3717
+ Dev server (debug) failed:`,e.message??e),process.exit(1)}})}function Wa(e){e.command(`info`).description(`Print system and framework info`).action(()=>{console.log(`
3677
3718
  KickJS CLI
3678
3719
 
3679
3720
  System:
@@ -3684,7 +3725,7 @@ export {}
3684
3725
  @forinda/kickjs workspace
3685
3726
  @forinda/kickjs-vite workspace
3686
3727
  @forinda/kickjs-cli workspace
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
3728
+ `)})}const{bold:X,dim:Z,green:Ga,red:Ka,yellow:qa,blue:Ja}=E;function Ya(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 Xa(e){let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw Error(`${t.status} ${t.statusText}`);return t.json()}async function Za(e,t){try{return await Xa(`${e}${t}`)}catch{return null}}async function Qa(e){let[t,n,r,i,a]=await Promise.all([Za(e,`/health`),Za(e,`/metrics`),Za(e,`/routes`),Za(e,`/container`),Za(e,`/ws`)]);return{health:t,metrics:n,routes:r,container:i,ws:a}}function $a(e,t){let{health:n,metrics:r,routes:i,container:a,ws:o}=t,s=Z(`─`.repeat(60));if(console.log(),console.log(X(` KickJS Inspector`)+Z(` → ${e}`)),console.log(s),n){let e=n.status===`healthy`?Ga(`● healthy`):Ka(`● `+n.status);console.log(` ${X(`Health:`)} ${e}`)}else console.log(` ${X(`Health:`)} ${Ka(`● unreachable`)}`);if(r){let e=((r.errorRate??0)*100).toFixed(1),t=r.errorRate>.1?Ka:r.errorRate>0?qa:Ga;console.log(` ${X(`Uptime:`)} ${Ya(r.uptimeSeconds)}`),console.log(` ${X(`Requests:`)} ${r.requests}`),console.log(` ${X(`Errors:`)} ${r.serverErrors} server, ${r.clientErrors??0} client ${Z(`(`)}${t(e+`%`)}${Z(`)`)}`)}if(a&&console.log(` ${X(`DI:`)} ${a.count} bindings`),o&&o.enabled&&console.log(` ${X(`WS:`)} ${o.connections??0} connections, ${o.namespaces??0} namespaces`),i?.routes?.length){console.log(),console.log(X(` Routes`)),console.log(s),console.log(` ${Z(`METHOD`)} ${Z(`PATH`.padEnd(36))} ${Z(`CONTROLLER`)}`);for(let e of i.routes){let t=e.path.length>36?e.path.slice(0,33)+`...`:e.path.padEnd(36);console.log(` ${Mt(e.method)} ${t} ${Ja(e.controller)}.${Z(e.handler)}`)}}console.log(s),console.log()}function eo(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 Qa(r);t.json?console.log(JSON.stringify(e,null,2)):$a(n,e)}catch(e){t.json?console.log(JSON.stringify({error:String(e)})):(console.error(Ka(` ✖ Could not connect to ${n}`)),console.error(Z(` ${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 to(e,t){let n=e.toLowerCase();return t.every(e=>n.includes(e.toLowerCase()))}function Q(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}const no=[{match(e,t){let n=to(e,[`config`,`get`])&&Q(e,[`undefined`,`null`]),r=e.includes(`@Value`)&&Q(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
3688
3729
  registers the env schema with kickjs at module-load time. Without it,
3689
3730
  ConfigService falls back to the base schema (PORT/NODE_ENV/LOG_LEVEL only)
3690
3731
  and every user-defined key reads as undefined. @Value() may *appear* to
@@ -3696,7 +3737,7 @@ import { modules } from './modules'
3696
3737
  import './config' // ← add this — registers env schema
3697
3738
  import { bootstrap } from '@forinda/kickjs'
3698
3739
  import { modules } from './modules'
3699
- `,docs:`https://forinda.github.io/kick-js/guide/configuration.html#wiring-the-schema-at-startup`}}}},{match(e,t){let n=Z(e,[`vitest`,`test`,`spec`,`__tests__`,`.test.`]);return Z(e,[`already registered`,`already exists`,`duplicate`,`has been registered`])?{confidence:n?85:60,diagnosis:{id:`container-not-reset-in-tests`,title:`DI container leaks between test cases`,explanation:`KickJS decorators register classes on the global Container at import time.
3740
+ `,docs:`https://forinda.github.io/kick-js/guide/configuration.html#wiring-the-schema-at-startup`}}}},{match(e,t){let n=Q(e,[`vitest`,`test`,`spec`,`__tests__`,`.test.`]);return Q(e,[`already registered`,`already exists`,`duplicate`,`has been registered`])?{confidence:n?85:60,diagnosis:{id:`container-not-reset-in-tests`,title:`DI container leaks between test cases`,explanation:`KickJS decorators register classes on the global Container at import time.
3700
3741
  When vitest re-imports your modules across tests, the same class can be
3701
3742
  registered twice and the container throws. The fix is to wipe the
3702
3743
  container between tests so each case starts fresh.`,fix:`Add Container.reset() to a beforeEach hook in the failing test file:`,codeAfter:`import { describe, it, beforeEach } from 'vitest'
@@ -3706,7 +3747,7 @@ describe('UserController', () => {
3706
3747
  beforeEach(() => Container.reset())
3707
3748
 
3708
3749
  it('does the thing', async () => { /* ... */ })
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
3750
+ })`,docs:`https://forinda.github.io/kick-js/guide/testing.html`}}:null}},{match(e,t){return e.includes(`@Module`)||to(e,[`Module`,`is not a function`])||to(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
3710
3751
  pattern instead: a class implements AppModule and exposes routes() that
3711
3752
  returns the controller wiring. This was a deliberate choice — modules
3712
3753
  become explicit values rather than metadata, which makes them easier to
@@ -3733,7 +3774,7 @@ KickRoutes["POST /users"]. The new form is per-controller, per-method,
3733
3774
  and matches the actual class names so refactors propagate via
3734
3775
  rename-symbol instead of grep.`,fix:`Update the Ctx<...> type parameter to use the namespace form:`,codeBefore:`@Post('/', { body: createUserSchema })
3735
3776
  create(ctx: Ctx<KickRoutes['POST /users']>) { /* ... */ }`,codeAfter:`@Post('/', { body: createUserSchema, name: 'CreateUser' })
3736
- create(ctx: Ctx<KickRoutes.UserController['create']>) { /* ... */ }`,docs:`https://forinda.github.io/kick-js/guide/typegen.html`}}:null}},{match(e,t){let n=Z(e,[`cluster`,`workers`,`two ports`,`duplicate server`]),r=Z(e,[`kick dev`,`vite`,`eaddrinuse`,`5173`,`5174`,`two servers`]);return!n||!r?null:{confidence:85,diagnosis:{id:`cluster-in-vite-dev`,title:"Cluster mode is incompatible with `kick dev` (Vite owns the server)",explanation:`In dev mode, Vite owns the HTTP server. If your bootstrap passes
3777
+ create(ctx: Ctx<KickRoutes.UserController['create']>) { /* ... */ }`,docs:`https://forinda.github.io/kick-js/guide/typegen.html`}}:null}},{match(e,t){let n=Q(e,[`cluster`,`workers`,`two ports`,`duplicate server`]),r=Q(e,[`kick dev`,`vite`,`eaddrinuse`,`5173`,`5174`,`two servers`]);return!n||!r?null:{confidence:85,diagnosis:{id:`cluster-in-vite-dev`,title:"Cluster mode is incompatible with `kick dev` (Vite owns the server)",explanation:`In dev mode, Vite owns the HTTP server. If your bootstrap passes
3737
3778
  cluster: { workers: N }, the framework forks N workers, each of which
3738
3779
  spins up its own Vite instance on a separate port. The fix landed in
3739
3780
  v2.2.5: McpAdapter (and bootstrap()) now detects Vite dev mode and
@@ -3741,7 +3782,7 @@ silently skips cluster, with a warning. If you see this on an older
3741
3782
  version, upgrade or guard the cluster option behind NODE_ENV.`,fix:`Either upgrade to v2.2.5+ or gate cluster mode on production:`,codeAfter:`export const app = await bootstrap({
3742
3783
  modules,
3743
3784
  cluster: process.env.NODE_ENV === 'production' ? { workers: 4 } : false,
3744
- })`,docs:`https://forinda.github.io/kick-js/guide/cluster.html`}}}},{match(e,t){return Z(e,[`reflect-metadata`,`Reflect.getMetadata is not a function`,`Reflect.defineMetadata`,`design:type`,`design:paramtypes`])?{confidence:90,diagnosis:{id:`reflect-metadata-missing`,title:`reflect-metadata is not loaded — DI cannot read decorator types`,explanation:`The DI container reads constructor parameter types via the
3785
+ })`,docs:`https://forinda.github.io/kick-js/guide/cluster.html`}}}},{match(e,t){return Q(e,[`reflect-metadata`,`Reflect.getMetadata is not a function`,`Reflect.defineMetadata`,`design:type`,`design:paramtypes`])?{confidence:90,diagnosis:{id:`reflect-metadata-missing`,title:`reflect-metadata is not loaded — DI cannot read decorator types`,explanation:`The DI container reads constructor parameter types via the
3745
3786
  reflect-metadata polyfill. The polyfill must be imported once,
3746
3787
  before any decorator runs. Most projects do this at the top of
3747
3788
  src/index.ts; missing the import causes obscure "design:paramtypes"
@@ -3750,7 +3791,7 @@ import './config'
3750
3791
  import { bootstrap } from '@forinda/kickjs'
3751
3792
  import { modules } from './modules'
3752
3793
 
3753
- export const app = await bootstrap({ modules })`,docs:`https://forinda.github.io/kick-js/guide/dependency-injection.html`}}:null}},{match(e,t){return Z(e,[`404`,`cannot get`,`cannot post`,`no route`])?{confidence:50,diagnosis:{id:`module-not-registered`,title:`A 404 may indicate a module is not in the modules array`,explanation:`KickJS only mounts modules listed in \`src/modules/index.ts\`. If you
3794
+ export const app = await bootstrap({ modules })`,docs:`https://forinda.github.io/kick-js/guide/dependency-injection.html`}}:null}},{match(e,t){return Q(e,[`404`,`cannot get`,`cannot post`,`no route`])?{confidence:50,diagnosis:{id:`module-not-registered`,title:`A 404 may indicate a module is not in the modules array`,explanation:`KickJS only mounts modules listed in \`src/modules/index.ts\`. If you
3754
3795
  generated a module via \`kick g module foo\` but the routes don't appear,
3755
3796
  the most likely cause is that the module is missing from the exported
3756
3797
  array. The CLI usually wires this automatically, but a hand-edit can
@@ -3758,24 +3799,24 @@ drop the entry.`,fix:`Open src/modules/index.ts and verify the module is in the
3758
3799
  import { UserModule } from './users/user.module'
3759
3800
  import { TaskModule } from './tasks/task.module' // ← was this missing?
3760
3801
 
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.
3802
+ export const modules: AppModuleEntry[] = [UserModule(), TaskModule()]`,docs:`https://forinda.github.io/kick-js/guide/project-structure.html`}}:null}}];function ro(e,t){let n=null;for(let r of no){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 io(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.
3762
3803
  export OPENAI_API_KEY="sk-..."
3763
3804
 
3764
3805
  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:
3765
3806
  kick add ai
3766
3807
 
3767
3808
  Or manually:
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.
3809
+ pnpm add @forinda/kickjs-ai`}}let{OpenAIProvider:i}=r,a=new i({apiKey:n,defaultChatModel:e.model??`gpt-4o-mini`}),o=ao(e.cwd),s=`Error or stack trace:\n\n${e.input.trim()}`;try{let e=oo((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 ao(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(`
3810
+ `)}function oo(e){let t=[e,so(e),co(e)].filter(e=>e!==null);for(let e of t)try{let t=JSON.parse(e);if(lo(t))return t}catch{continue}return null}function so(e){let t=e.match(/```(?:json)?\s*\n([\s\S]*?)```/);return t?t[1]?.trim()??null:null}function co(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 lo(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 uo(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 mo(e,t.message);(!n||n.trim().length===0)&&(process.stderr.write(`Error: no input provided.
3770
3811
 
3771
3812
  Pass a message as a positional arg, --message flag, or pipe via stdin:
3772
3813
  kick explain "config.get returned undefined"
3773
3814
  pnpm test 2>&1 | kick explain
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.
3815
+ `),process.exit(1));let r=go(),i=ro(n,r);if(t.json&&i){process.stdout.write(JSON.stringify({matched:!0,...i},null,2)+`
3816
+ `);return}if(i){_o(n,i.diagnosis,i.confidence);return}t.ai||(t.json&&(process.stdout.write(JSON.stringify({matched:!1},null,2)+`
3817
+ `),process.exit(2)),vo(n,!1),process.exit(2));let a=await io({input:n,model:t.model,cwd:r.cwd});t.json&&(process.stdout.write(JSON.stringify(fo(a),null,2)+`
3818
+ `),process.exit(a.kind===`ok`?0:2)),po(n,a),process.exit(a.kind===`ok`?0:2)})}function fo(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 po(e,t){if(t.kind===`ok`){_o(e,t.diagnosis,-1,!0);return}if(t.kind===`unavailable`){process.stdout.write(`\n Explaining: ${bo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback unavailable: ${t.reason}\n\n`),process.stdout.write(`${yo(t.suggestion,` `)}\n\n`);return}process.stdout.write(`\n Explaining: ${bo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback error: ${t.message}\n\n`)}async function mo(e,t){return e&&e.trim().length>0?e:t&&t.trim().length>0?t:process.stdin.isTTY?``:ho()}function ho(){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 go(){let e=process.cwd();return{cwd:e,hasFile:t=>r(v(e,t))}}function _o(e,t,n,r=!1){let i=bo(e.trim(),200),a=r?`AI-generated — verify before applying`:xo(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${yo(t.explanation,` `)}\n`),process.stdout.write(`\n Fix:\n${yo(t.fix,` `)}\n`),t.codeBefore&&process.stdout.write(`\n Before:\n${yo(t.codeBefore,` `)}\n`),t.codeAfter&&process.stdout.write(`\n After:\n${yo(t.codeAfter,` `)}\n`),t.docs&&process.stdout.write(`\n Docs: ${t.docs}\n`),process.stdout.write(`
3819
+ `)}function vo(e,t){let n=bo(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.
3779
3820
  When @forinda/kickjs-ai ships its provider implementations,
3780
3821
  this command will call the configured LLM with the error +
3781
3822
  project context and return a structured fix.
@@ -3792,12 +3833,12 @@ Pass a message as a positional arg, --message flag, or pipe via stdin:
3792
3833
  3. File an issue with the error text:
3793
3834
  https://github.com/forinda/kick-js/issues/new
3794
3835
 
3795
- `)}function lo(e,t){return e.split(`
3836
+ `)}function yo(e,t){return e.split(`
3796
3837
  `).map(e=>`${t}${e}`).join(`
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(`
3838
+ `)}function bo(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function xo(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function So(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(Co),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(wo)}function Co(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 wo(e){let t=process.cwd(),n=To(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)+`
3839
+ `,`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 To(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 Eo(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=Oo(t,`tsx`);i||(console.error(`
3799
3840
  Error: tsx not found. Install it: pnpm add -D tsx
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`
3841
+ `),process.exit(1));let a=Do(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 Do(e,t){return`
3801
3842
  import 'reflect-metadata'
3802
3843
 
3803
3844
  // Prevent bootstrap() from starting the HTTP server
@@ -3851,40 +3892,40 @@ server.on('exit', () => {
3851
3892
  console.log('\\n Goodbye!\\n')
3852
3893
  process.exit(0)
3853
3894
  })
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]!==`
3895
+ `}function Oo(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 ko(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]!==`
3855
3896
  `;)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]===`
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(`
3897
+ `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function Ao(e,t){let n=nr(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=ko(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 jo(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 Qe(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(`
3857
3898
  Cancelled.
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,`
3899
+ `);return}await ce(c,{recursive:!0,force:!0}),console.log(` Deleted: ${c}`);let l=h(n,`index.ts`);if(await Qe(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=Ao(e,o),e=e.replace(/\n{3,}/g,`
3859
3900
 
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(`
3901
+ `),e!==t&&(await w(l,e,`utf-8`),console.log(` Unregistered: ${o}Module from ${l}`))}console.log(`\n Module '${s}' removed.\n`)}function Mo(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 jo({name:n,modulesDir:v(r),force:t.force,pluralize:i})})}function No(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 Po(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function Fo(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=en(process.cwd()),n=await k(t);if(e.list){let{mergeCliPlugins:e}=await Promise.resolve().then(()=>We),{builtinCliPlugins:t}=await Promise.resolve().then(()=>Ys),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(`
3861
3902
  Registered typegen plugins:
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(`
3903
+ `);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=No(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,i=Po(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 xa(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{await q(a);let r=await Fa({cwd:t,config:n??null,silent:e.silent,check:e.check});e.check&&r.some(e=>e.status===`written`)&&process.exit(1),e.check||await ba(v(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r,e.silent??!1)}}catch(e){e instanceof Xi?console.error(`
3863
3904
  `+e.message+`
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(`
3905
+ `):e instanceof Error?console.error(`\n kick typegen failed: ${e.message}`):console.error(`\n kick typegen failed: ${JSON.stringify(e)}`),process.exit(1)}})}function Io(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(...Io(n))}else r.isFile()&&/\.tsx?$/.test(r.name)&&!r.name.endsWith(`.d.ts`)&&t.push(n)}return t}function Lo(e){try{return a(e,`utf-8`)}catch{return``}}const Ro=new Set([`secret`,`changeme`,`password`,`test`,`default`,``]);function zo(e,t){let n=Lo(h(e,`.env`));if(n){let e=n.match(/^JWT_SECRET\s*=\s*['"]?([^'"\n]*)['"]?/m);if(e){let t=e[1].trim();if(Ro.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 Bo(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 Vo(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 Ho(){return process.env.NODE_ENV===`production`?null:{severity:`WARNING`,message:`NODE_ENV is '${process.env.NODE_ENV??`undefined`}', not 'production'`}}function Uo(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 Wo(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 Go(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 Ko(e){let t=Io(h(e,`src`)).map(e=>Lo(e)),n=[],r=zo(e,t);r&&n.push(r);let i=Bo(t);i&&n.push(i);let a=Vo(t);a&&n.push(a);let o=Ho();o&&n.push(o);let s=Uo(t);return s&&n.push(s),n.push(Wo(t)),n.push(Go(t)),n}function qo(e){e.command(`check`).description(`Audit project for common issues`).option(`--deploy`,`Run production readiness checks`).action(e=>{if(!e.deploy){console.log(`
3865
3906
  Usage: kick check --deploy
3866
3907
 
3867
3908
  Available checks:
3868
3909
  --deploy Audit for production readiness (security, config, best practices)
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.
3910
+ `);return}let t=process.cwd();Pt(`KickJS Deploy Check`);let n=zt();n.start(`Scanning project...`);let r=Ko(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(`${Nt(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 Jo(e){try{return JSON.parse(a(e,`utf-8`))}catch{return null}}function Yo(e){try{return a(e,`utf-8`)}catch{return null}}function Xo(e){let t=Yo(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=Zo(e,r.extends);if(t){let e=Jo(t)??{};r.compilerOptions={...e.compilerOptions,...r.compilerOptions}}}return r}function Zo(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 Qo(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function $o(){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.
3911
+ Install a supported version via nvm / fnm / volta.`}:{name:`Node version`,status:`pass`,message:e}}function es(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 ts(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 ns(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.
3871
3912
  Install it: pnpm add reflect-metadata
3872
3913
  Then import it at the top of src/index.ts:
3873
3914
 
3874
3915
  import 'reflect-metadata'
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(`
3916
+ // ... rest of bootstrap`}}function rs(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 is(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(Yo(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=Yo(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+)?['"]${Qo(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 as(e,t=os){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 os=2e3;function ss(e){let t=h(e.cwd,`.kickjs`,`types`);if(!r(t))return null;let n=as(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 cs=[()=>$o(),es,ts,ns,rs,is,ss];async function ls(e,t={}){let n={cwd:e,pkg:Jo(h(e,`package.json`)),tsconfig:Xo(e)},r=[...cs,...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 us(e){switch(e){case`pass`:return E.green(`✔`);case`warn`:return E.yellow(`⚠`);case`fail`:return E.red(`✖`)}}function ds(e){let t=us(e.status),n=e.message?` ${E.dim(`(${e.message})`)}`:``;return`${t} ${e.name}${n}`}function fs(e){return e.split(`
3876
3917
  `).map(e=>` ${E.dim(`→`)} ${e}`).join(`
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.
3918
+ `)}function ps(e){return e?.doctor?.checks??[]}function ms(e){e.command(`doctor`).description(`Pre-flight checks for your KickJS project (dev environment health)`).action(async()=>{let e=process.cwd(),t=ps(await k(e));Pt(`KickJS Doctor`);let n=await ls(e,{extraChecks:t});for(let e of n)F.message(ds(e)),e.fix&&e.status!==`pass`&&F.message(fs(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 $(e){return Ee({configPath:u.resolve(process.cwd(),e.config)})}async function hs(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 gs(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 _s(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 vs(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 $(t),i=await gs(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 $(e),{adapter:n,cleanup:r}=await hs(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 $(e),{adapter:n,cleanup:r}=await hs(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 $(e),{adapter:n,cleanup:r}=await hs(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 $(e),{adapter:n,cleanup:r}=await hs(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 $(e),{adapter:n,cleanup:r}=await hs(t);try{_s(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 $(e),{adapter:n,cleanup:r}=await hs(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 ys(e){return e.optsWithGlobals().dryRun??!1}function bs(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.
3878
3919
  Direction defaults to \`modules.style\` from kick.config (or "define").
3879
3920
  --target define|class Override the migration direction.
3880
3921
  --apply Apply the changes (default: dry-run preview).
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(`
3922
+ --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=ys(t)||!e.apply;j(n),e.experimental||(console.error(`
3882
3923
  `+E.red(`Error:`)+` kick codemod modules is experimental — pass --experimental to acknowledge.
3883
3924
  The regex-based rewrite handles the shapes our templates produce.
3884
3925
  Hand-rolled modules with non-standard structures may be skipped.
3885
3926
  Always commit before running with --apply.
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}
3927
+ `),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 Rr(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 xs=[`src/db/schema.ts`,`src/db/schema/index.ts`,`src/db/schema`],Ss=()=>({id:`kick/db`,inputs:[`src/db/schema.ts`,`src/db/schema/**/*.ts`],async generate(e){let t=Cs(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 '${ws(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(`
3928
+ `)}});function Cs(e){for(let t of xs){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 ws(e){return e.replace(/\\/g,`/`)}const Ts=()=>({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=da(t.assetMap,e.cwd);return n.count===0?null:fa(n)}}),Es="/* 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 Ds(e,t,n){if(e.length===0)return`${Es}
3888
3929
  // (no routes discovered yet — annotate a controller method with
3889
3930
  // @Get/@Post/@Put/@Delete/@Patch and re-run \`kick typegen\`)
3890
3931
  declare global {
@@ -3893,8 +3934,8 @@ declare global {
3893
3934
  }
3894
3935
 
3895
3936
  export {}
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)}
3937
+ `;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=As(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??Os(e),l=ks(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(`
3938
+ `))}return`${Es}${js(i)}
3898
3939
  declare global {
3899
3940
  // eslint-disable-next-line @typescript-eslint/no-namespace
3900
3941
  namespace KickRoutes {
@@ -3904,9 +3945,9 @@ ${o.join(`
3904
3945
  }
3905
3946
 
3906
3947
  export {}
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(`
3948
+ `}function Os(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 ks(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 As(e,t,n,r,i){if(!e||r===!1||e.source===null)return null;let a=Ms(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 js(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(`
3908
3949
  `)+`
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 */
3950
+ `}function Ms(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 Ns=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:Ps(e),cwd:e.cwd,envFile:Fs(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=u.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return Ds(t.routes,r,n)}});function Ps(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Fs(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function Is(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 */
3910
3951
  // AUTO-GENERATED by \`kick typegen\`. DO NOT EDIT.
3911
3952
  // Re-run with \`kick typegen\` or rely on \`kick dev\` to refresh.
3912
3953
 
@@ -3944,4 +3985,4 @@ declare global {
3944
3985
  }
3945
3986
 
3946
3987
  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{};
3988
+ `}const Ls=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=zs(e);if(t===!1)return null;let n=await e.getScanResult({root:Rs(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 Is(n.env,i,r)}});function Rs(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function zs(e){return e.config?.typegen?.envFile}function Bs(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Vs(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function Hs(e){return{root:Bs(e),cwd:e.cwd,envFile:Vs(e)}}const Us=()=>({id:`kick/registry`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult(Hs(e)),n=u.resolve(e.cwd,`.kickjs/types/kick__registry.d.ts`),r=new Set(t.collisions.map(e=>e.className));return ea(t.classes,n,r)}}),Ws=()=>({id:`kick/services`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult(Hs(e)),n=new Set(t.collisions.map(e=>e.className));return ra(`ServiceToken`,ia(t.classes,t.tokens,t.injects,n),"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)")}}),Gs=()=>({id:`kick/modules`,inputs:[`src/**/*.ts`],async generate(e){return ra(`ModuleToken`,aa((await e.getScanResult(Hs(e))).classes),"(no @Module classes discovered — `kick g module <name>` to add one)")}}),Ks=()=>({id:`kick/plugins`,inputs:[`src/**/*.ts`],async generate(e){return oa((await e.getScanResult(Hs(e))).pluginsAndAdapters)}}),qs=()=>({id:`kick/augmentations`,inputs:[`src/**/*.ts`],async generate(e){return sa((await e.getScanResult(Hs(e))).augmentations)}}),Js=()=>({id:`kick/context`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult(Hs(e));return t.contextKeys.length===0?null:na(t.contextKeys)}});var Ys=D({builtinCliPlugins:()=>Xs});const Xs=[A({name:`kick/init`,register:Xt}),A({name:`kick/generate`,register:ka}),A({name:`kick/run`,register:Ua}),A({name:`kick/info`,register:Wa}),A({name:`kick/inspect`,register:eo}),A({name:`kick/add`,register:Jt}),A({name:`kick/list`,register:qt}),A({name:`kick/explain`,register:uo}),A({name:`kick/mcp`,register:So}),A({name:`kick/tinker`,register:Eo}),A({name:`kick/remove`,register:Mo}),A({name:`kick/typegen`,register:Fo}),A({name:`kick/check`,register:qo}),A({name:`kick/doctor`,register:ms}),A({name:`kick/db`,register:vs,typegens:[Ss()]}),A({name:`kick/codemod`,register:bs}),A({name:`kick/registry`,typegens:[Us()]}),A({name:`kick/services`,typegens:[Ws()]}),A({name:`kick/modules`,typegens:[Gs()]}),A({name:`kick/plugins`,typegens:[Ks()]}),A({name:`kick/augmentations`,typegens:[qs()]}),A({name:`kick/context`,typegens:[Js()]}),A({name:`kick/assets`,typegens:[Ts()]}),A({name:`kick/routes`,typegens:[Ns()]}),A({name:`kick/env`,typegens:[Ls()]})],Zs=f(b(import.meta.url)),Qs=JSON.parse(a(h(Zs,`..`,`package.json`),`utf-8`));async function $s(){let e=new t;e.name(`kick`).description(`KickJS — A production-grade, decorator-driven Node.js framework`).version(Qs.version);let n=en(process.cwd()),r=n,i=await k(r)??{},a=Ue([...Xs,...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)}$s().catch(e=>{console.error(e instanceof Error?e.message:e),process.exitCode=1});export{};