zerostart-cli 0.0.39 → 0.0.41

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 CHANGED
@@ -1,270 +1,195 @@
1
1
  # ZeroStart CLI 🚀
2
2
 
3
- Create and deploy a complete project with **one command**.
3
+ > **Create and deploy a complete project in seconds.**
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/zerostart-cli.svg)](https://www.npmjs.com/package/zerostart-cli)
6
- [![npm downloads](https://img.shields.io/npm/dm/zerostart-cli.svg)](https://www.npmjs.com/package/zerostart-cli)
5
+ [![npm version](https://img.shields.io/npm/v/zerostart-cli?color=cyan&label=version&style=flat-square)](https://www.npmjs.com/package/zerostart-cli)
6
+ [![npm downloads](https://img.shields.io/npm/dm/zerostart-cli?color=blue&style=flat-square)](https://www.npmjs.com/package/zerostart-cli)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](./LICENSE)
8
+
9
+ **ZeroStart** is a developer CLI that scaffolds a fully structured project, initializes Git with human-style commits, and optionally pushes to GitHub or deploys to Vercel — all from a single interactive command.
10
+
11
+ 🌐 **Website:** [zerostart.zeroonedevs.in](https://zerostart.zeroonedevs.in)
12
+ 📦 **npm:** [npmjs.com/package/zerostart-cli](https://www.npmjs.com/package/zerostart-cli)
7
13
 
8
14
  ---
9
15
 
10
16
  ## 📦 Installation
11
17
 
12
- **⚠️ IMPORTANT: Use the `-g` flag to install globally!**
18
+ Install globally to use the `zerostart` command anywhere:
13
19
 
14
20
  ```bash
15
21
  npm install -g zerostart-cli
16
22
  ```
17
23
 
18
- > **Why `-g`?** The `-g` flag installs ZeroStart globally on your system, making the `zerostart` command available from anywhere in your terminal. Without it, you'll only get `node_modules` and `package-lock.json` files, and the CLI won't work!
24
+ > ⚠️ **Must use `-g`** without the global flag, the CLI won't be available in your terminal.
19
25
 
20
26
  ---
21
27
 
22
- ## 🚀 Quick Start
23
-
24
- After installing globally, create a new project:
25
-
26
- ```bash
27
- zerostart my-awesome-project
28
- ```
29
-
30
- Or simply run:
28
+ ## Quick Start
31
29
 
32
30
  ```bash
33
31
  zerostart
34
32
  ```
35
33
 
36
- Then follow the interactive prompts!
34
+ That's it. Follow the interactive wizard to set up your project, push to GitHub, and optionally deploy to Vercel.
37
35
 
38
36
  ---
39
37
 
40
- ## ✨ Features
38
+ ## ✨ What It Does
41
39
 
42
- - 🎯 **Interactive CLI** - Guided prompts for project setup with **Back** button support
43
- - 🌐 **Modern Templates** - React, TypeScript, HTML/CSS, C++, Java, Python
44
- - 🚀 **Online GDB Support** - Instant browser redirect for Java, C++, and Python
45
- - 📦 **Auto-scaffolding** - Complete project structure generation
46
- - 📝 **Documentation** - Auto-generated README, roadmap, .gitignore
47
- - 🐙 **GitHub Integration** - Secure PAT-based creation and push
48
- - 🔒 **Vercel Deployment** - Instant deployment prompt for HTML projects
40
+ | Step | What Happens |
41
+ | :--- | :--- |
42
+ | 🎯 Pick a category | Web Dev or Competitive Programming |
43
+ | 🔤 Pick a language | React, TypeScript, HTML/CSS, C++, Java, Python |
44
+ | 📝 Name your project | Enter any project name |
45
+ | 🐙 GitHub integration | Optionally create a repo and push with real commits |
46
+ | 🚀 Deploy or run locally | Deploy to Vercel instantly, or get `cd` instructions |
49
47
 
50
48
  ---
51
49
 
52
- ## 📖 Usage
50
+ ## 🛠 Commands
53
51
 
54
- ### Basic Usage
52
+ ### Core
55
53
 
56
- ```bash
57
- # Create a project with interactive prompts
58
- zerostart
54
+ | Command | Description |
55
+ | :--- | :--- |
56
+ | `zerostart` | Launch the full interactive wizard |
57
+ | `zerostart init [name]` | Start a new project (with optional name) |
58
+ | `zerostart deploy` | Deploy the current project (Vercel / Netlify) |
59
+ | `zerostart git` | Initialize Git + optionally push to GitHub |
60
+ | `zerostart docs` | Open the ZeroStart website in your browser |
61
+ | `zerostart update` | Check for CLI updates |
59
62
 
60
- # Create a project with a specific name
61
- zerostart my-project-name
63
+ ### Shortcut Commands
62
64
 
63
- # Check version
64
- zerostart --version
65
+ Skip the wizard — create a project in one line:
65
66
 
66
- # Get help
67
- zerostart --help
67
+ ```bash
68
+ zerostart dsa-cpp my-solution
69
+ zerostart web-react my-portfolio
70
+ zerostart ml-py my-model
68
71
  ```
69
72
 
70
- ### Shortcut Commands ⚡
73
+ **All shortcuts:**
71
74
 
72
- Skip the wizard and build instantly:
73
-
74
- | Category | Shortcut Commands |
75
+ | Category | Commands |
75
76
  | :--- | :--- |
76
77
  | **DSA Practice** | `dsa-py`, `dsa-java`, `dsa-cpp` |
77
78
  | **Web Apps** | `web-react`, `web-html`, `web-py`, `web-java`, `web-cpp` |
78
79
  | **CLI Tools** | `cli-py`, `cli-java`, `cli-cpp` |
79
80
  | **ML Projects** | `ml-py`, `ml-java`, `ml-cpp` |
80
81
 
81
- **Example Usage**:
82
- ```bash
83
- zerostart dsa-cpp my-calculator
84
- ```
85
-
86
- ### Standalone Deployment
82
+ ### Dev Tools
87
83
 
88
- ```bash
89
- # Deploy the current project to Vercel
90
- zerostart deploy-vercel
91
- ```
84
+ | Command | Description |
85
+ | :--- | :--- |
86
+ | `zerostart dev` | Start the local development server |
87
+ | `zerostart build` | Build the project for production |
88
+ | `zerostart clean` | Remove `node_modules`, `dist`, cache files |
89
+ | `zerostart env` | Manage `.env` variables interactively |
90
+ | `zerostart test` | Set up a testing framework |
91
+ | `zerostart add [feature]` | Add features to an existing project |
92
92
 
93
- ### Example Workflow
93
+ ### Deployment
94
94
 
95
- ```bash
96
- $ zerostart my-web-app
97
-
98
- ZeroStart: Project Starter AI
99
-
100
- ? Select Programming Language: › Node.js
101
- ? Select Project Type: › Web App
102
- ? Select Repository Visibility: › Private
103
- ? Create GitHub Repository? › Yes
104
- ? Enter GitHub Personal Access Token: ********
105
-
106
- ✔ Generating project structure...
107
- ✔ Initializing Git...
108
- ✔ Creating GitHub Repository...
109
- ✔ Pushing to GitHub...
110
- ✔ Project 'my-web-app' created successfully!
111
-
112
- Path: C:\Users\YourName\my-web-app
113
- To get started:
114
- cd my-web-app
115
- code .
116
- ```
95
+ | Command | Description |
96
+ | :--- | :--- |
97
+ | `zerostart deploy-vercel` | Deploy current project to Vercel |
98
+ | `zerostart deploy-netlify` | Deploy current project to Netlify |
117
99
 
118
100
  ---
119
101
 
120
- ## 🛠️ Requirements
102
+ ## 🗂 Project Structure
121
103
 
122
- - **Node.js** (v18 or higher)
123
- - **Git** (must be installed and in PATH)
124
- - **GitHub Personal Access Token** (optional, for GitHub integration)
104
+ Every project created by ZeroStart includes:
125
105
 
126
- ### Getting a GitHub Token
106
+ ```
107
+ my-project/
108
+ ├── src/ ← Language-specific source files
109
+ ├── .gitignore
110
+ ├── README.md ← Auto-generated project README
111
+ ├── roadmap.md ← Editable project roadmap
112
+ └── (config files based on template)
113
+ ```
127
114
 
128
- 1. Go to [GitHub Settings → Developer settings → Personal access tokens](https://github.com/settings/tokens)
129
- 2. Click "Generate new token (classic)"
130
- 3. Select scopes: `repo` (full control of private repositories)
131
- 4. Copy the token and use it when prompted by ZeroStart
115
+ **Git history (2 human-style commits):**
116
+ ```
117
+ feat: initialize project with ZeroStart CLI
118
+ chore: add project structure and configuration files
119
+ ```
132
120
 
133
121
  ---
134
122
 
135
- ## 🏗️ What Gets Created
123
+ ## 🧰 Requirements
136
124
 
137
- ZeroStart automatically generates:
125
+ - **Node.js** v18 or higher
126
+ - **Git** — must be installed and in your PATH
127
+ - **GitHub PAT** — optional, only needed for GitHub push. [Create one here →](https://github.com/settings/tokens/new?scopes=repo&description=ZeroStart%20CLI%20Token)
138
128
 
129
+ ---
130
+
131
+ ## 🐛 Troubleshooting
132
+
133
+ **`zerostart: command not found`**
134
+ ```bash
135
+ # You missed the -g flag. Fix it:
136
+ npm install -g zerostart-cli
139
137
  ```
140
- my-project/
141
- ├── src/
142
- │ └── (language-specific files)
143
- ├── .gitignore
144
- ├── README.md
145
- ├── roadmap.md
146
- └── (additional config files based on language/type)
147
- ```
148
138
 
149
- Plus:
150
- - Git repository initialized
151
- - ✅ Initial commit made
152
- - ✅ GitHub repository created (if requested)
153
- - Code pushed to GitHub (if requested)
139
+ **`Git is not installed`**
140
+ Download and install Git from [git-scm.com](https://git-scm.com/)
141
+
142
+ **`GitHub repository creation failed`**
143
+ Make sure your token has the `repo` scope. [Generate a new token →](https://github.com/settings/tokens)
154
144
 
155
145
  ---
156
146
 
157
147
  ## 🔧 Development
158
148
 
159
- Want to contribute or modify ZeroStart?
160
-
161
- ### Setup
162
-
163
149
  ```bash
164
- # Clone the repository
165
- git clone https://github.com/yourusername/zerostart-cli.git
166
- cd zerostart-cli
150
+ # Clone the repo
151
+ git clone https://github.com/KushaalNayak/ZeroStart-cli.git
152
+ cd ZeroStart-cli
167
153
 
168
154
  # Install dependencies
169
155
  npm install
170
156
 
171
- # Build the project
157
+ # Build
172
158
  npm run compile
173
159
 
174
- # Test locally
175
- node ./out/cli.js --help
160
+ # Run locally
161
+ node ./out/cli.js
176
162
  ```
177
163
 
178
- ### Project Structure
164
+ ### Source Structure
179
165
 
180
166
  ```
181
167
  src/
182
- ├── cli.ts # CLI entry point
183
- ├── extension.ts # VS Code extension entry (legacy)
184
- ├── types.ts # TypeScript interfaces
168
+ ├── cli.ts CLI entry point & all commands
169
+ ├── types.ts TypeScript enums & interfaces
185
170
  ├── managers/
186
- │ ├── TemplateManager.ts # Project scaffolding
187
- │ ├── GitManager.ts # Git operations
188
- └── ProjectManager.ts # Main orchestration
171
+ │ ├── TemplateManager.ts Project file scaffolding
172
+ │ ├── GitManager.ts Git & GitHub operations
173
+ ├── ProjectManager.ts Orchestration
174
+ │ ├── VercelManager.ts ← Vercel deployment
175
+ │ └── NetlifyManager.ts ← Netlify deployment
189
176
  └── services/
190
- ├── GitHubServiceCLI.ts # GitHub API (CLI)
191
- └── GitHubService.ts # GitHub API (VS Code)
177
+ └── GitHubServiceCLI.ts GitHub REST API client
192
178
  ```
193
179
 
194
180
  ---
195
181
 
196
- ## 📝 Publishing Updates
197
-
198
- ```bash
199
- # Update version
200
- npm version patch # or minor, or major
201
-
202
- # Rebuild
203
- npm run compile
204
-
205
- # Publish to npm
206
- npm publish
207
- ```
208
-
209
- ---
210
-
211
- ## 🐛 Troubleshooting
212
-
213
- ### "zerostart: command not found"
214
-
215
- **Problem:** You installed without the `-g` flag.
216
-
217
- **Solution:**
218
- ```bash
219
- # Remove local installation
220
- rm -rf node_modules package-lock.json
221
-
222
- # Install globally
223
- npm install -g zerostart-cli
224
- ```
225
-
226
- ### "Git is not installed"
227
-
228
- **Problem:** Git is not in your system PATH.
229
-
230
- **Solution:** Install Git from [git-scm.com](https://git-scm.com/) and ensure it's in your PATH.
231
-
232
- ### "GitHub repository creation failed"
233
-
234
- **Problem:** Invalid or insufficient GitHub token permissions.
235
-
236
- **Solution:** Generate a new token with `repo` scope from GitHub settings.
237
-
238
- ---
239
-
240
182
  ## 📄 License
241
183
 
242
- MIT
184
+ MIT © [ZeroStart](https://zerostart.zeroonedevs.in)
243
185
 
244
186
  ---
245
187
 
246
188
  ## 🤝 Contributing
247
189
 
248
- Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
190
+ PRs and issues are welcome!
191
+ Open one at [github.com/KushaalNayak/ZeroStart-cli](https://github.com/KushaalNayak/ZeroStart-cli/issues)
249
192
 
250
193
  ---
251
194
 
252
- ## 📧 Support
253
-
254
- - 📦 npm: [zerostart-cli](https://www.npmjs.com/package/zerostart-cli)
255
- - 🐙 GitHub: [Issues](https://github.com/yourusername/zerostart-cli/issues)
256
-
257
- ---
258
-
259
- **Made with ❤️ by ZeroStart Team**
260
-
261
-
262
-
263
-
264
-
265
-
266
-
267
-
268
-
269
-
270
-
195
+ > **Made with ❤️ by the ZeroStart team — [zerostart.zeroonedevs.in](https://zerostart.zeroonedevs.in)**
package/out/cli.js CHANGED
@@ -57,7 +57,9 @@ function showBanner() {
57
57
  console.log(chalk_1.default.cyan('------------------------------------------------------------'));
58
58
  console.log(chalk_1.default.bold.white(' ZeroStart CLI '));
59
59
  console.log(chalk_1.default.gray(' Create and deploy projects in seconds '));
60
+ console.log(chalk_1.default.gray(' 📘 Docs: ') + chalk_1.default.cyan.underline('https://zerostart.zeroonedevs.in'));
60
61
  console.log(chalk_1.default.cyan('------------------------------------------------------------'));
62
+ console.log();
61
63
  }
62
64
  function openUrl(url) {
63
65
  const start = (process.platform == 'darwin' ? 'open' : process.platform == 'win32' ? 'start' : 'xdg-open');
@@ -75,6 +77,7 @@ function showGitHubTokenHelp() {
75
77
  openUrl(tokenUrl);
76
78
  }
77
79
  async function initializeProject(name, language, type, options) {
80
+ // Returns the project path so the wizard can continue with deploy steps
78
81
  const cwd = process.cwd();
79
82
  const projectPath = path.join(cwd, name);
80
83
  if (fs.existsSync(projectPath)) {
@@ -96,17 +99,23 @@ async function initializeProject(name, language, type, options) {
96
99
  const gitHubService = options.githubToken ? new GitHubServiceCLI_1.GitHubServiceCLI(options.githubToken) : null;
97
100
  if (!await gitManager.checkGitInstalled()) {
98
101
  spinner.fail(chalk_1.default.red('Git is not installed!'));
99
- return;
102
+ return projectPath;
100
103
  }
104
+ // ── Step 1: Create project files ────────────────────────────────────
101
105
  spinner.text = chalk_1.default.cyan('Generating project structure...');
102
106
  await templateManager.createProjectStructure(config);
103
107
  spinner.succeed(chalk_1.default.green('Project structure created'));
104
108
  if (type !== types_1.ProjectType.DSAPractice) {
109
+ // ── Step 2: Git init + FIRST human commit ────────────────────────
105
110
  spinner.start(chalk_1.default.cyan('Initializing Git repository...'));
106
111
  await gitManager.init(projectPath);
107
- await gitManager.commit(projectPath, "Initial commit");
108
- spinner.succeed(chalk_1.default.green('Git repository initialized'));
112
+ // First commit: just README and .gitignore (base project skeleton)
113
+ await gitManager.commitSelective(projectPath, ['README.md', '.gitignore', 'roadmap.md'], 'feat: initialize project with ZeroStart CLI');
114
+ // Second commit: everything else (source files, config, etc.)
115
+ await gitManager.commit(projectPath, 'chore: add project structure and configuration files');
116
+ spinner.succeed(chalk_1.default.green('Git repository initialized (2 commits)'));
109
117
  }
118
+ // ── Step 3: Create GitHub remote if requested ─────────────────────
110
119
  if (options.createRemote) {
111
120
  spinner.start(chalk_1.default.cyan('Creating GitHub repository...'));
112
121
  let repoUrl;
@@ -122,16 +131,17 @@ async function initializeProject(name, language, type, options) {
122
131
  if (options.authMethod !== 'GitHub CLI')
123
132
  await gitManager.addRemote(projectPath, repoUrl);
124
133
  await gitManager.push(projectPath);
125
- spinner.succeed(chalk_1.default.green('Pushed to GitHub'));
134
+ spinner.succeed(chalk_1.default.green('Pushed to GitHub'));
126
135
  }
127
136
  else {
128
- spinner.warn(chalk_1.default.yellow('GitHub repository creation failed'));
137
+ spinner.warn(chalk_1.default.yellow('GitHub repository creation failed — continuing locally'));
129
138
  }
130
139
  }
131
140
  console.log();
132
- console.log(chalk_1.default.bold.green(' Success! Your project is ready!'));
141
+ console.log(chalk_1.default.bold.green(' Success! Your project is ready!'));
133
142
  console.log(chalk_1.default.gray(' Location: ') + chalk_1.default.cyan(projectPath));
134
143
  console.log();
144
+ // ── CP languages: open browser + interactive terminal ─────────────
135
145
  if ([types_1.ProjectLanguage.Python, types_1.ProjectLanguage.Java, types_1.ProjectLanguage.CPP].includes(language)) {
136
146
  const gdbLinks = {
137
147
  [types_1.ProjectLanguage.Python]: 'https://www.onlinegdb.com/online_python_compiler',
@@ -143,7 +153,6 @@ async function initializeProject(name, language, type, options) {
143
153
  console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(link));
144
154
  console.log(chalk_1.default.gray(' (Opening in your browser...)'));
145
155
  openUrl(link);
146
- // Open a new terminal window with the language interpreter running
147
156
  const terminalCmds = {
148
157
  [types_1.ProjectLanguage.Python]: 'start cmd /k "python"',
149
158
  [types_1.ProjectLanguage.Java]: `start cmd /k "cd /d ${projectPath} && javac src/main/java/com/example/Main.java && java -cp src/main/java com.example.Main"`,
@@ -155,23 +164,21 @@ async function initializeProject(name, language, type, options) {
155
164
  (0, child_process_1.exec)(termCmd, { cwd: projectPath });
156
165
  }
157
166
  }
158
- if (language === types_1.ProjectLanguage.HTMLCSS) {
159
- console.log(chalk_1.default.bold.cyan('\n Deployment:'));
160
- console.log(chalk_1.default.gray(' To deploy to Vercel, run: ') + chalk_1.default.white('zerostart deploy-vercel'));
161
- }
162
167
  console.log(chalk_1.default.bold('\n Get started:'));
163
168
  console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(`cd ${name}`));
164
169
  console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan('code .') + chalk_1.default.gray(' (or your favorite editor)'));
165
170
  console.log();
171
+ return projectPath;
166
172
  }
167
173
  catch (error) {
168
174
  spinner.fail(chalk_1.default.red('Error: ' + error.message));
175
+ return projectPath;
169
176
  }
170
177
  }
171
178
  program
172
179
  .name('zerostart')
173
180
  .description('Create and deploy a complete project with one command')
174
- .version('0.0.38');
181
+ .version('0.0.41');
175
182
  // zerostart init [project-name]
176
183
  program
177
184
  .command('init [project-name]')
@@ -501,7 +508,7 @@ program
501
508
  return;
502
509
  }
503
510
  const latestVersion = stdout.trim();
504
- const currentVersion = '0.0.38';
511
+ const currentVersion = '0.0.41';
505
512
  if (latestVersion === currentVersion) {
506
513
  spinner.succeed(chalk_1.default.green('You are using the latest version!'));
507
514
  }
@@ -514,11 +521,14 @@ program
514
521
  // zerostart docs
515
522
  program
516
523
  .command('docs')
517
- .description('Open comprehensive documentation in your browser')
524
+ .description('Open the ZeroStart website and documentation in your browser')
518
525
  .action(() => {
519
526
  showBanner();
520
- const docsUrl = 'https://github.com/yourusername/zerostart-cli#readme';
521
- console.log(chalk_1.default.cyan(' Opening documentation...'));
527
+ const docsUrl = 'https://zerostart.zeroonedevs.in';
528
+ console.log(chalk_1.default.bold.cyan(' 🌐 Opening ZeroStart website...'));
529
+ console.log(chalk_1.default.gray(' URL: ') + chalk_1.default.cyan.underline(docsUrl));
530
+ console.log();
531
+ console.log(chalk_1.default.gray(' Explore commands, templates, and deployment guides at the site.'));
522
532
  openUrl(docsUrl);
523
533
  });
524
534
  // Standalone deployment commands
@@ -575,12 +585,14 @@ shortcuts.forEach(s => {
575
585
  });
576
586
  });
577
587
  async function startWizard(initialName) {
578
- // Steps:
579
- // 1 = Category (Web Dev / CP) — shown FIRST
580
- // 2 = Language sub-selection
581
- // 3 = Project Name
582
- // 4 = GitHub? (only for React/TS)
583
- // 5 = GitHub Token (only if GitHub = Yes)
588
+ // ── Wizard Steps ────────────────────────────────────────────────────────
589
+ // 1 What are you building? (Web Dev / CP)
590
+ // 2 Select Language
591
+ // 3 Project Name
592
+ // 4 [Web Dev only] Create GitHub repo? (Yes/No)
593
+ // 5 [Web Dev + GitHub=Yes] Enter GitHub token
594
+ // 6 → [Web Dev only] Run locally OR Deploy to Vercel?
595
+ // ────────────────────────────────────────────────────────────────────────
584
596
  let step = 1;
585
597
  let name = initialName;
586
598
  let category;
@@ -590,9 +602,9 @@ async function startWizard(initialName) {
590
602
  const BACK = '< Back';
591
603
  const CAT_WEB = '🌐 Web Development (React, TS, HTML/CSS)';
592
604
  const CAT_CP = '🏆 Competitive Programming (C++, Java, Python)';
593
- while (step > 0 && step <= 5) {
605
+ while (step > 0 && step <= 6) {
606
+ // ── STEP 1: Category ────────────────────────────────────────────────
594
607
  if (step === 1) {
595
- // Step 1: Category Selection — shown FIRST
596
608
  const ans = await inquirer_1.default.prompt([{
597
609
  type: 'list',
598
610
  name: 'category',
@@ -601,9 +613,9 @@ async function startWizard(initialName) {
601
613
  }]);
602
614
  category = ans.category;
603
615
  step++;
616
+ // ── STEP 2: Language ────────────────────────────────────────────────
604
617
  }
605
618
  else if (step === 2) {
606
- // Step 2: Language sub-selection
607
619
  const langChoices = category === CAT_WEB
608
620
  ? [types_1.ProjectLanguage.React, types_1.ProjectLanguage.TypeScript, types_1.ProjectLanguage.HTMLCSS, new inquirer_1.default.Separator(), BACK]
609
621
  : [types_1.ProjectLanguage.CPP, types_1.ProjectLanguage.Java, types_1.ProjectLanguage.Python, new inquirer_1.default.Separator(), BACK];
@@ -620,93 +632,183 @@ async function startWizard(initialName) {
620
632
  language = langAns.language;
621
633
  step++;
622
634
  }
635
+ // ── STEP 3: Project Name ────────────────────────────────────────────
623
636
  }
624
637
  else if (step === 3) {
625
- // Step 3: Project Name
626
638
  if (!name) {
627
639
  const ans = await inquirer_1.default.prompt([{
628
640
  type: 'input',
629
641
  name: 'name',
630
642
  message: 'Project Name:',
631
- default: 'my-project'
643
+ default: 'my-project',
644
+ validate: (v) => v.trim().length > 0 || 'Name cannot be empty'
632
645
  }]);
633
- name = ans.name;
646
+ name = ans.name.trim();
634
647
  }
635
648
  step++;
649
+ // ── STEP 4: GitHub repo? (Web Dev only) ────────────────────────────
636
650
  }
637
651
  else if (step === 4) {
638
- // Step 4: GitHub? (only for React/TS)
639
- if (language === types_1.ProjectLanguage.React || language === types_1.ProjectLanguage.TypeScript) {
652
+ if (category === CAT_WEB) {
640
653
  const ans = await inquirer_1.default.prompt([{
641
654
  type: 'list',
642
655
  name: 'github',
643
- message: 'Do you want to add this to GitHub?',
644
- choices: ['Yes', 'No', new inquirer_1.default.Separator(), BACK],
645
- default: 'Yes'
656
+ message: 'Create a GitHub repository for this project?',
657
+ choices: [
658
+ { name: 'Yes — push to GitHub', value: 'yes' },
659
+ { name: '❌ No — keep it local', value: 'no' },
660
+ new inquirer_1.default.Separator(),
661
+ { name: BACK, value: 'back' }
662
+ ],
663
+ default: 'yes'
646
664
  }]);
647
- if (ans.github === BACK) {
648
- name = undefined; // reset name so it's re-asked if they go back
665
+ if (ans.github === 'back') {
666
+ name = undefined;
649
667
  step--;
650
668
  }
651
669
  else {
652
- github = ans.github === 'Yes';
670
+ github = ans.github === 'yes';
653
671
  step++;
654
672
  }
655
673
  }
656
674
  else {
675
+ // CP projects skip straight to done
657
676
  github = false;
658
- step++;
677
+ step = 7; // jump past all web dev steps
659
678
  }
679
+ // ── STEP 5: GitHub Token ────────────────────────────────────────────
660
680
  }
661
681
  else if (step === 5) {
662
- // Step 5: GitHub Token (only if GitHub = Yes)
663
682
  if (github) {
664
683
  showGitHubTokenHelp();
665
- const ans = await inquirer_1.default.prompt([
666
- {
684
+ console.log(chalk_1.default.gray(' 💡 Tip: ') + chalk_1.default.white('Your token can be saved and reused for all future ZeroStart projects.'));
685
+ console.log(chalk_1.default.gray(' 💡 Tip: ') + chalk_1.default.white('Scopes needed: ') + chalk_1.default.cyan('repo'));
686
+ console.log();
687
+ const tokenAns = await inquirer_1.default.prompt([{
667
688
  type: 'password',
668
689
  name: 'token',
669
- message: 'Enter your GitHub Personal Access Token (or type "back" to return):',
670
- validate: (input) => input.length > 0 || 'Token is required'
671
- }
672
- ]);
673
- if (ans.token.toLowerCase() === 'back') {
690
+ message: 'Paste your GitHub Personal Access Token:',
691
+ validate: (input) => {
692
+ if (input.toLowerCase() === 'back')
693
+ return true;
694
+ if (input.trim().length < 10)
695
+ return 'That doesn\'t look like a valid token';
696
+ return true;
697
+ }
698
+ }]);
699
+ if (tokenAns.token.toLowerCase() === 'back') {
674
700
  step--;
675
701
  }
676
702
  else {
677
- githubToken = ans.token;
678
- step++;
703
+ // Validate token immediately
704
+ const spinner = (0, ora_1.default)({ text: 'Validating token...', color: 'cyan' }).start();
705
+ const svc = new GitHubServiceCLI_1.GitHubServiceCLI(tokenAns.token);
706
+ const user = await svc.validateToken();
707
+ if (user) {
708
+ spinner.succeed(chalk_1.default.green(`Token valid! Logged in as @${user.login}`));
709
+ githubToken = tokenAns.token;
710
+ step++;
711
+ }
712
+ else {
713
+ spinner.fail(chalk_1.default.red('Invalid token or no internet. Please try again.'));
714
+ // Stay on step 5 to retry
715
+ }
679
716
  }
680
717
  }
681
718
  else {
719
+ step++; // No GitHub — skip token step
720
+ }
721
+ // ── STEP 6: Run locally or Deploy to Vercel? (Web Dev only) ────────
722
+ }
723
+ else if (step === 6) {
724
+ const deployAns = await inquirer_1.default.prompt([{
725
+ type: 'list',
726
+ name: 'action',
727
+ message: 'What do you want to do next?',
728
+ choices: [
729
+ { name: '🚀 Deploy to Vercel (live URL in seconds)', value: 'vercel' },
730
+ { name: '💻 Run locally first (I\'ll deploy later)', value: 'local' },
731
+ new inquirer_1.default.Separator(),
732
+ { name: BACK, value: 'back' }
733
+ ],
734
+ default: 'local'
735
+ }]);
736
+ if (deployAns.action === 'back') {
737
+ step--;
738
+ }
739
+ else {
740
+ // Store deploy choice and break out of loop
741
+ startWizard._deployChoice = deployAns.action;
682
742
  step++;
683
743
  }
684
744
  }
685
745
  }
686
- if (step > 5 && name && language) {
746
+ // ── Execute the project creation ─────────────────────────────────────────
747
+ if ((step > 6 || step === 7) && name && language) {
687
748
  let type = types_1.ProjectType.WebApp;
688
749
  if (language === types_1.ProjectLanguage.TypeScript)
689
750
  type = types_1.ProjectType.CLITool;
690
751
  if (category === CAT_CP)
691
752
  type = types_1.ProjectType.DSAPractice;
692
- await initializeProject(name, language, type, {
753
+ const projectPath = await initializeProject(name, language, type, {
693
754
  isPublic: false,
694
755
  createRemote: !!githubToken,
695
- githubToken: githubToken,
756
+ githubToken,
696
757
  authMethod: 'none'
697
758
  });
698
- if (language === types_1.ProjectLanguage.HTMLCSS) {
699
- const { deploy } = await inquirer_1.default.prompt([
700
- { type: 'confirm', name: 'deploy', message: 'Do you want to deploy to Vercel right now?', default: true }
701
- ]);
702
- if (deploy) {
703
- const vercelManager = new VercelManager_1.VercelManager();
704
- const projectPath = path.join(process.cwd(), name);
705
- if (await vercelManager.checkAuth()) {
706
- await vercelManager.deploy(projectPath, name);
707
- }
759
+ // ── Post-creation: Web Dev deploy / local run ─────────────────────
760
+ const deployChoice = startWizard._deployChoice;
761
+ delete startWizard._deployChoice;
762
+ if (category === CAT_WEB && deployChoice === 'vercel') {
763
+ console.log();
764
+ console.log(chalk_1.default.bold.cyan(' 🚀 Starting Vercel deployment...'));
765
+ console.log(chalk_1.default.gray(' This will be tagged as a demo deployment from ZeroStart CLI'));
766
+ console.log();
767
+ const vercelManager = new VercelManager_1.VercelManager();
768
+ const isInstalled = await vercelManager.checkVercelInstalled();
769
+ if (!isInstalled) {
770
+ const installSpinner = (0, ora_1.default)({ text: 'Installing Vercel CLI...', color: 'cyan' }).start();
771
+ await vercelManager.installGlobal();
772
+ installSpinner.succeed(chalk_1.default.green('Vercel CLI installed'));
773
+ }
774
+ const isAuthed = await vercelManager.checkAuth();
775
+ if (!isAuthed) {
776
+ console.log(chalk_1.default.yellow(' You need to log in to Vercel first. Opening login...'));
777
+ await vercelManager.login();
778
+ }
779
+ const deploySpinner = (0, ora_1.default)({ text: `Deploying ${name} to Vercel...`, color: 'cyan' }).start();
780
+ const url = await vercelManager.deploy(projectPath, name);
781
+ if (url) {
782
+ deploySpinner.succeed(chalk_1.default.green('Deployed successfully!'));
783
+ console.log();
784
+ console.log(chalk_1.default.bold(' 🌐 Live URL: ') + chalk_1.default.cyan.underline(url));
785
+ console.log(chalk_1.default.gray(' (Demo deployment via ZeroStart CLI — upgrade in Vercel dashboard)'));
786
+ openUrl(url);
787
+ }
788
+ else {
789
+ deploySpinner.fail(chalk_1.default.red('Deployment failed. Run ' + chalk_1.default.white('vercel') + ' manually from project folder.'));
708
790
  }
709
791
  }
792
+ else if (category === CAT_WEB && deployChoice === 'local') {
793
+ console.log();
794
+ console.log(chalk_1.default.bold.cyan(' 💻 Run your project locally:'));
795
+ if (language === types_1.ProjectLanguage.React || language === types_1.ProjectLanguage.TypeScript) {
796
+ console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(`cd ${name}`));
797
+ console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan('npm install'));
798
+ console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan('npm run dev'));
799
+ console.log(chalk_1.default.gray('\n Then open: ') + chalk_1.default.cyan('http://localhost:5173'));
800
+ }
801
+ else if (language === types_1.ProjectLanguage.HTMLCSS) {
802
+ console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(`cd ${name}`));
803
+ console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan('Open index.html in your browser'));
804
+ console.log(chalk_1.default.gray(' - Or use: ') + chalk_1.default.cyan('npx serve .') + chalk_1.default.gray(' for a local server'));
805
+ }
806
+ }
807
+ console.log();
808
+ console.log(chalk_1.default.bold(' Get started:'));
809
+ console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(`cd ${name}`));
810
+ console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan('code .') + chalk_1.default.gray(' (or your favorite editor)'));
811
+ console.log();
710
812
  }
711
813
  }
712
814
  // Main wizard
@@ -67,6 +67,23 @@ class GitManager {
67
67
  console.warn(`Git commit failed (might be empty): ${error.message}`);
68
68
  }
69
69
  }
70
+ /**
71
+ * Stage only specific files and commit them.
72
+ * Used for the first human-style commit (README, .gitignore etc.) before
73
+ * committing the rest of the project structure as a second commit.
74
+ */
75
+ async commitSelective(cwd, files, message) {
76
+ try {
77
+ for (const file of files) {
78
+ // git add is silent if the file doesn't exist — that's fine
79
+ await exec(`git add "${file}"`, { cwd }).catch(() => { });
80
+ }
81
+ await exec(`git commit -m "${message}" --allow-empty`, { cwd });
82
+ }
83
+ catch (error) {
84
+ console.warn(`Selective git commit failed: ${error.message}`);
85
+ }
86
+ }
70
87
  async addRemote(cwd, url) {
71
88
  try {
72
89
  await exec(`git remote add origin ${url}`, { cwd });
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "zerostart": "./out/cli.js"
6
6
  },
7
7
  "description": "Create and deploy a complete project with one command.",
8
- "version": "0.0.39",
8
+ "version": "0.0.41",
9
9
  "engines": {
10
10
  "vscode": "^1.85.0"
11
11
  },
@@ -45,4 +45,4 @@
45
45
  "inquirer": "^9.3.8",
46
46
  "ora": "^5.4.1"
47
47
  }
48
- }
48
+ }