ineedcodes 0.1.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 (114) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -0
  3. package/docs/assets/ineed-logo.svg +161 -0
  4. package/docs/configuration.md +71 -0
  5. package/docs/skills.md +58 -0
  6. package/package.json +41 -0
  7. package/packages/agent/dist/boost.d.ts +34 -0
  8. package/packages/agent/dist/boost.js +138 -0
  9. package/packages/agent/dist/boost.js.map +1 -0
  10. package/packages/agent/dist/events.d.ts +67 -0
  11. package/packages/agent/dist/events.js +16 -0
  12. package/packages/agent/dist/events.js.map +1 -0
  13. package/packages/agent/dist/index.d.ts +6 -0
  14. package/packages/agent/dist/index.js +7 -0
  15. package/packages/agent/dist/index.js.map +1 -0
  16. package/packages/agent/dist/lead-agent.d.ts +85 -0
  17. package/packages/agent/dist/lead-agent.js +235 -0
  18. package/packages/agent/dist/lead-agent.js.map +1 -0
  19. package/packages/agent/dist/orchestrator.d.ts +43 -0
  20. package/packages/agent/dist/orchestrator.js +135 -0
  21. package/packages/agent/dist/orchestrator.js.map +1 -0
  22. package/packages/agent/dist/runtime.d.ts +44 -0
  23. package/packages/agent/dist/runtime.js +265 -0
  24. package/packages/agent/dist/runtime.js.map +1 -0
  25. package/packages/agent/dist/system-prompts.d.ts +24 -0
  26. package/packages/agent/dist/system-prompts.js +91 -0
  27. package/packages/agent/dist/system-prompts.js.map +1 -0
  28. package/packages/agent/package.json +21 -0
  29. package/packages/cli/dist/index.d.ts +3 -0
  30. package/packages/cli/dist/index.js +567 -0
  31. package/packages/cli/dist/index.js.map +1 -0
  32. package/packages/cli/dist/setup.d.ts +37 -0
  33. package/packages/cli/dist/setup.js +240 -0
  34. package/packages/cli/dist/setup.js.map +1 -0
  35. package/packages/cli/dist/tools-setup.d.ts +12 -0
  36. package/packages/cli/dist/tools-setup.js +28 -0
  37. package/packages/cli/dist/tools-setup.js.map +1 -0
  38. package/packages/cli/dist/ui/approval.d.ts +12 -0
  39. package/packages/cli/dist/ui/approval.js +52 -0
  40. package/packages/cli/dist/ui/approval.js.map +1 -0
  41. package/packages/cli/dist/ui/colors.d.ts +14 -0
  42. package/packages/cli/dist/ui/colors.js +21 -0
  43. package/packages/cli/dist/ui/colors.js.map +1 -0
  44. package/packages/cli/dist/ui/prompts.d.ts +46 -0
  45. package/packages/cli/dist/ui/prompts.js +135 -0
  46. package/packages/cli/dist/ui/prompts.js.map +1 -0
  47. package/packages/cli/dist/ui/renderer.d.ts +13 -0
  48. package/packages/cli/dist/ui/renderer.js +95 -0
  49. package/packages/cli/dist/ui/renderer.js.map +1 -0
  50. package/packages/cli/package.json +23 -0
  51. package/packages/core/dist/config/config.d.ts +32 -0
  52. package/packages/core/dist/config/config.js +43 -0
  53. package/packages/core/dist/config/config.js.map +1 -0
  54. package/packages/core/dist/context/engine.d.ts +25 -0
  55. package/packages/core/dist/context/engine.js +98 -0
  56. package/packages/core/dist/context/engine.js.map +1 -0
  57. package/packages/core/dist/index.d.ts +20 -0
  58. package/packages/core/dist/index.js +21 -0
  59. package/packages/core/dist/index.js.map +1 -0
  60. package/packages/core/dist/llm/openai-compatible.d.ts +23 -0
  61. package/packages/core/dist/llm/openai-compatible.js +177 -0
  62. package/packages/core/dist/llm/openai-compatible.js.map +1 -0
  63. package/packages/core/dist/memory/icm-adapter.d.ts +31 -0
  64. package/packages/core/dist/memory/icm-adapter.js +98 -0
  65. package/packages/core/dist/memory/icm-adapter.js.map +1 -0
  66. package/packages/core/dist/permissions/permissions.d.ts +28 -0
  67. package/packages/core/dist/permissions/permissions.js +89 -0
  68. package/packages/core/dist/permissions/permissions.js.map +1 -0
  69. package/packages/core/dist/security/secrets.d.ts +4 -0
  70. package/packages/core/dist/security/secrets.js +43 -0
  71. package/packages/core/dist/security/secrets.js.map +1 -0
  72. package/packages/core/dist/session/store.d.ts +16 -0
  73. package/packages/core/dist/session/store.js +54 -0
  74. package/packages/core/dist/session/store.js.map +1 -0
  75. package/packages/core/dist/shell/process.d.ts +26 -0
  76. package/packages/core/dist/shell/process.js +128 -0
  77. package/packages/core/dist/shell/process.js.map +1 -0
  78. package/packages/core/dist/skills/loader.d.ts +9 -0
  79. package/packages/core/dist/skills/loader.js +163 -0
  80. package/packages/core/dist/skills/loader.js.map +1 -0
  81. package/packages/core/dist/tools/fs.d.ts +10 -0
  82. package/packages/core/dist/tools/fs.js +409 -0
  83. package/packages/core/dist/tools/fs.js.map +1 -0
  84. package/packages/core/dist/tools/git.d.ts +7 -0
  85. package/packages/core/dist/tools/git.js +251 -0
  86. package/packages/core/dist/tools/git.js.map +1 -0
  87. package/packages/core/dist/tools/mcp.d.ts +42 -0
  88. package/packages/core/dist/tools/mcp.js +158 -0
  89. package/packages/core/dist/tools/mcp.js.map +1 -0
  90. package/packages/core/dist/tools/registry.d.ts +21 -0
  91. package/packages/core/dist/tools/registry.js +50 -0
  92. package/packages/core/dist/tools/registry.js.map +1 -0
  93. package/packages/core/dist/tools/search.d.ts +2 -0
  94. package/packages/core/dist/tools/search.js +243 -0
  95. package/packages/core/dist/tools/search.js.map +1 -0
  96. package/packages/core/dist/tools/shell.d.ts +8 -0
  97. package/packages/core/dist/tools/shell.js +164 -0
  98. package/packages/core/dist/tools/shell.js.map +1 -0
  99. package/packages/core/dist/tools/web.d.ts +14 -0
  100. package/packages/core/dist/tools/web.js +125 -0
  101. package/packages/core/dist/tools/web.js.map +1 -0
  102. package/packages/core/dist/types.d.ts +202 -0
  103. package/packages/core/dist/types.js +7 -0
  104. package/packages/core/dist/types.js.map +1 -0
  105. package/packages/core/dist/util/fs.d.ts +5 -0
  106. package/packages/core/dist/util/fs.js +33 -0
  107. package/packages/core/dist/util/fs.js.map +1 -0
  108. package/packages/core/dist/util/shell-quote.d.ts +7 -0
  109. package/packages/core/dist/util/shell-quote.js +20 -0
  110. package/packages/core/dist/util/shell-quote.js.map +1 -0
  111. package/packages/core/dist/workspace/workspace.d.ts +15 -0
  112. package/packages/core/dist/workspace/workspace.js +84 -0
  113. package/packages/core/dist/workspace/workspace.js.map +1 -0
  114. package/packages/core/package.json +21 -0
@@ -0,0 +1,251 @@
1
+ import { execShell } from '../shell/process.js';
2
+ import { shellQuote } from '../util/shell-quote.js';
3
+ import { str, num, bool, resolvePath, fail, guardPath } from './fs.js';
4
+ /**
5
+ * First-class Git tools. These are structured wrappers: the model does not
6
+ * need to build raw Git command lines for common operations. Raw Git still
7
+ * works through shell_exec when needed.
8
+ */
9
+ export function createGitTools() {
10
+ const git_status = {
11
+ name: 'git_status',
12
+ description: 'Show the current Git branch, staged/unstaged changes, and untracked files.',
13
+ permissions: ['read'],
14
+ readonly: true,
15
+ inputSchema: { type: 'object', properties: {} },
16
+ async execute(_input, ctx) {
17
+ const guard = await guardRepo(ctx);
18
+ if (guard)
19
+ return guard;
20
+ const branch = await execShell('git rev-parse --abbrev-ref HEAD', ctx.cwd);
21
+ const status = await execShell('git status --porcelain', ctx.cwd);
22
+ return {
23
+ ok: branch.exitCode === 0,
24
+ summary: branch.exitCode === 0 ? `Git status for branch ${branch.stdout.trim()}.` : 'Not a Git repository.',
25
+ data: {
26
+ branch: branch.stdout.trim() || null,
27
+ changes: status.stdout || '(clean)'
28
+ }
29
+ };
30
+ }
31
+ };
32
+ const git_diff = {
33
+ name: 'git_diff',
34
+ description: 'Show the diff of changes. Use staged=true to diff the index.',
35
+ permissions: ['read'],
36
+ readonly: true,
37
+ inputSchema: {
38
+ type: 'object',
39
+ properties: { staged: { type: 'boolean' }, path: { type: 'string' } }
40
+ },
41
+ async execute(input, ctx) {
42
+ const guard = await guardRepo(ctx);
43
+ if (guard)
44
+ return guard;
45
+ const args = ['git', 'diff', '--stat'];
46
+ if (bool(input, 'staged'))
47
+ args.push('--cached');
48
+ const target = str(input, 'path');
49
+ if (target)
50
+ args.push('--', target);
51
+ const result = await execShell(args.join(' '), ctx.cwd);
52
+ const full = await execShell(args.join(' ').replace('--stat', ''), ctx.cwd);
53
+ return {
54
+ ok: result.exitCode === 0,
55
+ summary: result.stdout.trim() ? 'Diff produced.' : 'No changes to diff.',
56
+ data: { stat: result.stdout, patch: full.stdout.slice(0, 32_000) }
57
+ };
58
+ }
59
+ };
60
+ const git_log = {
61
+ name: 'git_log',
62
+ description: 'Show recent commit history.',
63
+ permissions: ['read'],
64
+ readonly: true,
65
+ inputSchema: { type: 'object', properties: { count: { type: 'number' } } },
66
+ async execute(input, ctx) {
67
+ const guard = await guardRepo(ctx);
68
+ if (guard)
69
+ return guard;
70
+ const count = num(input, 'count', 10);
71
+ const result = await execShell(`git log --oneline -${Math.min(100, Math.max(1, count))}`, ctx.cwd);
72
+ return {
73
+ ok: result.exitCode === 0,
74
+ summary: result.exitCode === 0 ? `${result.stdout.split('\n').filter(Boolean).length} recent commit(s).` : 'No commits yet.',
75
+ data: result.stdout
76
+ };
77
+ }
78
+ };
79
+ const git_branch = {
80
+ name: 'git_branch',
81
+ description: 'Create, list, or switch branches. mode: list | create | checkout.',
82
+ permissions: ['write'],
83
+ readonly: false,
84
+ inputSchema: {
85
+ type: 'object',
86
+ properties: {
87
+ mode: { type: 'string', enum: ['list', 'create', 'checkout'] },
88
+ name: { type: 'string' }
89
+ },
90
+ required: ['mode']
91
+ },
92
+ async execute(input, ctx) {
93
+ const guard = await guardRepo(ctx);
94
+ if (guard)
95
+ return guard;
96
+ const mode = str(input, 'mode', 'list');
97
+ const name = str(input, 'name');
98
+ if (mode === 'list') {
99
+ const result = await execShell('git branch -a', ctx.cwd);
100
+ return { ok: result.exitCode === 0, summary: 'Branches listed.', data: result.stdout };
101
+ }
102
+ if (!name)
103
+ return fail(`Branch name is required for mode "${mode}".`, 'missing_name');
104
+ const cmd = mode === 'create' ? `git checkout -b ${shellQuote(name)}` : `git checkout ${shellQuote(name)}`;
105
+ const result = await execShell(cmd, ctx.cwd);
106
+ return {
107
+ ok: result.exitCode === 0,
108
+ summary: result.exitCode === 0 ? `${mode === 'create' ? 'Created and switched to' : 'Switched to'} branch ${name}.` : `Branch operation failed: ${result.stderr.trim()}`,
109
+ data: result.stderr
110
+ };
111
+ }
112
+ };
113
+ const git_worktree = {
114
+ name: 'git_worktree',
115
+ description: 'Manage Git worktrees. mode: list | add | remove. Used for isolated experimental work (e.g. Boost runs).',
116
+ permissions: ['write'],
117
+ readonly: false,
118
+ inputSchema: {
119
+ type: 'object',
120
+ properties: {
121
+ mode: { type: 'string', enum: ['list', 'add', 'remove'] },
122
+ path: { type: 'string' },
123
+ branch: { type: 'string' }
124
+ },
125
+ required: ['mode']
126
+ },
127
+ async execute(input, ctx) {
128
+ const guard = await guardRepo(ctx);
129
+ if (guard)
130
+ return guard;
131
+ const mode = str(input, 'mode', 'list');
132
+ if (mode === 'list') {
133
+ const result = await execShell('git worktree list', ctx.cwd);
134
+ return { ok: result.exitCode === 0, summary: 'Worktrees listed.', data: result.stdout };
135
+ }
136
+ const wPath = str(input, 'path');
137
+ if (!wPath)
138
+ return fail('path is required for add/remove.', 'missing_path');
139
+ if (mode === 'add') {
140
+ const branch = str(input, 'branch') || `ineedcodes-${Date.now()}`;
141
+ const result = await execShell(`git worktree add -b ${shellQuote(branch)} ${shellQuote(wPath)}`, ctx.cwd);
142
+ return {
143
+ ok: result.exitCode === 0,
144
+ summary: result.exitCode === 0 ? `Created worktree ${wPath} on branch ${branch}.` : `Worktree add failed: ${result.stderr.trim()}`,
145
+ data: { path: wPath, branch }
146
+ };
147
+ }
148
+ const result = await execShell(`git worktree remove ${shellQuote(wPath)} --force`, ctx.cwd);
149
+ return {
150
+ ok: result.exitCode === 0,
151
+ summary: result.exitCode === 0 ? `Removed worktree ${wPath}.` : `Worktree remove failed: ${result.stderr.trim()}`
152
+ };
153
+ }
154
+ };
155
+ const git_add = {
156
+ name: 'git_add',
157
+ description: 'Stage files for commit. Pass "*" to stage everything.',
158
+ permissions: ['write'],
159
+ readonly: false,
160
+ inputSchema: { type: 'object', properties: { paths: { type: 'string' } }, required: ['paths'] },
161
+ async execute(input, ctx) {
162
+ const guard = await guardRepo(ctx);
163
+ if (guard)
164
+ return guard;
165
+ const paths = str(input, 'paths', '.');
166
+ const result = await execShell(`git add ${paths === '*' ? '.' : shellQuote(paths)}`, ctx.cwd);
167
+ return {
168
+ ok: result.exitCode === 0,
169
+ summary: result.exitCode === 0 ? `Staged ${paths}.` : `git add failed: ${result.stderr.trim()}`
170
+ };
171
+ }
172
+ };
173
+ const git_commit = {
174
+ name: 'git_commit',
175
+ description: 'Create a commit from staged changes with the given message.',
176
+ permissions: ['write'],
177
+ readonly: false,
178
+ inputSchema: { type: 'object', properties: { message: { type: 'string' } }, required: ['message'] },
179
+ async execute(input, ctx) {
180
+ const guard = await guardRepo(ctx);
181
+ if (guard)
182
+ return guard;
183
+ const message = str(input, 'message');
184
+ if (!message.trim())
185
+ return fail('Commit message must not be empty.', 'empty_message');
186
+ const result = await execShell(`git commit -m ${shellQuote(message)}`, ctx.cwd);
187
+ return {
188
+ ok: result.exitCode === 0,
189
+ summary: result.exitCode === 0 ? `Committed: ${result.stdout.trim().split('\n')[0]}` : `Commit failed: ${result.stderr.trim()}`,
190
+ data: { stdout: result.stdout, stderr: result.stderr }
191
+ };
192
+ }
193
+ };
194
+ const git_restore = {
195
+ name: 'git_restore',
196
+ description: 'Discard unstaged changes in a file (git restore). Destructive: needs approval.',
197
+ permissions: ['write', 'destructive'],
198
+ readonly: false,
199
+ inputSchema: { type: 'object', properties: { path: { type: 'string' } }, required: ['path'] },
200
+ async execute(input, ctx) {
201
+ const guard = await guardRepo(ctx);
202
+ if (guard)
203
+ return guard;
204
+ const target = str(input, 'path');
205
+ const decision = await ctx.permissions.check(['destructive'], `discard changes in ${target}`);
206
+ if (!decision.allowed)
207
+ return fail(decision.reason, 'destructive_denied');
208
+ const result = await execShell(`git restore ${shellQuote(target)}`, ctx.cwd);
209
+ return {
210
+ ok: result.exitCode === 0,
211
+ summary: result.exitCode === 0 ? `Restored ${target} to last committed state.` : `git restore failed: ${result.stderr.trim()}`
212
+ };
213
+ }
214
+ };
215
+ const git_push = {
216
+ name: 'git_push',
217
+ description: 'Push commits to a remote. Requires git_remote permission; never runs automatically.',
218
+ permissions: ['git_remote'],
219
+ readonly: false,
220
+ inputSchema: {
221
+ type: 'object',
222
+ properties: { remote: { type: 'string' }, branch: { type: 'string' } }
223
+ },
224
+ async execute(input, ctx) {
225
+ const guard = await guardRepo(ctx);
226
+ if (guard)
227
+ return guard;
228
+ const remote = str(input, 'remote', 'origin');
229
+ const branch = str(input, 'branch');
230
+ const cmd = branch ? `git push ${shellQuote(remote)} ${shellQuote(branch)}` : `git push ${shellQuote(remote)}`;
231
+ const result = await execShell(cmd, ctx.cwd);
232
+ return {
233
+ ok: result.exitCode === 0,
234
+ summary: result.exitCode === 0 ? 'Pushed to remote.' : `Push failed: ${result.stderr.trim()}`,
235
+ data: { stdout: result.stdout, stderr: result.stderr }
236
+ };
237
+ }
238
+ };
239
+ return [
240
+ git_status, git_diff, git_log, git_branch, git_worktree,
241
+ git_add, git_commit, git_restore, git_push
242
+ ];
243
+ }
244
+ async function guardRepo(ctx) {
245
+ const cwd = resolvePath(ctx, '.');
246
+ const guard = await guardPath(ctx, cwd, false);
247
+ if (guard)
248
+ return guard;
249
+ return null;
250
+ }
251
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/tools/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import type { Tool } from '../types.js';
3
+ /**
4
+ * Native MCP (Model Context Protocol) client over stdio.
5
+ * Connects to configured MCP servers, discovers their tools, and adapts
6
+ * them into the normal iNeedCodes tool registry (plan §28).
7
+ * Protocol: JSON-RPC 2.0, one JSON message per line.
8
+ */
9
+ export interface MCPServerConfig {
10
+ command: string;
11
+ args?: string[];
12
+ env?: Record<string, string>;
13
+ }
14
+ interface MCPToolDef {
15
+ name: string;
16
+ description?: string;
17
+ inputSchema?: Record<string, unknown>;
18
+ }
19
+ export declare class MCPConnection {
20
+ private readonly serverName;
21
+ private readonly config;
22
+ private child?;
23
+ private pending;
24
+ private buffer;
25
+ private nextId;
26
+ constructor(serverName: string, config: MCPServerConfig);
27
+ connect(timeoutMs?: number): Promise<void>;
28
+ private handleLine;
29
+ private request;
30
+ private notify;
31
+ listTools(): Promise<MCPToolDef[]>;
32
+ callTool(name: string, args: Record<string, unknown>): Promise<unknown>;
33
+ close(): void;
34
+ }
35
+ /** Adapt MCP tools into the iNeedCodes Tool interface. */
36
+ export declare function connectMCPServer(serverName: string, config: MCPServerConfig): Promise<Tool[]>;
37
+ /** Connect every configured MCP server; failures are reported, never fatal. */
38
+ export declare function connectAllMCPServers(servers: Record<string, MCPServerConfig> | undefined): Promise<{
39
+ tools: Tool[];
40
+ errors: string[];
41
+ }>;
42
+ export { randomUUID };
@@ -0,0 +1,158 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { randomUUID } from 'node:crypto';
3
+ export class MCPConnection {
4
+ serverName;
5
+ config;
6
+ child;
7
+ pending = new Map();
8
+ buffer = '';
9
+ nextId = 1;
10
+ constructor(serverName, config) {
11
+ this.serverName = serverName;
12
+ this.config = config;
13
+ }
14
+ async connect(timeoutMs = 10_000) {
15
+ this.child = spawn(this.config.command, this.config.args ?? [], {
16
+ stdio: ['pipe', 'pipe', 'pipe'],
17
+ env: { ...process.env, ...this.config.env }
18
+ });
19
+ this.child.stdout?.on('data', (chunk) => {
20
+ this.buffer += chunk.toString('utf8');
21
+ let newline;
22
+ while ((newline = this.buffer.indexOf('\n')) >= 0) {
23
+ const line = this.buffer.slice(0, newline).trim();
24
+ this.buffer = this.buffer.slice(newline + 1);
25
+ if (line)
26
+ this.handleLine(line);
27
+ }
28
+ });
29
+ this.child.stderr?.on('data', (chunk) => {
30
+ // Server logs go to our stderr for debugging; never into model context.
31
+ process.stderr.write(`[mcp:${this.serverName}] ${chunk.toString('utf8')}`);
32
+ });
33
+ this.child.on('exit', () => {
34
+ for (const pending of this.pending.values()) {
35
+ clearTimeout(pending.timer);
36
+ pending.reject(new Error(`MCP server "${this.serverName}" exited.`));
37
+ }
38
+ this.pending.clear();
39
+ });
40
+ await this.request('initialize', {
41
+ protocolVersion: '2024-11-05',
42
+ capabilities: {},
43
+ clientInfo: { name: 'ineedcodes', version: '0.1.0' }
44
+ }, timeoutMs);
45
+ this.notify('notifications/initialized', {});
46
+ }
47
+ handleLine(line) {
48
+ let msg;
49
+ try {
50
+ msg = JSON.parse(line);
51
+ }
52
+ catch {
53
+ return;
54
+ }
55
+ if (msg.id !== undefined && this.pending.has(String(msg.id))) {
56
+ const pending = this.pending.get(String(msg.id));
57
+ this.pending.delete(String(msg.id));
58
+ clearTimeout(pending.timer);
59
+ if (msg.error) {
60
+ pending.reject(new Error(msg.error.message ?? 'MCP request failed'));
61
+ }
62
+ else {
63
+ pending.resolve(msg.result);
64
+ }
65
+ }
66
+ }
67
+ request(method, params, timeoutMs = 30_000) {
68
+ return new Promise((resolve, reject) => {
69
+ if (!this.child?.stdin?.writable) {
70
+ reject(new Error(`MCP server "${this.serverName}" is not connected.`));
71
+ return;
72
+ }
73
+ const id = String(this.nextId++);
74
+ const timer = setTimeout(() => {
75
+ this.pending.delete(id);
76
+ reject(new Error(`MCP request ${method} timed out.`));
77
+ }, timeoutMs);
78
+ this.pending.set(id, { resolve, reject, timer });
79
+ const msg = JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n';
80
+ this.child.stdin.write(msg);
81
+ });
82
+ }
83
+ notify(method, params) {
84
+ if (!this.child?.stdin?.writable)
85
+ return;
86
+ this.child.stdin.write(JSON.stringify({ jsonrpc: '2.0', method, params }) + '\n');
87
+ }
88
+ async listTools() {
89
+ const result = await this.request('tools/list', {});
90
+ return result.tools ?? [];
91
+ }
92
+ async callTool(name, args) {
93
+ return this.request('tools/call', { name, arguments: args }, 120_000);
94
+ }
95
+ close() {
96
+ try {
97
+ this.child?.kill('SIGTERM');
98
+ }
99
+ catch {
100
+ // best effort
101
+ }
102
+ }
103
+ }
104
+ /** Adapt MCP tools into the iNeedCodes Tool interface. */
105
+ export async function connectMCPServer(serverName, config) {
106
+ const conn = new MCPConnection(serverName, config);
107
+ await conn.connect();
108
+ const defs = await conn.listTools();
109
+ const tools = defs.map((def) => {
110
+ const mcpName = `mcp_${serverName}_${def.name}`;
111
+ const tool = {
112
+ name: mcpName,
113
+ description: `[MCP:${serverName}] ${def.description ?? def.name}`,
114
+ inputSchema: def.inputSchema ?? { type: 'object', properties: {} },
115
+ permissions: ['read', 'execute'],
116
+ readonly: false,
117
+ async execute(input, ctx) {
118
+ void ctx;
119
+ try {
120
+ const result = await conn.callTool(def.name, (input ?? {}));
121
+ const text = (result.content ?? [])
122
+ .map((c) => c.text ?? '')
123
+ .filter(Boolean)
124
+ .join('\n');
125
+ return {
126
+ ok: !result.isError,
127
+ summary: text.split('\n')[0]?.slice(0, 200) ?? `MCP tool ${def.name} completed.`,
128
+ data: text
129
+ };
130
+ }
131
+ catch (err) {
132
+ const message = err instanceof Error ? err.message : String(err);
133
+ return { ok: false, summary: `MCP tool ${def.name} failed: ${message}`, error: 'mcp_error' };
134
+ }
135
+ }
136
+ };
137
+ return tool;
138
+ });
139
+ return tools;
140
+ }
141
+ /** Connect every configured MCP server; failures are reported, never fatal. */
142
+ export async function connectAllMCPServers(servers) {
143
+ const tools = [];
144
+ const errors = [];
145
+ if (!servers)
146
+ return { tools, errors };
147
+ for (const [name, config] of Object.entries(servers)) {
148
+ try {
149
+ tools.push(...await connectMCPServer(name, config));
150
+ }
151
+ catch (err) {
152
+ errors.push(`MCP server "${name}": ${err instanceof Error ? err.message : String(err)}`);
153
+ }
154
+ }
155
+ return { tools, errors };
156
+ }
157
+ export { randomUUID };
158
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/tools/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { JsonValue, Tool, ToolContext, ToolResult } from '../types.js';
2
+ /**
3
+ * The tool registry is the single source of truth for what the agent can do.
4
+ * Tools are model-independent: they receive JSON, return JSON.
5
+ */
6
+ export declare class ToolRegistry {
7
+ private tools;
8
+ register(tool: Tool): void;
9
+ get(name: string): Tool | undefined;
10
+ has(name: string): boolean;
11
+ list(): Tool[];
12
+ names(): string[];
13
+ unregister(name: string): boolean;
14
+ /** JSON-schema list for the LLM provider. */
15
+ schemas(): {
16
+ name: string;
17
+ description: string;
18
+ inputSchema: Tool['inputSchema'];
19
+ }[];
20
+ execute(name: string, input: JsonValue, ctx: ToolContext): Promise<ToolResult>;
21
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The tool registry is the single source of truth for what the agent can do.
3
+ * Tools are model-independent: they receive JSON, return JSON.
4
+ */
5
+ export class ToolRegistry {
6
+ tools = new Map();
7
+ register(tool) {
8
+ if (this.tools.has(tool.name)) {
9
+ throw new Error(`Tool "${tool.name}" is already registered.`);
10
+ }
11
+ this.tools.set(tool.name, tool);
12
+ }
13
+ get(name) {
14
+ return this.tools.get(name);
15
+ }
16
+ has(name) {
17
+ return this.tools.has(name);
18
+ }
19
+ list() {
20
+ return [...this.tools.values()];
21
+ }
22
+ names() {
23
+ return [...this.tools.keys()];
24
+ }
25
+ unregister(name) {
26
+ return this.tools.delete(name);
27
+ }
28
+ /** JSON-schema list for the LLM provider. */
29
+ schemas() {
30
+ return this.list().map((t) => ({
31
+ name: t.name,
32
+ description: t.description,
33
+ inputSchema: t.inputSchema
34
+ }));
35
+ }
36
+ async execute(name, input, ctx) {
37
+ const tool = this.tools.get(name);
38
+ if (!tool) {
39
+ return { ok: false, summary: `Unknown tool: ${name}`, error: `unknown_tool:${name}` };
40
+ }
41
+ try {
42
+ return await tool.execute(input, ctx);
43
+ }
44
+ catch (err) {
45
+ const message = err instanceof Error ? err.message : String(err);
46
+ return { ok: false, summary: `Tool "${name}" failed: ${message}`, error: message };
47
+ }
48
+ }
49
+ }
50
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,YAAY;IACf,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;IAExC,QAAQ,CAAC,IAAU;QACjB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,0BAA0B,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,KAAK;QACH,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,6CAA6C;IAC7C,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,KAAgB,EAAE,GAAgB;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE,KAAK,EAAE,gBAAgB,IAAI,EAAE,EAAE,CAAC;QACxF,CAAC;QACD,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,IAAI,aAAa,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QACrF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import type { Tool } from '../types.js';
2
+ export declare function createSearchTools(): Tool[];