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 +104 -179
- package/out/cli.js +162 -60
- package/out/managers/GitManager.js +17 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,270 +1,195 @@
|
|
|
1
1
|
# ZeroStart CLI 🚀
|
|
2
2
|
|
|
3
|
-
Create and deploy a complete project
|
|
3
|
+
> **Create and deploy a complete project — in seconds.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/zerostart-cli)
|
|
6
|
+
[](https://www.npmjs.com/package/zerostart-cli)
|
|
7
|
+
[](./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
|
-
|
|
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
|
-
> **
|
|
24
|
+
> ⚠️ **Must use `-g`** — without the global flag, the CLI won't be available in your terminal.
|
|
19
25
|
|
|
20
26
|
---
|
|
21
27
|
|
|
22
|
-
##
|
|
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
|
-
|
|
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
|
-
## ✨
|
|
38
|
+
## ✨ What It Does
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
##
|
|
50
|
+
## 🛠 Commands
|
|
53
51
|
|
|
54
|
-
###
|
|
52
|
+
### Core
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
61
|
-
zerostart my-project-name
|
|
63
|
+
### Shortcut Commands ⚡
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
zerostart --version
|
|
65
|
+
Skip the wizard — create a project in one line:
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
zerostart
|
|
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
|
-
|
|
73
|
+
**All shortcuts:**
|
|
71
74
|
|
|
72
|
-
|
|
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
|
-
|
|
82
|
-
```bash
|
|
83
|
-
zerostart dsa-cpp my-calculator
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Standalone Deployment
|
|
82
|
+
### Dev Tools
|
|
87
83
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
zerostart
|
|
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
|
-
###
|
|
93
|
+
### Deployment
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
##
|
|
102
|
+
## 🗂 Project Structure
|
|
121
103
|
|
|
122
|
-
|
|
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
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
##
|
|
123
|
+
## 🧰 Requirements
|
|
136
124
|
|
|
137
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
|
165
|
-
git clone https://github.com/
|
|
166
|
-
cd
|
|
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
|
|
157
|
+
# Build
|
|
172
158
|
npm run compile
|
|
173
159
|
|
|
174
|
-
#
|
|
175
|
-
node ./out/cli.js
|
|
160
|
+
# Run locally
|
|
161
|
+
node ./out/cli.js
|
|
176
162
|
```
|
|
177
163
|
|
|
178
|
-
###
|
|
164
|
+
### Source Structure
|
|
179
165
|
|
|
180
166
|
```
|
|
181
167
|
src/
|
|
182
|
-
├── cli.ts
|
|
183
|
-
├──
|
|
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
|
|
187
|
-
│ ├── GitManager.ts
|
|
188
|
-
│
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
108
|
-
|
|
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.
|
|
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.
|
|
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
|
|
524
|
+
.description('Open the ZeroStart website and documentation in your browser')
|
|
518
525
|
.action(() => {
|
|
519
526
|
showBanner();
|
|
520
|
-
const docsUrl = 'https://
|
|
521
|
-
console.log(chalk_1.default.cyan(' Opening
|
|
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
|
|
580
|
-
// 2
|
|
581
|
-
// 3
|
|
582
|
-
// 4
|
|
583
|
-
// 5
|
|
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 <=
|
|
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
|
-
|
|
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: '
|
|
644
|
-
choices: [
|
|
645
|
-
|
|
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 ===
|
|
648
|
-
name = undefined;
|
|
665
|
+
if (ans.github === 'back') {
|
|
666
|
+
name = undefined;
|
|
649
667
|
step--;
|
|
650
668
|
}
|
|
651
669
|
else {
|
|
652
|
-
github = ans.github === '
|
|
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
|
-
|
|
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: '
|
|
670
|
-
validate: (input) =>
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
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
|
-
|
|
678
|
-
|
|
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
|
-
|
|
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
|
|
756
|
+
githubToken,
|
|
696
757
|
authMethod: 'none'
|
|
697
758
|
});
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
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.
|
|
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
|
+
}
|