@appinit/cli 0.0.0-canary-20251127090111
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 +111 -0
- package/bin/appinit.js +15 -0
- package/dist/index.js +25 -0
- package/package.json +50 -0
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.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {existsSync}from'fs';import He,{readFile}from'fs/promises';import*as G from'path';import G__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(G.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",Ge=S.env.APPINIT_DEBUG==="1",R=S.env.NO_COLOR!=="1";function g(e){let t=V[B];return V[e]<=t}function ze(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?" "+ze(n):"";return `${r} ${o} ${b.bold(t)}${i}`}var v={debug(e,t){Ge&&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 z(e){let t=G__default.resolve(e);for(let[n,a]of We)try{return await He.access(G__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=G__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 z(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:"0.0.0-canary-20251127090111"};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
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@appinit/cli",
|
|
3
|
+
"version": "0.0.0-canary-20251127090111",
|
|
4
|
+
"type": "module",
|
|
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
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"appinit": "./bin/appinit.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"bin"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@appinit/types": "0.0.0-canary-20251127090111",
|
|
23
|
+
"@appinit/utils": "0.0.0-canary-20251127090111",
|
|
24
|
+
"@appinit/resolver": "0.0.0-canary-20251127090111",
|
|
25
|
+
"@appinit/core": "0.0.0-canary-20251127090111"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"typescript": "^5.4.0",
|
|
29
|
+
"@types/node": "^20.0.0",
|
|
30
|
+
"vitest": "^1.5.0"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20.11.0"
|
|
37
|
+
},
|
|
38
|
+
"author": {
|
|
39
|
+
"name": "Pradeep Kumar",
|
|
40
|
+
"url": "git@fwak:frontendweb-ak/appinit.git"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"clean": "node ../../scripts/clean-dist.mjs dist",
|
|
44
|
+
"prebuild": "pnpm clean",
|
|
45
|
+
"build": "tsup src/index.ts --format esm --clean",
|
|
46
|
+
"dev": "tsup src/index.ts --format esm --watch",
|
|
47
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
48
|
+
"test": "vitest"
|
|
49
|
+
}
|
|
50
|
+
}
|