vibecodingmachine-core 2025.12.6-1702 → 2025.12.22-2230

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,92 @@
1
+ const fs = require('fs');
2
+ const { pipeline } = require('stream');
3
+ const { promisify } = require('util');
4
+ const streamPipeline = promisify(pipeline);
5
+ const ora = require('ora');
6
+
7
+ function progressBar(percent, width) {
8
+ const fill = Math.round((percent / 100) * width);
9
+ return '█'.repeat(fill) + '-'.repeat(Math.max(0, width - fill));
10
+ }
11
+
12
+ function formatEta(sec) {
13
+ if (!isFinite(sec) || sec === null) return '--:--';
14
+ const s = Math.max(0, Math.round(sec));
15
+ const m = Math.floor(s / 60);
16
+ const ss = s % 60;
17
+ return `${m}:${ss.toString().padStart(2, '0')}`;
18
+ }
19
+
20
+ async function downloadWithProgress(url, dest, opts = {}) {
21
+ const fetch = require('node-fetch');
22
+ const spinner = opts.spinner || ora();
23
+ const label = opts.label || 'Downloading...';
24
+ const onProgress = typeof opts.onProgress === 'function' ? opts.onProgress : null;
25
+
26
+ spinner.start(label);
27
+
28
+ const res = await fetch(url);
29
+ if (!res.ok) {
30
+ spinner.fail(`Download failed: ${res.status} ${res.statusText}`);
31
+ throw new Error(`Failed to download ${url}: ${res.status}`);
32
+ }
33
+ // Stop the spinner so progress prints are not overwritten
34
+ try { spinner.stop(); } catch (e) {}
35
+ try { process.stdout.write('\r\x1b[2KDownloading: 0.0 MB'); } catch (e) {}
36
+
37
+ const total = Number(res.headers.get('content-length')) || 0;
38
+ const fileStream = fs.createWriteStream(dest);
39
+
40
+ return await new Promise((resolve, reject) => {
41
+ let downloaded = 0;
42
+ const start = Date.now();
43
+ let lastPercent = -1;
44
+
45
+ res.body.on('data', (chunk) => {
46
+ downloaded += chunk.length;
47
+ if (total) {
48
+ const percent = Math.round((downloaded / total) * 100);
49
+ if (percent !== lastPercent) {
50
+ lastPercent = percent;
51
+ const mbDownloaded = (downloaded / (1024 * 1024)).toFixed(1);
52
+ const mbTotal = (total / (1024 * 1024)).toFixed(1);
53
+ const elapsed = Math.max(0.001, (Date.now() - start) / 1000);
54
+ const speed = downloaded / elapsed; // bytes/sec
55
+ const etaSec = (total - downloaded) / (speed || 1);
56
+ const eta = formatEta(etaSec);
57
+ const bar = progressBar(percent, 30);
58
+ // CLI/UI progress
59
+ if (onProgress) {
60
+ onProgress({ percent, downloaded, total, mbDownloaded, mbTotal, eta, bar });
61
+ } else {
62
+ process.stdout.write(`\r\x1b[2K[${bar}] ${percent}% ${mbDownloaded}MB / ${mbTotal}MB ETA: ${eta}`);
63
+ }
64
+ }
65
+ } else {
66
+ const mbDownloaded = (downloaded / (1024 * 1024)).toFixed(1);
67
+ if (onProgress) onProgress({ percent: null, downloaded, total, mbDownloaded });
68
+ else process.stdout.write(`\r\x1b[2K${label} ${mbDownloaded} MB`);
69
+ }
70
+ });
71
+
72
+ res.body.on('error', (err) => {
73
+ spinner.fail('Download error');
74
+ reject(err);
75
+ });
76
+
77
+ fileStream.on('error', (err) => {
78
+ spinner.fail('File write error');
79
+ reject(err);
80
+ });
81
+
82
+ fileStream.on('finish', () => {
83
+ process.stdout.write('\n');
84
+ spinner.succeed('Download complete');
85
+ resolve();
86
+ });
87
+
88
+ res.body.pipe(fileStream);
89
+ });
90
+ }
91
+
92
+ module.exports = { downloadWithProgress };
@@ -39,12 +39,19 @@ function formatVersionTimestamp(versionString, date) {
39
39
  }
40
40
  }
41
41
 
42
+ const { shouldCheckUpdates } = require('./env-helpers');
43
+
42
44
  /**
43
45
  * Check for Electron app updates from S3 version manifest
44
46
  * @param {string} currentVersion - Current version (e.g., '2025.11.26-0519')
45
47
  * @returns {Promise<Object>} Update info or null if no update available
46
48
  */
47
49
  async function checkForElectronUpdates(currentVersion) {
50
+ if (!shouldCheckUpdates()) {
51
+ console.log('ℹ️ [UPDATE CHECK] Skipped in development environment');
52
+ return { hasUpdate: false, currentVersion };
53
+ }
54
+
48
55
  return new Promise((resolve, reject) => {
49
56
  const manifestUrl = `https://d3fh7zgi8horze.cloudfront.net/downloads/version.json?t=${Date.now()}`;
50
57
  console.log(`🔍 [UPDATE CHECK] Current version: ${currentVersion}`);
@@ -0,0 +1,54 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+
4
+ /**
5
+ * Check if running in development environment
6
+ * @returns {boolean} True if in development
7
+ */
8
+ function isDevelopment() {
9
+ // Check standard environment variables
10
+ if (process.env.NODE_ENV === 'development' ||
11
+ process.env.VIBECODINGMACHINE_ENV === 'development' ||
12
+ process.env.ELECTRON_IS_DEV === '1') {
13
+ return true;
14
+ }
15
+
16
+ // Check for --dev flag in arguments
17
+ if (process.argv.includes('--dev')) {
18
+ return true;
19
+ }
20
+
21
+ // Heuristics for local development
22
+ // 1. Check if we are in a git repository that looks like the source code
23
+ // Root of the monorepo usually has 'packages' directory and 'lerna.json' or 'pnpm-workspace.yaml'
24
+ // But this might be too aggressive if user installs via git clone.
25
+
26
+ // 2. Check if electron is running from default app (not packaged)
27
+ if (process.versions && process.versions.electron) {
28
+ const electron = require('electron');
29
+ if (electron.app && !electron.app.isPackaged) {
30
+ return true;
31
+ }
32
+ }
33
+
34
+ return false;
35
+ }
36
+
37
+ /**
38
+ * Check if we should perform update checks
39
+ * @returns {boolean} True if update checks are allowed
40
+ */
41
+ function shouldCheckUpdates() {
42
+ // Don't check updates in development unless explicitly forced (not implemented yet)
43
+ if (isDevelopment()) {
44
+ return false;
45
+ }
46
+
47
+ // Can add more logic here (e.g. disable updates via config)
48
+ return true;
49
+ }
50
+
51
+ module.exports = {
52
+ isDevelopment,
53
+ shouldCheckUpdates
54
+ };