@heetmehta18/autodev 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,49 @@
1
+
2
+
3
+ > @heetmehta18/autodev@0.1.6 test /media/heet18/Futuristic/Heet/Github/Autodev/packages/npm-cli
4
+ > node bin/index.js --help
5
+
6
+
7
+ █████╗ ██╗ ██╗████████╗ ██████╗ ██████╗ ███████╗██╗ ██╗
8
+ ██╔══██╗██║ ██║╚══██╔══╝██╔═══██╗██╔══██╗██╔════╝██║ ██║
9
+ ███████║██║ ██║ ██║ ██║ ██║██║ ██║█████╗ ██║ ██║
10
+ ██╔══██║██║ ██║ ██║ ██║ ██║██║ ██║██╔══╝ ╚██╗ ██╔╝
11
+ ██║ ██║╚██████╔╝ ██║ ╚██████╔╝██████╔╝███████╗ ╚████╔╝
12
+ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚══════╝ ╚═══╝
13
+
14
+ The App Store for Developers.
15
+ Run with no arguments to open the interactive installer.
16
+
17
+ Usage:
18
+ autodev [flags]
19
+ autodev [command]
20
+
21
+ Available Commands:
22
+ audit Audit repository dependencies for security vulnerabilities
23
+ clean Remove AutoDev cache and temp files
24
+ clone Clone a Git repository, scan it, and install all missing dependencies
25
+ completion Generate the autocompletion script for the specified shell
26
+ doctor Check the health of your development environment
27
+ export Export environment as a reproducible JSON lockfile
28
+ github Scan all public repositories for a GitHub user
29
+ help Help about any command
30
+ install Install a specific package by ID
31
+ mcp Start a Model Context Protocol (MCP) server
32
+ profile Install a pre-defined developer profile (role-based tool set)
33
+ report Generate a detailed environment report (HTML, JSON, Markdown)
34
+ scan Scan a repository for languages, frameworks, and dependencies
35
+ setup Detect and install all missing runtimes and dependencies
36
+ skills Generate a personalized learning roadmap based on detected technologies
37
+ ui Start the local AutoDev interactive web dashboard
38
+ update Check for and apply updates to managed packages
39
+
40
+ Flags:
41
+ --config string config file (default: .autodev.yaml)
42
+ --dry-run preview actions without executing
43
+ -h, --help help for autodev
44
+ --json output results as JSON
45
+ --no-color disable color output
46
+ -v, --verbose verbose output
47
+ --version version for autodev
48
+
49
+ Use "autodev [command] --help" for more information about a command.
package/bin/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { spawnSync } = require('child_process');
3
+ const { spawnSync, execSync } = require('child_process');
4
4
  const path = require('path');
5
5
  const fs = require('fs');
6
6
  const os = require('os');
7
- const { execSync } = require('child_process');
7
+ const https = require('https');
8
+ const http = require('http');
8
9
 
9
10
  // Determine OS & Arch mapping
10
11
  const platformMap = {
@@ -29,12 +30,42 @@ if (!platform || !arch) {
29
30
  const ext = platform === 'windows' ? 'zip' : 'tar.gz';
30
31
  const binaryName = platform === 'windows' ? 'autodev.exe' : 'autodev';
31
32
 
32
- // Version mapped to package.json
33
+ // Version: prefer the latest GitHub release tag; fall back to package.json
33
34
  const pkgJson = require('../package.json');
34
- const version = `v${pkgJson.version}`; // E.g., v0.1.0
35
+ const fallbackVersion = `v${pkgJson.version}`;
36
+
37
+ function getLatestReleaseTag() {
38
+ return new Promise((resolve) => {
39
+ const options = {
40
+ hostname: 'api.github.com',
41
+ path: '/repos/HEETMEHTA18/autodev/releases/latest',
42
+ headers: {
43
+ 'User-Agent': 'autodev-npm-cli'
44
+ },
45
+ timeout: 5000
46
+ };
47
+
48
+ https.get(options, (res) => {
49
+ let body = '';
50
+ res.on('data', (chunk) => body += chunk);
51
+ res.on('end', () => {
52
+ try {
53
+ const json = JSON.parse(body);
54
+ if (json.tag_name) {
55
+ resolve(json.tag_name);
56
+ return;
57
+ }
58
+ } catch (_) {}
59
+ resolve(fallbackVersion);
60
+ });
61
+ }).on('error', () => {
62
+ resolve(fallbackVersion);
63
+ });
64
+ });
65
+ }
35
66
 
36
67
  // Resolve target paths
37
- const binDir = path.join(__dirname, '..', 'bin');
68
+ const binDir = __dirname;
38
69
  const binaryPath = path.join(binDir, binaryName);
39
70
 
40
71
  // Development fallback paths
@@ -54,9 +85,43 @@ for (const devPath of devPaths) {
54
85
  }
55
86
  }
56
87
 
57
- function downloadBinary() {
88
+ /**
89
+ * Download a file using Node.js built-in https module (follows redirects).
90
+ * This avoids issues with curl/wget not being available or behaving
91
+ * differently in sandboxed npx environments.
92
+ */
93
+ function download(url, destPath, maxRedirects = 5) {
94
+ return new Promise((resolve, reject) => {
95
+ if (maxRedirects <= 0) return reject(new Error('Too many redirects'));
96
+
97
+ const client = url.startsWith('https') ? https : http;
98
+ client.get(url, (res) => {
99
+ // Follow redirects (GitHub releases return 302)
100
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
101
+ return download(res.headers.location, destPath, maxRedirects - 1)
102
+ .then(resolve)
103
+ .catch(reject);
104
+ }
105
+
106
+ if (res.statusCode !== 200) {
107
+ return reject(new Error(`HTTP ${res.statusCode} from ${url}`));
108
+ }
109
+
110
+ const fileStream = fs.createWriteStream(destPath);
111
+ res.pipe(fileStream);
112
+ fileStream.on('finish', () => {
113
+ fileStream.close();
114
+ resolve();
115
+ });
116
+ fileStream.on('error', reject);
117
+ }).on('error', reject);
118
+ });
119
+ }
120
+
121
+ async function downloadBinary() {
122
+ let version = await getLatestReleaseTag();
58
123
  console.log(`\n[autodev] Native binary not found. Downloading AutoDev ${version} for ${platform}/${arch}...`);
59
-
124
+
60
125
  if (!fs.existsSync(binDir)) {
61
126
  fs.mkdirSync(binDir, { recursive: true });
62
127
  }
@@ -64,27 +129,48 @@ function downloadBinary() {
64
129
  // Construct download URL
65
130
  const archiveName = `autodev_${platform}_${arch}`;
66
131
  const archiveFile = `${archiveName}.${ext}`;
67
- // Using the user's repository URL
68
- const url = `https://github.com/HEETMEHTA18/autodev/releases/download/${version}/${archiveFile}`;
69
-
70
- const tempFile = path.join(os.tmpdir(), archiveFile);
71
-
72
- // Download using curl / wget / powershell
132
+ let url = `https://github.com/HEETMEHTA18/autodev/releases/download/${version}/${archiveFile}`;
133
+
134
+ const tempFile = path.join(os.tmpdir(), `autodev_download_${Date.now()}.${ext}`);
135
+
136
+ // Download using Node.js built-in HTTPS (handles redirects properly)
73
137
  try {
74
- if (process.platform === 'win32') {
75
- execSync(`powershell -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '${url}' -OutFile '${tempFile}'"`, { stdio: 'inherit' });
76
- } else {
77
- if (spawnSync('command', ['-v', 'curl'], { shell: true }).status === 0) {
78
- execSync(`curl -fsSL "${url}" -o "${tempFile}"`, { stdio: 'inherit' });
79
- } else if (spawnSync('command', ['-v', 'wget'], { shell: true }).status === 0) {
80
- execSync(`wget -q "${url}" -O "${tempFile}"`, { stdio: 'inherit' });
81
- } else {
82
- throw new Error('Neither curl nor wget was found on the system path.');
138
+ console.log(`[autodev] Downloading from: ${url}`);
139
+ await download(url, tempFile);
140
+ } catch (err) {
141
+ const stableFallback = 'v0.2.0';
142
+ if (version !== stableFallback) {
143
+ console.warn(`\n[autodev] Failed to download version ${version}: ${err.message}`);
144
+ console.warn(`[autodev] Falling back to last known stable release: ${stableFallback}...`);
145
+ version = stableFallback;
146
+ url = `https://github.com/HEETMEHTA18/autodev/releases/download/${version}/${archiveFile}`;
147
+ try {
148
+ console.log(`[autodev] Downloading from: ${url}`);
149
+ await download(url, tempFile);
150
+ } catch (retryErr) {
151
+ console.error(`\n[autodev] Error downloading stable release asset: ${retryErr.message}`);
152
+ console.error(`[autodev] Please verify your network connection.`);
153
+ process.exit(1);
83
154
  }
155
+ } else {
156
+ console.error(`\n[autodev] Error downloading release asset: ${err.message}`);
157
+ console.error(`[autodev] URL: ${url}`);
158
+ process.exit(1);
84
159
  }
160
+ }
161
+
162
+ try {
163
+ // Verify the file was actually downloaded
164
+ if (!fs.existsSync(tempFile)) {
165
+ throw new Error('Download completed but file not found on disk.');
166
+ }
167
+ const stat = fs.statSync(tempFile);
168
+ if (stat.size < 1000) {
169
+ throw new Error(`Downloaded file is too small (${stat.size} bytes), likely an error page.`);
170
+ }
171
+ console.log(`[autodev] Downloaded ${(stat.size / 1024 / 1024).toFixed(1)} MB`);
85
172
  } catch (err) {
86
- console.error(`\n[autodev] Error downloading release asset: ${err.message}`);
87
- console.error(`Please verify that the release version ${version} exists and has compiled assets.`);
173
+ console.error(`\n[autodev] Error verifying download: ${err.message}`);
88
174
  process.exit(1);
89
175
  }
90
176
 
@@ -100,30 +186,41 @@ function downloadBinary() {
100
186
  } else {
101
187
  execSync(`tar -xzf "${tempFile}" -C "${binDir}"`, { stdio: 'inherit' });
102
188
  }
103
-
189
+
104
190
  // Clean up temp archive
105
191
  if (fs.existsSync(tempFile)) {
106
192
  fs.unlinkSync(tempFile);
107
193
  }
108
-
194
+
109
195
  // Set execution permissions on Linux/macOS
110
- if (process.platform !== 'win32') {
196
+ if (process.platform !== 'win32' && fs.existsSync(binaryPath)) {
111
197
  fs.chmodSync(binaryPath, 0o755);
112
198
  }
113
199
  console.log(`[autodev] Installation successful.\n`);
114
200
  } catch (err) {
201
+ // Clean up temp file on error too
202
+ if (fs.existsSync(tempFile)) {
203
+ fs.unlinkSync(tempFile);
204
+ }
115
205
  console.error(`\n[autodev] Error extracting archive: ${err.message}`);
116
206
  process.exit(1);
117
207
  }
118
208
  }
119
209
 
120
- // If no local dev binary is found and the packaged binary is missing, download it
121
- if (activeBinaryPath === binaryPath && !fs.existsSync(binaryPath)) {
122
- downloadBinary();
123
- }
210
+ async function main() {
211
+ // If no local dev binary is found and the packaged binary is missing, download it
212
+ if (activeBinaryPath === binaryPath && !fs.existsSync(binaryPath)) {
213
+ await downloadBinary();
214
+ }
124
215
 
125
- // Forward execution
126
- const args = process.argv.slice(2);
127
- const result = spawnSync(activeBinaryPath, args, { stdio: 'inherit' });
216
+ // Forward execution
217
+ const args = process.argv.slice(2);
218
+ const result = spawnSync(activeBinaryPath, args, { stdio: 'inherit' });
128
219
 
129
- process.exit(result.status ?? 0);
220
+ process.exit(result.status ?? 0);
221
+ }
222
+
223
+ main().catch((err) => {
224
+ console.error(`[autodev] Fatal error: ${err.message}`);
225
+ process.exit(1);
226
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heetmehta18/autodev",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "The App Store for Developers. Install languages, frameworks, and databases with a single command.",
5
5
  "main": "bin/index.js",
6
6
  "bin": {