olly-molly 0.2.11 → 0.2.12

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.
Files changed (3) hide show
  1. package/README.md +9 -0
  2. package/bin/cli.js +51 -11
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -79,6 +79,15 @@ That's it. Open `http://localhost:1234` and start managing your AI team.
79
79
  npx olly-molly
80
80
  ```
81
81
 
82
+ On macOS (arm64/x64) and Windows x64, `npx olly-molly` will use prebuilt bundles
83
+ from GitHub Releases when available. Asset naming:
84
+
85
+ ```
86
+ olly-molly-darwin-arm64.tar.gz
87
+ olly-molly-darwin-x64.tar.gz
88
+ olly-molly-win32-x64.tar.gz
89
+ ```
90
+
82
91
  ### Or install globally
83
92
 
84
93
  ```bash
package/bin/cli.js CHANGED
@@ -10,7 +10,8 @@ const PACKAGE_NAME = 'olly-molly';
10
10
  const REPO = 'ruucm/olly-molly';
11
11
  const APP_DIR = path.join(os.homedir(), '.olly-molly');
12
12
  const DB_DIR = path.join(APP_DIR, 'db');
13
- const TARBALL_URL = `https://github.com/${REPO}/archive/refs/heads/main.tar.gz`;
13
+ const SOURCE_TARBALL_URL = `https://github.com/${REPO}/archive/refs/heads/main.tar.gz`;
14
+ const RELEASE_BASE_URL = `https://github.com/${REPO}/releases/download`;
14
15
 
15
16
  console.log('\nšŸ™ Olly Molly\n');
16
17
 
@@ -31,23 +32,48 @@ function getNpmVersion() {
31
32
  });
32
33
  }
33
34
 
34
- function download(url, destDir) {
35
+ function getPrebuiltUrl(version) {
36
+ if (!version) return null;
37
+ const platform = process.platform;
38
+ const arch = process.arch;
39
+
40
+ if (platform === 'darwin' && (arch === 'arm64' || arch === 'x64')) {
41
+ return `${RELEASE_BASE_URL}/v${version}/olly-molly-darwin-${arch}.tar.gz`;
42
+ }
43
+ if (platform === 'win32' && arch === 'x64') {
44
+ return `${RELEASE_BASE_URL}/v${version}/olly-molly-win32-${arch}.tar.gz`;
45
+ }
46
+ return null;
47
+ }
48
+
49
+ function download(url, destDir, { allowNotFound = false } = {}) {
35
50
  return new Promise((resolve, reject) => {
36
51
  const tmp = path.join(os.tmpdir(), 'olly-molly.tar.gz');
37
52
  const file = fs.createWriteStream(tmp);
53
+ const cleanupTmp = () => {
54
+ try { file.close(); } catch {}
55
+ try { fs.unlinkSync(tmp); } catch {}
56
+ };
38
57
  const get = (u) => {
39
58
  https.get(u, (res) => {
40
59
  if (res.statusCode === 302 || res.statusCode === 301) return get(res.headers.location);
41
- if (res.statusCode !== 200) return reject(new Error('Download failed'));
60
+ if (res.statusCode !== 200) {
61
+ cleanupTmp();
62
+ if (allowNotFound && res.statusCode === 404) return resolve(false);
63
+ return reject(new Error(`Download failed (${res.statusCode})`));
64
+ }
42
65
  res.pipe(file);
43
66
  file.on('finish', () => {
44
67
  file.close();
45
68
  fs.mkdirSync(destDir, { recursive: true });
46
69
  execSync(`tar -xzf "${tmp}" -C "${destDir}" --strip-components=1`, { stdio: 'pipe' });
47
70
  fs.unlinkSync(tmp);
48
- resolve();
71
+ resolve(true);
49
72
  });
50
- }).on('error', reject);
73
+ }).on('error', (err) => {
74
+ cleanupTmp();
75
+ reject(err);
76
+ });
51
77
  };
52
78
  get(url);
53
79
  });
@@ -110,9 +136,23 @@ function restoreUserData(backupDir) {
110
136
  async function main() {
111
137
  let needsInstall = false;
112
138
  let needsBuild = false;
139
+ let usedPrebuilt = false;
113
140
 
114
141
  const localVersion = getLocalVersion();
115
142
  const npmVersion = await getNpmVersion();
143
+ const prebuiltUrl = getPrebuiltUrl(npmVersion);
144
+
145
+ async function downloadApp() {
146
+ if (prebuiltUrl) {
147
+ const ok = await download(prebuiltUrl, APP_DIR, { allowNotFound: true });
148
+ if (ok) {
149
+ usedPrebuilt = true;
150
+ return;
151
+ }
152
+ }
153
+ await download(SOURCE_TARBALL_URL, APP_DIR);
154
+ usedPrebuilt = false;
155
+ }
116
156
 
117
157
  // Update if npm version is newer
118
158
  if (localVersion && npmVersion && localVersion !== npmVersion) {
@@ -120,20 +160,20 @@ async function main() {
120
160
  const userDataBackup = backupUserData();
121
161
  fs.rmSync(APP_DIR, { recursive: true, force: true });
122
162
  console.log('šŸ“„ Downloading...');
123
- await download(TARBALL_URL, APP_DIR);
163
+ await downloadApp();
124
164
  console.log('āœ… Downloaded\n');
125
165
  restoreUserData(userDataBackup);
126
- needsInstall = true;
127
- needsBuild = true;
166
+ needsInstall = !usedPrebuilt;
167
+ needsBuild = !usedPrebuilt;
128
168
  }
129
169
 
130
170
  // First time
131
171
  if (!fs.existsSync(APP_DIR)) {
132
172
  console.log('šŸ“„ Downloading...');
133
- await download(TARBALL_URL, APP_DIR);
173
+ await downloadApp();
134
174
  console.log('āœ… Downloaded\n');
135
- needsInstall = true;
136
- needsBuild = true;
175
+ needsInstall = !usedPrebuilt;
176
+ needsBuild = !usedPrebuilt;
137
177
  }
138
178
 
139
179
  // Install
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "olly-molly",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "Your AI Development Team, Running Locally - Manage AI agents (PM, Frontend, Backend, QA) from a beautiful kanban board",
5
5
  "keywords": [
6
6
  "ai",
@@ -29,7 +29,7 @@
29
29
  ],
30
30
  "scripts": {
31
31
  "dev": "next dev --port 1234",
32
- "build": "next build",
32
+ "build": "next build --webpack",
33
33
  "start": "next start --port 1234",
34
34
  "lint": "eslint",
35
35
  "tauri": "tauri",