zerostart-cli 0.0.36 → 0.0.38

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/out/cli.js CHANGED
@@ -132,24 +132,23 @@ async function initializeProject(name, language, type, options) {
132
132
  console.log(chalk_1.default.bold.green(' Success! Your project is ready!'));
133
133
  console.log(chalk_1.default.gray(' Location: ') + chalk_1.default.cyan(projectPath));
134
134
  console.log();
135
- const isWeb = [types_1.ProjectLanguage.React, types_1.ProjectLanguage.HTMLCSS].includes(language);
136
- const isPractice = type === types_1.ProjectType.DSAPractice;
137
- if (!isWeb || isPractice) {
135
+ if ([types_1.ProjectLanguage.Python, types_1.ProjectLanguage.Java, types_1.ProjectLanguage.CPP].includes(language)) {
138
136
  const gdbLinks = {
139
137
  [types_1.ProjectLanguage.Python]: 'https://www.onlinegdb.com/online_python_compiler',
140
138
  [types_1.ProjectLanguage.Java]: 'https://www.onlinegdb.com/online_java_compiler',
141
- [types_1.ProjectLanguage.CPP]: 'https://www.onlinegdb.com/online_c++_compiler',
142
- [types_1.ProjectLanguage.NodeJS]: 'https://www.onlinegdb.com/online_node.js_compiler',
143
- [types_1.ProjectLanguage.React]: 'https://www.onlinegdb.com/'
139
+ [types_1.ProjectLanguage.CPP]: 'https://www.onlinegdb.com/online_c++_compiler'
144
140
  };
145
- const link = gdbLinks[language] || 'https://www.onlinegdb.com/';
141
+ const link = gdbLinks[language];
146
142
  console.log(chalk_1.default.bold.yellow(' Practice Online:'));
147
143
  console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(link));
148
144
  console.log(chalk_1.default.gray(' (Opening in your browser...)'));
149
145
  openUrl(link);
150
- return;
151
146
  }
152
- console.log(chalk_1.default.bold(' Get started:'));
147
+ if (language === types_1.ProjectLanguage.HTMLCSS) {
148
+ console.log(chalk_1.default.bold.cyan('\n Deployment:'));
149
+ console.log(chalk_1.default.gray(' To deploy to Vercel, run: ') + chalk_1.default.white('zerostart deploy-vercel'));
150
+ }
151
+ console.log(chalk_1.default.bold('\n Get started:'));
153
152
  console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan(`cd ${name}`));
154
153
  console.log(chalk_1.default.gray(' - ') + chalk_1.default.cyan('code .') + chalk_1.default.gray(' (or your favorite editor)'));
155
154
  console.log();
@@ -161,25 +160,14 @@ async function initializeProject(name, language, type, options) {
161
160
  program
162
161
  .name('zerostart')
163
162
  .description('Create and deploy a complete project with one command')
164
- .version('0.0.36');
163
+ .version('0.0.38');
165
164
  // zerostart init [project-name]
166
165
  program
167
166
  .command('init [project-name]')
168
167
  .description('Initialize a new project with interactive prompts')
169
168
  .action(async (projectName) => {
170
169
  showBanner();
171
- const answers = await inquirer_1.default.prompt([
172
- { type: 'input', name: 'name', message: 'Project Name:', when: !projectName, default: 'my-project' },
173
- { type: 'list', name: 'language', message: 'Language:', choices: Object.values(types_1.ProjectLanguage) },
174
- { type: 'list', name: 'type', message: 'Type:', choices: Object.values(types_1.ProjectType) },
175
- { type: 'list', name: 'createRemote', message: 'Push to GitHub?', choices: ['Yes', 'No'], default: 'No', when: (ans) => ans.type !== types_1.ProjectType.DSAPractice }
176
- ]);
177
- await initializeProject(projectName || answers.name, answers.language, answers.type, {
178
- isPublic: false,
179
- createRemote: answers.createRemote === 'Yes',
180
- githubToken: null,
181
- authMethod: 'none'
182
- });
170
+ await startWizard(projectName);
183
171
  });
184
172
  // zerostart deploy
185
173
  program
@@ -502,7 +490,7 @@ program
502
490
  return;
503
491
  }
504
492
  const latestVersion = stdout.trim();
505
- const currentVersion = '0.0.36';
493
+ const currentVersion = '0.0.38';
506
494
  if (latestVersion === currentVersion) {
507
495
  spinner.succeed(chalk_1.default.green('You are using the latest version!'));
508
496
  }
@@ -552,24 +540,20 @@ program
552
540
  console.log(chalk_1.default.green(' ✔ Deployed to Netlify!'));
553
541
  }
554
542
  });
555
- // Shortcut commands (18 total)
543
+ // Shortcut commands (Removed Node.js shortcuts)
556
544
  const shortcuts = [
557
545
  { cmd: 'dsa-py', lang: types_1.ProjectLanguage.Python, type: types_1.ProjectType.DSAPractice },
558
546
  { cmd: 'dsa-java', lang: types_1.ProjectLanguage.Java, type: types_1.ProjectType.DSAPractice },
559
547
  { cmd: 'dsa-cpp', lang: types_1.ProjectLanguage.CPP, type: types_1.ProjectType.DSAPractice },
560
- { cmd: 'dsa-node', lang: types_1.ProjectLanguage.NodeJS, type: types_1.ProjectType.DSAPractice },
561
548
  { cmd: 'web-react', lang: types_1.ProjectLanguage.React, type: types_1.ProjectType.WebApp },
562
549
  { cmd: 'web-html', lang: types_1.ProjectLanguage.HTMLCSS, type: types_1.ProjectType.WebApp },
563
- { cmd: 'web-node', lang: types_1.ProjectLanguage.NodeJS, type: types_1.ProjectType.WebApp },
564
550
  { cmd: 'web-py', lang: types_1.ProjectLanguage.Python, type: types_1.ProjectType.WebApp },
565
551
  { cmd: 'web-java', lang: types_1.ProjectLanguage.Java, type: types_1.ProjectType.WebApp },
566
552
  { cmd: 'web-cpp', lang: types_1.ProjectLanguage.CPP, type: types_1.ProjectType.WebApp },
567
553
  { cmd: 'cli-py', lang: types_1.ProjectLanguage.Python, type: types_1.ProjectType.CLITool },
568
- { cmd: 'cli-node', lang: types_1.ProjectLanguage.NodeJS, type: types_1.ProjectType.CLITool },
569
554
  { cmd: 'cli-java', lang: types_1.ProjectLanguage.Java, type: types_1.ProjectType.CLITool },
570
555
  { cmd: 'cli-cpp', lang: types_1.ProjectLanguage.CPP, type: types_1.ProjectType.CLITool },
571
556
  { cmd: 'ml-py', lang: types_1.ProjectLanguage.Python, type: types_1.ProjectType.MLProject },
572
- { cmd: 'ml-node', lang: types_1.ProjectLanguage.NodeJS, type: types_1.ProjectType.MLProject },
573
557
  { cmd: 'ml-java', lang: types_1.ProjectLanguage.Java, type: types_1.ProjectType.MLProject },
574
558
  { cmd: 'ml-cpp', lang: types_1.ProjectLanguage.CPP, type: types_1.ProjectType.MLProject },
575
559
  ];
@@ -579,21 +563,138 @@ shortcuts.forEach(s => {
579
563
  initializeProject(n, s.lang, s.type, { isPublic: false, createRemote: false, githubToken: null, authMethod: 'none' });
580
564
  });
581
565
  });
566
+ async function startWizard(initialName) {
567
+ let step = 1;
568
+ let name = initialName;
569
+ let category;
570
+ let language;
571
+ let github = false;
572
+ let githubToken = null;
573
+ const BACK = '< Back';
574
+ const CAT_WEB = '🌐 Web Development (React, TS, HTML/CSS)';
575
+ const CAT_CP = '🏆 Competitive Programming (C++, Java, Python)';
576
+ while (step > 0 && step <= 4) {
577
+ if (step === 1) {
578
+ if (!name) {
579
+ const ans = await inquirer_1.default.prompt([{
580
+ type: 'input',
581
+ name: 'name',
582
+ message: 'Project Name:',
583
+ default: 'my-project'
584
+ }]);
585
+ name = ans.name;
586
+ }
587
+ step++;
588
+ }
589
+ else if (step === 2) {
590
+ // Category Selection
591
+ const ans = await inquirer_1.default.prompt([{
592
+ type: 'list',
593
+ name: 'category',
594
+ message: 'What are you building?',
595
+ choices: [CAT_WEB, CAT_CP, new inquirer_1.default.Separator(), BACK]
596
+ }]);
597
+ if (ans.category === BACK) {
598
+ name = undefined;
599
+ step--;
600
+ }
601
+ else {
602
+ category = ans.category;
603
+ // Sub-selection for languages
604
+ const langChoices = category === CAT_WEB
605
+ ? [types_1.ProjectLanguage.React, types_1.ProjectLanguage.TypeScript, types_1.ProjectLanguage.HTMLCSS, BACK]
606
+ : [types_1.ProjectLanguage.CPP, types_1.ProjectLanguage.Java, types_1.ProjectLanguage.Python, BACK];
607
+ const langAns = await inquirer_1.default.prompt([{
608
+ type: 'list',
609
+ name: 'language',
610
+ message: 'Select Language:',
611
+ choices: langChoices
612
+ }]);
613
+ if (langAns.language === BACK) {
614
+ // Stay on step 2, loop back to category selection
615
+ continue;
616
+ }
617
+ else {
618
+ language = langAns.language;
619
+ step++;
620
+ }
621
+ }
622
+ }
623
+ else if (step === 3) {
624
+ if (language === types_1.ProjectLanguage.React || language === types_1.ProjectLanguage.TypeScript) {
625
+ const ans = await inquirer_1.default.prompt([{
626
+ type: 'list',
627
+ name: 'github',
628
+ message: 'Do you want to add this to GitHub?',
629
+ choices: ['Yes', 'No', BACK],
630
+ default: 'Yes'
631
+ }]);
632
+ if (ans.github === BACK) {
633
+ step--;
634
+ }
635
+ else {
636
+ github = ans.github === 'Yes';
637
+ step++;
638
+ }
639
+ }
640
+ else {
641
+ github = false;
642
+ step++;
643
+ }
644
+ }
645
+ else if (step === 4) {
646
+ if (github) {
647
+ showGitHubTokenHelp();
648
+ const ans = await inquirer_1.default.prompt([
649
+ {
650
+ type: 'password',
651
+ name: 'token',
652
+ message: 'Enter your GitHub Personal Access Token (or type "back" to return):',
653
+ validate: (input) => input.length > 0 || 'Token is required'
654
+ }
655
+ ]);
656
+ if (ans.token.toLowerCase() === 'back') {
657
+ step--;
658
+ }
659
+ else {
660
+ githubToken = ans.token;
661
+ step++;
662
+ }
663
+ }
664
+ else {
665
+ step++;
666
+ }
667
+ }
668
+ }
669
+ if (step > 4 && name && language) {
670
+ let type = types_1.ProjectType.WebApp;
671
+ if (language === types_1.ProjectLanguage.TypeScript)
672
+ type = types_1.ProjectType.CLITool;
673
+ if (category === CAT_CP)
674
+ type = types_1.ProjectType.DSAPractice;
675
+ await initializeProject(name, language, type, {
676
+ isPublic: false,
677
+ createRemote: !!githubToken,
678
+ githubToken: githubToken,
679
+ authMethod: 'none'
680
+ });
681
+ if (language === types_1.ProjectLanguage.HTMLCSS) {
682
+ const { deploy } = await inquirer_1.default.prompt([
683
+ { type: 'confirm', name: 'deploy', message: 'Do you want to deploy to Vercel right now?', default: true }
684
+ ]);
685
+ if (deploy) {
686
+ const vercelManager = new VercelManager_1.VercelManager();
687
+ const projectPath = path.join(process.cwd(), name);
688
+ if (await vercelManager.checkAuth()) {
689
+ await vercelManager.deploy(projectPath, name);
690
+ }
691
+ }
692
+ }
693
+ }
694
+ }
582
695
  // Main wizard
583
696
  program.argument('[projectName]').action(async (projectName) => {
584
697
  showBanner();
585
- let name = projectName;
586
- const answers = await inquirer_1.default.prompt([
587
- { type: 'input', name: 'name', message: 'Project Name:', skip: !!projectName, when: !projectName },
588
- { type: 'list', name: 'language', message: 'Language:', choices: Object.values(types_1.ProjectLanguage) },
589
- { type: 'list', name: 'type', message: 'Type:', choices: Object.values(types_1.ProjectType) },
590
- { type: 'list', name: 'createRemote', message: 'Push to GitHub?', choices: ['Yes', 'No'], default: 'No', when: (ans) => ans.type !== types_1.ProjectType.DSAPractice }
591
- ]);
592
- await initializeProject(projectName || answers.name, answers.language, answers.type, {
593
- isPublic: false,
594
- createRemote: answers.createRemote === 'Yes',
595
- githubToken: null,
596
- authMethod: 'none'
597
- });
698
+ await startWizard(projectName);
598
699
  });
599
700
  program.parse(process.argv);
@@ -40,6 +40,7 @@ const types_1 = require("../types");
40
40
  const TemplateManager_1 = require("./TemplateManager");
41
41
  const GitHubService_1 = require("../services/GitHubService");
42
42
  const GitManager_1 = require("./GitManager");
43
+ const VercelManager_1 = require("./VercelManager");
43
44
  class ProjectManager {
44
45
  constructor() {
45
46
  this.templateManager = new TemplateManager_1.TemplateManager();
@@ -66,26 +67,35 @@ class ProjectManager {
66
67
  }
67
68
  if (!name)
68
69
  return;
69
- // 2. Get Programming Language
70
- const language = await vscode.window.showQuickPick(Object.values(types_1.ProjectLanguage), {
71
- placeHolder: 'Select Programming Language'
70
+ // 2. Get Programming Template
71
+ const templates = [
72
+ types_1.ProjectLanguage.React,
73
+ types_1.ProjectLanguage.TypeScript,
74
+ types_1.ProjectLanguage.HTMLCSS,
75
+ types_1.ProjectLanguage.CPP,
76
+ types_1.ProjectLanguage.Java,
77
+ types_1.ProjectLanguage.Python
78
+ ];
79
+ const language = await vscode.window.showQuickPick(templates, {
80
+ placeHolder: 'Select Project Template'
72
81
  });
73
82
  if (!language)
74
83
  return;
75
- // 3. Get Project Type
76
- const type = await vscode.window.showQuickPick(Object.values(types_1.ProjectType), {
77
- placeHolder: 'Select Project Type'
78
- });
79
- if (!type)
80
- return;
81
- // 4. Get GitHub Repository Visibility
82
- const visibilityParts = ['Public', 'Private'];
83
- const visibilitySelection = await vscode.window.showQuickPick(visibilityParts, {
84
- placeHolder: 'Select Repository Visibility'
85
- });
86
- if (!visibilitySelection)
87
- return;
88
- const isPublic = visibilitySelection === 'Public';
84
+ // 3. GitHub Option
85
+ let createRemote = false;
86
+ let isPublic = false;
87
+ if (language === types_1.ProjectLanguage.React || language === types_1.ProjectLanguage.TypeScript) {
88
+ const githubResult = await vscode.window.showQuickPick(['Yes', 'No'], {
89
+ placeHolder: 'Add this project to GitHub?'
90
+ });
91
+ if (githubResult === 'Yes') {
92
+ createRemote = true;
93
+ const visibilityResult = await vscode.window.showQuickPick(['Public', 'Private'], {
94
+ placeHolder: 'Select Repository Visibility'
95
+ });
96
+ isPublic = visibilityResult === 'Public';
97
+ }
98
+ }
89
99
  // 5. Select Parent Folder
90
100
  const folderResult = await vscode.window.showOpenDialog({
91
101
  canSelectFiles: false,
@@ -97,6 +107,11 @@ class ProjectManager {
97
107
  return;
98
108
  const parentPath = folderResult[0].fsPath;
99
109
  const projectPath = path.join(parentPath, name);
110
+ let type = types_1.ProjectType.WebApp;
111
+ if (language === types_1.ProjectLanguage.TypeScript)
112
+ type = types_1.ProjectType.CLITool;
113
+ if ([types_1.ProjectLanguage.CPP, types_1.ProjectLanguage.Java, types_1.ProjectLanguage.Python].includes(language))
114
+ type = types_1.ProjectType.DSAPractice;
100
115
  const config = {
101
116
  name,
102
117
  language: language,
@@ -117,24 +132,61 @@ class ProjectManager {
117
132
  await this.gitManager.init(config.path);
118
133
  // Create initial commit
119
134
  await this.gitManager.commit(config.path, "Initial commit configured by Project Starter AI");
120
- progress.report({ increment: 50, message: "Creating GitHub Repository..." });
121
- const repoUrl = await this.gitHubService.createRepo(config);
122
- if (repoUrl && repoUrl.trim().length > 0) {
123
- progress.report({ increment: 70, message: "Pushing to GitHub..." });
124
- await this.gitManager.addRemote(config.path, repoUrl);
125
- await this.gitManager.push(config.path);
126
- // Clean up token from remote URL if it was injected
127
- if (repoUrl.includes('x-access-token')) {
128
- const cleanUrl = repoUrl.replace(/x-access-token:[^@]+@/, '');
129
- await this.gitManager.setRemoteUrl(config.path, cleanUrl);
135
+ if (createRemote) {
136
+ progress.report({ increment: 50, message: "Creating GitHub Repository..." });
137
+ const repoUrl = await this.gitHubService.createRepo(config);
138
+ if (repoUrl && repoUrl.trim().length > 0) {
139
+ progress.report({ increment: 70, message: "Pushing to GitHub..." });
140
+ await this.gitManager.addRemote(config.path, repoUrl);
141
+ await this.gitManager.push(config.path);
142
+ // Clean up token from remote URL if it was injected
143
+ if (repoUrl.includes('x-access-token')) {
144
+ const cleanUrl = repoUrl.replace(/x-access-token:[^@]+@/, '');
145
+ await this.gitManager.setRemoteUrl(config.path, cleanUrl);
146
+ }
130
147
  }
131
148
  }
132
149
  progress.report({ increment: 100, message: "Done!" });
133
150
  });
134
- const action = await vscode.window.showInformationMessage(`Project '${name}' created successfully!`, 'Open Project');
135
- if (action === 'Open Project') {
136
- const uri = vscode.Uri.file(projectPath);
137
- await vscode.commands.executeCommand('vscode.openFolder', uri);
151
+ if ([types_1.ProjectLanguage.Python, types_1.ProjectLanguage.Java, types_1.ProjectLanguage.CPP].includes(language)) {
152
+ const gdbLinks = {
153
+ [types_1.ProjectLanguage.Python]: 'https://www.onlinegdb.com/online_python_compiler',
154
+ [types_1.ProjectLanguage.Java]: 'https://www.onlinegdb.com/online_java_compiler',
155
+ [types_1.ProjectLanguage.CPP]: 'https://www.onlinegdb.com/online_c++_compiler'
156
+ };
157
+ const link = gdbLinks[language];
158
+ const action = await vscode.window.showInformationMessage(`Project '${name}' created! Practice online?`, 'Open GDB Link', 'Open Project');
159
+ if (action === 'Open GDB Link') {
160
+ vscode.env.openExternal(vscode.Uri.parse(link));
161
+ }
162
+ else if (action === 'Open Project') {
163
+ const uri = vscode.Uri.file(projectPath);
164
+ await vscode.commands.executeCommand('vscode.openFolder', uri);
165
+ }
166
+ }
167
+ else if (language === types_1.ProjectLanguage.HTMLCSS) {
168
+ const action = await vscode.window.showInformationMessage(`Project '${name}' created! Deploy to Vercel?`, 'Deploy Now', 'Open Project');
169
+ if (action === 'Deploy Now') {
170
+ const vm = new VercelManager_1.VercelManager();
171
+ if (await vm.checkAuth()) {
172
+ await vm.deploy(projectPath, name);
173
+ vscode.window.showInformationMessage('Deployment started!');
174
+ }
175
+ else {
176
+ vscode.window.showErrorMessage('Vercel not authenticated. Please run "vercel login" in terminal.');
177
+ }
178
+ }
179
+ else if (action === 'Open Project') {
180
+ const uri = vscode.Uri.file(projectPath);
181
+ await vscode.commands.executeCommand('vscode.openFolder', uri);
182
+ }
183
+ }
184
+ else {
185
+ const action = await vscode.window.showInformationMessage(`Project '${name}' created successfully!`, 'Open Project');
186
+ if (action === 'Open Project') {
187
+ const uri = vscode.Uri.file(projectPath);
188
+ await vscode.commands.executeCommand('vscode.openFolder', uri);
189
+ }
138
190
  }
139
191
  }
140
192
  catch (error) {