orquesta-cli 0.2.107 → 0.2.111

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 (38) hide show
  1. package/dist/cli.js +27 -4
  2. package/dist/core/commands/help.js +4 -0
  3. package/dist/core/commands/index.js +7 -0
  4. package/dist/core/commands/lsp.d.ts +3 -0
  5. package/dist/core/commands/lsp.js +37 -0
  6. package/dist/core/commands/mcp.d.ts +3 -0
  7. package/dist/core/commands/mcp.js +46 -0
  8. package/dist/core/commands/undo.d.ts +4 -0
  9. package/dist/core/commands/undo.js +45 -0
  10. package/dist/core/config/auto-detect.js +4 -4
  11. package/dist/core/config/config-manager.d.ts +7 -1
  12. package/dist/core/config/config-manager.js +36 -0
  13. package/dist/core/config/providers.d.ts +3 -0
  14. package/dist/core/config/providers.js +87 -3
  15. package/dist/core/file-snapshot-store.d.ts +25 -0
  16. package/dist/core/file-snapshot-store.js +104 -0
  17. package/dist/core/lsp/index.d.ts +6 -0
  18. package/dist/core/lsp/index.js +75 -0
  19. package/dist/core/lsp/jsonrpc.d.ts +18 -0
  20. package/dist/core/lsp/jsonrpc.js +38 -0
  21. package/dist/core/lsp/lsp-client.d.ts +40 -0
  22. package/dist/core/lsp/lsp-client.js +201 -0
  23. package/dist/core/lsp/server-registry.d.ts +14 -0
  24. package/dist/core/lsp/server-registry.js +85 -0
  25. package/dist/eval/eval-runner.js +14 -0
  26. package/dist/orchestration/plan-executor.js +2 -0
  27. package/dist/tools/llm/simple/file-tools.js +8 -2
  28. package/dist/tools/mcp/index.d.ts +3 -0
  29. package/dist/tools/mcp/index.js +3 -0
  30. package/dist/tools/mcp/mcp-client.d.ts +16 -0
  31. package/dist/tools/mcp/mcp-client.js +180 -0
  32. package/dist/tools/mcp/mcp-config.d.ts +4 -0
  33. package/dist/tools/mcp/mcp-config.js +87 -0
  34. package/dist/types/index.d.ts +21 -0
  35. package/dist/ui/hooks/slashCommandProcessor.js +17 -0
  36. package/package.json +2 -1
  37. package/dist/core/git-auto-updater.d.ts +0 -58
  38. package/dist/core/git-auto-updater.js +0 -374
@@ -0,0 +1,75 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { findServerForFile } from './server-registry.js';
4
+ import { getOrCreateClient, shutdownAllLspClients, getActiveLspClientCount } from './lsp-client.js';
5
+ import { configManager } from '../config/config-manager.js';
6
+ import { logger } from '../../utils/logger.js';
7
+ const ROOT_MARKERS = ['tsconfig.json', 'package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml', '.git'];
8
+ function findProjectRoot(absPath) {
9
+ let dir = path.dirname(absPath);
10
+ for (;;) {
11
+ for (const marker of ROOT_MARKERS) {
12
+ if (fs.existsSync(path.join(dir, marker)))
13
+ return dir;
14
+ }
15
+ const parent = path.dirname(dir);
16
+ if (parent === dir)
17
+ return path.dirname(absPath);
18
+ dir = parent;
19
+ }
20
+ }
21
+ function isEnabled() {
22
+ try {
23
+ return configManager.isLspEnabled();
24
+ }
25
+ catch {
26
+ return true;
27
+ }
28
+ }
29
+ const SEVERITY_LABEL = { 1: 'error', 2: 'warning', 3: 'info', 4: 'hint' };
30
+ export function formatDiagnostics(relPath, diags) {
31
+ const relevant = diags.filter((d) => d.severity <= 2);
32
+ if (relevant.length === 0)
33
+ return '';
34
+ relevant.sort((a, b) => a.severity - b.severity || a.line - b.line);
35
+ const MAX = 20;
36
+ const shown = relevant.slice(0, MAX);
37
+ const lines = shown.map((d) => {
38
+ const label = SEVERITY_LABEL[d.severity] ?? 'error';
39
+ const src = d.source ? ` (${d.source})` : '';
40
+ return ` ${label} [${d.line + 1}:${d.character + 1}]${src}: ${d.message.replace(/\s+/g, ' ').trim()}`;
41
+ });
42
+ const errorCount = relevant.filter((d) => d.severity === 1).length;
43
+ const warnCount = relevant.length - errorCount;
44
+ const header = `Diagnostics for ${relPath} — ${errorCount} error(s), ${warnCount} warning(s):`;
45
+ const more = relevant.length > MAX ? `\n …and ${relevant.length - MAX} more` : '';
46
+ return `\n\n${header}\n${lines.join('\n')}${more}`;
47
+ }
48
+ export async function getDiagnosticsForFile(absPath) {
49
+ if (!isEnabled())
50
+ return '';
51
+ try {
52
+ const server = findServerForFile(absPath);
53
+ if (!server)
54
+ return '';
55
+ let text;
56
+ try {
57
+ text = fs.readFileSync(absPath, 'utf-8');
58
+ }
59
+ catch {
60
+ return '';
61
+ }
62
+ const root = findProjectRoot(absPath);
63
+ const client = getOrCreateClient(server.def, root);
64
+ const diags = await client.getDiagnostics(absPath, text);
65
+ const rel = path.relative(process.cwd(), absPath) || path.basename(absPath);
66
+ return formatDiagnostics(rel, diags);
67
+ }
68
+ catch (err) {
69
+ logger.warn('LSP diagnostics failed', { path: absPath, error: err instanceof Error ? err.message : String(err) });
70
+ return '';
71
+ }
72
+ }
73
+ export { shutdownAllLspClients, getActiveLspClientCount };
74
+ export { findServerForFile, getServerDefs, resolveServerBinary } from './server-registry.js';
75
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,18 @@
1
+ export interface JsonRpcMessage {
2
+ jsonrpc: '2.0';
3
+ id?: number | string;
4
+ method?: string;
5
+ params?: unknown;
6
+ result?: unknown;
7
+ error?: {
8
+ code: number;
9
+ message: string;
10
+ data?: unknown;
11
+ };
12
+ }
13
+ export declare function encodeMessage(msg: JsonRpcMessage): Buffer;
14
+ export declare class MessageDecoder {
15
+ private buffer;
16
+ push(chunk: Buffer): JsonRpcMessage[];
17
+ }
18
+ //# sourceMappingURL=jsonrpc.d.ts.map
@@ -0,0 +1,38 @@
1
+ export function encodeMessage(msg) {
2
+ const json = JSON.stringify(msg);
3
+ const body = Buffer.from(json, 'utf-8');
4
+ const header = Buffer.from(`Content-Length: ${body.length}\r\n\r\n`, 'ascii');
5
+ return Buffer.concat([header, body]);
6
+ }
7
+ export class MessageDecoder {
8
+ buffer = Buffer.alloc(0);
9
+ push(chunk) {
10
+ this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);
11
+ const out = [];
12
+ for (;;) {
13
+ const headerEnd = this.buffer.indexOf('\r\n\r\n');
14
+ if (headerEnd === -1)
15
+ break;
16
+ const header = this.buffer.subarray(0, headerEnd).toString('ascii');
17
+ const match = /Content-Length:\s*(\d+)/i.exec(header);
18
+ if (!match) {
19
+ this.buffer = this.buffer.subarray(headerEnd + 4);
20
+ continue;
21
+ }
22
+ const contentLength = parseInt(match[1], 10);
23
+ const bodyStart = headerEnd + 4;
24
+ const bodyEnd = bodyStart + contentLength;
25
+ if (this.buffer.length < bodyEnd)
26
+ break;
27
+ const body = this.buffer.subarray(bodyStart, bodyEnd).toString('utf-8');
28
+ this.buffer = this.buffer.subarray(bodyEnd);
29
+ try {
30
+ out.push(JSON.parse(body));
31
+ }
32
+ catch {
33
+ }
34
+ }
35
+ return out;
36
+ }
37
+ }
38
+ //# sourceMappingURL=jsonrpc.js.map
@@ -0,0 +1,40 @@
1
+ import { fileURLToPath } from 'url';
2
+ import { LspServerDef } from './server-registry.js';
3
+ export interface Diagnostic {
4
+ severity: number;
5
+ line: number;
6
+ character: number;
7
+ message: string;
8
+ source?: string;
9
+ }
10
+ declare class LspClient {
11
+ private def;
12
+ private rootDir;
13
+ private proc;
14
+ private decoder;
15
+ private nextId;
16
+ private pendingRequests;
17
+ private diagnostics;
18
+ private diagWaiters;
19
+ private openDocs;
20
+ private initialized;
21
+ private version;
22
+ constructor(def: LspServerDef, rootDir: string);
23
+ private send;
24
+ private request;
25
+ private notify;
26
+ private handleMessage;
27
+ start(): Promise<void>;
28
+ getDiagnostics(absPath: string, text: string): Promise<Diagnostic[]>;
29
+ private onceDiagnostics;
30
+ private delay;
31
+ private waitFor;
32
+ private teardown;
33
+ stop(): Promise<void>;
34
+ }
35
+ export declare function getOrCreateClient(def: LspServerDef, rootDir: string): LspClient;
36
+ export declare function shutdownAllLspClients(): Promise<void>;
37
+ export declare function getActiveLspClientCount(): number;
38
+ export { fileURLToPath };
39
+ export type { LspClient };
40
+ //# sourceMappingURL=lsp-client.d.ts.map
@@ -0,0 +1,201 @@
1
+ import { spawn } from 'child_process';
2
+ import * as path from 'path';
3
+ import { pathToFileURL, fileURLToPath } from 'url';
4
+ import { encodeMessage, MessageDecoder } from './jsonrpc.js';
5
+ import { logger } from '../../utils/logger.js';
6
+ const INIT_TIMEOUT_MS = Number(process.env['ORQUESTA_LSP_INIT_TIMEOUT_MS']) || 12000;
7
+ const DIAGNOSTICS_WAIT_MS = Number(process.env['ORQUESTA_LSP_DIAG_TIMEOUT_MS']) || 2500;
8
+ class LspClient {
9
+ def;
10
+ rootDir;
11
+ proc = null;
12
+ decoder = new MessageDecoder();
13
+ nextId = 1;
14
+ pendingRequests = new Map();
15
+ diagnostics = new Map();
16
+ diagWaiters = new Map();
17
+ openDocs = new Set();
18
+ initialized = false;
19
+ version = new Map();
20
+ constructor(def, rootDir) {
21
+ this.def = def;
22
+ this.rootDir = rootDir;
23
+ }
24
+ send(msg) {
25
+ if (!this.proc)
26
+ return;
27
+ this.proc.stdin.write(encodeMessage({ jsonrpc: '2.0', ...msg }));
28
+ }
29
+ request(method, params) {
30
+ const id = this.nextId++;
31
+ return new Promise((resolve, reject) => {
32
+ this.pendingRequests.set(id, { resolve: resolve, reject });
33
+ this.send({ id, method, params });
34
+ });
35
+ }
36
+ notify(method, params) {
37
+ this.send({ method, params });
38
+ }
39
+ handleMessage(msg) {
40
+ if (msg.id !== undefined && (msg.result !== undefined || msg.error !== undefined)) {
41
+ const pending = this.pendingRequests.get(msg.id);
42
+ if (pending) {
43
+ this.pendingRequests.delete(msg.id);
44
+ if (msg.error)
45
+ pending.reject(new Error(msg.error.message));
46
+ else
47
+ pending.resolve(msg.result);
48
+ }
49
+ return;
50
+ }
51
+ if (msg.method === 'textDocument/publishDiagnostics') {
52
+ const params = msg.params;
53
+ const diags = (params.diagnostics || []).map((d) => ({
54
+ severity: d.severity ?? 1,
55
+ line: d.range?.start?.line ?? 0,
56
+ character: d.range?.start?.character ?? 0,
57
+ message: d.message ?? '',
58
+ source: d.source,
59
+ }));
60
+ this.diagnostics.set(params.uri, diags);
61
+ const waiters = this.diagWaiters.get(params.uri);
62
+ if (waiters) {
63
+ this.diagWaiters.delete(params.uri);
64
+ for (const w of waiters)
65
+ w();
66
+ }
67
+ return;
68
+ }
69
+ if (msg.id !== undefined && msg.method) {
70
+ this.send({ id: msg.id, result: null });
71
+ }
72
+ }
73
+ async start() {
74
+ if (this.initialized)
75
+ return;
76
+ if (this.proc) {
77
+ await this.waitFor(() => this.initialized, INIT_TIMEOUT_MS);
78
+ return;
79
+ }
80
+ logger.flow('LSP starting server', { id: this.def.id, root: this.rootDir });
81
+ const proc = spawn(this.def.command, this.def.args, {
82
+ cwd: this.rootDir,
83
+ stdio: ['pipe', 'pipe', 'pipe'],
84
+ env: process.env,
85
+ });
86
+ this.proc = proc;
87
+ proc.stdout.on('data', (chunk) => {
88
+ for (const msg of this.decoder.push(chunk))
89
+ this.handleMessage(msg);
90
+ });
91
+ proc.stderr.on('data', () => {
92
+ });
93
+ proc.on('error', (err) => {
94
+ logger.warn('LSP server process error', { id: this.def.id, error: err.message });
95
+ this.teardown();
96
+ });
97
+ proc.on('exit', () => this.teardown());
98
+ await this.request('initialize', {
99
+ processId: process.pid,
100
+ rootUri: pathToFileURL(this.rootDir).toString(),
101
+ rootPath: this.rootDir,
102
+ capabilities: {
103
+ textDocument: {
104
+ synchronization: { didSave: true, dynamicRegistration: false },
105
+ publishDiagnostics: { relatedInformation: false },
106
+ },
107
+ },
108
+ workspaceFolders: [{ uri: pathToFileURL(this.rootDir).toString(), name: path.basename(this.rootDir) }],
109
+ });
110
+ this.notify('initialized', {});
111
+ this.initialized = true;
112
+ logger.flow('LSP server initialized', { id: this.def.id });
113
+ }
114
+ async getDiagnostics(absPath, text) {
115
+ await this.start();
116
+ const uri = pathToFileURL(absPath).toString();
117
+ this.diagnostics.delete(uri);
118
+ const arrived = this.onceDiagnostics(uri);
119
+ if (!this.openDocs.has(uri)) {
120
+ this.openDocs.add(uri);
121
+ this.version.set(uri, 1);
122
+ this.notify('textDocument/didOpen', {
123
+ textDocument: { uri, languageId: this.def.id, version: 1, text },
124
+ });
125
+ }
126
+ else {
127
+ const v = (this.version.get(uri) ?? 1) + 1;
128
+ this.version.set(uri, v);
129
+ this.notify('textDocument/didChange', {
130
+ textDocument: { uri, version: v },
131
+ contentChanges: [{ text }],
132
+ });
133
+ }
134
+ this.notify('textDocument/didSave', { textDocument: { uri }, text });
135
+ await Promise.race([arrived, this.delay(DIAGNOSTICS_WAIT_MS)]);
136
+ return this.diagnostics.get(uri) ?? [];
137
+ }
138
+ onceDiagnostics(uri) {
139
+ return new Promise((resolve) => {
140
+ const list = this.diagWaiters.get(uri) ?? [];
141
+ list.push(resolve);
142
+ this.diagWaiters.set(uri, list);
143
+ });
144
+ }
145
+ delay(ms) {
146
+ return new Promise((r) => {
147
+ const t = setTimeout(r, ms);
148
+ if (typeof t.unref === 'function')
149
+ t.unref();
150
+ });
151
+ }
152
+ async waitFor(cond, timeoutMs) {
153
+ const start = Date.now();
154
+ while (!cond() && Date.now() - start < timeoutMs) {
155
+ await this.delay(50);
156
+ }
157
+ }
158
+ teardown() {
159
+ this.initialized = false;
160
+ for (const [, p] of this.pendingRequests)
161
+ p.reject(new Error('LSP server exited'));
162
+ this.pendingRequests.clear();
163
+ this.proc = null;
164
+ }
165
+ async stop() {
166
+ if (!this.proc)
167
+ return;
168
+ try {
169
+ await Promise.race([this.request('shutdown', null), this.delay(1000)]);
170
+ this.notify('exit', null);
171
+ }
172
+ catch {
173
+ }
174
+ try {
175
+ this.proc.kill();
176
+ }
177
+ catch {
178
+ }
179
+ this.teardown();
180
+ }
181
+ }
182
+ const clients = new Map();
183
+ export function getOrCreateClient(def, rootDir) {
184
+ const key = `${def.id}::${rootDir}`;
185
+ let client = clients.get(key);
186
+ if (!client) {
187
+ client = new LspClient(def, rootDir);
188
+ clients.set(key, client);
189
+ }
190
+ return client;
191
+ }
192
+ export async function shutdownAllLspClients() {
193
+ const all = Array.from(clients.values());
194
+ clients.clear();
195
+ await Promise.all(all.map((c) => c.stop().catch(() => undefined)));
196
+ }
197
+ export function getActiveLspClientCount() {
198
+ return clients.size;
199
+ }
200
+ export { fileURLToPath };
201
+ //# sourceMappingURL=lsp-client.js.map
@@ -0,0 +1,14 @@
1
+ export interface LspServerDef {
2
+ id: string;
3
+ extensions: string[];
4
+ command: string;
5
+ args: string[];
6
+ }
7
+ export declare function resolveServerBinary(command: string): string | null;
8
+ export declare function getServerDefs(): LspServerDef[];
9
+ export declare function findServerForFile(absPath: string): {
10
+ def: LspServerDef;
11
+ binary: string;
12
+ } | null;
13
+ export declare function clearResolveCache(): void;
14
+ //# sourceMappingURL=server-registry.d.ts.map
@@ -0,0 +1,85 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { configManager } from '../config/config-manager.js';
4
+ const DEFAULT_SERVERS = [
5
+ {
6
+ id: 'typescript',
7
+ extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.mts', '.cts'],
8
+ command: 'typescript-language-server',
9
+ args: ['--stdio'],
10
+ },
11
+ { id: 'python', extensions: ['.py', '.pyi'], command: 'pyright-langserver', args: ['--stdio'] },
12
+ { id: 'rust', extensions: ['.rs'], command: 'rust-analyzer', args: [] },
13
+ { id: 'go', extensions: ['.go'], command: 'gopls', args: [] },
14
+ { id: 'ruby', extensions: ['.rb'], command: 'solargraph', args: ['stdio'] },
15
+ ];
16
+ function execCandidates(command) {
17
+ if (path.isAbsolute(command))
18
+ return [command];
19
+ if (process.platform === 'win32') {
20
+ const exts = (process.env['PATHEXT'] || '.COM;.EXE;.BAT;.CMD').split(';');
21
+ return [command, ...exts.map((e) => command + e.toLowerCase()), ...exts.map((e) => command + e)];
22
+ }
23
+ return [command];
24
+ }
25
+ const resolveCache = new Map();
26
+ export function resolveServerBinary(command) {
27
+ if (resolveCache.has(command))
28
+ return resolveCache.get(command);
29
+ const tryFile = (p) => {
30
+ try {
31
+ const st = fs.statSync(p);
32
+ if (st.isFile())
33
+ return p;
34
+ }
35
+ catch {
36
+ }
37
+ return null;
38
+ };
39
+ let found = null;
40
+ if (path.isAbsolute(command) || command.includes('/') || command.includes('\\')) {
41
+ for (const cand of execCandidates(command)) {
42
+ found = tryFile(path.resolve(cand));
43
+ if (found)
44
+ break;
45
+ }
46
+ }
47
+ else {
48
+ const pathDirs = (process.env['PATH'] || '').split(path.delimiter).filter(Boolean);
49
+ outer: for (const dir of pathDirs) {
50
+ for (const cand of execCandidates(command)) {
51
+ found = tryFile(path.join(dir, cand));
52
+ if (found)
53
+ break outer;
54
+ }
55
+ }
56
+ }
57
+ resolveCache.set(command, found);
58
+ return found;
59
+ }
60
+ export function getServerDefs() {
61
+ let custom = [];
62
+ try {
63
+ custom = configManager.getLspServers();
64
+ }
65
+ catch {
66
+ }
67
+ return [...custom, ...DEFAULT_SERVERS];
68
+ }
69
+ export function findServerForFile(absPath) {
70
+ const ext = path.extname(absPath).toLowerCase();
71
+ if (!ext)
72
+ return null;
73
+ for (const def of getServerDefs()) {
74
+ if (!def.extensions.includes(ext))
75
+ continue;
76
+ const binary = resolveServerBinary(def.command);
77
+ if (binary)
78
+ return { def: { ...def, command: binary }, binary };
79
+ }
80
+ return null;
81
+ }
82
+ export function clearResolveCache() {
83
+ resolveCache.clear();
84
+ }
85
+ //# sourceMappingURL=server-registry.js.map
@@ -40,6 +40,12 @@ export class EvalRunner {
40
40
  if (input.working_dir) {
41
41
  process.chdir(input.working_dir);
42
42
  }
43
+ try {
44
+ const { initializeMcpServers } = await import('../tools/mcp/index.js');
45
+ await initializeMcpServers(process.cwd());
46
+ }
47
+ catch {
48
+ }
43
49
  const startEvent = {
44
50
  event: 'start',
45
51
  timestamp: now(),
@@ -58,6 +64,14 @@ export class EvalRunner {
58
64
  this.emitError(error instanceof Error ? error.message : String(error));
59
65
  this.emitEnd(false);
60
66
  }
67
+ finally {
68
+ try {
69
+ const { shutdownAllLspClients } = await import('../core/lsp/index.js');
70
+ await shutdownAllLspClients();
71
+ }
72
+ catch {
73
+ }
74
+ }
61
75
  }
62
76
  async execute(prompt) {
63
77
  if (!this.llmClient) {
@@ -2,6 +2,7 @@ import { PlanningLLM } from '../agents/planner/index.js';
2
2
  import { sessionManager } from '../core/session/session-manager.js';
3
3
  import { CompactManager, contextTracker, buildCompactedMessages, } from '../core/compact/index.js';
4
4
  import { configManager } from '../core/config/config-manager.js';
5
+ import { fileSnapshotStore } from '../core/file-snapshot-store.js';
5
6
  import { setTodoWriteCallback, clearTodoCallbacks, } from '../tools/llm/simple/todo-tools.js';
6
7
  import { setGetTodosCallback, setFinalResponseCallback, setMarkTodosCompletedCallback, clearFinalResponseCallbacks, } from '../tools/llm/simple/final-response-tool.js';
7
8
  import { eventBus, Events } from '../core/event-bus.js';
@@ -54,6 +55,7 @@ export class PlanExecutor {
54
55
  });
55
56
  this.currentLLMClient = llmClient;
56
57
  setDocsSearchLLMClientGetter(() => this.currentLLMClient);
58
+ fileSnapshotStore.beginTurn(userMessage);
57
59
  isInterruptedRef.current = false;
58
60
  callbacks.setIsInterrupted(false);
59
61
  callbacks.setTodos([]);
@@ -3,6 +3,8 @@ import * as path from 'path';
3
3
  import { logger } from '../../../utils/logger.js';
4
4
  import { shouldIgnore } from '../../../core/ignore-filter.js';
5
5
  import { getCachedFile, setCachedFile, invalidateCache } from '../../../core/file-cache.js';
6
+ import { fileSnapshotStore } from '../../../core/file-snapshot-store.js';
7
+ import { getDiagnosticsForFile } from '../../../core/lsp/index.js';
6
8
  const EXCLUDED_DIRS = new Set([
7
9
  'node_modules',
8
10
  '.git',
@@ -193,10 +195,12 @@ async function _executeCreateFile(args) {
193
195
  }
194
196
  const dir = path.dirname(resolvedPath);
195
197
  await fs.mkdir(dir, { recursive: true });
198
+ fileSnapshotStore.record(resolvedPath, null);
196
199
  await fs.writeFile(resolvedPath, content, 'utf-8');
197
200
  invalidateCache(resolvedPath);
198
201
  const lines = content.split('\n').length;
199
202
  logger.toolSuccess('create_file', args, { file: displayPath, lines }, 0);
203
+ const diagnostics = await getDiagnosticsForFile(resolvedPath);
200
204
  return {
201
205
  success: true,
202
206
  result: JSON.stringify({
@@ -204,7 +208,7 @@ async function _executeCreateFile(args) {
204
208
  file: displayPath,
205
209
  lines: lines,
206
210
  message: `Created ${displayPath} (${lines} lines)`,
207
- }),
211
+ }) + diagnostics,
208
212
  };
209
213
  }
210
214
  catch (error) {
@@ -356,6 +360,7 @@ async function _executeEditFile(args) {
356
360
  error: `Modified content too large (${(newContentSize / 1024 / 1024).toFixed(2)}MB). Maximum: ${MAX_WRITE_SIZE / 1024 / 1024}MB`,
357
361
  };
358
362
  }
363
+ fileSnapshotStore.record(resolvedPath, originalContent);
359
364
  await fs.writeFile(resolvedPath, newContent, 'utf-8');
360
365
  invalidateCache(resolvedPath);
361
366
  const oldLinesArr = oldString.split('\n');
@@ -371,6 +376,7 @@ async function _executeEditFile(args) {
371
376
  if (newLinesArr.length > 5)
372
377
  diffPreview.push('+ ...');
373
378
  logger.toolSuccess('edit_file', args, { file: displayPath, replacements, oldLines: oldLinesArr.length, newLines: newLinesArr.length }, 0);
379
+ const diagnostics = await getDiagnosticsForFile(resolvedPath);
374
380
  return {
375
381
  success: true,
376
382
  result: JSON.stringify({
@@ -383,7 +389,7 @@ async function _executeEditFile(args) {
383
389
  ? `Replaced ${replacements} occurrence(s) in ${displayPath}`
384
390
  : `Updated ${displayPath}`,
385
391
  diff: diffPreview,
386
- }),
392
+ }) + diagnostics,
387
393
  };
388
394
  }
389
395
  catch (error) {
@@ -0,0 +1,3 @@
1
+ export { initializeMcpServers, disconnectMcpServers, getConnectedMcpServers, namespacedToolName, type McpInitResult, } from './mcp-client.js';
2
+ export { loadMcpServerConfigs, normalizeSource } from './mcp-config.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export { initializeMcpServers, disconnectMcpServers, getConnectedMcpServers, namespacedToolName, } from './mcp-client.js';
2
+ export { loadMcpServerConfigs, normalizeSource } from './mcp-config.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,16 @@
1
+ export declare function namespacedToolName(server: string, tool: string): string;
2
+ export interface McpInitResult {
3
+ servers: number;
4
+ tools: number;
5
+ errors: Array<{
6
+ server: string;
7
+ error: string;
8
+ }>;
9
+ }
10
+ export declare function initializeMcpServers(cwd?: string): Promise<McpInitResult>;
11
+ export declare function getConnectedMcpServers(): Array<{
12
+ name: string;
13
+ tools: string[];
14
+ }>;
15
+ export declare function disconnectMcpServers(): Promise<void>;
16
+ //# sourceMappingURL=mcp-client.d.ts.map