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/projects.test.js (2666 bytes)

1 import assert from 'node:assert/strict';
2 import fs from 'node:fs';
3 import os from 'node:os';
4 import path from 'node:path';
5 import { test } from 'node:test';
6 import { findProject, knownProjects } from '../src/projects.js';
7 
8 test('knownProjects lists real project folders once, each with a short description', () => {
9   const root = fs.mkdtempSync(path.join(os.tmpdir(), 'ideamine-known-'));
10   const dir = (...parts) => {
11     const d = path.join(root, ...parts);
12     fs.mkdirSync(d, { recursive: true });
13     return d;
14   };
15   const alpha = dir('alpha');
16   const beta = dir('beta');
17   const bare = dir('bare');
18   const otherAlpha = dir('work', 'alpha'); // the same folder name as the first alpha
19   const scratch = dir('Claude', 'scratch-workspaces', 'abc', 'scratch-2026-09-21-1a2b3c');
20   fs.writeFileSync(path.join(alpha, 'README.md'), '\n# Alpha: a scroller extension\n\nMore text.\n');
21   fs.writeFileSync(path.join(beta, 'package.json'), JSON.stringify({ description: 'Beta, a logo maker' }));
22   const config = dir('config');
23   const claudeProjects = {
24     [alpha.replaceAll('\\', '/')]: {}, // Claude Code keeps some paths with forward slashes
25     [scratch]: {},
26     [path.join(root, 'gone')]: {},
27     [os.homedir()]: {},
28     [bare]: {},
29     [otherAlpha]: {},
30   };
31   fs.writeFileSync(path.join(config, '.claude.json'), JSON.stringify({ projects: claudeProjects }));
32 
33   const db = { ideas: [{ project: beta }, { project: alpha }, { project: scratch }, { project: null }] };
34   const found = knownProjects(db, { configDir: config });
35   // The folders of the ideas come first, then the other Claude Code projects. Each name is unique.
36   assert.deepEqual(found, [
37     { name: 'beta', dir: beta, about: 'Beta, a logo maker' },
38     { name: 'alpha', dir: alpha, about: 'Alpha: a scroller extension' },
39     { name: 'bare', dir: bare, about: '' },
40     { name: 'alpha-2', dir: otherAlpha, about: '' },
41   ]);
42   assert.deepEqual(knownProjects(db, { configDir: path.join(root, 'no-config') }).map((p) => p.dir), [beta, alpha]);
43 });
44 
45 test('findProject matches the name that the triage gives, or the full path', () => {
46   const projects = [
47     { name: 'alpha', dir: path.resolve('/p/alpha'), about: '' },
48     { name: 'alpha-2', dir: path.resolve('/q/alpha'), about: '' },
49   ];
50   assert.equal(findProject(projects, 'alpha').dir, path.resolve('/p/alpha'));
51   assert.equal(findProject(projects, 'ALPHA-2').dir, path.resolve('/q/alpha'));
52   assert.equal(findProject(projects, path.resolve('/q/alpha')).name, 'alpha-2');
53   assert.equal(findProject(projects, ''), null);
54   assert.equal(findProject(projects, 'gamma'), null);
55   assert.equal(findProject(projects, undefined), null);
56 });