Ferrell Synthetic Intelligence commited on
Commit
ca49d41
·
1 Parent(s): aec1ded

Add simple doctor and launcher workflow

Browse files
Files changed (4) hide show
  1. README.md +9 -4
  2. package.json +3 -1
  3. scripts/doctor.mjs +23 -0
  4. scripts/start.mjs +22 -0
README.md CHANGED
@@ -34,10 +34,15 @@ The public pack includes registry entries for three optional Apache-2.0 models:
34
 
35
  ## Offline Use
36
 
37
- 1. Serve this repository locally with `python -m http.server 4173 --bind 127.0.0.1`.
38
- 2. Start a local OpenAI-compatible runtime for the selected model on loopback.
39
- 3. Open `http://127.0.0.1:4173/`.
40
- 4. Use **TEST LOCAL RUNTIME** and then **START BOUNDED REVIEW**.
 
 
 
 
 
41
 
42
  See `runtime/README.md` and `models/manifest.json` for the adapter contract and model configuration. AIDE does not apply model-generated patches automatically.
43
 
 
34
 
35
  ## Offline Use
36
 
37
+ Install Node.js 20+ and run:
38
+
39
+ ```bash
40
+ npm install
41
+ npm run doctor
42
+ npm start
43
+ ```
44
+
45
+ Then open `http://127.0.0.1:4173/`. The doctor reports missing optional runtimes as warnings instead of hiding them. Import a model pack from the Model Lanes panel and use **START / TEST RUNTIME**.
46
 
47
  See `runtime/README.md` and `models/manifest.json` for the adapter contract and model configuration. AIDE does not apply model-generated patches automatically.
48
 
package.json CHANGED
@@ -5,13 +5,15 @@
5
  "description": "Local-first sovereign development workbench",
6
  "type": "module",
7
  "scripts": {
8
- "test": "node tests/smoke.mjs && node harness/test-orchestrator.mjs && node daemon/test-model-manager.mjs && node daemon/test-community-store.mjs && node daemon/test-lsp-manager.mjs && node daemon/test-dap-manager.mjs && node daemon/test-workspace-manager.mjs && node daemon/test-training-manager.mjs && node daemon/test-replay-store.mjs && node benchmarks/test-run.mjs && node benchmarks/test-arena.mjs && node capsules/test-create.mjs && node scripts/e2e.mjs",
9
  "check": "node --check app.js && node --check daemon/server.mjs && node --check harness/orchestrator.mjs && node --check harness/checks.mjs",
10
  "veritas": "node harness/run-veritas.mjs",
11
  "benchmarks": "node benchmarks/run.mjs",
12
  "arena": "node benchmarks/arena.mjs",
13
  "e2e": "node scripts/e2e.mjs",
14
  "capsule": "node capsules/create.mjs",
 
 
15
  "desktop:dev": "tauri dev --config desktop/tauri.conf.json",
16
  "desktop:prepare": "node desktop/prepare.mjs",
17
  "desktop:build": "npm run desktop:prepare && tauri build --config desktop/tauri.conf.json"
 
5
  "description": "Local-first sovereign development workbench",
6
  "type": "module",
7
  "scripts": {
8
+ "test": "node tests/smoke.mjs && node harness/test-orchestrator.mjs && node daemon/test-model-manager.mjs && node daemon/test-community-store.mjs && node daemon/test-lsp-manager.mjs && node daemon/test-dap-manager.mjs && node daemon/test-workspace-manager.mjs && node daemon/test-training-manager.mjs && node daemon/test-replay-store.mjs && node daemon/test-agent-policy.mjs && node benchmarks/test-run.mjs && node benchmarks/test-arena.mjs && node capsules/test-create.mjs && node scripts/e2e.mjs",
9
  "check": "node --check app.js && node --check daemon/server.mjs && node --check harness/orchestrator.mjs && node --check harness/checks.mjs",
10
  "veritas": "node harness/run-veritas.mjs",
11
  "benchmarks": "node benchmarks/run.mjs",
12
  "arena": "node benchmarks/arena.mjs",
13
  "e2e": "node scripts/e2e.mjs",
14
  "capsule": "node capsules/create.mjs",
15
+ "doctor": "node scripts/doctor.mjs",
16
+ "start": "node scripts/start.mjs",
17
  "desktop:dev": "tauri dev --config desktop/tauri.conf.json",
18
  "desktop:prepare": "node desktop/prepare.mjs",
19
  "desktop:build": "npm run desktop:prepare && tauri build --config desktop/tauri.conf.json"
scripts/doctor.mjs ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ const root = path.resolve(process.cwd());
5
+ const checks = [];
6
+ const pass = (name, detail) => checks.push({ name, detail, ok: true });
7
+ const warn = (name, detail) => checks.push({ name, detail, ok: true, warning: true });
8
+ const fail = (name, detail) => checks.push({ name, detail, ok: false });
9
+
10
+ if (Number(process.versions.node.split('.')[0]) >= 20) pass('Node.js', process.version); else fail('Node.js', 'Node 20 or newer is required');
11
+ for (const file of ['models/manifest.json', 'community/node-manifest.json', 'training/manifest.json']) {
12
+ try { JSON.parse(await fs.readFile(path.join(root, file), 'utf8')); pass(file, 'valid JSON'); } catch { fail(file, 'missing or invalid JSON'); }
13
+ }
14
+ try { await fs.access(path.join(root, 'daemon/server.mjs')); pass('Local daemon', 'available'); } catch { fail('Local daemon', 'daemon/server.mjs missing'); }
15
+ try { await fs.access(process.env.AIDE_LLAMA_SERVER || '/root/runtime/llama-b10333/llama-server'); pass('llama.cpp', 'runtime binary found'); } catch { warn('llama.cpp', 'install a local llama-server runtime before starting models'); }
16
+ const manifest = JSON.parse(await fs.readFile(path.join(root, 'models/manifest.json'), 'utf8'));
17
+ const ready = manifest.models.filter(model => model.status === 'ready').length;
18
+ if (ready) pass('Model packs', `${ready} ready pack(s)`); else warn('Model packs', 'import at least one model pack');
19
+ console.log('\nAIDE Doctor\n');
20
+ for (const check of checks) console.log(`${check.ok ? (check.warning ? 'WARN' : 'OK') : 'FAIL'} ${check.name}: ${check.detail}`);
21
+ const failures = checks.filter(check => !check.ok).length;
22
+ console.log(`\n${failures ? 'Preflight failed' : 'Preflight passed'}: ${checks.length - failures}/${checks.length} checks\n`);
23
+ if (failures) process.exitCode = 1;
scripts/start.mjs ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import http from 'node:http';
2
+ import { createReadStream } from 'node:fs';
3
+ import { promises as fs } from 'node:fs';
4
+ import path from 'node:path';
5
+ import { spawn } from 'node:child_process';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
9
+ const port = Number(process.env.AIDE_UI_PORT || 4173);
10
+ const daemon = spawn(process.execPath, ['daemon/server.mjs'], { cwd: root, env: { ...process.env, AIDE_WORKSPACE: root }, stdio: 'inherit' });
11
+ const types = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.md': 'text/plain' };
12
+ const server = http.createServer(async (request, response) => {
13
+ const requested = decodeURIComponent((request.url || '/').split('?')[0]);
14
+ const relative = requested === '/' ? 'index.html' : requested.replace(/^\//, '');
15
+ const file = path.resolve(root, relative);
16
+ if (!file.startsWith(`${root}${path.sep}`)) return response.writeHead(403).end();
17
+ try { await fs.access(file); response.writeHead(200, { 'Content-Type': types[path.extname(file)] || 'application/octet-stream' }); createReadStream(file).pipe(response); }
18
+ catch { response.writeHead(404).end('Not found'); }
19
+ });
20
+ server.listen(port, '127.0.0.1', () => console.log(`AIDE running at http://127.0.0.1:${port}`));
21
+ const stop = () => { server.close(); daemon.kill('SIGTERM'); };
22
+ process.on('SIGINT', stop); process.on('SIGTERM', stop); daemon.on('exit', code => { if (code && code !== 143) console.error(`daemon exited with ${code}`); });