ineedcodes 0.1.7 → 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.
- package/agent.mjs +244 -0
- package/package.json +10 -25
- package/docs/assets/ineed-logo.svg +0 -161
- package/docs/configuration.md +0 -71
- package/docs/skills.md +0 -58
- package/packages/agent/dist/boost.d.ts +0 -34
- package/packages/agent/dist/boost.js +0 -138
- package/packages/agent/dist/boost.js.map +0 -1
- package/packages/agent/dist/events.d.ts +0 -67
- package/packages/agent/dist/events.js +0 -16
- package/packages/agent/dist/events.js.map +0 -1
- package/packages/agent/dist/index.d.ts +0 -6
- package/packages/agent/dist/index.js +0 -7
- package/packages/agent/dist/index.js.map +0 -1
- package/packages/agent/dist/lead-agent.d.ts +0 -85
- package/packages/agent/dist/lead-agent.js +0 -235
- package/packages/agent/dist/lead-agent.js.map +0 -1
- package/packages/agent/dist/orchestrator.d.ts +0 -43
- package/packages/agent/dist/orchestrator.js +0 -135
- package/packages/agent/dist/orchestrator.js.map +0 -1
- package/packages/agent/dist/runtime.d.ts +0 -44
- package/packages/agent/dist/runtime.js +0 -265
- package/packages/agent/dist/runtime.js.map +0 -1
- package/packages/agent/dist/system-prompts.d.ts +0 -24
- package/packages/agent/dist/system-prompts.js +0 -91
- package/packages/agent/dist/system-prompts.js.map +0 -1
- package/packages/agent/package.json +0 -21
- package/packages/cli/dist/index.d.ts +0 -3
- package/packages/cli/dist/index.js +0 -11426
- package/packages/cli/dist/index.js.map +0 -1
- package/packages/cli/dist/setup.d.ts +0 -37
- package/packages/cli/dist/setup.js +0 -250
- package/packages/cli/dist/setup.js.map +0 -1
- package/packages/cli/dist/tools-setup.d.ts +0 -12
- package/packages/cli/dist/tools-setup.js +0 -28
- package/packages/cli/dist/tools-setup.js.map +0 -1
- package/packages/cli/dist/ui/approval.d.ts +0 -12
- package/packages/cli/dist/ui/approval.js +0 -52
- package/packages/cli/dist/ui/approval.js.map +0 -1
- package/packages/cli/dist/ui/colors.d.ts +0 -14
- package/packages/cli/dist/ui/colors.js +0 -21
- package/packages/cli/dist/ui/colors.js.map +0 -1
- package/packages/cli/dist/ui/prompts.d.ts +0 -46
- package/packages/cli/dist/ui/prompts.js +0 -135
- package/packages/cli/dist/ui/prompts.js.map +0 -1
- package/packages/cli/dist/ui/renderer.d.ts +0 -13
- package/packages/cli/dist/ui/renderer.js +0 -95
- package/packages/cli/dist/ui/renderer.js.map +0 -1
- package/packages/cli/package.json +0 -23
- package/packages/core/dist/config/config.d.ts +0 -32
- package/packages/core/dist/config/config.js +0 -43
- package/packages/core/dist/config/config.js.map +0 -1
- package/packages/core/dist/context/engine.d.ts +0 -25
- package/packages/core/dist/context/engine.js +0 -98
- package/packages/core/dist/context/engine.js.map +0 -1
- package/packages/core/dist/index.d.ts +0 -20
- package/packages/core/dist/index.js +0 -21
- package/packages/core/dist/index.js.map +0 -1
- package/packages/core/dist/llm/openai-compatible.d.ts +0 -23
- package/packages/core/dist/llm/openai-compatible.js +0 -177
- package/packages/core/dist/llm/openai-compatible.js.map +0 -1
- package/packages/core/dist/memory/icm-adapter.d.ts +0 -31
- package/packages/core/dist/memory/icm-adapter.js +0 -98
- package/packages/core/dist/memory/icm-adapter.js.map +0 -1
- package/packages/core/dist/permissions/permissions.d.ts +0 -28
- package/packages/core/dist/permissions/permissions.js +0 -89
- package/packages/core/dist/permissions/permissions.js.map +0 -1
- package/packages/core/dist/security/secrets.d.ts +0 -4
- package/packages/core/dist/security/secrets.js +0 -43
- package/packages/core/dist/security/secrets.js.map +0 -1
- package/packages/core/dist/session/store.d.ts +0 -16
- package/packages/core/dist/session/store.js +0 -54
- package/packages/core/dist/session/store.js.map +0 -1
- package/packages/core/dist/shell/process.d.ts +0 -26
- package/packages/core/dist/shell/process.js +0 -128
- package/packages/core/dist/shell/process.js.map +0 -1
- package/packages/core/dist/skills/loader.d.ts +0 -9
- package/packages/core/dist/skills/loader.js +0 -163
- package/packages/core/dist/skills/loader.js.map +0 -1
- package/packages/core/dist/tools/fs.d.ts +0 -10
- package/packages/core/dist/tools/fs.js +0 -409
- package/packages/core/dist/tools/fs.js.map +0 -1
- package/packages/core/dist/tools/git.d.ts +0 -7
- package/packages/core/dist/tools/git.js +0 -251
- package/packages/core/dist/tools/git.js.map +0 -1
- package/packages/core/dist/tools/mcp.d.ts +0 -42
- package/packages/core/dist/tools/mcp.js +0 -158
- package/packages/core/dist/tools/mcp.js.map +0 -1
- package/packages/core/dist/tools/registry.d.ts +0 -21
- package/packages/core/dist/tools/registry.js +0 -50
- package/packages/core/dist/tools/registry.js.map +0 -1
- package/packages/core/dist/tools/search.d.ts +0 -2
- package/packages/core/dist/tools/search.js +0 -243
- package/packages/core/dist/tools/search.js.map +0 -1
- package/packages/core/dist/tools/shell.d.ts +0 -8
- package/packages/core/dist/tools/shell.js +0 -164
- package/packages/core/dist/tools/shell.js.map +0 -1
- package/packages/core/dist/tools/web.d.ts +0 -14
- package/packages/core/dist/tools/web.js +0 -125
- package/packages/core/dist/tools/web.js.map +0 -1
- package/packages/core/dist/types.d.ts +0 -202
- package/packages/core/dist/types.js +0 -7
- package/packages/core/dist/types.js.map +0 -1
- package/packages/core/dist/util/fs.d.ts +0 -5
- package/packages/core/dist/util/fs.js +0 -33
- package/packages/core/dist/util/fs.js.map +0 -1
- package/packages/core/dist/util/shell-quote.d.ts +0 -7
- package/packages/core/dist/util/shell-quote.js +0 -20
- package/packages/core/dist/util/shell-quote.js.map +0 -1
- package/packages/core/dist/workspace/workspace.d.ts +0 -15
- package/packages/core/dist/workspace/workspace.js +0 -84
- package/packages/core/dist/workspace/workspace.js.map +0 -1
- 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.
|
|
4
|
-
"description": "ineed
|
|
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": "
|
|
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>
|
package/docs/configuration.md
DELETED
|
@@ -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[];
|