@learnrudi/cli 1.8.0 → 1.8.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learnrudi/cli",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "RUDI CLI - Install and manage MCP stacks, runtimes, and AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -14,20 +14,23 @@
14
14
  ],
15
15
  "scripts": {
16
16
  "start": "node src/index.js",
17
- "build": "esbuild src/index.js --bundle --platform=node --format=cjs --outfile=dist/index.cjs --external:better-sqlite3",
17
+ "build": "esbuild src/index.js --bundle --platform=node --format=cjs --outfile=dist/index.cjs --external:better-sqlite3 --external:@learnrudi/core --external:@learnrudi/db --external:@learnrudi/env --external:@learnrudi/manifest --external:@learnrudi/mcp --external:@learnrudi/registry-client --external:@learnrudi/runner --external:@learnrudi/secrets --external:@learnrudi/utils",
18
18
  "postinstall": "node scripts/postinstall.js",
19
19
  "prepublishOnly": "npm run build",
20
20
  "test": "node --test src/__tests__/"
21
21
  },
22
22
  "dependencies": {
23
- "better-sqlite3": "^12.5.0"
24
- },
25
- "devDependencies": {
26
23
  "@learnrudi/core": "workspace:*",
24
+ "@learnrudi/db": "workspace:*",
27
25
  "@learnrudi/env": "workspace:*",
28
26
  "@learnrudi/manifest": "workspace:*",
27
+ "@learnrudi/mcp": "workspace:*",
29
28
  "@learnrudi/registry-client": "workspace:*",
30
29
  "@learnrudi/runner": "workspace:*",
30
+ "@learnrudi/secrets": "workspace:*",
31
+ "@learnrudi/utils": "workspace:*"
32
+ },
33
+ "devDependencies": {
31
34
  "esbuild": "^0.27.2"
32
35
  },
33
36
  "engines": {
@@ -145,6 +145,46 @@ function initSecrets() {
145
145
  }
146
146
  }
147
147
 
148
+ // Download a binary from manifest
149
+ async function downloadBinary(binaryName, platformArch) {
150
+ const manifestUrl = `${REGISTRY_BASE}/catalog/binaries/${binaryName}.json`;
151
+
152
+ try {
153
+ const manifest = await fetchJson(manifestUrl);
154
+ const upstream = manifest.upstream?.[platformArch];
155
+
156
+ if (!upstream) {
157
+ console.log(` ⚠ No ${binaryName} available for ${platformArch}`);
158
+ return false;
159
+ }
160
+
161
+ const destDir = path.join(RUDI_HOME, 'tools', binaryName);
162
+ const binaryPath = path.join(destDir, manifest.binary || binaryName);
163
+
164
+ // Skip if already installed
165
+ if (fs.existsSync(binaryPath)) {
166
+ console.log(` ✓ ${manifest.name || binaryName} already installed`);
167
+ return true;
168
+ }
169
+
170
+ return await downloadAndExtract(upstream, destDir, manifest.name || binaryName);
171
+ } catch (error) {
172
+ console.log(` ⚠ Failed to fetch ${binaryName} manifest: ${error.message}`);
173
+ return false;
174
+ }
175
+ }
176
+
177
+ // Check if RUDI is already initialized (by Studio or previous install)
178
+ function isRudiInitialized() {
179
+ const nodeBin = path.join(RUDI_HOME, 'runtimes', 'node', 'bin', 'node');
180
+ const pythonBin = path.join(RUDI_HOME, 'runtimes', 'python', 'bin', 'python3');
181
+ const db = path.join(RUDI_HOME, 'rudi.db');
182
+
183
+ return fs.existsSync(nodeBin) &&
184
+ fs.existsSync(pythonBin) &&
185
+ fs.existsSync(db);
186
+ }
187
+
148
188
  // Main setup
149
189
  async function setup() {
150
190
  console.log('\nSetting up RUDI...\n');
@@ -156,6 +196,14 @@ async function setup() {
156
196
  return;
157
197
  }
158
198
 
199
+ // Check if already initialized (by Studio or previous install)
200
+ if (isRudiInitialized()) {
201
+ console.log('✓ RUDI already initialized');
202
+ console.log(' Skipping runtime and binary downloads\n');
203
+ console.log('Run `rudi doctor` to check system health\n');
204
+ return;
205
+ }
206
+
159
207
  // Create directories
160
208
  ensureDirectories();
161
209
  console.log('✓ Created ~/.rudi directory structure\n');
@@ -165,6 +213,11 @@ async function setup() {
165
213
  await downloadRuntime('node', platformArch);
166
214
  await downloadRuntime('python', platformArch);
167
215
 
216
+ // Download essential binaries
217
+ console.log('\nInstalling essential binaries...');
218
+ await downloadBinary('sqlite', platformArch);
219
+ await downloadBinary('ripgrep', platformArch);
220
+
168
221
  // Create shim
169
222
  console.log('\nSetting up shims...');
170
223
  createShim();