Recently Written · git

ideamine

An idea inbox for Claude Code: /idea saves ideas at zero tokens; Claude triages them and routes each to the cheapest model that can build it.

git clone https://github.com/equwal/ideamine

Log | Files | Refs


tests/fixtures/server-process.js (2054 bytes)

1 // An ideamine server in its own process, as on a real server: its own IDEAMINE_HOME, sync off. The
2 // tests switch IDEAMINE_HOME between machines in the test process, so the server must not share it.
3 
4 import { spawn } from 'node:child_process';
5 import fs from 'node:fs';
6 import net from 'node:net';
7 import os from 'node:os';
8 import path from 'node:path';
9 import { fileURLToPath } from 'node:url';
10 
11 const BIN = fileURLToPath(new URL('../../bin/ideamine.js', import.meta.url));
12 
13 /** A port that nothing listens on now. */
14 export async function freePort() {
15   const s = net.createServer();
16   await new Promise((resolve) => s.listen(0, '127.0.0.1', resolve));
17   const { port } = s.address();
18   await new Promise((resolve) => s.close(resolve));
19   return port;
20 }
21 
22 /** Start `ideamine serve`. Resolves to { url, home, port, stop }. `env` adds settings. */
23 export async function startServerProcess(env = {}) {
24   const home = fs.mkdtempSync(path.join(os.tmpdir(), 'ideamine-server-'));
25   const port = await freePort();
26   const clean = { ...process.env };
27   for (const key of Object.keys(clean)) if (key.startsWith('IDEAMINE_')) delete clean[key];
28   const child = spawn(process.execPath, [BIN, 'serve', '--port', String(port)], {
29     env: { ...clean, IDEAMINE_HOME: home, IDEAMINE_EMBED_URL: 'http://127.0.0.1:9/v1', ...env },
30     stdio: ['ignore', 'pipe', 'pipe'],
31   });
32   let output = '';
33   child.stdout.on('data', (d) => (output += d));
34   child.stderr.on('data', (d) => (output += d));
35   const url = `http://127.0.0.1:${port}/`;
36   for (let i = 0; ; i++) {
37     try {
38       if ((await fetch(`${url}api/ping`)).ok) break;
39     } catch {
40       // Not listening yet.
41     }
42     if (i > 100 || child.exitCode !== null) throw new Error(`the server did not start: ${output}`);
43     await new Promise((resolve) => setTimeout(resolve, 50));
44   }
45   const stop = () =>
46     new Promise((resolve) => {
47       if (child.exitCode !== null) return resolve();
48       child.once('exit', resolve);
49       child.kill();
50     });
51   return { url, home, port, stop, output: () => output };
52 }