@arkenv/cli 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.cjs +33 -97
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -108,9 +108,25 @@ ${t?(0,a.styleText)(`cyan`,B):``}
108
108
  outdir: "./dist",
109
109
  ${y.default.green(`plugins: [arkenv]`)}
110
110
  });
111
- `),{success:!0,instructions:a.trim()}}async function Dt(e,t){let n=t||await q();if(!n)return{status:`not_found`};let i=r.default.basename(n);try{let t=await e.readFile(n);if((0,u.parse)(t)?.compilerOptions?.strict===!0)return{status:`already_strict`,file:i};let r=(0,u.applyEdits)(t,(0,u.modify)(t,[`compilerOptions`,`strict`],!0,{formattingOptions:{insertSpaces:!0,tabSize:2}}));return await e.writeFile(n,r),{status:`updated`,file:i}}catch{return{status:`error`,file:i}}}var Ot=class{constructor(e,t){this.isQuiet=e,this.stdio=t}async exists(e){try{return await n.default.access(e),!0}catch{return!1}}async readFile(e){return n.default.readFile(e,`utf-8`)}async writeFile(e,t){await n.default.writeFile(e,t,`utf-8`)}async mkdir(e,t){await n.default.mkdir(e,{recursive:t})}async execute(e,t=[],n){return new Promise((r,i)=>{let a=(0,d.spawn)(e,t,{cwd:n,stdio:this.isQuiet?`pipe`:this.stdio,shell:!1}),o=``,s=``,c=1e4;this.isQuiet&&(a.stdout?.on(`data`,e=>{o=(o+e.toString()).slice(-c)}),a.stderr?.on(`data`,e=>{s=(s+e.toString()).slice(-c)})),a.on(`close`,(e,t)=>{if(e===0)r();else{let n=e===null?`Command terminated by signal ${t}`:`Command failed with code ${e}`;this.isQuiet&&(o&&(n+=`\n${y.default.dim(`STDOUT:`)}\n${o}`),s&&(n+=`\n${y.default.red(`STDERR:`)}\n${s}`)),i(Error(n))}}),a.on(`error`,i)})}async updateTsConfigToStrict(e){return Dt(this,e)}async findViteConfig(e){return Ct(e)}async findBunConfig(e){return wt(e)}async bootstrapViteConfig(e,t){return Tt(this,e,t)}async bootstrapBunConfig(e,t){return Et(e,t)}async safeAppend(e,t,n){let{safeAppend:r}=await Promise.resolve().then(()=>p);return r(e,t,n)}};async function kt(e){let t=e.defaultPath||`./src/env.ts`;if(e.hasEnvSchemaFile){let e=await H({message:y.default.yellow(`An existing ArkEnv configuration was found at ${Y(t)}. Do you want to overwrite it?`),initialValue:!1,active:`Yes (override my configuration)`,inactive:`No (abort)`});return N(e)||!e?null:e}return!0}async function At(e){let t=e.detectedKeys,n=e.keysSource||`.env.example`;if(t&&t.length>0){let e=t.length,r=e===1,i=await H({message:n===`.env.example`?`Detected ${Y(`.env.example`)} with ${e} ${r?`key`:`keys`}. Use ${r?`it`:`them`} for your schema?`:`Detected ${e} environment variable${r?``:`s`} used in your project. Use ${r?`it`:`them`} for your schema?`,active:`Yes (Recommended)`,initialValue:!0});return N(i)?null:i}return!1}async function jt(e){if(e.framework===`vite`||e.framework===`bun-fullstack`){let t=e.framework===`vite`?`vite-env.d.ts`:`bun-env.d.ts`;if(e.hasTypeFile)return!0;let n=await H({message:`Establish ${Y(t)} for typesafe environment variables?`,initialValue:!0,active:`Yes (Recommended)`,inactive:`No`});return N(n)?null:n}return!0}async function Mt(e){if(!e.installTypeDefinitions||e.framework!==`vite`&&e.framework!==`bun-fullstack`)return`skip`;let t=e.framework===`vite`?`vite-env.d.ts`:`bun-env.d.ts`;if(e.hasTypeFile){let e=await G({message:`Found existing ${Y(t)}. How should we handle ArkEnv types?`,options:[{value:`append`,label:`Append types safely (if needed)`,hint:`Recommended`},{value:`overwrite`,label:`Overwrite entirely`,hint:`Destructive`},{value:`skip`,label:`Skip`}]});return N(e)?null:e}return`overwrite`}async function Nt(e){let t=await G({message:`Select an example:`,options:e.examples.map(e=>({value:e.id,label:e.name,...e.description?{hint:e.description}:{}}))});return N(t)?null:t}async function Pt(e){let t=await G({message:`Select your framework or build tool:`,initialValue:e.framework,options:[{value:`vanilla`,label:`Vanilla${e.framework===`vanilla`?` (Detected)`:``}`,hint:`Node.js, Bun, server-side or runtime-only validation`},{value:`vite`,label:`Vite${e.framework===`vite`?` (Detected)`:``}`,hint:`Client-side and static inlining validation`},{value:`bun-fullstack`,label:`Bun fullstack dev server${e.framework===`bun-fullstack`?` (Detected)`:``}`,hint:`Client-side bundling and Bun.serve integration`},{value:`nextjs`,label:`Next.js${e.framework===`nextjs`?` (Detected)`:``}`,hint:`Next.js App or Pages Router with build and runtime validation`}]});return N(t)?null:t}async function Ft(e){let t=await H({message:`Optional: Would you also like to bootstrap a custom Bun.build script for programmatic bundling?`,initialValue:e.initialValue??!1});return N(t)?null:t}async function It(){let e=await G({message:`Select your preferred validator library:`,options:[{value:`arktype`,label:`ArkType (Recommended)`,hint:`TypeScript's 1:1 validator, optimized from editor to runtime`},{value:`zod`,label:`Zod`,hint:`TypeScript-first schema validation with static type inference`},{value:`valibot`,label:`Valibot`,hint:`The modular and type safe schema library`}]});return N(e)?null:e}async function Lt(e){let t=await H({message:`Use default config path (${Y(e.defaultEnvPath||`./src/env.ts`)})?`,initialValue:!0,active:`Yes (Recommended)`,inactive:`No, let me customize it`});return N(t)?null:t}async function Rt(e){let t=e.defaultEnvPath||`./src/env.ts`;if(!e.useDefaultPath){let e=await et({message:`Where should we create the ArkEnv config?`,placeholder:t,initialValue:t,defaultValue:t});if(N(e))return null;let n=typeof e==`string`?e.trim():``;return n===``?t:n}return t}const X={example:Nt,overwriteEnvSchemaFile:kt,framework:Pt,bunBuild:Ft,useDefaultPath:Lt,path:Rt,installTypeDefinitions:jt,envDtsHandling:Mt,validator:It,useEnvExample:At};async function zt(e,t=!1){return(e?.mode||`existing`)===`new`?Bt(e,t):Vt(e,t)}async function Bt(e,t=!1){let n=e?.examples||[],i=`arkenv-project`;try{let a;if(e?.name){let t=e.name.trim();a=t===`.`||t===`./`||r.default.resolve(process.cwd(),t)===process.cwd()?`.`:t}else if(t)a=i;else{let e=(Z(await et({message:`Project name:`,placeholder:i,defaultValue:i}))||i).trim();a=e===`.`||e===`./`||r.default.resolve(process.cwd(),e)===process.cwd()?`.`:e}let o=e?.example;!o&&!t?o=Z(await X.example({examples:n})):!o&&t&&(o=`basic`);let s=n.find(e=>e.id===o);if(!s){let e=n.map(e=>e.id).join(`, `);throw Error(`Unknown example ${o}. Available examples: ${e}`)}return{mode:`new`,example:s.id,name:a,path:`./src/env.ts`,validator:`arktype`,framework:s.framework,language:`ts`,installSkill:!1}}catch(e){if(e instanceof Ut)return null;throw e}}async function Vt(e,n=!1){let r=e?.defaultEnvPath||`./src/env.ts`,i=e?.envKeys||null,a=e?.envKeysSource||`.env.example`;if(n){let n=e?.framework||`vanilla`,a=await Ht(e,n,r),o;return(n===`vite`||n===`bun-fullstack`)&&(o=a?`append`:`overwrite`),(0,t.shake)({mode:`existing`,path:r,validator:`arktype`,framework:n,bunFeatures:n===`bun-fullstack`?e?.bunFeatures??[`serve`]:void 0,language:`ts`,overwriteEnvSchemaFile:!0,installTypeDefinitions:n===`vite`||n===`bun-fullstack`,installSkill:!1,envDtsHandling:o,envKeys:i??void 0})}try{let n=Z(await X.overwriteEnvSchemaFile({hasEnvSchemaFile:e?.hasEnvSchemaFile??!1,defaultPath:r})),o=Z(await X.framework({framework:e?.framework})),s;if(o===`bun-fullstack`){let t=!!e?.bunFeatures?.includes(`build`);s=Z(await X.bunBuild({initialValue:t}))}let c=Z(await X.useDefaultPath({defaultEnvPath:r})),l=Z(await X.path({useDefaultPath:c,defaultEnvPath:r})),u=await Ht(e,o,l),d=Z(await X.installTypeDefinitions({framework:o,hasTypeFile:u})),f=Z(await X.envDtsHandling({framework:o,installTypeDefinitions:d,hasTypeFile:u})),p=Z(await X.validator()),m=Z(await X.useEnvExample({detectedKeys:i,keysSource:a}));return(0,t.shake)({mode:`existing`,overwriteEnvSchemaFile:n,framework:o,path:l,installTypeDefinitions:d,envDtsHandling:f,validator:p,bunFeatures:o===`bun-fullstack`?s?[`serve`,`build`]:[`serve`]:void 0,language:`ts`,installSkill:!1,envKeys:m?i??void 0:void 0})}catch(e){if(e instanceof Ut)return null;throw e}}async function Ht(e,t,n){return await e?.hasTypeFileAtPath?.({framework:t,envPath:n})??e?.hasTypeFile??!1}var Ut=class extends Error{constructor(){super(`Operation cancelled`)}};function Z(e){if(e===null||N(e))throw Ke(`Operation cancelled`),new Ut;return e}var Wt=class{async confirm(e,n=!0,r,i){let a=await H((0,t.shake)({message:e,initialValue:n,active:r,inactive:i}));return N(a)?null:a}async runWizard(e,t=!1){return zt(e,t)}};const Q={isYes:{long:`--yes`,short:`-y`,kind:`boolean`},isForce:{long:`--force`,short:`-f`,kind:`boolean`},isQuiet:{long:`--quiet`,short:`-q`,kind:`boolean`},isJson:{long:`--json`,short:`-j`,kind:`boolean`},isAgent:{long:`--agent`,short:`-a`,kind:`boolean`},helpRequested:{long:`--help`,short:`-h`,kind:`boolean`},example:{long:`--example`,short:`-e`,kind:`value`}},Gt=new Set(Object.values(Q).flatMap(e=>[e.long,e.short])),Kt=new Set(Object.values(Q).filter(e=>e.kind===`value`).flatMap(e=>[e.long,e.short]));var qt=class{constructor(e,t={}){let n=e.slice(2),r=[],i=!1;for(let e of n){if(i){r.push(e),i=!1;continue}if(Kt.has(e)){r.push(e),i=!0;continue}if(/^-[a-zA-Z]{2,}$/.test(e)){let t=e.slice(1).split(``);for(let e of t)r.push(`-${e}`);Kt.has(`-${t[t.length-1]}`)&&(i=!0)}else r.push(e)}this.args=r,this.command=this.args[0];let a=1,o=[];for(this.validationError=void 0;a<this.args.length;){let e=this.args[a];if(e.startsWith(`-`)){if(!Gt.has(e)){this.validationError=`Unknown argument: ${e}`;break}if(Kt.has(e))if(a+1<this.args.length&&!this.args[a+1].startsWith(`-`))a+=2;else{this.validationError=`Missing value for option: ${e}`;break}else a+=1}else o.push(e),a+=1}this.validationError||(o.length>1?this.validationError=`Unknown argument: ${o[1]}`:this.name=o[0]),this.logger=t.logger||new nt({isQuiet:this.isQuiet,isJson:this.isJson,isYes:this.isYes})}get isAgent(){return this.hasFlag(`isAgent`)}get isYes(){return this.isAgent||this.hasFlag(`isYes`)}get isQuiet(){return this.isAgent||this.hasFlag(`isQuiet`)}get isJson(){return this.isAgent||this.hasFlag(`isJson`)}get isForce(){return this.hasFlag(`isForce`)}get helpRequested(){return this.hasFlag(`helpRequested`)}get example(){let e=Q.example;return this.getFlagValue(e.long,e.short)}hasFlag(e){let t=Q[e];return this.args.includes(t.long)||this.args.includes(t.short)}get initInput(){let e={isYes:this.isYes,isForce:this.isForce,isQuiet:this.isQuiet,isAgent:this.isAgent};return this.example!==void 0&&(e.example=this.example),this.name!==void 0&&(e.name=this.name),e}getFlagValue(e,t){let n=this.args.findIndex(n=>n===e||n===t);if(n!==-1&&this.args[n+1]&&!this.args[n+1].startsWith(`-`))return this.args[n+1]}},Jt=`0.2.3`;function Yt(e,t=2,n=4){let r=Math.max(...e.map(e=>e.left.length),0),i=` `.repeat(t);return e.map(e=>{let t=` `.repeat(r-e.left.length+n);return`${i}${e.left}${t}${e.right}`})}var Xt=class{constructor(e){this.logger=e}async execute(){let e=[{left:`arkenv init [project-name]`,right:`Set up ArkEnv in your project`}],t=[{left:`--yes, -y`,right:`Skip prompts and use defaults (also passed to subprocesses)`},{left:`--force, -f`,right:`Bypass technical requirement checks and force scaffolding`},{left:`--agent, -a`,right:`Agent mode: --yes --quiet --json`},{left:`--example, -e`,right:`Specify an example name when creating a new project`},{left:`--quiet, -q`,right:`Quiet mode: Suppress output, capture logs on failure`},{left:`--json, -j`,right:`Output structured JSON to stdout`},{left:`--help, -h`,right:`Show this help message`}];this.logger.log(`ArkEnv CLI v${Jt}`),this.logger.log(`\n${y.default.bold(`Usage:`)}`);for(let t of Yt(e))this.logger.log(t);this.logger.log(`\n${y.default.bold(`Options:`)}`);for(let e of Yt(t))this.logger.log(e)}};const Zt=(e,t)=>{let n=e?.length?e.map(e=>`\t\t${e}: "string = ''",`).join(`
111
+ `),{success:!0,instructions:a.trim()}}async function Dt(e,t){let n=t||await q();if(!n)return{status:`not_found`};let i=r.default.basename(n);try{let t=await e.readFile(n);if((0,u.parse)(t)?.compilerOptions?.strict===!0)return{status:`already_strict`,file:i};let r=(0,u.applyEdits)(t,(0,u.modify)(t,[`compilerOptions`,`strict`],!0,{formattingOptions:{insertSpaces:!0,tabSize:2}}));return await e.writeFile(n,r),{status:`updated`,file:i}}catch{return{status:`error`,file:i}}}var Ot=class{constructor(e,t){this.isQuiet=e,this.stdio=t}async exists(e){try{return await n.default.access(e),!0}catch{return!1}}async readFile(e){return n.default.readFile(e,`utf-8`)}async writeFile(e,t){await n.default.writeFile(e,t,`utf-8`)}async mkdir(e,t){await n.default.mkdir(e,{recursive:t})}async execute(e,t=[],n){return new Promise((r,i)=>{let a=(0,d.spawn)(e,t,{cwd:n,stdio:this.isQuiet?`pipe`:this.stdio,shell:!1}),o=``,s=``,c=1e4;this.isQuiet&&(a.stdout?.on(`data`,e=>{o=(o+e.toString()).slice(-c)}),a.stderr?.on(`data`,e=>{s=(s+e.toString()).slice(-c)})),a.on(`close`,(e,t)=>{if(e===0)r();else{let n=e===null?`Command terminated by signal ${t}`:`Command failed with code ${e}`;this.isQuiet&&(o&&(n+=`\n${y.default.dim(`STDOUT:`)}\n${o}`),s&&(n+=`\n${y.default.red(`STDERR:`)}\n${s}`)),i(Error(n))}}),a.on(`error`,i)})}async updateTsConfigToStrict(e){return Dt(this,e)}async findViteConfig(e){return Ct(e)}async findBunConfig(e){return wt(e)}async bootstrapViteConfig(e,t){return Tt(this,e,t)}async bootstrapBunConfig(e,t){return Et(e,t)}async safeAppend(e,t,n){let{safeAppend:r}=await Promise.resolve().then(()=>p);return r(e,t,n)}};async function kt(e){let t=e.defaultPath||`./src/env.ts`;if(e.hasEnvSchemaFile){let e=await H({message:y.default.yellow(`An existing ArkEnv configuration was found at ${Y(t)}. Do you want to overwrite it?`),initialValue:!1,active:`Yes (override my configuration)`,inactive:`No (abort)`});return N(e)||!e?null:e}return!0}async function At(e){let t=e.detectedKeys,n=e.keysSource||`.env.example`;if(t&&t.length>0){let e=t.length,r=e===1,i=await H({message:n===`.env.example`?`Detected ${Y(`.env.example`)} with ${e} ${r?`key`:`keys`}. Use ${r?`it`:`them`} for your schema?`:`Detected ${e} environment variable${r?``:`s`} used in your project. Use ${r?`it`:`them`} for your schema?`,active:`Yes (Recommended)`,initialValue:!0});return N(i)?null:i}return!1}async function jt(e){if(e.framework===`vite`||e.framework===`bun-fullstack`){let t=e.framework===`vite`?`vite-env.d.ts`:`bun-env.d.ts`;if(e.hasTypeFile)return!0;let n=await H({message:`Establish ${Y(t)} for typesafe environment variables?`,initialValue:!0,active:`Yes (Recommended)`,inactive:`No`});return N(n)?null:n}return!0}async function Mt(e){if(!e.installTypeDefinitions||e.framework!==`vite`&&e.framework!==`bun-fullstack`)return`skip`;let t=e.framework===`vite`?`vite-env.d.ts`:`bun-env.d.ts`;if(e.hasTypeFile){let e=await G({message:`Found existing ${Y(t)}. How should we handle ArkEnv types?`,options:[{value:`append`,label:`Append types safely (if needed)`,hint:`Recommended`},{value:`overwrite`,label:`Overwrite entirely`,hint:`Destructive`},{value:`skip`,label:`Skip`}]});return N(e)?null:e}return`overwrite`}async function Nt(e){let t=await G({message:`Select an example:`,options:e.examples.map(e=>({value:e.id,label:e.name,...e.description?{hint:e.description}:{}}))});return N(t)?null:t}async function Pt(e){let t=await G({message:`Select your framework or build tool:`,initialValue:e.framework,options:[{value:`vanilla`,label:`Vanilla${e.framework===`vanilla`?` (Detected)`:``}`,hint:`Node.js, Bun, server-side or runtime-only validation`},{value:`vite`,label:`Vite${e.framework===`vite`?` (Detected)`:``}`,hint:`Client-side and static inlining validation`},{value:`bun-fullstack`,label:`Bun fullstack dev server${e.framework===`bun-fullstack`?` (Detected)`:``}`,hint:`Client-side bundling and Bun.serve integration`},{value:`nextjs`,label:`Next.js${e.framework===`nextjs`?` (Detected)`:``}`,hint:`Next.js App or Pages Router with build and runtime validation`}]});return N(t)?null:t}async function Ft(e){let t=await H({message:`Optional: Would you also like to bootstrap a custom Bun.build script for programmatic bundling?`,initialValue:e.initialValue??!1});return N(t)?null:t}async function It(){let e=await G({message:`Select your preferred validator library:`,options:[{value:`arktype`,label:`ArkType (Recommended)`,hint:`TypeScript's 1:1 validator, optimized from editor to runtime`},{value:`zod`,label:`Zod`,hint:`TypeScript-first schema validation with static type inference`},{value:`valibot`,label:`Valibot`,hint:`The modular and type safe schema library`}]});return N(e)?null:e}async function Lt(e){let t=await H({message:`Use default config path (${Y(e.defaultEnvPath||`./src/env.ts`)})?`,initialValue:!0,active:`Yes (Recommended)`,inactive:`No, let me customize it`});return N(t)?null:t}async function Rt(e){let t=e.defaultEnvPath||`./src/env.ts`;if(!e.useDefaultPath){let e=await et({message:`Where should we create the ArkEnv config?`,placeholder:t,initialValue:t,defaultValue:t});if(N(e))return null;let n=typeof e==`string`?e.trim():``;return n===``?t:n}return t}const X={example:Nt,overwriteEnvSchemaFile:kt,framework:Pt,bunBuild:Ft,useDefaultPath:Lt,path:Rt,installTypeDefinitions:jt,envDtsHandling:Mt,validator:It,useEnvExample:At};async function zt(e,t=!1){return(e?.mode||`existing`)===`new`?Bt(e,t):Vt(e,t)}async function Bt(e,t=!1){let n=e?.examples||[],i=`arkenv-project`;try{let a;if(e?.name){let t=e.name.trim();a=t===`.`||t===`./`||r.default.resolve(process.cwd(),t)===process.cwd()?`.`:t}else if(t)a=i;else{let e=(Z(await et({message:`Project name:`,placeholder:i,defaultValue:i}))||i).trim();a=e===`.`||e===`./`||r.default.resolve(process.cwd(),e)===process.cwd()?`.`:e}let o=e?.example;!o&&!t?o=Z(await X.example({examples:n})):!o&&t&&(o=`basic`);let s=n.find(e=>e.id===o);if(!s){let e=n.map(e=>e.id).join(`, `);throw Error(`Unknown example ${o}. Available examples: ${e}`)}return{mode:`new`,example:s.id,name:a,path:`./src/env.ts`,validator:`arktype`,framework:s.framework,language:`ts`,installSkill:!1}}catch(e){if(e instanceof Ut)return null;throw e}}async function Vt(e,n=!1){let r=e?.defaultEnvPath||`./src/env.ts`,i=e?.envKeys||null,a=e?.envKeysSource||`.env.example`;if(n){let n=e?.framework||`vanilla`,a=await Ht(e,n,r),o;return(n===`vite`||n===`bun-fullstack`)&&(o=a?`append`:`overwrite`),(0,t.shake)({mode:`existing`,path:r,validator:`arktype`,framework:n,bunFeatures:n===`bun-fullstack`?e?.bunFeatures??[`serve`]:void 0,language:`ts`,overwriteEnvSchemaFile:!0,installTypeDefinitions:n===`vite`||n===`bun-fullstack`,installSkill:!1,envDtsHandling:o,envKeys:i??void 0})}try{let n=Z(await X.overwriteEnvSchemaFile({hasEnvSchemaFile:e?.hasEnvSchemaFile??!1,defaultPath:r})),o=Z(await X.framework({framework:e?.framework})),s;if(o===`bun-fullstack`){let t=!!e?.bunFeatures?.includes(`build`);s=Z(await X.bunBuild({initialValue:t}))}let c=Z(await X.useDefaultPath({defaultEnvPath:r})),l=Z(await X.path({useDefaultPath:c,defaultEnvPath:r})),u=await Ht(e,o,l),d=Z(await X.installTypeDefinitions({framework:o,hasTypeFile:u})),f=Z(await X.envDtsHandling({framework:o,installTypeDefinitions:d,hasTypeFile:u})),p=Z(await X.validator()),m=Z(await X.useEnvExample({detectedKeys:i,keysSource:a}));return(0,t.shake)({mode:`existing`,overwriteEnvSchemaFile:n,framework:o,path:l,installTypeDefinitions:d,envDtsHandling:f,validator:p,bunFeatures:o===`bun-fullstack`?s?[`serve`,`build`]:[`serve`]:void 0,language:`ts`,installSkill:!1,envKeys:m?i??void 0:void 0})}catch(e){if(e instanceof Ut)return null;throw e}}async function Ht(e,t,n){return await e?.hasTypeFileAtPath?.({framework:t,envPath:n})??e?.hasTypeFile??!1}var Ut=class extends Error{constructor(){super(`Operation cancelled`)}};function Z(e){if(e===null||N(e))throw Ke(`Operation cancelled`),new Ut;return e}var Wt=class{async confirm(e,n=!0,r,i){let a=await H((0,t.shake)({message:e,initialValue:n,active:r,inactive:i}));return N(a)?null:a}async runWizard(e,t=!1){return zt(e,t)}};const Q={isYes:{long:`--yes`,short:`-y`,kind:`boolean`},isForce:{long:`--force`,short:`-f`,kind:`boolean`},isQuiet:{long:`--quiet`,short:`-q`,kind:`boolean`},isJson:{long:`--json`,short:`-j`,kind:`boolean`},isAgent:{long:`--agent`,short:`-a`,kind:`boolean`},helpRequested:{long:`--help`,short:`-h`,kind:`boolean`},example:{long:`--example`,short:`-e`,kind:`value`}},Gt=new Set(Object.values(Q).flatMap(e=>[e.long,e.short])),Kt=new Set(Object.values(Q).filter(e=>e.kind===`value`).flatMap(e=>[e.long,e.short]));var qt=class{constructor(e,t={}){let n=e.slice(2),r=[],i=!1;for(let e of n){if(i){r.push(e),i=!1;continue}if(Kt.has(e)){r.push(e),i=!0;continue}if(/^-[a-zA-Z]{2,}$/.test(e)){let t=e.slice(1).split(``);for(let e of t)r.push(`-${e}`);Kt.has(`-${t[t.length-1]}`)&&(i=!0)}else r.push(e)}this.args=r,this.command=this.args[0];let a=1,o=[];for(this.validationError=void 0;a<this.args.length;){let e=this.args[a];if(e.startsWith(`-`)){if(!Gt.has(e)){this.validationError=`Unknown argument: ${e}`;break}if(Kt.has(e))if(a+1<this.args.length&&!this.args[a+1].startsWith(`-`))a+=2;else{this.validationError=`Missing value for option: ${e}`;break}else a+=1}else o.push(e),a+=1}this.validationError||(o.length>1?this.validationError=`Unknown argument: ${o[1]}`:this.name=o[0]),this.logger=t.logger||new nt({isQuiet:this.isQuiet,isJson:this.isJson,isYes:this.isYes})}get isAgent(){return this.hasFlag(`isAgent`)}get isYes(){return this.isAgent||this.hasFlag(`isYes`)}get isQuiet(){return this.isAgent||this.hasFlag(`isQuiet`)}get isJson(){return this.isAgent||this.hasFlag(`isJson`)}get isForce(){return this.hasFlag(`isForce`)}get helpRequested(){return this.hasFlag(`helpRequested`)}get example(){let e=Q.example;return this.getFlagValue(e.long,e.short)}hasFlag(e){let t=Q[e];return this.args.includes(t.long)||this.args.includes(t.short)}get initInput(){let e={isYes:this.isYes,isForce:this.isForce,isQuiet:this.isQuiet,isAgent:this.isAgent};return this.example!==void 0&&(e.example=this.example),this.name!==void 0&&(e.name=this.name),e}getFlagValue(e,t){let n=this.args.findIndex(n=>n===e||n===t);if(n!==-1&&this.args[n+1]&&!this.args[n+1].startsWith(`-`))return this.args[n+1]}},Jt=`0.2.4`;function Yt(e,t=2,n=4){let r=Math.max(...e.map(e=>e.left.length),0),i=` `.repeat(t);return e.map(e=>{let t=` `.repeat(r-e.left.length+n);return`${i}${e.left}${t}${e.right}`})}var Xt=class{constructor(e){this.logger=e}async execute(){let e=[{left:`arkenv init [project-name]`,right:`Set up ArkEnv in your project`}],t=[{left:`--yes, -y`,right:`Skip prompts and use defaults (also passed to subprocesses)`},{left:`--force, -f`,right:`Bypass technical requirement checks and force scaffolding`},{left:`--agent, -a`,right:`Agent mode: --yes --quiet --json`},{left:`--example, -e`,right:`Specify an example name when creating a new project`},{left:`--quiet, -q`,right:`Quiet mode: Suppress output, capture logs on failure`},{left:`--json, -j`,right:`Output structured JSON to stdout`},{left:`--help, -h`,right:`Show this help message`}];this.logger.log(`ArkEnv CLI v${Jt}`),this.logger.log(`\n${y.default.bold(`Usage:`)}`);for(let t of Yt(e))this.logger.log(t);this.logger.log(`\n${y.default.bold(`Options:`)}`);for(let e of Yt(t))this.logger.log(e)}};function Zt(e,t){let{extraImports:n,serverField:r,clientField:i,sharedField:a,defaultServerFields:o,defaultClientFields:s,defaultSharedFields:c}=t,l=[],u=[],d=[],f=[];if(e&&e.length>0)for(let t of e)t.startsWith(`NEXT_PUBLIC_`)?(u.push(i(t)),f.push(`\t\t${t}: process.env.${t},`)):t===`NODE_ENV`||t===`PORT`?(d.push(a(t,t===`PORT`)),f.push(`\t\t${t}: process.env.${t},`)):l.push(r(t));else l.push(...o),u.push(...s),d.push(...c),f.push(` NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,`,` NODE_ENV: process.env.NODE_ENV,`);let p=[];return l.length>0&&p.push(`\tserver: {\n${l.join(`
112
+ `)}\n\t}`),u.length>0&&p.push(`\tclient: {\n${u.join(`
113
+ `)}\n\t}`),d.length>0&&p.push(`\tshared: {\n${d.join(`
114
+ `)}\n\t}`),p.push(`\truntimeEnv: {\n${f.join(`
115
+ `)}\n\t}`),`${[`import arkenv from "@arkenv/nextjs";`,...n?[n]:[]].join(`
116
+ `)}
117
+
118
+ /**
119
+ * Environment variable schema.
120
+ * In Next.js, use \`@arkenv/nextjs\` to validate variables at build-time and runtime.
121
+ * Enforces client/server separation and prevents secret leaks.
122
+ */
123
+ export const env = arkenv({
124
+ ${p.join(`,
125
+ `)},
126
+ });
127
+ `}const Qt=(e,t)=>{let n=e?.length?e.map(e=>`\t\t${e}: "string = ''",`).join(`
112
128
  `):` NODE_ENV: "'development' | 'production' | 'test' = 'development'",
113
- PORT: "number.port = 3000",`;if(t===`vite`)return i.default`
129
+ PORT: "number.port = 3000",`;return t===`vite`?i.default`
114
130
  import { type } from "arkenv";
115
131
 
116
132
  /**
@@ -121,7 +137,7 @@ ${t?(0,a.styleText)(`cyan`,B):``}
121
137
  export const Env = type({
122
138
  ${n}
123
139
  });
124
- `;if(t===`bun-fullstack`)return i.default`
140
+ `:t===`bun-fullstack`?i.default`
125
141
  import { type } from "arkenv";
126
142
 
127
143
  /**
@@ -132,33 +148,7 @@ ${n}
132
148
  export const Env = type({
133
149
  ${n}
134
150
  });
135
- `;if(t===`nextjs`){let t=[],n=[],r=[],a=[];if(e&&e.length>0)for(let i of e)i.startsWith(`NEXT_PUBLIC_`)?(n.push(`\t\t${i}: "string = ''",`),a.push(`\t\t${i}: process.env.${i},`)):i===`NODE_ENV`||i===`PORT`?(r.push(`\t\t${i}: "${i===`PORT`?`number.port = 3000`:`'development' | 'production' | 'test' = 'development'`}",`),a.push(`\t\t${i}: process.env.${i},`)):t.push(`\t\t${i}: "string = ''",`);else t.push(` DATABASE_URL: "string = 'postgres://localhost:5432/mydb'",`),n.push(` NEXT_PUBLIC_API_URL: "string = 'https://api.example.com'",`),r.push(` NODE_ENV: "'development' | 'production' | 'test' = 'development'",`),a.push(` NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,`),a.push(` NODE_ENV: process.env.NODE_ENV,`);return i.default`
136
- import arkenv from "@arkenv/nextjs";
137
-
138
- /**
139
- * Environment variable schema.
140
- * In Next.js, use \`@arkenv/nextjs\` to validate variables at build-time and runtime.
141
- * Enforces client/server separation and prevents secret leaks.
142
- */
143
- export const env = arkenv({
144
- server: {
145
- ${t.join(`
146
- `)}
147
- },
148
- client: {
149
- ${n.join(`
150
- `)}
151
- },
152
- shared: {
153
- ${r.join(`
154
- `)}
155
- },
156
- runtimeEnv: {
157
- ${a.join(`
158
- `)}
159
- },
160
- });
161
- `}return i.default`
151
+ `:t===`nextjs`?Zt(e,{serverField:e=>`\t\t${e}: "string = ''",`,clientField:e=>`\t\t${e}: "string = ''",`,sharedField:(e,t)=>`\t\t${e}: "${t?`number.port = 3000`:`'development' | 'production' | 'test' = 'development'`}",`,defaultServerFields:[` DATABASE_URL: "string = 'postgres://localhost:5432/mydb'",`],defaultClientFields:[` NEXT_PUBLIC_API_URL: "string = 'https://api.example.com'",`],defaultSharedFields:[` NODE_ENV: "'development' | 'production' | 'test' = 'development'",`]}):i.default`
162
152
  import arkenv, { type } from "arkenv";
163
153
 
164
154
  /**
@@ -169,7 +159,7 @@ ${n}
169
159
  });
170
160
 
171
161
  export const env = arkenv(Env);
172
- `},Qt=e=>i.default`
162
+ `},$t=e=>i.default`
173
163
  /// <reference types="vite/client" />
174
164
 
175
165
  type ImportMetaEnvAugmented =
@@ -182,7 +172,7 @@ ${n}
182
172
  interface ImportMeta {
183
173
  readonly env: ImportMetaEnv;
184
174
  }
185
- `,$t=e=>i.default`
175
+ `,en=e=>i.default`
186
176
  /// <reference types="bun-types" />
187
177
 
188
178
  type ProcessEnvAugmented = import("@arkenv/bun-plugin").ProcessEnvAugmented<
@@ -192,9 +182,9 @@ ${n}
192
182
  declare namespace NodeJS {
193
183
  interface ProcessEnv extends ProcessEnvAugmented {}
194
184
  }
195
- `,en=(e,t)=>{let n=e?.length?e.map(e=>`\t\t${e}: v.optional(v.string(), ""),`).join(`
185
+ `,tn=(e,t)=>{let n=e?.length?e.map(e=>`\t\t${e}: v.optional(v.string(), ""),`).join(`
196
186
  `):` NODE_ENV: v.optional(v.picklist(["development", "production", "test"]), "development"),
197
- PORT: v.optional(v.pipe(v.string(), v.transform(Number), v.number(), v.integer(), v.minValue(1), v.maxValue(65535)), 3000),`;if(t===`vite`)return i.default`
187
+ PORT: v.optional(v.pipe(v.string(), v.transform(Number), v.number(), v.integer(), v.minValue(1), v.maxValue(65535)), 3000),`;return t===`vite`?i.default`
198
188
  import { type } from "arkenv";
199
189
  import * as v from "valibot";
200
190
 
@@ -206,7 +196,7 @@ ${n}
206
196
  export const Env = type({
207
197
  ${n}
208
198
  });
209
- `;if(t===`bun-fullstack`)return i.default`
199
+ `:t===`bun-fullstack`?i.default`
210
200
  import { type } from "arkenv";
211
201
  import * as v from "valibot";
212
202
 
@@ -218,34 +208,7 @@ ${n}
218
208
  export const Env = type({
219
209
  ${n}
220
210
  });
221
- `;if(t===`nextjs`){let t=[],n=[],r=[],a=[];if(e&&e.length>0)for(let i of e)i.startsWith(`NEXT_PUBLIC_`)?(n.push(`\t\t${i}: v.optional(v.string(), ""),`),a.push(`\t\t${i}: process.env.${i},`)):i===`NODE_ENV`||i===`PORT`?(r.push(`\t\t${i}: ${i===`PORT`?`v.optional(v.pipe(v.string(), v.transform(Number), v.number(), v.integer(), v.minValue(1), v.maxValue(65535)), 3000)`:`v.optional(v.picklist(["development", "production", "test"]), "development")`},`),a.push(`\t\t${i}: process.env.${i},`)):t.push(`\t\t${i}: v.optional(v.string(), ""),`);else t.push(` DATABASE_URL: v.optional(v.pipe(v.string(), v.url()), "postgres://localhost:5432/mydb"),`),n.push(` NEXT_PUBLIC_API_URL: v.optional(v.pipe(v.string(), v.url()), "https://api.example.com"),`),r.push(` NODE_ENV: v.optional(v.picklist(["development", "production", "test"]), "development"),`),a.push(` NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,`),a.push(` NODE_ENV: process.env.NODE_ENV,`);return i.default`
222
- import arkenv from "@arkenv/nextjs";
223
- import * as v from "valibot";
224
-
225
- /**
226
- * Environment variable schema.
227
- * In Next.js, use \`@arkenv/nextjs\` to validate variables at build-time and runtime.
228
- * Enforces client/server separation and prevents secret leaks.
229
- */
230
- export const env = arkenv({
231
- server: {
232
- ${t.join(`
233
- `)}
234
- },
235
- client: {
236
- ${n.join(`
237
- `)}
238
- },
239
- shared: {
240
- ${r.join(`
241
- `)}
242
- },
243
- runtimeEnv: {
244
- ${a.join(`
245
- `)}
246
- },
247
- });
248
- `}return i.default`
211
+ `:t===`nextjs`?Zt(e,{extraImports:`import * as v from "valibot";`,serverField:e=>`\t\t${e}: v.optional(v.string(), ""),`,clientField:e=>`\t\t${e}: v.optional(v.string(), ""),`,sharedField:(e,t)=>`\t\t${e}: ${t?`v.optional(v.pipe(v.string(), v.transform(Number), v.number(), v.integer(), v.minValue(1), v.maxValue(65535)), 3000)`:`v.optional(v.picklist(["development", "production", "test"]), "development")`},`,defaultServerFields:[` DATABASE_URL: v.optional(v.pipe(v.string(), v.url()), "postgres://localhost:5432/mydb"),`],defaultClientFields:[` NEXT_PUBLIC_API_URL: v.optional(v.pipe(v.string(), v.url()), "https://api.example.com"),`],defaultSharedFields:[` NODE_ENV: v.optional(v.picklist(["development", "production", "test"]), "development"),`]}):i.default`
249
212
  import arkenv from "arkenv/standard";
250
213
  import * as v from "valibot";
251
214
 
@@ -255,9 +218,9 @@ ${n}
255
218
  export const env = arkenv({
256
219
  ${n}
257
220
  });
258
- `},tn=(e,t)=>{let n=e?.length?e.map(e=>`\t\t${e}: z.string().default(""),`).join(`
221
+ `},nn=(e,t)=>{let n=e?.length?e.map(e=>`\t\t${e}: z.string().default(""),`).join(`
259
222
  `):` NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
260
- PORT: z.coerce.number().int().min(1).max(65535).default(3000),`;if(t===`vite`)return i.default`
223
+ PORT: z.coerce.number().int().min(1).max(65535).default(3000),`;return t===`vite`?i.default`
261
224
  import { type } from "arkenv";
262
225
  import { z } from "zod";
263
226
 
@@ -269,7 +232,7 @@ ${n}
269
232
  export const Env = type({
270
233
  ${n}
271
234
  });
272
- `;if(t===`bun-fullstack`)return i.default`
235
+ `:t===`bun-fullstack`?i.default`
273
236
  import { type } from "arkenv";
274
237
  import { z } from "zod";
275
238
 
@@ -281,34 +244,7 @@ ${n}
281
244
  export const Env = type({
282
245
  ${n}
283
246
  });
284
- `;if(t===`nextjs`){let t=[],n=[],r=[],a=[];if(e&&e.length>0)for(let i of e)i.startsWith(`NEXT_PUBLIC_`)?(n.push(`\t\t${i}: z.string().default(""),`),a.push(`\t\t${i}: process.env.${i},`)):i===`NODE_ENV`||i===`PORT`?(r.push(`\t\t${i}: ${i===`PORT`?`z.coerce.number().int().min(1).max(65535).default(3000)`:`z.enum(["development", "production", "test"]).default("development")`},`),a.push(`\t\t${i}: process.env.${i},`)):t.push(`\t\t${i}: z.string().default(""),`);else t.push(` DATABASE_URL: z.string().url().default("postgres://localhost:5432/mydb"),`),n.push(` NEXT_PUBLIC_API_URL: z.string().url().default("https://api.example.com"),`),r.push(` NODE_ENV: z.enum(["development", "production", "test"]).default("development"),`),a.push(` NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,`),a.push(` NODE_ENV: process.env.NODE_ENV,`);return i.default`
285
- import arkenv from "@arkenv/nextjs";
286
- import { z } from "zod";
287
-
288
- /**
289
- * Environment variable schema.
290
- * In Next.js, use \`@arkenv/nextjs\` to validate variables at build-time and runtime.
291
- * Enforces client/server separation and prevents secret leaks.
292
- */
293
- export const env = arkenv({
294
- server: {
295
- ${t.join(`
296
- `)}
297
- },
298
- client: {
299
- ${n.join(`
300
- `)}
301
- },
302
- shared: {
303
- ${r.join(`
304
- `)}
305
- },
306
- runtimeEnv: {
307
- ${a.join(`
308
- `)}
309
- },
310
- });
311
- `}return i.default`
247
+ `:t===`nextjs`?Zt(e,{extraImports:`import { z } from "zod";`,serverField:e=>`\t\t${e}: z.string().default(""),`,clientField:e=>`\t\t${e}: z.string().default(""),`,sharedField:(e,t)=>`\t\t${e}: ${t?`z.coerce.number().int().min(1).max(65535).default(3000)`:`z.enum(["development", "production", "test"]).default("development")`},`,defaultServerFields:[` DATABASE_URL: z.string().url().default("postgres://localhost:5432/mydb"),`],defaultClientFields:[` NEXT_PUBLIC_API_URL: z.string().url().default("https://api.example.com"),`],defaultSharedFields:[` NODE_ENV: z.enum(["development", "production", "test"]).default("development"),`]}):i.default`
312
248
  import arkenv from "arkenv/standard";
313
249
  import { z } from "zod";
314
250
 
@@ -318,12 +254,12 @@ ${n}
318
254
  export const env = arkenv({
319
255
  ${n}
320
256
  });
321
- `};function nn(e){let{validator:t,envKeys:n,framework:r}=e;switch(t){case`arktype`:return`${Zt(n,r)}\n`;case`zod`:return`${tn(n,r)}\n`;case`valibot`:return`${en(n,r)}\n`;default:throw Error(`Unsupported validator: ${t}`)}}async function rn(e,t){let i=t.targetDir??process.cwd(),a=r.default.join(process.cwd(),`.arkenv-temp`);await e.mkdir(a,!0),t.targetDir&&await e.mkdir(i,!0);try{await e.execute(`git`,[`clone`,`--filter=blob:none`,`--sparse`,t.repository,a]);let o=`examples/${t.example}`;await e.execute(`git`,[`-C`,a,`sparse-checkout`,`set`,o]);let s=r.default.join(a,o),c=await n.default.readdir(s),l=[];for(let t of c){let n=r.default.join(i,t);await e.exists(n)&&l.push(t)}if(l.length>0)throw Error(`Scaffolding into a non-empty directory failed. The following paths already exist: ${l.join(`, `)}`);await an(s,i);for(let e of[`package-lock.json`,`pnpm-lock.yaml`,`yarn.lock`,`bun.lockb`,`bun.lock`])await n.default.rm(r.default.join(i,e),{force:!0});let u=r.default.join(i,`package.json`);if(await e.exists(u)){let n=await e.readFile(u),r=JSON.parse(n);r.name=t.targetName,delete r.packageManager,await e.writeFile(u,JSON.stringify(r,null,2))}}finally{await n.default.rm(a,{recursive:!0,force:!0})}}async function an(e,t){let i=await n.default.readdir(e);await Promise.all(i.map(i=>n.default.cp(r.default.join(e,i),r.default.join(t,i),{recursive:!0,force:!1})))}function on(e,t){let n=t.length>0;switch(e){case`pnpm`:return[`pnpm`,[n?`add`:`install`,...t]];case`yarn`:return[`yarn`,[n?`add`:`install`,...t]];case`bun`:return[`bun`,[n?`add`:`install`,...t]];default:return[`npm`,[`install`,...t]]}}function sn(e){return e.metadata.framework===`vite`?`2. Access via ${Y(`import.meta.env.YOUR_VAR`)}`:e.metadata.framework===`bun-fullstack`?`2. Access via ${Y(`process.env.YOUR_VAR`)}`:`2. Import and use: ${Y(`import { env } from "${e.metadata.importPath}"`)}`}function cn(e,t){if(t)return{message:i.default`
257
+ `};function rn(e){let{validator:t,envKeys:n,framework:r}=e;switch(t){case`arktype`:return`${Qt(n,r)}\n`;case`zod`:return`${nn(n,r)}\n`;case`valibot`:return`${tn(n,r)}\n`;default:throw Error(`Unsupported validator: ${t}`)}}async function an(e,t){let i=t.targetDir??process.cwd(),a=r.default.join(process.cwd(),`.arkenv-temp`);await e.mkdir(a,!0),t.targetDir&&await e.mkdir(i,!0);try{await e.execute(`git`,[`clone`,`--filter=blob:none`,`--sparse`,t.repository,a]);let o=`examples/${t.example}`;await e.execute(`git`,[`-C`,a,`sparse-checkout`,`set`,o]);let s=r.default.join(a,o),c=await n.default.readdir(s),l=[];for(let t of c){let n=r.default.join(i,t);await e.exists(n)&&l.push(t)}if(l.length>0)throw Error(`Scaffolding into a non-empty directory failed. The following paths already exist: ${l.join(`, `)}`);await on(s,i);for(let e of[`package-lock.json`,`pnpm-lock.yaml`,`yarn.lock`,`bun.lockb`,`bun.lock`])await n.default.rm(r.default.join(i,e),{force:!0});let u=r.default.join(i,`package.json`);if(await e.exists(u)){let n=await e.readFile(u),r=JSON.parse(n);r.name=t.targetName,delete r.packageManager,await e.writeFile(u,JSON.stringify(r,null,2))}}finally{await n.default.rm(a,{recursive:!0,force:!0})}}async function on(e,t){let i=await n.default.readdir(e);await Promise.all(i.map(i=>n.default.cp(r.default.join(e,i),r.default.join(t,i),{recursive:!0,force:!1})))}function sn(e,t){let n=t.length>0;switch(e){case`pnpm`:return[`pnpm`,[n?`add`:`install`,...t]];case`yarn`:return[`yarn`,[n?`add`:`install`,...t]];case`bun`:return[`bun`,[n?`add`:`install`,...t]];default:return[`npm`,[`install`,...t]]}}function cn(e){return e.metadata.framework===`vite`?`2. Access via ${Y(`import.meta.env.YOUR_VAR`)}`:e.metadata.framework===`bun-fullstack`?`2. Access via ${Y(`process.env.YOUR_VAR`)}`:`2. Import and use: ${Y(`import { env } from "${e.metadata.importPath}"`)}`}function ln(e,t){if(t)return{message:i.default`
322
258
  Inside your AI assistant (e.g. Claude Code), use:
323
259
  ${Y(`/arkenv`)} - automatically refine your schema and configure integrations.
324
- `,title:`Next steps`};let n=e.skill?.dlxCommand.join(` `)||`npx`,r=e.skill?.packageName||`yamcodes/arkenv`,a=sn(e);return{message:i.default`
260
+ `,title:`Next steps`};let n=e.skill?.dlxCommand.join(` `)||`npx`,r=e.skill?.packageName||`yamcodes/arkenv`,a=cn(e);return{message:i.default`
325
261
  1. Check ${Y(e.metadata.displayPath)} and refine your environment schema.
326
262
  ${a}
327
263
  3. (Recommended) Install the AI skill: ${Y(`${n} skills add ${r}`)}
328
264
  Then run ${Y(`/arkenv`)} inside your AI assistant to finish.
329
- `,title:`Next steps`}}var ln=class{constructor(e,t){this.workspace=e,this.reporter=t}async execute(e){let t=this.reporter.spinner();t.start(`Scaffolding ArkEnv configuration...`);try{e.clone&&(t.stop(`Starting new project scaffolding...`),this.reporter.step(`Cloning example ${Y(e.clone.example)}...`),await rn(this.workspace,e.clone),t.start(`Scaffolding complete, finalizing...`));for(let t of e.files){if(t.action===`append`){if(!e.bootstrap||e.bootstrap.framework!==`vite`&&e.bootstrap.framework!==`bun-fullstack`){this.reporter.warn(`Skipping safe-append for ${Y(r.default.basename(t.path))}: unsupported framework.`);continue}await this.workspace.safeAppend(t.path,t.content,e.bootstrap.framework)?this.reporter.info(`Appended ArkEnv types to ${Y(r.default.basename(t.path))}.`):this.reporter.info(`${Y(r.default.basename(t.path))} already contains ArkEnv types.`);continue}if(await this.workspace.mkdir(r.default.dirname(t.path),!0),await this.workspace.writeFile(t.path,t.content),t.label!==`environment schema`&&t.label?.includes(`types`)){let e=t.action===`overwrite`?`Updated`:`Created`;this.reporter.info(`${e} ${Y(r.default.basename(t.path))} for typesafe environment variables.`)}}if(t.stop(`Configuration scaffolded!`),e.install&&process.env.SKIP_INSTALL!==`true`){this.reporter.step(`Installing dependencies with ${Y(e.install.packageManager)}...`);let[t,n]=on(e.install.packageManager,e.install.dependencies);await this.workspace.execute(t,n,e.install.cwd??e.cwd)}let n=!1;if(e.tsConfig){let t=await this.workspace.updateTsConfigToStrict(e.tsConfig.path);t.status===`updated`?(this.reporter.info(`Enforced strict: true in your ${Y(t.file)}`),n=!0):t.status===`error`&&this.reporter.warn(`Could not automatically update ${Y(t.file||`tsconfig.json`)}. Please ensure 'strict: true' is set manually.`)}if(e.bootstrap){if(e.bootstrap.framework===`vite`){let t=await this.workspace.findViteConfig(e.cwd);if(t){this.reporter.step(`Bootstrapping Vite plugin...`);let n=await this.workspace.bootstrapViteConfig(t,e.bootstrap.importPath||`./src/env`);n.success?n.updated&&this.reporter.info(`Updated ${Y(r.default.basename(t))}`):(this.reporter.warn(`Could not automatically update ${Y(r.default.basename(t))}: ${n.error}`),this.reporter.info(`Please add ${Y(`@arkenv/vite-plugin`)} manually.`))}else this.reporter.info(`No Vite config found — please add ${Y(`@arkenv/vite-plugin`)} to your Vite config manually.`)}else if(e.bootstrap.framework===`bun-fullstack`){let t=await this.workspace.findBunConfig(e.cwd),n=await this.workspace.bootstrapBunConfig(t,e.bootstrap.bunFeatures);n.success&&n.instructions?this.reporter.info(n.instructions):n.success||this.reporter.error(n.error||`Bun bootstrap failed`)}}let i=!1;if(e.skill&&process.env.SKIP_INSTALL!==`true`){this.reporter.step(`Installing ArkEnv agent skill...`);try{let[t,...n]=e.skill.dlxCommand,r=[...n,`skills`,`add`,e.skill.packageName];e.skill.isYes&&r.push(`--yes`),await this.workspace.execute(t,r,e.cwd),i=!0}catch(e){let t=e instanceof Error?e.message:String(e);this.reporter.warn(`Failed to install ArkEnv AI skill: ${t}`)}}let a=cn(e,i);this.reporter.note(a.message,a.title),this.reporter.finish(`${xt} ArkEnv scaffolding complete. Happy coding!`,{path:e.metadata.displayPath,framework:e.metadata.framework,validator:e.metadata.validator,packageManager:e.metadata.packageManager,tsConfigUpdated:n,skillInstalled:i})}catch(e){throw t.stop(`Scaffolding failed.`),e}}};function un(e){switch(e){case`pnpm`:return[`pnpm`,`dlx`];case`yarn`:return[`yarn`,`dlx`];case`bun`:return[`bunx`];default:return[`npx`]}}function dn(e){let{mode:n,options:i,packageManager:a,tsConfig:o,shouldUpdateTsConfig:s,cwd:c,existingFiles:l}=e,u=i.name&&i.name!==`.`?r.default.basename(i.name):void 0,d={files:[],cwd:c,metadata:(0,t.shake)({displayPath:``,framework:i.framework,validator:i.validator,packageManager:a,importPath:``,mode:n,example:i.example,name:u})};if(n===`new`){if(!i.example)throw Error(`New project scaffolding requires an example.`);let t=i.name&&i.name!==`.`?r.default.join(c,i.name):void 0,n=i.name&&i.name!==`.`?r.default.basename(i.name):r.default.basename(c);return d.clone={repository:`https://github.com/yamcodes/arkenv.git`,example:i.example,targetName:n,...t!==void 0&&{targetDir:t}},d.install={packageManager:a,dependencies:[],...t!==void 0&&{cwd:t}},i.installSkill&&(d.skill={dlxCommand:un(a),packageName:`yamcodes/arkenv`,isYes:e.isYes}),d.metadata.displayPath=`./src/env.ts`,d.metadata.importPath=`./src/env`,d}let f=r.default.resolve(c,i.path),p=r.default.dirname(f),m=nn(i),h=l.includes(f);(!h||i.overwriteEnvSchemaFile!==!1)&&d.files.push({path:f,content:m,action:h?`overwrite`:`create`,label:`environment schema`});let g=[`arkenv`,i.validator];if(i.framework===`vite`&&g.push(`@arkenv/vite-plugin`),i.framework===`bun-fullstack`&&i.bunFeatures?.length&&g.push(`@arkenv/bun-plugin`),i.framework===`nextjs`&&g.push(`@arkenv/nextjs`),(i.framework===`vite`||i.framework===`nextjs`||i.framework===`bun-fullstack`&&i.bunFeatures?.length)&&!g.includes(`arktype`)&&g.push(`arktype`),d.install={packageManager:a,dependencies:g},s&&o.file&&(d.tsConfig={path:r.default.resolve(c,o.file),action:`strict`}),(i.framework===`vite`||i.framework===`bun-fullstack`&&i.bunFeatures?.length)&&i.installTypeDefinitions!==!1){let e=i.framework===`vite`?`vite-env.d.ts`:`bun-env.d.ts`,t=r.default.join(p,e),n=l.includes(t);if(i.envDtsHandling!==`skip`)if(i.envDtsHandling===`append`||!i.envDtsHandling&&n)d.files.push({path:t,content:f,action:`append`,label:`${i.framework} types`});else{let e=i.framework===`vite`?Qt(i.path):$t(i.path);d.files.push({path:t,content:e,action:n?`overwrite`:`create`,label:`${i.framework} types`})}}(i.framework===`vite`||i.framework===`bun-fullstack`)&&(d.bootstrap=(0,t.shake)({framework:i.framework,bunFeatures:i.framework===`bun-fullstack`?i.bunFeatures:void 0})),i.installSkill&&(d.skill={dlxCommand:un(a),packageName:`yamcodes/arkenv`,isYes:e.isYes});let _=r.default.relative(c,f).replace(/\\/g,`/`),v=_.startsWith(`.`)?_:`./${_}`,y=v.replace(/\.(ts|js|tsx|jsx)$/,``);return d.metadata.displayPath=v,d.metadata.importPath=y,d.bootstrap&&(d.bootstrap.importPath=y),d}var fn=class{async fetchRegistry(){try{let e=await fetch(`https://raw.githubusercontent.com/yamcodes/arkenv/main/examples/registry.json`);if(!e.ok)throw Error(`Failed to fetch registry: ${e.statusText}`);return await e.json()}catch{return{examples:[{id:`basic`,name:`Basic`,description:`A minimal ArkEnv setup in Node.js`,framework:`vanilla`},{id:`with-nextjs`,name:`Next.js`,description:`Minimal Next.js project with ArkType`,framework:`nextjs`},{id:`with-vite-react`,name:`React + Vite`,framework:`vite`},{id:`with-bun`,name:`Bun (Vanilla)`,description:`Minimal Bun project with ArkType`,framework:`vanilla`},{id:`with-bun-react`,name:`React + Bun fullstack dev server`,framework:`bun-fullstack`},{id:`with-zod`,name:`Zod`,description:`ArkEnv with Zod in Node.js`,framework:`vanilla`}]}}}},pn=class{constructor(e,t,n,r,i=new fn){this.logger=e,this.workspace=t,this.prompt=n,this.scanner=r,this.registry=i}async execute(e){let t=await this.collect(e);if(!t)return!1;let n=dn(t),r=new ln(this.workspace,this.logger);try{await r.execute(n)}catch(e){this.logger.fatal(`Scaffolding failed.`,e)}return!0}async collect(e){this.logger.interactiveStdout(!0);try{let t=e.name;t&&r.default.resolve(process.cwd(),t)===process.cwd()&&(t=`.`);let n={...e,...t!==void 0&&{name:t}},i=t&&t!==`.`?r.default.resolve(process.cwd(),t):process.cwd(),a=await this.workspace.exists(i),o=a?await this.scanner.hasPackageJson(i):!1,s=a?await this.scanner.isEmptyDirectory(i):!0;return n.example===void 0?o?await this.collectExistingProject(n,i):s||n.isForce?await this.collectNewProject(n,s):(this.logger.error(`Directory is not empty and no ${Y(`package.json`)} was found.`),this.logger.info(`To scaffold a new project, run ${Y(`arkenv init`)} in an empty directory or use ${Y(`--force`)} to proceed anyway.`),null):await this.collectNewProject(n,s)}finally{this.logger.interactiveStdout(!1)}}async collectExistingProject(e,n){let{isYes:i,isForce:a,isAgent:o}=e,s=await this.scanner.checkRequirements(n),c=s.filter(e=>e.status===`fail`),l=s.filter(e=>e.status===`warn`);for(let e of l)this.logger.warn(`${e.requirement}: ${e.message}`);if(c.length>0)if(a){this.logger.warn(`Technical requirements not met, but continuing due to --force flag.`);for(let e of c)this.logger.warn(`${e.requirement}: ${e.message}`)}else{this.logger.error(`Technical requirements not met:`);for(let e of c)this.logger.error(`- ${e.requirement}: ${e.message}${e.current?` (Current: ${e.current}, Expected: ${e.expected})`:``}`);return this.logger.info(`Use --force to bypass these checks.`),null}let u=!1,d=await this.scanner.checkTsConfig(n);if(d.status===`not_strict`)if(i)u=!0;else{this.logger.warn(`TypeScript strict mode is not enabled in your ${Y(d.file)}.`);let e=await this.prompt.confirm(`ArkEnv requires ${Y(`strict`)} mode in your ${Y(d.file)}. Would you like to enable it now?`,!0,`Yes (Recommended)`);if(e===null)return null;if(!e)return this.logger.cancel(`Operation cancelled.`),null;u=!0}let f=await this.scanner.detectFramework(n,d.parsed),p=f===`bun-fullstack`?await this.scanner.detectBunFeatures(n,d.parsed):void 0,m=await this.scanner.suggestDefaultEnvPath(n,d.parsed),h=r.default.resolve(n,m),g=await this.scanner.getEnvExampleKeys(n,d.parsed,h),_=await this.workspace.exists(h),v=async({framework:e,envPath:t})=>{if(e!==`vite`&&e!==`bun-fullstack`)return!1;let i=e===`vite`?`vite-env.d.ts`:`bun-env.d.ts`,a=r.default.resolve(n,t),o=r.default.dirname(a),s=r.default.join(o,i);return this.workspace.exists(s)},y=await v({framework:f,envPath:m}),b=await this.prompt.runWizard((0,t.shake)({mode:`existing`,framework:f,bunFeatures:p,defaultEnvPath:m,tsConfig:d.parsed??null,envKeys:g?.keys,envKeysSource:g?.source,hasTypeFileAtPath:v,hasTypeFile:y,hasEnvSchemaFile:_}),i);if(b===null)return null;if(o)b.installSkill=!1;else if(i)b.installSkill=!0;else{let e=await this.prompt.confirm(`Would you like to install the ArkEnv agent skill?`,!0,`Yes (Recommended)`);if(e===null)return null;b.installSkill=e}let x=r.default.resolve(n,b.path);if(await this.workspace.exists(x)&&b.overwriteEnvSchemaFile===void 0){let e=await this.prompt.confirm(`File ${Y(r.default.basename(x))} already exists. Overwrite?`,!1);if(e===null)return null;if(!e)return this.logger.cancel(`Operation cancelled.`),null;b.overwriteEnvSchemaFile=e}let S=await this.scanner.detectPackageManager(n,d.parsed),C=[];await this.workspace.exists(x)&&C.push(x);let w;if(b.framework===`vite`?w=`vite-env.d.ts`:b.framework===`bun-fullstack`&&(w=`bun-env.d.ts`),w){let e=r.default.dirname(x),t=r.default.join(e,w);await this.workspace.exists(t)&&C.push(t)}return(0,t.shake)({mode:`existing`,cwd:n,options:b,detectedFramework:f,detectedBunFeatures:p,packageManager:S,tsConfig:d,shouldUpdateTsConfig:u,existingFiles:C,isYes:i})}async collectNewProject(e,n=!0){let{isYes:r,example:i,name:a,isForce:o}=e,s=await this.registry.fetchRegistry(),c=await this.prompt.runWizard((0,t.shake)({mode:`new`,examples:s.examples,example:i,name:a}),r);if(c===null)return null;if(c.name===`.`&&!n&&!o)return this.logger.error(`Cannot scaffold into ${Y(`.`)} because the current directory is not empty.`),this.logger.info(`Run ${Y(`arkenv init`)} in an empty directory or choose a sub-directory name instead.`),null;let l=this.detectPackageManager();return(0,t.shake)({mode:`new`,cwd:process.cwd(),options:c,detectedFramework:c.framework,packageManager:l,tsConfig:{status:`not_found`},shouldUpdateTsConfig:!1,existingFiles:[],isYes:r})}detectPackageManager(){let e=process.env.npm_config_user_agent||``;return e.includes(`pnpm`)?`pnpm`:e.includes(`yarn`)?`yarn`:e.includes(`bun`)?`bun`:`npm`}};function mn(e){let t=new qt(e),n=t.logger,r=new Ot(t.isQuiet,n.stdio),i=new Wt;return{cli:t,logger:n,workspace:r,prompt:i,initUseCase:new pn(n,r,i,new bt),helpUseCase:new Xt(n)}}let $,hn=!1;async function gn(){if(process.env.INIT_CWD)try{process.chdir(process.env.INIT_CWD)}catch{}let{cli:e,logger:n,initUseCase:r,helpUseCase:i}=mn(process.argv);$=n,_n(n),e.validationError&&(n.error(e.validationError),await i.execute(),await n.flush(),process.exit(1)),e.helpRequested&&(await i.execute(),await n.flush(),process.exit(0)),e.command!==`init`&&(e.command?n.error(`Unknown command: ${e.command}`):n.error(`Missing command.`),await i.execute(),await n.flush(),process.exit(1));try{await r.execute((0,t.shake)(e.initInput))||(await n.flush(),process.exit(1))}catch(e){try{n.fatal(`An unexpected error occurred`,e)}catch{}await n.flush(),process.exit(1)}}function _n(e){let t=async t=>{hn&&process.exit(t),hn=!0,setTimeout(()=>{process.exit(t)},2e3).unref(),e.interactiveStdout&&e.interactiveStdout(!1);try{e.cancel(`Operation cancelled.`),await e.flush()}catch(t){e.error&&e.error(`Logger failed during shutdown`,t)}finally{process.exit(t)}};process.on(`SIGINT`,()=>t(130)),process.on(`SIGTERM`,()=>t(143))}gn(),process.on(`unhandledRejection`,async e=>{if($){try{$.fatal(`Unhandled rejection`,e)}catch{}await $.flush()}else console.error(`Unhandled rejection`,e);process.exit(1)}),process.on(`uncaughtException`,async e=>{if($){try{$.fatal(`Uncaught exception`,e)}catch{}await $.flush()}else console.error(`Uncaught exception`,e);process.exit(1)});
265
+ `,title:`Next steps`}}var un=class{constructor(e,t){this.workspace=e,this.reporter=t}async execute(e){let t=this.reporter.spinner();t.start(`Scaffolding ArkEnv configuration...`);try{e.clone&&(t.stop(`Starting new project scaffolding...`),this.reporter.step(`Cloning example ${Y(e.clone.example)}...`),await an(this.workspace,e.clone),t.start(`Scaffolding complete, finalizing...`));for(let t of e.files){if(t.action===`append`){if(!e.bootstrap||e.bootstrap.framework!==`vite`&&e.bootstrap.framework!==`bun-fullstack`){this.reporter.warn(`Skipping safe-append for ${Y(r.default.basename(t.path))}: unsupported framework.`);continue}await this.workspace.safeAppend(t.path,t.content,e.bootstrap.framework)?this.reporter.info(`Appended ArkEnv types to ${Y(r.default.basename(t.path))}.`):this.reporter.info(`${Y(r.default.basename(t.path))} already contains ArkEnv types.`);continue}if(await this.workspace.mkdir(r.default.dirname(t.path),!0),await this.workspace.writeFile(t.path,t.content),t.label!==`environment schema`&&t.label?.includes(`types`)){let e=t.action===`overwrite`?`Updated`:`Created`;this.reporter.info(`${e} ${Y(r.default.basename(t.path))} for typesafe environment variables.`)}}if(t.stop(`Configuration scaffolded!`),e.install&&process.env.SKIP_INSTALL!==`true`){this.reporter.step(`Installing dependencies with ${Y(e.install.packageManager)}...`);let[t,n]=sn(e.install.packageManager,e.install.dependencies);await this.workspace.execute(t,n,e.install.cwd??e.cwd)}let n=!1;if(e.tsConfig){let t=await this.workspace.updateTsConfigToStrict(e.tsConfig.path);t.status===`updated`?(this.reporter.info(`Enforced strict: true in your ${Y(t.file)}`),n=!0):t.status===`error`&&this.reporter.warn(`Could not automatically update ${Y(t.file||`tsconfig.json`)}. Please ensure 'strict: true' is set manually.`)}if(e.bootstrap){if(e.bootstrap.framework===`vite`){let t=await this.workspace.findViteConfig(e.cwd);if(t){this.reporter.step(`Bootstrapping Vite plugin...`);let n=await this.workspace.bootstrapViteConfig(t,e.bootstrap.importPath||`./src/env`);n.success?n.updated&&this.reporter.info(`Updated ${Y(r.default.basename(t))}`):(this.reporter.warn(`Could not automatically update ${Y(r.default.basename(t))}: ${n.error}`),this.reporter.info(`Please add ${Y(`@arkenv/vite-plugin`)} manually.`))}else this.reporter.info(`No Vite config found — please add ${Y(`@arkenv/vite-plugin`)} to your Vite config manually.`)}else if(e.bootstrap.framework===`bun-fullstack`){let t=await this.workspace.findBunConfig(e.cwd),n=await this.workspace.bootstrapBunConfig(t,e.bootstrap.bunFeatures);n.success&&n.instructions?this.reporter.info(n.instructions):n.success||this.reporter.error(n.error||`Bun bootstrap failed`)}}let i=!1;if(e.skill&&process.env.SKIP_INSTALL!==`true`){this.reporter.step(`Installing ArkEnv agent skill...`);try{let[t,...n]=e.skill.dlxCommand,r=[...n,`skills`,`add`,e.skill.packageName];e.skill.isYes&&r.push(`--yes`),await this.workspace.execute(t,r,e.cwd),i=!0}catch(e){let t=e instanceof Error?e.message:String(e);this.reporter.warn(`Failed to install ArkEnv AI skill: ${t}`)}}let a=ln(e,i);this.reporter.note(a.message,a.title),this.reporter.finish(`${xt} ArkEnv scaffolding complete. Happy coding!`,{path:e.metadata.displayPath,framework:e.metadata.framework,validator:e.metadata.validator,packageManager:e.metadata.packageManager,tsConfigUpdated:n,skillInstalled:i})}catch(e){throw t.stop(`Scaffolding failed.`),e}}};function dn(e){switch(e){case`pnpm`:return[`pnpm`,`dlx`];case`yarn`:return[`yarn`,`dlx`];case`bun`:return[`bunx`];default:return[`npx`]}}function fn(e){let{mode:n,options:i,packageManager:a,tsConfig:o,shouldUpdateTsConfig:s,cwd:c,existingFiles:l}=e,u=i.name&&i.name!==`.`?r.default.basename(i.name):void 0,d={files:[],cwd:c,metadata:(0,t.shake)({displayPath:``,framework:i.framework,validator:i.validator,packageManager:a,importPath:``,mode:n,example:i.example,name:u})};if(n===`new`){if(!i.example)throw Error(`New project scaffolding requires an example.`);let t=i.name&&i.name!==`.`?r.default.join(c,i.name):void 0,n=i.name&&i.name!==`.`?r.default.basename(i.name):r.default.basename(c);return d.clone={repository:`https://github.com/yamcodes/arkenv.git`,example:i.example,targetName:n,...t!==void 0&&{targetDir:t}},d.install={packageManager:a,dependencies:[],...t!==void 0&&{cwd:t}},i.installSkill&&(d.skill={dlxCommand:dn(a),packageName:`yamcodes/arkenv`,isYes:e.isYes}),d.metadata.displayPath=`./src/env.ts`,d.metadata.importPath=`./src/env`,d}let f=r.default.resolve(c,i.path),p=r.default.dirname(f),m=rn(i),h=l.includes(f);(!h||i.overwriteEnvSchemaFile!==!1)&&d.files.push({path:f,content:m,action:h?`overwrite`:`create`,label:`environment schema`});let g=[`arkenv`,i.validator];if(i.framework===`vite`&&g.push(`@arkenv/vite-plugin`),i.framework===`bun-fullstack`&&i.bunFeatures?.length&&g.push(`@arkenv/bun-plugin`),i.framework===`nextjs`&&g.push(`@arkenv/nextjs`),(i.framework===`vite`||i.framework===`nextjs`||i.framework===`bun-fullstack`&&i.bunFeatures?.length)&&!g.includes(`arktype`)&&g.push(`arktype`),d.install={packageManager:a,dependencies:g},s&&o.file&&(d.tsConfig={path:r.default.resolve(c,o.file),action:`strict`}),(i.framework===`vite`||i.framework===`bun-fullstack`&&i.bunFeatures?.length)&&i.installTypeDefinitions!==!1){let e=i.framework===`vite`?`vite-env.d.ts`:`bun-env.d.ts`,t=r.default.join(p,e),n=l.includes(t);if(i.envDtsHandling!==`skip`)if(i.envDtsHandling===`append`||!i.envDtsHandling&&n)d.files.push({path:t,content:f,action:`append`,label:`${i.framework} types`});else{let e=i.framework===`vite`?$t(i.path):en(i.path);d.files.push({path:t,content:e,action:n?`overwrite`:`create`,label:`${i.framework} types`})}}(i.framework===`vite`||i.framework===`bun-fullstack`)&&(d.bootstrap=(0,t.shake)({framework:i.framework,bunFeatures:i.framework===`bun-fullstack`?i.bunFeatures:void 0})),i.installSkill&&(d.skill={dlxCommand:dn(a),packageName:`yamcodes/arkenv`,isYes:e.isYes});let _=r.default.relative(c,f).replace(/\\/g,`/`),v=_.startsWith(`.`)?_:`./${_}`,y=v.replace(/\.(ts|js|tsx|jsx)$/,``);return d.metadata.displayPath=v,d.metadata.importPath=y,d.bootstrap&&(d.bootstrap.importPath=y),d}var pn=class{async fetchRegistry(){try{let e=await fetch(`https://raw.githubusercontent.com/yamcodes/arkenv/main/examples/registry.json`);if(!e.ok)throw Error(`Failed to fetch registry: ${e.statusText}`);return await e.json()}catch{return{examples:[{id:`basic`,name:`Basic`,description:`A minimal ArkEnv setup in Node.js`,framework:`vanilla`},{id:`with-nextjs`,name:`Next.js`,description:`Minimal Next.js project with ArkType`,framework:`nextjs`},{id:`with-vite-react`,name:`React + Vite`,framework:`vite`},{id:`with-bun`,name:`Bun (Vanilla)`,description:`Minimal Bun project with ArkType`,framework:`vanilla`},{id:`with-bun-react`,name:`React + Bun fullstack dev server`,framework:`bun-fullstack`},{id:`with-zod`,name:`Zod`,description:`ArkEnv with Zod in Node.js`,framework:`vanilla`}]}}}},mn=class{constructor(e,t,n,r,i=new pn){this.logger=e,this.workspace=t,this.prompt=n,this.scanner=r,this.registry=i}async execute(e){let t=await this.collect(e);if(!t)return!1;let n=fn(t),r=new un(this.workspace,this.logger);try{await r.execute(n)}catch(e){this.logger.fatal(`Scaffolding failed.`,e)}return!0}async collect(e){this.logger.interactiveStdout(!0);try{let t=e.name;t&&r.default.resolve(process.cwd(),t)===process.cwd()&&(t=`.`);let n={...e,...t!==void 0&&{name:t}},i=t&&t!==`.`?r.default.resolve(process.cwd(),t):process.cwd(),a=await this.workspace.exists(i),o=a?await this.scanner.hasPackageJson(i):!1,s=a?await this.scanner.isEmptyDirectory(i):!0;return n.example===void 0?o?await this.collectExistingProject(n,i):s||n.isForce?await this.collectNewProject(n,s):(this.logger.error(`Directory is not empty and no ${Y(`package.json`)} was found.`),this.logger.info(`To scaffold a new project, run ${Y(`arkenv init`)} in an empty directory or use ${Y(`--force`)} to proceed anyway.`),null):await this.collectNewProject(n,s)}finally{this.logger.interactiveStdout(!1)}}async collectExistingProject(e,n){let{isYes:i,isForce:a,isAgent:o}=e,s=await this.scanner.checkRequirements(n),c=s.filter(e=>e.status===`fail`),l=s.filter(e=>e.status===`warn`);for(let e of l)this.logger.warn(`${e.requirement}: ${e.message}`);if(c.length>0)if(a){this.logger.warn(`Technical requirements not met, but continuing due to --force flag.`);for(let e of c)this.logger.warn(`${e.requirement}: ${e.message}`)}else{this.logger.error(`Technical requirements not met:`);for(let e of c)this.logger.error(`- ${e.requirement}: ${e.message}${e.current?` (Current: ${e.current}, Expected: ${e.expected})`:``}`);return this.logger.info(`Use --force to bypass these checks.`),null}let u=!1,d=await this.scanner.checkTsConfig(n);if(d.status===`not_strict`)if(i)u=!0;else{this.logger.warn(`TypeScript strict mode is not enabled in your ${Y(d.file)}.`);let e=await this.prompt.confirm(`ArkEnv requires ${Y(`strict`)} mode in your ${Y(d.file)}. Would you like to enable it now?`,!0,`Yes (Recommended)`);if(e===null)return null;if(!e)return this.logger.cancel(`Operation cancelled.`),null;u=!0}let f=await this.scanner.detectFramework(n,d.parsed),p=f===`bun-fullstack`?await this.scanner.detectBunFeatures(n,d.parsed):void 0,m=await this.scanner.suggestDefaultEnvPath(n,d.parsed),h=r.default.resolve(n,m),g=await this.scanner.getEnvExampleKeys(n,d.parsed,h),_=await this.workspace.exists(h),v=async({framework:e,envPath:t})=>{if(e!==`vite`&&e!==`bun-fullstack`)return!1;let i=e===`vite`?`vite-env.d.ts`:`bun-env.d.ts`,a=r.default.resolve(n,t),o=r.default.dirname(a),s=r.default.join(o,i);return this.workspace.exists(s)},y=await v({framework:f,envPath:m}),b=await this.prompt.runWizard((0,t.shake)({mode:`existing`,framework:f,bunFeatures:p,defaultEnvPath:m,tsConfig:d.parsed??null,envKeys:g?.keys,envKeysSource:g?.source,hasTypeFileAtPath:v,hasTypeFile:y,hasEnvSchemaFile:_}),i);if(b===null)return null;if(o)b.installSkill=!1;else if(i)b.installSkill=!0;else{let e=await this.prompt.confirm(`Would you like to install the ArkEnv agent skill?`,!0,`Yes (Recommended)`);if(e===null)return null;b.installSkill=e}let x=r.default.resolve(n,b.path);if(await this.workspace.exists(x)&&b.overwriteEnvSchemaFile===void 0){let e=await this.prompt.confirm(`File ${Y(r.default.basename(x))} already exists. Overwrite?`,!1);if(e===null)return null;if(!e)return this.logger.cancel(`Operation cancelled.`),null;b.overwriteEnvSchemaFile=e}let S=await this.scanner.detectPackageManager(n,d.parsed),C=[];await this.workspace.exists(x)&&C.push(x);let w;if(b.framework===`vite`?w=`vite-env.d.ts`:b.framework===`bun-fullstack`&&(w=`bun-env.d.ts`),w){let e=r.default.dirname(x),t=r.default.join(e,w);await this.workspace.exists(t)&&C.push(t)}return(0,t.shake)({mode:`existing`,cwd:n,options:b,detectedFramework:f,detectedBunFeatures:p,packageManager:S,tsConfig:d,shouldUpdateTsConfig:u,existingFiles:C,isYes:i})}async collectNewProject(e,n=!0){let{isYes:r,example:i,name:a,isForce:o}=e,s=await this.registry.fetchRegistry(),c=await this.prompt.runWizard((0,t.shake)({mode:`new`,examples:s.examples,example:i,name:a}),r);if(c===null)return null;if(c.name===`.`&&!n&&!o)return this.logger.error(`Cannot scaffold into ${Y(`.`)} because the current directory is not empty.`),this.logger.info(`Run ${Y(`arkenv init`)} in an empty directory or choose a sub-directory name instead.`),null;let l=this.detectPackageManager();return(0,t.shake)({mode:`new`,cwd:process.cwd(),options:c,detectedFramework:c.framework,packageManager:l,tsConfig:{status:`not_found`},shouldUpdateTsConfig:!1,existingFiles:[],isYes:r})}detectPackageManager(){let e=process.env.npm_config_user_agent||``;return e.includes(`pnpm`)?`pnpm`:e.includes(`yarn`)?`yarn`:e.includes(`bun`)?`bun`:`npm`}};function hn(e){let t=new qt(e),n=t.logger,r=new Ot(t.isQuiet,n.stdio),i=new Wt;return{cli:t,logger:n,workspace:r,prompt:i,initUseCase:new mn(n,r,i,new bt),helpUseCase:new Xt(n)}}let $,gn=!1;async function _n(){if(process.env.INIT_CWD)try{process.chdir(process.env.INIT_CWD)}catch{}let{cli:e,logger:n,initUseCase:r,helpUseCase:i}=hn(process.argv);$=n,vn(n),e.validationError&&(n.error(e.validationError),await i.execute(),await n.flush(),process.exit(1)),e.helpRequested&&(await i.execute(),await n.flush(),process.exit(0)),e.command!==`init`&&(e.command?n.error(`Unknown command: ${e.command}`):n.error(`Missing command.`),await i.execute(),await n.flush(),process.exit(1));try{await r.execute((0,t.shake)(e.initInput))||(await n.flush(),process.exit(1))}catch(e){try{n.fatal(`An unexpected error occurred`,e)}catch{}await n.flush(),process.exit(1)}}function vn(e){let t=async t=>{gn&&process.exit(t),gn=!0,setTimeout(()=>{process.exit(t)},2e3).unref(),e.interactiveStdout&&e.interactiveStdout(!1);try{e.cancel(`Operation cancelled.`),await e.flush()}catch(t){e.error&&e.error(`Logger failed during shutdown`,t)}finally{process.exit(t)}};process.on(`SIGINT`,()=>t(130)),process.on(`SIGTERM`,()=>t(143))}_n(),process.on(`unhandledRejection`,async e=>{if($){try{$.fatal(`Unhandled rejection`,e)}catch{}await $.flush()}else console.error(`Unhandled rejection`,e);process.exit(1)}),process.on(`uncaughtException`,async e=>{if($){try{$.fatal(`Uncaught exception`,e)}catch{}await $.flush()}else console.error(`Uncaught exception`,e);process.exit(1)});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arkenv/cli",
3
3
  "type": "module",
4
- "version": "0.2.3",
4
+ "version": "0.2.4",
5
5
  "description": "Interactive CLI for scaffolding ArkEnv projects",
6
6
  "bin": {
7
7
  "arkenv": "./dist/index.cjs"