ineedcodes 0.1.5 → 0.2.0

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 (113) hide show
  1. package/agent.mjs +244 -0
  2. package/package.json +10 -25
  3. package/docs/assets/ineed-logo.svg +0 -161
  4. package/docs/configuration.md +0 -71
  5. package/docs/skills.md +0 -58
  6. package/packages/agent/dist/boost.d.ts +0 -34
  7. package/packages/agent/dist/boost.js +0 -138
  8. package/packages/agent/dist/boost.js.map +0 -1
  9. package/packages/agent/dist/events.d.ts +0 -67
  10. package/packages/agent/dist/events.js +0 -16
  11. package/packages/agent/dist/events.js.map +0 -1
  12. package/packages/agent/dist/index.d.ts +0 -6
  13. package/packages/agent/dist/index.js +0 -7
  14. package/packages/agent/dist/index.js.map +0 -1
  15. package/packages/agent/dist/lead-agent.d.ts +0 -85
  16. package/packages/agent/dist/lead-agent.js +0 -235
  17. package/packages/agent/dist/lead-agent.js.map +0 -1
  18. package/packages/agent/dist/orchestrator.d.ts +0 -43
  19. package/packages/agent/dist/orchestrator.js +0 -135
  20. package/packages/agent/dist/orchestrator.js.map +0 -1
  21. package/packages/agent/dist/runtime.d.ts +0 -44
  22. package/packages/agent/dist/runtime.js +0 -265
  23. package/packages/agent/dist/runtime.js.map +0 -1
  24. package/packages/agent/dist/system-prompts.d.ts +0 -24
  25. package/packages/agent/dist/system-prompts.js +0 -91
  26. package/packages/agent/dist/system-prompts.js.map +0 -1
  27. package/packages/agent/package.json +0 -21
  28. package/packages/cli/dist/index.d.ts +0 -3
  29. package/packages/cli/dist/index.js +0 -11440
  30. package/packages/cli/dist/index.js.map +0 -1
  31. package/packages/cli/dist/setup.d.ts +0 -37
  32. package/packages/cli/dist/setup.js +0 -250
  33. package/packages/cli/dist/setup.js.map +0 -1
  34. package/packages/cli/dist/tools-setup.d.ts +0 -12
  35. package/packages/cli/dist/tools-setup.js +0 -28
  36. package/packages/cli/dist/tools-setup.js.map +0 -1
  37. package/packages/cli/dist/ui/approval.d.ts +0 -12
  38. package/packages/cli/dist/ui/approval.js +0 -52
  39. package/packages/cli/dist/ui/approval.js.map +0 -1
  40. package/packages/cli/dist/ui/colors.d.ts +0 -14
  41. package/packages/cli/dist/ui/colors.js +0 -21
  42. package/packages/cli/dist/ui/colors.js.map +0 -1
  43. package/packages/cli/dist/ui/prompts.d.ts +0 -46
  44. package/packages/cli/dist/ui/prompts.js +0 -135
  45. package/packages/cli/dist/ui/prompts.js.map +0 -1
  46. package/packages/cli/dist/ui/renderer.d.ts +0 -13
  47. package/packages/cli/dist/ui/renderer.js +0 -95
  48. package/packages/cli/dist/ui/renderer.js.map +0 -1
  49. package/packages/cli/package.json +0 -23
  50. package/packages/core/dist/config/config.d.ts +0 -32
  51. package/packages/core/dist/config/config.js +0 -43
  52. package/packages/core/dist/config/config.js.map +0 -1
  53. package/packages/core/dist/context/engine.d.ts +0 -25
  54. package/packages/core/dist/context/engine.js +0 -98
  55. package/packages/core/dist/context/engine.js.map +0 -1
  56. package/packages/core/dist/index.d.ts +0 -20
  57. package/packages/core/dist/index.js +0 -21
  58. package/packages/core/dist/index.js.map +0 -1
  59. package/packages/core/dist/llm/openai-compatible.d.ts +0 -23
  60. package/packages/core/dist/llm/openai-compatible.js +0 -177
  61. package/packages/core/dist/llm/openai-compatible.js.map +0 -1
  62. package/packages/core/dist/memory/icm-adapter.d.ts +0 -31
  63. package/packages/core/dist/memory/icm-adapter.js +0 -98
  64. package/packages/core/dist/memory/icm-adapter.js.map +0 -1
  65. package/packages/core/dist/permissions/permissions.d.ts +0 -28
  66. package/packages/core/dist/permissions/permissions.js +0 -89
  67. package/packages/core/dist/permissions/permissions.js.map +0 -1
  68. package/packages/core/dist/security/secrets.d.ts +0 -4
  69. package/packages/core/dist/security/secrets.js +0 -43
  70. package/packages/core/dist/security/secrets.js.map +0 -1
  71. package/packages/core/dist/session/store.d.ts +0 -16
  72. package/packages/core/dist/session/store.js +0 -54
  73. package/packages/core/dist/session/store.js.map +0 -1
  74. package/packages/core/dist/shell/process.d.ts +0 -26
  75. package/packages/core/dist/shell/process.js +0 -128
  76. package/packages/core/dist/shell/process.js.map +0 -1
  77. package/packages/core/dist/skills/loader.d.ts +0 -9
  78. package/packages/core/dist/skills/loader.js +0 -163
  79. package/packages/core/dist/skills/loader.js.map +0 -1
  80. package/packages/core/dist/tools/fs.d.ts +0 -10
  81. package/packages/core/dist/tools/fs.js +0 -409
  82. package/packages/core/dist/tools/fs.js.map +0 -1
  83. package/packages/core/dist/tools/git.d.ts +0 -7
  84. package/packages/core/dist/tools/git.js +0 -251
  85. package/packages/core/dist/tools/git.js.map +0 -1
  86. package/packages/core/dist/tools/mcp.d.ts +0 -42
  87. package/packages/core/dist/tools/mcp.js +0 -158
  88. package/packages/core/dist/tools/mcp.js.map +0 -1
  89. package/packages/core/dist/tools/registry.d.ts +0 -21
  90. package/packages/core/dist/tools/registry.js +0 -50
  91. package/packages/core/dist/tools/registry.js.map +0 -1
  92. package/packages/core/dist/tools/search.d.ts +0 -2
  93. package/packages/core/dist/tools/search.js +0 -243
  94. package/packages/core/dist/tools/search.js.map +0 -1
  95. package/packages/core/dist/tools/shell.d.ts +0 -8
  96. package/packages/core/dist/tools/shell.js +0 -164
  97. package/packages/core/dist/tools/shell.js.map +0 -1
  98. package/packages/core/dist/tools/web.d.ts +0 -14
  99. package/packages/core/dist/tools/web.js +0 -125
  100. package/packages/core/dist/tools/web.js.map +0 -1
  101. package/packages/core/dist/types.d.ts +0 -202
  102. package/packages/core/dist/types.js +0 -7
  103. package/packages/core/dist/types.js.map +0 -1
  104. package/packages/core/dist/util/fs.d.ts +0 -5
  105. package/packages/core/dist/util/fs.js +0 -33
  106. package/packages/core/dist/util/fs.js.map +0 -1
  107. package/packages/core/dist/util/shell-quote.d.ts +0 -7
  108. package/packages/core/dist/util/shell-quote.js +0 -20
  109. package/packages/core/dist/util/shell-quote.js.map +0 -1
  110. package/packages/core/dist/workspace/workspace.d.ts +0 -15
  111. package/packages/core/dist/workspace/workspace.js +0 -84
  112. package/packages/core/dist/workspace/workspace.js.map +0 -1
  113. package/packages/core/package.json +0 -22
package/agent.mjs ADDED
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env node
2
+ // ineed — minimal, self-contained terminal AI agent. No dependencies.
3
+
4
+ import * as fs from 'node:fs';
5
+ import * as os from 'node:os';
6
+ import * as path from 'node:path';
7
+ import { spawn } from 'node:child_process';
8
+ import * as readline from 'node:readline';
9
+
10
+ const VERSION = '0.2.0';
11
+ const CONFIG_DIR = path.join(os.homedir(), '.ineedcodes');
12
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
13
+ const A = (c, t) => process.stdout.isTTY ? `\x1b[${c}m${t}\x1b[0m` : t;
14
+ const bold = t => A('1', t), dim = t => A('2', t), green = t => A('32', t);
15
+ const red = t => A('31', t), yellow = t => A('33', t), cyan = t => A('36', t), gray = t => A('90', t);
16
+ const trunc = (s, n = 120) => { const o = s.replaceAll('\n', ' '); return o.length > n ? o.slice(0, n - 1) + '…' : o; };
17
+
18
+ /* ── config ─────────────────────────────────────────────── */
19
+ function loadConfig() {
20
+ try { return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8')); } catch { return null; }
21
+ }
22
+ function saveConfig(cfg) {
23
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
24
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2));
25
+ }
26
+
27
+ /* ── provider API (OpenAI-compatible) ───────────────────── */
28
+ async function chat(cfg, messages, tools) {
29
+ const body = { model: cfg.model, messages, temperature: 0.2 };
30
+ if (tools?.length) body.tools = tools.map(t => ({ type: 'function', function: { name: t.name, description: t.description, parameters: t.parameters } }));
31
+ const res = await fetch(cfg.baseUrl.replace(/\/+$/, '') + '/chat/completions', {
32
+ method: 'POST',
33
+ headers: { 'content-type': 'application/json', authorization: `Bearer ${cfg.apiKey}` },
34
+ body: JSON.stringify(body)
35
+ });
36
+ if (!res.ok) throw new Error(`HTTP ${res.status}: ${(await res.text()).slice(0, 200)}`);
37
+ return (await res.json()).choices?.[0]?.message ?? { role: 'assistant', content: '', tool_calls: [] };
38
+ }
39
+
40
+ /* ── tools ──────────────────────────────────────────────── */
41
+ const TOOLS = [
42
+ { name: 'read_file', description: 'Read a text file (UTF-8).', parameters: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'] } },
43
+ { name: 'write_file', description: 'Create or overwrite a file.', parameters: { type: 'object', properties: { path: { type: 'string' }, content: { type: 'string' } }, required: ['path', 'content'] } },
44
+ { name: 'list_files', description: 'List files in a directory (recursive, skips node_modules/.git/dist).', parameters: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'] } },
45
+ { name: 'shell', description: 'Run a shell command and capture stdout, stderr, exit code.', parameters: { type: 'object', properties: { command: { type: 'string' } }, required: ['command'] } }
46
+ ];
47
+
48
+ function runTool(name, input, cwd) {
49
+ try {
50
+ if (name === 'read_file') {
51
+ const p = path.resolve(cwd, input.path);
52
+ if (path.basename(p).startsWith('.env') || /(^|\/)\.ssh\//.test(p)) return { ok: false, output: 'Refused: looks like a secret file.' };
53
+ return { ok: true, output: fs.readFileSync(p, 'utf8').slice(0, 60_000) };
54
+ }
55
+ if (name === 'write_file') {
56
+ const p = path.resolve(cwd, input.path);
57
+ fs.mkdirSync(path.dirname(p), { recursive: true });
58
+ fs.writeFileSync(p, input.content);
59
+ return { ok: true, output: `Wrote ${p} (${input.content.length} bytes).` };
60
+ }
61
+ if (name === 'list_files') {
62
+ const out = [];
63
+ const skip = new Set(['node_modules', '.git', 'dist', 'build', '.next']);
64
+ (function walk(d, depth) {
65
+ if (out.length > 400 || depth > 4) return;
66
+ for (const e of fs.readdirSync(d, { withFileTypes: true })) {
67
+ if (skip.has(e.name)) continue;
68
+ out.push((e.isDirectory() ? e.name + '/' : e.name));
69
+ if (e.isDirectory()) walk(path.join(d, e.name), depth + 1);
70
+ }
71
+ })(path.resolve(cwd, input.path || '.'), 0);
72
+ return { ok: true, output: out.join('\n') };
73
+ }
74
+ if (name === 'shell') {
75
+ return { ok: true, output: 'RUNNING' }; // replaced by async shellRun
76
+ }
77
+ return { ok: false, output: `Unknown tool: ${name}` };
78
+ } catch (err) {
79
+ return { ok: false, output: `Error: ${err.message}` };
80
+ }
81
+ }
82
+
83
+ function shellRun(command, cwd) {
84
+ return new Promise(resolve => {
85
+ const child = spawn(command, { cwd, shell: true, env: { ...process.env, NO_COLOR: '1' } });
86
+ let out = '';
87
+ const timer = setTimeout(() => { try { child.kill('SIGKILL'); } catch {} out += '\n[timeout after 120s]'; }, 120_000);
88
+ child.stdout.on('data', c => { out += c.toString(); if (out.length > 100_000) child.kill('SIGKILL'); });
89
+ child.stderr.on('data', c => { out += c.toString(); });
90
+ child.on('close', code => { clearTimeout(timer); resolve({ ok: code === 0, output: `exit code: ${code}\n${out.slice(0, 20_000)}` }); });
91
+ child.on('error', err => { clearTimeout(timer); resolve({ ok: false, output: `spawn error: ${err.message}` }); });
92
+ });
93
+ }
94
+
95
+ /* ── agent loop ─────────────────────────────────────────── */
96
+ const SYSTEM = `You are ineed, an autonomous terminal agent on the user's machine.
97
+ Rules:
98
+ - Use the tools to do real work. Never invent command output; success claims need evidence.
99
+ - Prefer targeted edits over full rewrites. Work only inside the current folder.
100
+ - Never push to remotes or delete data without being asked.
101
+ - When the objective is met, reply with the final result: what changed, what you ran, and the evidence.`;
102
+
103
+ async function runObjective(cfg, objective, cwd, history) {
104
+ const messages = [
105
+ { role: 'system', content: `${SYSTEM}\nWorking directory: ${cwd}` },
106
+ ...history,
107
+ { role: 'user', content: objective }
108
+ ];
109
+ let answer = '';
110
+
111
+ for (let step = 0; step < 30; step++) {
112
+ const msg = await chat(cfg, messages, TOOLS);
113
+ messages.push(msg);
114
+
115
+ if (msg.content) { console.log(' ' + dim(trunc(msg.content, 200))); answer = msg.content; }
116
+ const calls = msg.tool_calls ?? [];
117
+ if (calls.length === 0) return { answer, history: [{ role: 'user', content: objective }, { role: 'assistant', content: answer }] };
118
+
119
+ for (const call of calls) {
120
+ const input = JSON.parse(call.function?.arguments || '{}');
121
+ console.log(' ' + cyan('▸ ' + call.function?.name) + ' ' + gray(trunc(call.function?.arguments || '', 90)));
122
+ let result;
123
+ if (call.function?.name === 'shell') result = await shellRun(input.command, cwd);
124
+ else result = runTool(call.function?.name, input, cwd);
125
+ console.log(' ' + (result.ok ? green('◂ ok') : red('◂ fail')) + ' ' + gray(trunc(result.output, 100)));
126
+ messages.push({ role: 'tool', tool_call_id: call.id, content: result.output.slice(0, 20_000) });
127
+ }
128
+ }
129
+ return { answer: answer || 'Stopped: too many steps.', history: [{ role: 'user', content: objective }, { role: 'assistant', content: answer }] };
130
+ }
131
+
132
+ /* ── setup wizard ───────────────────────────────────────── */
133
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
134
+ let askQueue = [];
135
+ let askPending = null;
136
+ let wizardMode = true;
137
+ let replHandler = null;
138
+ rl.on('line', l => {
139
+ const line = l.trim();
140
+ if (askPending) { const r = askPending; askPending = null; r(line); return; }
141
+ if (wizardMode) { askQueue.push(line); return; }
142
+ if (replHandler) replHandler(line);
143
+ });
144
+ rl.on('close', () => { if (askPending) { const r = askPending; askPending = null; r(''); } });
145
+ const ask = q => new Promise(res => {
146
+ process.stdout.write(q + ' ');
147
+ if (askQueue.length > 0) res(askQueue.shift());
148
+ else askPending = res;
149
+ });
150
+
151
+ async function wizard() {
152
+ console.log('\n' + bold('Welcome to ineed!') + ' Let me connect to your AI provider. One time only.\n');
153
+ const baseUrl = await ask(cyan('1. API base URL (e.g. https://api.openai.com/v1):'));
154
+ const apiKey = await ask(cyan('2. API key:'));
155
+ if (!baseUrl || !apiKey) { console.log(red('Both are required. Run `ineed` again.')); process.exit(1); }
156
+ console.log(dim('\nChecking…'));
157
+ let models = [];
158
+ try {
159
+ const res = await fetch(baseUrl.replace(/\/+$/, '') + '/models', { headers: { authorization: `Bearer ${apiKey}` } });
160
+ if (res.ok) models = (await res.json()).data?.map(m => m.id).filter(Boolean) ?? [];
161
+ } catch {}
162
+ if (models.length > 0) console.log(green(`✓ Connected. ${models.length} models found.`));
163
+ else console.log(yellow('⚠ Could not list models (some servers hide them). Type a model id from the provider docs.'));
164
+ const model = await ask(cyan(`3. Model id ${models.length ? '(e.g. ' + (models.find(m => /gpt-4o-mini|fast|flash/i.test(m)) ?? models[0]) + ')' : ''}:`));
165
+ if (!model) { console.log(red('Model is required. Run `ineed` again.')); process.exit(1); }
166
+
167
+ console.log(dim('\nSending a test message…'));
168
+ try {
169
+ const m = await chat({ baseUrl, apiKey, model }, [{ role: 'user', content: 'Reply with exactly: OK' }]);
170
+ console.log(green('✓ Works!') + dim(` model replied: ${trunc(m.content ?? '', 40)}`));
171
+ } catch (err) {
172
+ console.log(yellow(`⚠ Test failed: ${err.message}`));
173
+ const keep = await ask(yellow('Save anyway? [y/N]:'));
174
+ if (!/^y/i.test(keep)) { console.log(dim('Not saved. Run `ineed` to retry.')); process.exit(1); }
175
+ }
176
+ saveConfig({ baseUrl, apiKey, model });
177
+ console.log(green('\nSaved to ' + CONFIG_FILE));
178
+ console.log('All set! Type your goal below.\n');
179
+ }
180
+
181
+ /* ── main ───────────────────────────────────────────────── */
182
+ const args = process.argv.slice(2);
183
+ if (args[0] === '--version' || args[0] === '-v') { console.log(`ineed ${VERSION}`); process.exit(0); }
184
+ if (args[0] === '--help' || args[0] === '-h') {
185
+ console.log(`
186
+ ${bold('ineed')} v${VERSION} — your terminal, now autonomous
187
+
188
+ ${cyan('ineed')} interactive session here
189
+ ${cyan('ineed "do something"')} one-shot task
190
+ ${cyan('ineed --reset')} forget saved config and run the wizard again
191
+ `);
192
+ process.exit(0);
193
+ }
194
+
195
+ const cwd = process.cwd();
196
+ let cfg = loadConfig();
197
+ if (args[0] === '--reset') { try { fs.unlinkSync(CONFIG_FILE); } catch {} cfg = null; }
198
+
199
+ if (!cfg) { await wizard(); cfg = loadConfig(); }
200
+
201
+ if (args.length) {
202
+ const { answer } = await runObjective(cfg, args.join(' '), cwd, []);
203
+ console.log('\n' + bold(green('Done')) + (answer ? '\n ' + trunc(answer, 500) : ''));
204
+ process.exit(0);
205
+ }
206
+
207
+ console.log(bold(green('ineed')) + dim(` v${VERSION} · ${cfg.model} · ${cwd}`));
208
+ console.log(dim('Say what you want. /help for commands. Ctrl+C twice to exit.\n'));
209
+
210
+ // main REPL reuses the shared rl above
211
+ rl.setPrompt('\n' + bold(green('ineed')) + dim(' ❯ '));
212
+ let lastAnswer = '';
213
+ const history = [];
214
+
215
+ const handleLine = async input => {
216
+ if (!input) { rl.prompt(); return; }
217
+ if (input === '/exit' || input === '/quit' || input === 'exit') { console.log(dim('Goodbye.')); process.exit(0); }
218
+ if (input === '/help') {
219
+ console.log(' ' + cyan('/model') + ' show or change model ' + cyan('/reset') + ' redo setup ' + cyan('/exit') + ' quit');
220
+ rl.prompt(); return;
221
+ }
222
+ if (input.startsWith('/model')) {
223
+ console.log('Model: ' + bold(cfg.model) + dim(' — change with `ineed --reset` or edit ' + CONFIG_FILE));
224
+ rl.prompt(); return;
225
+ }
226
+ if (input === '/reset') { try { fs.unlinkSync(CONFIG_FILE); } catch {} console.log(dim('Config cleared. Exiting: run `ineed` to set up again.')); process.exit(0); }
227
+
228
+ try {
229
+ const { answer, history: h } = await runObjective(cfg, input, cwd, history);
230
+ history.push(...h);
231
+ lastAnswer = answer;
232
+ console.log('\n' + bold(green('Done')) + (answer ? '\n ' + answer.split('\n').slice(0, 12).join('\n ') : ''));
233
+ } catch (err) {
234
+ console.log(red('\nError: ' + err.message));
235
+ }
236
+ rl.prompt();
237
+ };
238
+
239
+ wizardMode = false;
240
+ replHandler = handleLine;
241
+ const backlog = askQueue.splice(0);
242
+ for (const line of backlog) await handleLine(line);
243
+ rl.prompt();
244
+ rl.on('SIGINT', () => { console.log(dim('\nGoodbye.')); process.exit(0); });
package/package.json CHANGED
@@ -1,36 +1,16 @@
1
1
  {
2
2
  "name": "ineedcodes",
3
- "version": "0.1.5",
4
- "description": "ineed your terminal, now autonomous. CLI-first general-purpose autonomous AI agent.",
3
+ "version": "0.2.0",
4
+ "description": "ineed: your terminal, now autonomous. Minimal, self-contained AI agent.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
8
- "ineed": "packages/cli/dist/index.js"
9
- },
10
- "files": [
11
- "packages/core/dist",
12
- "packages/agent/dist",
13
- "packages/cli/dist",
14
- "packages/core/package.json",
15
- "packages/agent/package.json",
16
- "packages/cli/package.json",
17
- "docs",
18
- "README.md",
19
- "LICENSE"
20
- ],
21
- "scripts": {
22
- "prepare": "npm run build",
23
- "build": "tsc -b packages/core packages/agent packages/cli",
24
- "clean": "rm -rf packages/*/dist",
25
- "typecheck": "tsc -b packages/core packages/agent packages/cli --force",
26
- "dev": "npm run build && node packages/cli/dist/index.js"
8
+ "ineed": "agent.mjs"
27
9
  },
10
+ "scripts": {},
28
11
  "engines": {
29
12
  "node": ">=20.0.0"
30
13
  },
31
- "workspaces": [
32
- "packages/*"
33
- ],
34
14
  "repository": {
35
15
  "type": "git"
36
16
  },
@@ -47,5 +27,10 @@
47
27
  "@types/node": "^22.10.2",
48
28
  "esbuild": "^0.28.2",
49
29
  "typescript": "^5.6.3"
50
- }
30
+ },
31
+ "files": [
32
+ "agent.mjs",
33
+ "README.md",
34
+ "LICENSE"
35
+ ]
51
36
  }
@@ -1,161 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1380" height="406" viewBox="0 0 1380 406">
2
- <defs>
3
- <linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
4
- <stop offset="0" stop-color="#161b22"/>
5
- <stop offset="1" stop-color="#0d1117"/>
6
- </linearGradient>
7
- </defs>
8
- <!-- terminal window -->
9
- <rect x="2" y="2" width="1376" height="402" rx="18" fill="url(#bg)" stroke="#30363d" stroke-width="2"/>
10
- <!-- traffic lights -->
11
- <circle cx="60" cy="28" r="7" fill="#ff5f57"/>
12
- <circle cx="86" cy="28" r="7" fill="#febc2e"/>
13
- <circle cx="112" cy="28" r="7" fill="#28c840"/>
14
- <text x="1320" y="33" text-anchor="end" font-family="ui-monospace, Menlo, monospace" font-size="14" fill="#8b949e">~/project: ineed</text>
15
-
16
- <!-- INEED block art -->
17
- <rect x="60" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
18
- <rect x="90" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
19
- <rect x="120" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
20
- <rect x="60" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
21
- <rect x="90" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
22
- <rect x="60" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
23
- <rect x="90" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
24
- <rect x="60" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
25
- <rect x="90" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
26
- <rect x="60" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
27
- <rect x="90" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
28
- <rect x="60" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
29
- <rect x="90" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
30
- <rect x="120" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
31
- <rect x="210" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
32
- <rect x="240" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
33
- <rect x="270" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
34
- <rect x="450" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
35
- <rect x="480" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
36
- <rect x="210" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
37
- <rect x="240" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
38
- <rect x="270" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
39
- <rect x="300" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
40
- <rect x="450" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
41
- <rect x="480" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
42
- <rect x="210" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
43
- <rect x="240" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
44
- <rect x="270" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
45
- <rect x="300" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
46
- <rect x="330" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
47
- <rect x="360" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
48
- <rect x="450" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
49
- <rect x="210" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
50
- <rect x="240" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
51
- <rect x="270" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
52
- <rect x="330" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
53
- <rect x="360" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
54
- <rect x="390" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
55
- <rect x="450" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
56
- <rect x="210" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
57
- <rect x="240" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
58
- <rect x="270" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
59
- <rect x="360" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
60
- <rect x="390" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
61
- <rect x="420" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
62
- <rect x="450" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
63
- <rect x="210" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
64
- <rect x="240" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
65
- <rect x="270" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
66
- <rect x="360" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
67
- <rect x="390" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
68
- <rect x="420" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
69
- <rect x="450" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
70
- <rect x="480" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
71
- <rect x="570" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
72
- <rect x="600" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
73
- <rect x="630" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
74
- <rect x="660" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
75
- <rect x="690" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
76
- <rect x="720" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
77
- <rect x="750" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
78
- <rect x="570" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
79
- <rect x="600" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
80
- <rect x="570" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
81
- <rect x="600" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
82
- <rect x="630" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
83
- <rect x="570" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
84
- <rect x="600" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
85
- <rect x="570" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
86
- <rect x="600" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
87
- <rect x="630" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
88
- <rect x="660" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
89
- <rect x="690" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
90
- <rect x="570" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
91
- <rect x="600" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
92
- <rect x="630" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
93
- <rect x="660" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
94
- <rect x="690" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
95
- <rect x="720" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
96
- <rect x="840" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
97
- <rect x="870" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
98
- <rect x="900" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
99
- <rect x="930" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
100
- <rect x="960" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
101
- <rect x="990" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
102
- <rect x="1020" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
103
- <rect x="840" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
104
- <rect x="870" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
105
- <rect x="840" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
106
- <rect x="870" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
107
- <rect x="900" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
108
- <rect x="840" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
109
- <rect x="870" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
110
- <rect x="840" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
111
- <rect x="870" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
112
- <rect x="900" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
113
- <rect x="930" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
114
- <rect x="960" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
115
- <rect x="840" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
116
- <rect x="870" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
117
- <rect x="900" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
118
- <rect x="930" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
119
- <rect x="960" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
120
- <rect x="990" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
121
- <rect x="1110" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
122
- <rect x="1140" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
123
- <rect x="1170" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
124
- <rect x="1200" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
125
- <rect x="1230" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
126
- <rect x="1260" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
127
- <rect x="1290" y="90" width="27" height="27" rx="4" fill="#4ade80"/>
128
- <rect x="1110" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
129
- <rect x="1140" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
130
- <rect x="1260" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
131
- <rect x="1290" y="120" width="27" height="27" rx="4" fill="#4ade80"/>
132
- <rect x="1110" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
133
- <rect x="1140" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
134
- <rect x="1260" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
135
- <rect x="1290" y="150" width="27" height="27" rx="4" fill="#22d3ee"/>
136
- <rect x="1110" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
137
- <rect x="1140" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
138
- <rect x="1260" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
139
- <rect x="1290" y="180" width="27" height="27" rx="4" fill="#22d3ee"/>
140
- <rect x="1110" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
141
- <rect x="1140" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
142
- <rect x="1170" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
143
- <rect x="1200" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
144
- <rect x="1230" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
145
- <rect x="1260" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
146
- <rect x="1290" y="210" width="27" height="27" rx="4" fill="#e879f9"/>
147
- <rect x="1110" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
148
- <rect x="1140" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
149
- <rect x="1170" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
150
- <rect x="1200" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
151
- <rect x="1230" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
152
- <rect x="1260" y="240" width="27" height="27" rx="4" fill="#e879f9"/>
153
-
154
- <!-- prompt line -->
155
- <text x="60" y="296" font-family="ui-monospace, Menlo, monospace" font-size="26">
156
- <tspan fill="#4ade80">❯</tspan><tspan fill="#e6edf3" dx="14">ineed</tspan><tspan fill="#8b949e" dx="14">"fix the build errors"</tspan><tspan fill="#4ade80">▮</tspan>
157
- </text>
158
-
159
- <!-- tagline -->
160
- <text x="60" y="348" font-family="ui-monospace, Menlo, monospace" font-size="17" letter-spacing="4" fill="#6e7681">YOUR TERMINAL, NOW AUTONOMOUS</text>
161
- </svg>
@@ -1,71 +0,0 @@
1
- # Configuration Reference
2
-
3
- iNeedCodes reads `~/.ineedcodes/config.json`. Every field is optional; environment variables work too.
4
-
5
- ## Providers (LLM)
6
-
7
- Any OpenAI-compatible endpoint works (OpenAI, iNeed API, local servers, …):
8
-
9
- ```json
10
- {
11
- "providers": {
12
- "default": { "baseUrl": "https://api.openai.com/v1", "apiKey": "sk-...", "model": "gpt-4.1-mini" },
13
- "fast": { "baseUrl": "http://localhost:11434/v1", "apiKey": "x", "model": "qwen2.5-coder", "contextLimit": 32768 }
14
- },
15
- "defaultProvider": "default",
16
- "roleProviders": { "lead": "default", "research": "fast" }
17
- }
18
- ```
19
-
20
- Environment variables: `INEEDCODES_BASE_URL`, `INEEDCODES_API_KEY`, `INEEDCODES_MODEL`.
21
-
22
- ## Permissions
23
-
24
- ```json
25
- { "permissions": { "mode": "workspace", "allow": ["git_remote"], "deny": ["destructive"], "maxParallelAgents": 4 } }
26
- ```
27
-
28
- - `ask`: every tool action needs approval.
29
- - `workspace` (default): reading, writing, and running commands inside the project
30
- flow freely; outside-workspace access, remote Git pushes, destructive operations,
31
- and secret access need approval.
32
- - `autonomous`: no interruptions (use with care).
33
-
34
- Change at runtime with `/permissions <mode>` or `ineedcodes -p <mode>`.
35
-
36
- ## Memory
37
-
38
- ```json
39
- { "memory": { "backend": "icm" } }
40
- ```
41
-
42
- ICM is the memory engine. Each project gets an isolated database at
43
- `~/.ineedcodes/projects/<project-id>/memory/icm.db`. Memories never mix
44
- between repositories. Set `"backend": "off"` to disable.
45
-
46
- ## Web search (optional)
47
-
48
- ```json
49
- { "webSearch": { "provider": "brave", "apiKey": "..." } }
50
- ```
51
-
52
- Without it, `fetch_url` still works for known URLs and the agent honestly
53
- reports that search is unavailable instead of pretending.
54
-
55
- ## MCP servers (optional)
56
-
57
- ```json
58
- {
59
- "mcpServers": {
60
- "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "..." } }
61
- }
62
- }
63
- ```
64
-
65
- MCP tools appear in the normal registry as `mcp_<server>_<tool>` and need no
66
- special handling by the agent. A failing server is reported, never fatal.
67
-
68
- ## Project instructions
69
-
70
- Drop an `AGENTS.md` or `.ineedcodes/instructions.md` in your repository and
71
- the agent applies them automatically when working there.
package/docs/skills.md DELETED
@@ -1,58 +0,0 @@
1
- # Skills in iNeedCodes
2
-
3
- Skills are portable instruction packs that teach the agent specialized workflows.
4
- A skill is a folder with a single `SKILL.md` file using YAML frontmatter.
5
-
6
- ## Format
7
-
8
- ```markdown
9
- ---
10
- name: my-skill
11
- description: One sentence: when the agent should use this skill.
12
- version: 1.0.0 # optional
13
- allowed-tools: # optional hint, informational
14
- - read_file
15
- - search_text
16
- ---
17
-
18
- # My Skill
19
-
20
- Instructions the agent follows when the skill is active...
21
- ```
22
-
23
- ## Locations (priority order)
24
-
25
- 1. **Project**: `<project>/.ineedcodes/skills/<name>/SKILL.md`
26
- 2. **Project (alternate)**: `<project>/skills/<name>/SKILL.md`
27
- 3. **Global user**: `~/.ineedcodes/skills/<name>/SKILL.md`
28
- 4. **Built-in**: shipped with iNeedCodes (`boost`, `humanizer`)
29
-
30
- A project skill with the same name overrides the global one, which overrides
31
- the built-in. `/skills` shows each skill's scope so overrides are visible.
32
-
33
- ## Invocation
34
-
35
- - Explicit: `/boost`, `/humanizer`, or just name the skill in a sentence.
36
- - Natural: *"Use boost to verify this implementation."*
37
- - Automatic: the Lead Agent may pick a skill when its description clearly matches the task.
38
-
39
- ## Built-in: boost
40
-
41
- An advanced execution-and-verification protocol. When invoked, the agent:
42
-
43
- 1. Creates an isolated Git worktree (`.ineedcodes/boost-<timestamp>`)
44
- 2. Investigates root causes
45
- 3. Implements changes there; your working tree stays clean
46
- 4. Runs tests with real evidence
47
- 5. Verifies independently
48
- 6. Reconciles (merges) only on success, with your approval
49
- 7. Cleans up the worktree either way
50
-
51
- A failed Boost run never merges broken changes. Good for hard debugging,
52
- major refactors, and regression-sensitive work. Simple tasks should not use it.
53
-
54
- ## Built-in: humanizer
55
-
56
- Rewrites prose (README, docs, release notes, explanations) so it reads naturally.
57
- Never applied to code, JSON, YAML, commands, or technical values. Meaning and
58
- technical facts are always preserved.
@@ -1,34 +0,0 @@
1
- import type { ToolRegistry, ToolContext, ToolResult } from '@ineedcodes/core';
2
- /**
3
- * Boost integration (plan §19–20): an advanced execution and verification
4
- * protocol running on top of the multi-agent runtime, in an isolated
5
- * Git worktree. The user's active working tree stays clean.
6
- *
7
- * Lifecycle: start → investigate → implement → test → verify → reconcile | abort → cleanup
8
- */
9
- export type BoostPhase = 'start' | 'investigate' | 'implement' | 'test' | 'verify' | 'reconcile' | 'abort' | 'cleanup';
10
- export interface BoostRun {
11
- id: string;
12
- worktreePath: string;
13
- branch: string;
14
- phase: BoostPhase;
15
- startedAt: number;
16
- }
17
- export declare class BoostIntegration {
18
- private readonly registry;
19
- private readonly toolContext;
20
- private readonly emit;
21
- private run?;
22
- constructor(registry: ToolRegistry, toolContext: ToolContext, emit: (event: import('./events.js').RuntimeEvent) => Promise<void>);
23
- active(): boolean;
24
- current(): BoostRun | undefined;
25
- private exec;
26
- start(objective: string): Promise<ToolResult>;
27
- worktreeContext(): ToolContext | undefined;
28
- /** Commit any uncommitted work inside the Boost worktree so it can merge. */
29
- private commitWorktreeChanges;
30
- reconcile(): Promise<ToolResult>;
31
- abort(reason: string): Promise<ToolResult>;
32
- cleanup(): Promise<ToolResult>;
33
- }
34
- export declare const BOOST_PHASES: readonly BoostPhase[];