@appinit/cli 1.0.0 → 1.1.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.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # **@appinit/cli**
2
+
3
+ The official command-line interface for **AppInit OS**.
4
+
5
+ `@appinit/cli` provides all executable commands used to create, configure, and manage AppInit projects.
6
+ It connects the user experience (prompts, commands, flags) with the internal systems (core engine, resolver, and template/module execution pipeline).
7
+
8
+ This is the primary entrypoint for developers using AppInit.
9
+
10
+ ---
11
+
12
+ ## 📦 About
13
+
14
+ `@appinit/cli` enables:
15
+
16
+ - project creation
17
+
18
+ ```
19
+ appinit create <project-name>
20
+ ```
21
+
22
+ - feature / module installation
23
+
24
+ ```
25
+ appinit add <feature>
26
+ ```
27
+
28
+ - generating components, routes, API handlers
29
+
30
+ ```
31
+ appinit generate <component|page|api>
32
+ ```
33
+
34
+ - doctor, sync, upgrade, debugging tools
35
+
36
+ ```
37
+ appinit doctor
38
+ appinit sync
39
+ appinit upgrade
40
+ ```
41
+
42
+ - interactive prompts powered by **APS (AppInit Prompt Spec)**
43
+
44
+ - smart suggestions & stack detection
45
+
46
+ - safe, deterministic scaffolding
47
+
48
+ The CLI orchestrates interactions between:
49
+
50
+ - **resolver** (`@appinit/resolver`)
51
+ - **engine** (`@appinit/engine`)
52
+ - **core context** (`@appinit/core`)
53
+ - **types & specs** (`@appinit/types`)
54
+
55
+ ---
56
+
57
+ ## 📘 Usage
58
+
59
+ Global usage:
60
+
61
+ ```sh
62
+ npx appinit create my-app
63
+ ```
64
+
65
+ Local workspace usage:
66
+
67
+ ```sh
68
+ pnpm appinit create my-app
69
+ ```
70
+
71
+ Internal usage:
72
+
73
+ ```ts
74
+ import { runCLI } from "@appinit/cli";
75
+
76
+ runCLI(process.argv.slice(2));
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 🛠 Development
82
+
83
+ Build:
84
+
85
+ ```
86
+ pnpm -F @appinit/cli build
87
+ ```
88
+
89
+ Watch mode:
90
+
91
+ ```
92
+ pnpm -F @appinit/cli dev
93
+ ```
94
+
95
+ Type-check:
96
+
97
+ ```
98
+ pnpm -F @appinit/cli typecheck
99
+ ```
100
+
101
+ Run locally (linked):
102
+
103
+ ```
104
+ pnpm -F @appinit/cli appinit create test
105
+ ```
106
+
107
+ ---
108
+
109
+ ## 📄 License
110
+
111
+ Internal – © AppInit
package/bin/appinit.js ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+
3
+ import("../dist/index.js")
4
+ .then((mod) => {
5
+ if (mod && mod.start) {
6
+ mod.start(process.argv);
7
+ } else {
8
+ console.error("AppInit: No 'start' export found in CLI module.");
9
+ process.exit(1);
10
+ }
11
+ })
12
+ .catch((err) => {
13
+ console.error("AppInit CLI failed:", err);
14
+ process.exit(1);
15
+ });
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- export {};
2
- //# sourceMappingURL=index.d.ts.map
1
+ #!/usr/bin/env node
2
+ declare function start(argv: string[]): void;
3
+
4
+ export { start };
package/dist/index.js CHANGED
@@ -1,2 +1,25 @@
1
- console.log("Hello cli");
2
- export {};
1
+ #!/usr/bin/env node
2
+ import {existsSync}from'fs';import He,{readFile}from'fs/promises';import*as z from'path';import z__default from'path';import {isatty}from'tty';import p from'kleur';import {exec}from'child_process';import Ve,{promisify}from'util';import S from'process';import {spinner,multiselect,confirm,select,isCancel,cancel,text}from'@clack/prompts';import rt from'os';import nt from'mri';var M=process.stdout?.columns||80;process.stdout?.rows||24;var A=async e=>existsSync(e),F=e=>readFile(e,"utf8");function Oe(e){return e.replace(/\\/g,"/")}function x(e,t){return Oe(z.join(e,t))}var O=e=>e.replace(/-([a-zA-Z0-9])/g,(t,n)=>n.toUpperCase());var D=()=>!!process.env.npm_lifecycle_event;async function L(){try{if(process.env.DOCKER||process.env.CONTAINER||await A("/.dockerenv"))return !0;if(await A("/proc/1/cgroup")){let e=await F("/proc/1/cgroup");if(e.includes("docker")||e.includes("container"))return !0}return !1}catch{return false}}var U=e=>["turborepo","nx","monorepo"].includes(e);var d=()=>["CI","GITHUB_ACTIONS","BITBUCKET_PIPELINES","BUILDKITE","GITLAB_CI","CIRCLECI","JENKINS_HOME"].some(e=>process.env[e]==="true");async function De(e){return !((e??{}).nonInteractive||!process.stdin.isTTY||!process.stdout.isTTY||d()||D()||await L())}var _=De;var y=!!(process.stdout&&process.stdout.isTTY&&isatty(1));process.platform==="win32";var T={brand:p.cyan,primary:p.cyan,success:p.green,danger:p.red,warning:p.yellow,info:p.blue,dim:p.gray,red:p.red,green:p.green,yellow:p.yellow,blue:p.blue,cyan:p.cyan,magenta:p.magenta,gray:p.gray};({bgRed:p.bgRed,bgGreen:p.bgGreen,bgYellow:p.bgYellow,bgBlue:p.bgBlue,bgMagenta:p.bgMagenta,bgCyan:p.bgCyan,bgWhite:p.bgWhite,bgBlack:p.bgBlack});var b={bold:e=>p.bold(e),italic:e=>p.italic(e),underline:e=>p.underline(e),apply:(...e)=>t=>e.reduce((n,a)=>a(n),t)};var $={default:{brand:e=>p.cyan().bold(e),primary:e=>p.cyan(e),success:e=>p.green().bold(e),danger:e=>p.red().bold(e),warning:e=>p.yellow().bold(e),info:e=>p.blue(e),dim:e=>p.gray(e)},dark:{brand:e=>p.magenta().bold(e),primary:e=>p.white(e),success:e=>p.green(e),danger:e=>p.red(e),warning:e=>p.yellow(e),info:e=>p.cyan(e),dim:e=>p.gray(e)},neon:{brand:e=>p.magenta().bold().underline(e),primary:e=>p.green().bold(e),success:e=>p.cyan().bold(e),danger:e=>p.red().bold(e),warning:e=>p.yellow().bold().underline(e),info:e=>p.blue().bold(e),dim:e=>p.gray(e)},mono:{brand:e=>e,primary:e=>e,success:e=>e,danger:e=>e,warning:e=>e,info:e=>e,dim:e=>e}};var Ue="default";var l=new Proxy({},{get(e,t){return $[Ue][t]}});promisify(exec);var V={silent:0,error:1,warn:2,info:3,debug:4,success:5},B=S.env.APPINIT_LOG_LEVEL||"info",Be=S.env.APPINIT_LOG==="json",ze=S.env.APPINIT_DEBUG==="1",R=S.env.NO_COLOR!=="1";function g(e){let t=V[B];return V[e]<=t}function Ge(e){return e?Ve.inspect(e,{colors:R,depth:5}):""}function k(e,t,n){let a=new Date().toISOString();if(Be)return JSON.stringify({ts:a,level:e,message:t,meta:n});let o=e.toUpperCase();if(R)switch(e){case "debug":o=l.info(o);break;case "info":o=l.primary(o);break;case "warn":o=l.warning(o);break;case "error":o=l.danger(o);break;}let r=R?l.dim(a):a,i=n?" "+Ge(n):"";return `${r} ${o} ${b.bold(t)}${i}`}var v={debug(e,t){ze&&g("debug")&&console.debug(k("debug",e,t));},info(e,t){g("info")&&console.info(k("info",e,t));},warn(e,t){g("warn")&&console.warn(k("warn",e,t));},error(e,t){g("error")&&console.error(k("error",e,t));},raw(e){B!=="silent"&&console.log(e);},step(e){g("info")&&console.log(k("info",`\u25B6 ${e}`));},title(e){g("info")&&console.log(`
3
+ `+l.brand(b.bold(`\u{1F680} ${e}`))+`
4
+ `);},success(e){g("info")&&console.log(`
5
+ `+l.success(b.bold(`\u2714 ${e}`))+`
6
+ `);}};var We=[["pnpm","pnpm-lock.yaml"],["yarn","yarn.lock"],["bun","bun.lockb"],["npm","package-lock.json"]];async function G(e){let t=z__default.resolve(e);for(let[n,a]of We)try{return await He.access(z__default.join(t,a)),n}catch{}return "npm"}var Je=/[&|<>*?!%^"'$;{}()=@]/,Ye=/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;function H(e){let t=z__default.basename(e);return Ye.test(t)?`The folder name "${t}" is reserved on Windows.`:Je.test(e)?`The path contains forbidden characters: & | < > * ? ! % ^ " ' $ ; { } ( ) = @`:/[. ]$/.test(t)?"Folder name cannot end with a dot or space.":/\/\s|\s\//.test(e.replace(/\\/g,"/"))?"Folder path contains invalid spacing around slashes.":null}async function W(e){let t=process.stdout.columns||80,n="\u2500".repeat(Math.min(t,60));console.log(""),console.log(l.success(n)),console.log(l.success("\u2728 Project created successfully!")),console.log("");let a=await G(e),o="",r="";switch(a){case "pnpm":o="pnpm install",r="pnpm dev";break;case "yarn":o="yarn",r="yarn dev";break;case "bun":o="bun install",r="bun dev";break;default:case "npm":o="npm install",r="npm run dev";break}console.log(b.bold("\u{1F449} Next steps:")),console.log(` ${l.primary(`cd ${e}`)}`),console.log(` ${l.primary(o)}`),console.log(` ${l.primary(r)}`),console.log(""),console.log(l.dim("\u{1F4A1} You\u2019re ready to start building your app.")),console.log(l.dim("\u{1F4A1} Use `appinit add` to include packs, modules, and capabilities.")),console.log(l.dim("\u{1F4A1} Need help? Run `appinit help`")),console.log(""),console.log(l.success(n)),console.log("");}var qe=`
7
+ \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
8
+ \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D
9
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551
10
+ \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551
11
+ \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551
12
+ \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
13
+ `;async function K(){for(let e of qe.trimEnd().split(`
14
+ `))console.log(e);}var Qe="AppInit OS",Ze="Developer Operating System",J=false;async function Y(e){if(J||d()||!y)return;J=true,console.log(""),await _(e.flags??{})&&M>=72&&(await K(),console.log("")),console.log(l.brand(`${Qe} \u2014 ${Ze}`)),console.log(l.primary(l.dim(`v${e.version}`))),console.log("");}function q(e){console.log("AppInit OS \u2014 Developer Operating System"),console.log(`v${e}`),console.log(""),console.log(`Usage:
15
+ appinit create <project-name> Create project (guided or fast)
16
+ appinit add <capability> Add AI, DB, auth, UI, etc.
17
+ appinit doctor Analyze & validate project
18
+ appinit deploy Deploy via supported targets
19
+ appinit ai AI engineering helpers
20
+
21
+ Example:
22
+ appinit create my-app
23
+ `);}var et=process.platform==="win32";function Q(e){let{text:t,color:n="brand",indicator:a="dots",quiet:o}=e,r=!!(o||d()||!y);et&&!process.env.TERM_PROGRAM&&(r=true);let i=s=>typeof n=="function"?n(s):l[n]?l[n](s):T[n]?T[n](s):s;if(r)return console.log(l.dim(`\u203A ${t}`)),{start(){},stop(){},success(s){console.log(l.success(`\u2714 ${s??t}`));},error(s){console.log(l.danger(`\u2716 ${s??t}`));},message(s){console.log(l.dim(`\u203A ${s}`));},persist(s){console.log(s);},async run(s){try{let m=await s();return console.log(l.success(`\u2714 ${t}`)),m}catch(m){throw console.log(l.danger(`\u2716 ${t}`)),m}}};let c=spinner({indicator:a});return {start(s){c.start(i(s??t));},stop(s){c.stop(i(s??t));},success(s){c.stop(l.success(s??t));},error(s){c.stop(l.danger(s??t));},message(s){c.message(i(s));},persist(s){c.stop(s);},async run(s){try{let m=await s();return c.stop(l.success(t)),m}catch(m){throw c.stop(l.danger(t)),m}}}}function Z(e){let t=e.flags?.quiet||d()||!y;function n(o){let r=Q({text:o,color:"primary",quiet:t});return {start(i){r.start(i??o);},success(i){r.success(i??o);},error(i){r.error(i??o);},message(i){r.message(i);},async run(i){try{r.start(o);let c=await i();return r.success(o),c}catch(c){throw r.error(o),c}}}}function a(o){return console.log(l.brand(`
24
+ ${o}
25
+ `)),{title:o,step(r){return n(r)},complete(r){console.log(l.success(`\u2714 ${r??o}`));},error(r){console.log(l.danger(`\u2716 ${r??o}`));}}}return {group:a,step:n}}var X={version:"1.1.0"};function ee(){return ((process.argv[1]??"").split(/[/\\]/).pop()??"").replace(/\.(js|ts|mjs|cjs)$/i,"")||"appinit"}function w(){return X?.version}async function te(e){let t=process.cwd(),n=x(rt.homedir(),".appinit/cache");return {cwd:t,cacheDir:n,command:e.name,flags:e.flags,args:e.args,cliName:ee(),cliVersion:process.env.APPINIT_CLI_VERSION??w(),runtime:"cli",outputMode:e.flags.json?"json":"text",interactive:!e.flags.nonInteractive,logger:v,spinner:void 0,task:{createManager:()=>Z(e)}}}var oe=["help","version","nonInteractive","skipInstall","skipGit","skipDefaultPacks","dryRun","force","quiet"],ae=["template","projectType"],re={"non-interactive":"nonInteractive","skip-install":"skipInstall","skip-git":"skipGit","project-type":"projectType","skip-default-packs":"skipDefaultPacks","dry-run":"dryRun"},ne={help:"help",h:"help",version:"version",v:"version",json:"json",f:"force",q:"quiet","non-interactive":"nonInteractive","skip-install":"skipInstall","skip-git":"skipGit","project-type":"projectType","dry-run":"dryRun"},I={quiet:false,verbose:false,debug:false,nonInteractive:false,skipInstall:false,skipGit:false,json:"",projectType:"frontend",skipDefaultPacks:false,dryRun:false,force:false};function ie(e){let t=e.splice(2),n=nt(t,{boolean:oe.map(r=>r.toLowerCase()),string:ae.map(r=>r.toLowerCase()),default:I}),a=String(n._?.[0]??"help"),o=ot(n);return {name:a,args:t,flags:o}}function ot(e){let t={...I};for(let[n,a]of Object.entries(e)){if(n==="_"||typeof n!="string")continue;let o=at(n);if(o){if(n.startsWith("no-")){t[o]=false;continue}t[o]=a;}}return t}function at(e){if(!e)return "";if(e=e.replace(/^--?/,"").toLowerCase(),ne[e])return ne[e];if(e in re)return re[e];let t=O(e);return t in I||oe.includes(t)||ae.includes(t)?t:""}function se(e){isCancel(e)&&(cancel("Operation cancelled."),process.exit(1));}async function le(e){let t=await text({message:e.message,initialValue:e.initial});return isCancel(t)&&(cancel("Operation cancelled."),process.exit(1)),t}async function ce(e,t={}){let a=(typeof e.choices=="function"?await e.choices(t):e.choices??[]).map(r=>({label:r.label??r.title??String(r.value),value:r.value,hint:r.hint})),o=await select({...e,initialValue:e.initialValue,options:a});return isCancel(o)&&(cancel("Operation cancelled."),process.exit(1)),o}async function pe(e){let t=await confirm({...e,message:e.message});return se(t),t}async function ue(e,t={}){let a=(typeof e.choices=="function"?await e.choices(t):e.choices??[]).map(r=>({label:r.label??r.title??String(r.value),value:r.value,hint:r.hint})),o=await multiselect({...e,options:a});return se(o),o}async function f(e,t={},n){let a={...t};for(let o of e){if(typeof o.when=="function"&&!await o.when(a))continue;let r;switch(o.type){case "text":r=await le(o);break;case "select":r=await ce(o,a);break;case "confirm":case "toggle":r=await pe(o);break;case "multiselect":r=await ue(o,a);break;default:throw new Error(`Unsupported prompt type "${o.type}`)}if(typeof o.format=="function"&&(r=o.format(r)),typeof o.validate=="function"){let i=await o.validate(r);if(i!==true)throw new Error(`Validation failed for "${o.name}": ${i}`)}a[o.name]=r;}return a}var me=[{label:"React",value:"react",hint:"**The most popular library.** Component-based UI with a huge ecosystem (often paired with Vite or Next.js)."},{label:"Next.js",value:"next",hint:"**Production-ready full-stack React framework.** Excellent for SSR, routing, and APIs."},{label:"Vue",value:"vue",hint:"**Progressive and approachable framework.** Fully-featured with great official libraries (Vue Router, Pinia)."},{label:"Svelte",value:"svelte",hint:"**The compiler.** No virtual DOM. Generates highly optimized vanilla JS for faster runtime performance."},{label:"Angular",value:"angular",hint:"**Opinionated, full-featured framework.** Best for large-scale enterprise applications with built-in tooling."},{label:"SolidJS",value:"solid",hint:"**Fine-grained reactivity.** High performance using compiled JSX and actual DOM nodes, no Virtual DOM."},{label:"Qwik",value:"qwik",hint:"Focuses on **Resumability** to achieve near-instant loading times by lazy loading and resuming application state."},{label:"Astro",value:"astro",hint:"An **all-in-one framework** for building fast, content-focused websites using 'Islands of Interactivity'."},{label:"Framer Motion",value:"framer",hint:"Used primarily for **animation and interactive design.** Not a general-purpose framework, but a powerful animation library."},{label:"React Router",value:"react-router",hint:"A declarative routing library for React (often associated with **Remix** full-stack framework)."},{label:"None",value:"none",hint:"**Vanilla JavaScript/TypeScript.** No framework or library required."}];var de=[{label:"Next.js",value:"next",hint:"**The leading React full-stack framework.** Excellent for server-side rendering (SSR), static site generation (SSG), and API routes."},{label:"Remix",value:"react-router",hint:"**Full-stack React framework built on web standards.** Focuses on route-level data fetching and seamless integration with React Router."},{label:"SvelteKit",value:"svelte",hint:"**The full-stack Svelte framework.** Extremely fast, uses a compiler approach, and offers flexible adapters for deployment."},{label:"Nuxt (Vue)",value:"vue",hint:"**The full-stack Vue framework.** Rich feature set including file-system routing, auto-imports, and powerful module ecosystem."}];var fe=[{label:"Express",value:"express",hint:"**Most popular Node backend.** Simple routing, middleware based, huge ecosystem."},{label:"Koa",value:"koa",hint:"A **minimalist framework** designed by the Express team. Smaller footprint, uses `async/await` for cleaner middleware flow and better error handling."},{label:"Fastify",value:"fastify",hint:"**High-performance & plugin-based.** Best for APIs requiring throughput."},{label:"NestJS",value:"nest",hint:"**Enterprise-grade architecture.** Built-in DI, modules, and scalable structure."},{label:"AdonisJS",value:"adonis",hint:"A **full-featured, opinionated MVC framework** inspired by Laravel/Rails. Comes with its own ORM, CLI, and authentication built-in."},{label:"Hono (Edge-optimized)",value:"hono",hint:"**Tiny + ultra fast for edge runtimes.** Perfect for Cloudflare, Deno, Bun."},{label:"Elysia (Bun)",value:"elysia",hint:"**Deep Bun integration.** Modern type-safe router + middleware."},{label:"None",value:"none",hint:"Choose this if you intend to use a different framework or build your server from scratch."}],ge=[{label:"REST",value:"rest",hint:"**Standard + universal.** Works everywhere and easy to scale gradually."},{label:"tRPC",value:"trpc",hint:"**Full end-to-end types.** Great with React/Next fullstack workflows."},{label:"GraphQL",value:"graphql",hint:"**Flexible querying.** Best for complex relational or mobile apps."}],he=[{label:"Monolith",value:"monolith",hint:"**Single, unified unit.** All components (UI, logic, data) are in one codebase and deployed together. **Simple to develop initially**."},{label:"Modular",value:"modular",hint:"A Monolith where code is **logically separated** into independent modules (features/domains) within the *same* codebase. Easier to maintain than a traditional Monolith."},{label:"Microservices",value:"microservices",hint:"**Independent, specialized services.** Each feature runs as its own separate application with its own database, communicating via APIs. **Highly scalable and fault-tolerant**."},{label:"None",value:"none",hint:"No default architecture"}];var ye={name:"backend",priority:40,condition:(e,t)=>["next","framer","nuxt"].includes(t.frontendFramework)?false:["backend","fullstack"].includes(t.projectType??""),handler:async(e,t,n)=>{if(!e.interactive){let r=e.savedConfig??{};return {backendFramework:n.backendFramework??r.backendFramework??"express",apiStyle:n.apiStyle??r.apiStyle??"rest",backendMode:n.backendMode??r.backendMode??"none"}}return await f([{type:"select",name:"backendFramework",message:"\u{1F9F1} Backend Framework:",choices:fe,initialValue:n.backendFramework??"express"},{type:"select",name:"apiStyle",message:"\u{1F50C} API Style:",choices:ge,initialValue:n.apiStyle??"rest"},{type:"select",name:"backendMode",message:"\u2699\uFE0F Backend Architecture Mode:",choices:he,initialValue:n.backendMode??"none"}],n)}};var be={name:"environment",priority:55,handler:async(e,t,n)=>{let a=e.interactive,o={packageManager:n.packageManager??"pnpm",workspace:n.workspace??"single"};return a?await f([{type:"select",name:"packageManager",message:"\u{1F4E6} Package manager:",choices:pt,initial:n.packageManager??"pnpm"},{type:"select",name:"workspace",message:"\u{1F9E9} Workspace type:",choices:ut,initial:n.workspace??"single"}],n):o}},pt=[{label:"npm",value:"npm",hint:"The **default and most widely-adopted** package manager for Node.js. Great for simplicity and maximum package compatibility."},{label:"pnpm",value:"pnpm",hint:"Focuses on **disk-space efficiency and speed** using content-addressable storage (hard links). Excellent for monorepos."},{label:"yarn",value:"yarn",hint:"Known for **speed, reliability, and monorepo support** (workspaces). Yarn 2+ introduced the Plug'n'Play (PnP) architecture."},{label:"bun",value:"bun",hint:"A **blazingly fast** all-in-one JavaScript runtime, bundler, and package manager. Best for performance-critical or new projects."}],ut=[{label:"Single project",value:"single",hint:"A **traditional project structure** where all code lives in one package. Simple and easy to manage for small-to-medium applications."},{label:"Turborepo (monorepo)",value:"turborepo",hint:"A fast, lightweight build system by Vercel for monorepos. Focuses on **caching and remote computation**."},{label:"Nx (monorepo)",value:"nx",hint:"A **powerful, full-featured monorepo toolkit** that uses a deep graph to understand project dependencies for faster builds and better tooling."},{label:"Lerna (monorepo)",value:"lerna",hint:"A classic tool to manage JavaScript monorepos. Best for **publishing multiple packages** from a single repository."}];var ve={name:"framework",priority:2,condition:(e,t)=>t.projectType==="frontend"||t.projectType==="fullstack",handler:async(e,t,n)=>{let a=e.interactive,o=n.projectType,r=n.frontendFramework??t.frontendFramework??"react",i=o==="fullstack";return a?{frontendFramework:(await f([{type:"select",name:"frontendFramework",message:`\u2699\uFE0F ${i?"Fullstack":"Frontend"} Framework:`,choices:i?de:me,initial:r??(i?"next":"react")}],n)).frontendFramework}:{frontendFramework:r}}};var we=[{label:"MIT",value:"MIT",hint:"A short, permissive license with conditions only requiring preservation of copyright and license notices. Great for maximum compatibility."},{label:"Apache-2.0",value:"Apache-2.0",hint:"A permissive license similar to MIT, but providing an express grant of patent rights from contributors to users."},{label:"GPL-3.0",value:"GPL-3.0",hint:"A strong copyleft license. If you modify or redistribute code under this license, you must also release your source code under GPL-3.0."},{label:"Unlicense",value:"Unlicense",hint:"Dedicates the work to the public domain, offering the fewest restrictions possible."},{label:"Other",value:"Other",hint:"Choose this if your license is not listed above and you will provide details later."}];var ke=[{label:"Frontend Application",value:"frontend",hint:"**A pure client-side application (SPA).** Good for UIs, dashboards, and static sites that consume an existing external API."},{label:"Backend API",value:"backend",hint:"A **server-only project** dedicated to data, business logic, and API endpoints (e.g., using Node.js, Python, or Go)."},{label:"Fullstack (UI + API)",value:"fullstack",hint:"**The modern monolith.** A single project containing both the user interface and the API/server logic (e.g., Next.js, SvelteKit)."},{label:"Library / SDK",value:"library",hint:"A **reusable package** of code meant to be published to NPM and used by other applications (e.g., component library, utility functions)."},{label:"CLI Tool",value:"cli",hint:"A **command-line application** that runs in the terminal. Excellent for automation, deployment, or scaffold generation."}];var j=e=>String(e).trim().toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-_]/g,"").replace(/^-+|-+$/g,"");var h=(...e)=>e.find(t=>t!=null&&t!=="");function xe(e,t,n){let a=n.projectType??t.projectType;return a==="library"||a==="cli"||U(t?.workspaceTool)}var P=e=>{if(typeof e!="string")return null;let t=e.trim().replace(/^@/,"");return t?`@${t}`:null};function Se(e){if(!e||typeof e!="string")return "Name cannot be empty";let t=e.trim();if(!t.length)return "Name cannot be empty";if(/\s/.test(t))return "Spaces are not allowed \u2014 use dash or underscore";if(/[A-Z]/.test(t))return "Use lowercase letters only (npm package rule)";if(/[~'!()*]/.test(t))return "Name contains forbidden characters ~ ' ! ( ) *";if(/[<>:\"\\|?*]/.test(t))return 'Name contains Windows-forbidden characters < > : " \\ | ? *';if(/[/.]$/.test(t))return "Name cannot end with a dot or slash";if(t.startsWith("@")){if(!/^@[a-z0-9\-_]+\/[a-z0-9\-_]+$/.test(t))return "Invalid scoped package. Use @scope/name"}else if(!/^[a-z0-9\-_]+$/.test(t))return "Use only letters, numbers, dash (-), and underscore (_)";return ["node_modules","favicon","core","con","aux","nul","prn"].includes(t.toLowerCase())?`"${t}" is a reserved name`:true}var Pe={name:"meta",priority:1,before(e){console.log("I am meta pack");},handler:async(e,t,n)=>{let a=e.savedConfig??{},o=e.interactive,r={projectName:h(t.projectName,n.projectName,a.projectName,"appinit-app"),projectType:h(t.projectType,n.projectType,a.projectType,"frontend"),description:h(t.description,n.description,a.description,""),licenseType:h(t.licenseType,n.licenseType,a.licenseType,"MIT"),author:h(t.author,n.author,a.author,"appinit"),packageScope:P(h(t.packageScope,n.packageScope,a.packageScope,"@"))};if(!o)return r;let i=[];(!t.projectName||t.projectName.trim()==="")&&i.push({type:"text",name:"projectName",message:"\u{1F9F1} Project name:",initial:a.projectName??"my-appinit-app",format:s=>s?j(s):null,validate:s=>Se(j(s||""))}),i.push({type:"text",name:"description",message:"\u{1F4DD} Short description:",initial:r.description,defaultValue:""},{type:"text",name:"author",message:"\u{1F464} Author (name/email):",initial:r.author,defaultValue:"appinit"},{type:"select",name:"licenseType",message:"\u{1F4DC} License:",choices:we,initial:r.licenseType},{type:"select",name:"projectType",message:"\u{1F4E6} Project type:",choices:ke,initial:r.projectType}),xe(e,t,n)&&i.push({type:"text",name:"packageScope",message:"\u{1F4E6} Package scope (optional, without @):",initial:a.packageScope?.replace?.(/^@/,"")??"",format:s=>s?P(s):null});let c=await f(i,n);return c.packageScope&&(c.packageScope=P(c.packageScope)),{...r,...c}}};var mt=[Pe,ve,be,ye];async function Ce(e,t){let n=e.args[1],a=e.logger,o=[],r={},i={projectName:n,projectType:e.flags.projectType};e.flags.skipDefaultPacks||(o=[...mt]),Array.isArray(t)&&(o=[...o,...t]),o.sort((c,s)=>(c.priority??100)-(s.priority??100)),Object.freeze(o),i.hooks?.beforeAll&&await i.hooks.beforeAll(i,r);for(let c of o)try{if(c.condition&&!await c.condition(i,r)){a.info(`\u23ED\uFE0F Skipping pack: ${c.name}`);continue}i.hooks?.beforeEach&&await i.hooks.beforeEach(c,i,r),c.before&&await c.before(e,i,r);let s=await c.handler(e,i,r);console.log("PACK-",r,c.name,s),s&&typeof s=="object"&&Object.assign(r,s),c.after&&await c.after(e,i,r),i.hooks?.afterEach&&await i.hooks.afterEach(c,i,r);}catch(s){throw a.error(`\u274C Pack failed: "${c.name}"`),a.error(`Reason: ${s.message}`),s}return i.hooks?.afterAll&&await i.hooks.afterAll(i,r),r}var Ae={name:"create",description:"Create new AppInit project",async run(e){let {args:t,task:n,logger:a}=e,o=t[1]??"";n.createManager();await Y({version:w()});let i;try{i=await Ce(e);}catch(je){a?.error("\u274C Prompt engine failed"),a?.error(String(je)),process.exit(1);}console.log("An",i),e.answers=i;let c=i.projectName,s=x(e.cwd,c),m=H(s);m&&(a?.error(`\u274C Invalid target directory: ${s}`),a?.error(`Reason: ${m}`),process.exit(1)),console.log("COnfig",e),W(o);}};var Te={name:"help",description:"",async run(e){return q(w())}};var Re={create:Ae,help:Te};async function Ie(e,t){let n=Re[e];return n||(v.error(`Unknown command: ${e}`),process.exit(1)),n.run(t)}function Ne(e){return e?["init","new"].includes(e)?"create":e.toLowerCase():"help"}async function Ee(e){let t=ie(e),n=Ne(t.name),a=await te(t);try{await Ie(n,a);}catch(o){v.error(`CLI command failed, ${o}`),process.exitCode=1;}}function To(e){Ee(e);}export{To as start};
package/package.json CHANGED
@@ -1,28 +1,49 @@
1
1
  {
2
2
  "name": "@appinit/cli",
3
- "version": "1.0.0",
4
- "description": "The command-line interface for Forge AI, driving scaffolding and management.",
5
- "private": false,
3
+ "version": "1.1.0",
6
4
  "type": "module",
7
- "main": "dist/index.js",
8
- "types": "dist/index.d.ts",
5
+ "private": false,
6
+ "description": "The command-line interface for Appinit OS.",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
9
14
  "bin": {
10
- "forge": "./bin/cli.js"
15
+ "appinit": "./bin/appinit.js"
11
16
  },
12
- "keywords": [],
13
- "author": "frontendweb-sg",
14
- "license": "ISC",
17
+ "files": [
18
+ "dist"
19
+ ],
15
20
  "dependencies": {
16
- "@appinit/ui": "1.0.0",
17
- "@appinit/engine": "1.0.0"
21
+ "@clack/prompts": "^0.11.0",
22
+ "kleur": "^4.1.5",
23
+ "mri": "^1.2.0",
24
+ "zod": "^4.1.12"
25
+ },
26
+ "devDependencies": {
27
+ "typescript": "^5.4.0",
28
+ "@types/node": "^20.0.0",
29
+ "vitest": "^1.5.0"
18
30
  },
19
31
  "publishConfig": {
20
32
  "access": "public"
21
33
  },
34
+ "engines": {
35
+ "node": ">=20.11.0"
36
+ },
37
+ "author": {
38
+ "name": "Pradeep Kumar",
39
+ "url": "git@fwak:frontendweb-ak/appinit.git"
40
+ },
22
41
  "scripts": {
23
- "build": "tsc",
24
- "dev": "tsx src/index.ts",
25
- "start": "node dist/index.js",
26
- "clean": "rm -rf dist"
42
+ "clean": "node ../../scripts/clean-dist.mjs dist",
43
+ "prebuild": "pnpm clean",
44
+ "build": "tsup src/index.ts --format esm --clean",
45
+ "dev": "tsup src/index.ts --format esm --watch",
46
+ "typecheck": "tsc -p tsconfig.json --noEmit",
47
+ "test": "vitest"
27
48
  }
28
49
  }
@@ -1,4 +0,0 @@
1
-
2
- > @appinit/cli@1.0.0 build /home/runner/work/appinit/appinit/packages/cli
3
- > tsc
4
-
package/bin/cli.js DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // This ensures the node environment runs the compiled JavaScript logic.
4
- // The build process (npm run build) compiles src/index.ts to dist/index.js.
5
- import('./dist/index.js');
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=add.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=create.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=doctor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
File without changes
File without changes
File without changes
File without changes
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- console.log("Hello cli")
package/tsconfig.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "baseUrl": ".",
5
- "rootDir": "./src",
6
- "outDir": "./dist",
7
- "noEmit": false, // Set to false so 'tsc' generates output files
8
- "module": "NodeNext", // Use NodeNext/ESNext for modern Node.js CLI projects
9
- "moduleResolution": "NodeNext",
10
- "declaration": true,
11
- "declarationMap": true
12
- },
13
- "include": ["src/**/*"],
14
- "exclude": ["node_modules", "dist"]
15
- }