nomoreide 0.1.22 → 0.1.24
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/dist/core/error-inbox.d.ts +71 -0
- package/dist/core/error-inbox.js +277 -0
- package/dist/core/error-inbox.js.map +1 -0
- package/dist/core/log-store.d.ts +5 -0
- package/dist/core/log-store.js +19 -0
- package/dist/core/log-store.js.map +1 -1
- package/dist/mcp/server.d.ts +4 -2
- package/dist/mcp/server.js +6 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/agent.d.ts +4 -0
- package/dist/mcp/tools/agent.js +19 -0
- package/dist/mcp/tools/agent.js.map +1 -0
- package/dist/mcp/tools/context.d.ts +28 -0
- package/dist/mcp/tools/context.js +57 -0
- package/dist/mcp/tools/context.js.map +1 -0
- package/dist/mcp/tools/errors.d.ts +5 -0
- package/dist/mcp/tools/errors.js +40 -0
- package/dist/mcp/tools/errors.js.map +1 -0
- package/dist/mcp/tools/git.d.ts +4 -0
- package/dist/mcp/tools/git.js +120 -0
- package/dist/mcp/tools/git.js.map +1 -0
- package/dist/mcp/{tools.d.ts → tools/index.d.ts} +13 -14
- package/dist/mcp/tools/index.js +30 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/services.d.ts +4 -0
- package/dist/mcp/tools/services.js +177 -0
- package/dist/mcp/tools/services.js.map +1 -0
- package/dist/web/client/assets/index-CgtUFH5U.css +1 -0
- package/dist/web/client/assets/index-DNUDJ5VX.js +24 -0
- package/dist/web/client/index.html +2 -2
- package/dist/web/routes/context.d.ts +2 -0
- package/dist/web/routes/context.js.map +1 -1
- package/dist/web/routes/errors-routes.d.ts +3 -0
- package/dist/web/routes/errors-routes.js +44 -0
- package/dist/web/routes/errors-routes.js.map +1 -0
- package/dist/web/routes/index.js +2 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/server.js +3 -0
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/mcp/tools.js +0 -354
- package/dist/mcp/tools.js.map +0 -1
- package/dist/web/client/assets/index-BmUyXrPp.css +0 -1
- package/dist/web/client/assets/index-DxODKxSd.js +0 -23
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { ConfigStore } from "./config-store.js";
|
|
2
|
+
import type { LogStore } from "./log-store.js";
|
|
3
|
+
import type { LogEntry } from "./types.js";
|
|
4
|
+
export type IncidentLevel = "error" | "warning";
|
|
5
|
+
export interface ErrorIncident {
|
|
6
|
+
id: number;
|
|
7
|
+
service: string;
|
|
8
|
+
level: IncidentLevel;
|
|
9
|
+
/** Stable dedupe key derived from the trigger line. */
|
|
10
|
+
signature: string;
|
|
11
|
+
/** The trigger line, trimmed. */
|
|
12
|
+
title: string;
|
|
13
|
+
/** Top stack frame, if one was found near the trigger. */
|
|
14
|
+
file?: string;
|
|
15
|
+
line?: number;
|
|
16
|
+
firstSeen: string;
|
|
17
|
+
lastSeen: string;
|
|
18
|
+
count: number;
|
|
19
|
+
/** The trigger line plus the surrounding log context. */
|
|
20
|
+
logExcerpt: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface ErrorInboxPrompt {
|
|
23
|
+
incident: ErrorIncident;
|
|
24
|
+
/** Resolved file path used for the diff, if any. */
|
|
25
|
+
file?: string;
|
|
26
|
+
/** Markdown payload ready to paste into an agent. */
|
|
27
|
+
prompt: string;
|
|
28
|
+
}
|
|
29
|
+
interface ErrorInboxOptions {
|
|
30
|
+
logStore: LogStore;
|
|
31
|
+
configStore: ConfigStore;
|
|
32
|
+
/** Repo/workspace root used when a service has no own cwd. */
|
|
33
|
+
cwd?: string;
|
|
34
|
+
/** Max distinct incidents kept in the ring buffer. */
|
|
35
|
+
capacity?: number;
|
|
36
|
+
}
|
|
37
|
+
type IncidentListener = (incident: ErrorIncident) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Watches every log line via {@link LogStore.subscribe}, distils error and
|
|
40
|
+
* stack-trace lines into deduped incidents, and assembles a copy-to-agent
|
|
41
|
+
* prompt (incident + affected-file diff + recent logs) on demand.
|
|
42
|
+
*/
|
|
43
|
+
export declare class ErrorInbox {
|
|
44
|
+
private readonly logStore;
|
|
45
|
+
private readonly configStore;
|
|
46
|
+
private readonly cwd;
|
|
47
|
+
private readonly capacity;
|
|
48
|
+
private readonly incidents;
|
|
49
|
+
private readonly byId;
|
|
50
|
+
private readonly bySignature;
|
|
51
|
+
private readonly stateByService;
|
|
52
|
+
private readonly listeners;
|
|
53
|
+
private nextId;
|
|
54
|
+
private readonly unsubscribe;
|
|
55
|
+
constructor(options: ErrorInboxOptions);
|
|
56
|
+
/** Stop observing the log store. */
|
|
57
|
+
dispose(): void;
|
|
58
|
+
list(limit?: number): ErrorIncident[];
|
|
59
|
+
get(id: number): ErrorIncident | undefined;
|
|
60
|
+
subscribe(listener: IncidentListener): () => void;
|
|
61
|
+
/** Feed one log line through the detectors. Returns a touched incident, if any. */
|
|
62
|
+
ingest(entry: LogEntry): ErrorIncident | null;
|
|
63
|
+
private recordIncident;
|
|
64
|
+
/** Assemble the copy-to-agent payload for an incident. */
|
|
65
|
+
buildPrompt(id: number): Promise<ErrorInboxPrompt | null>;
|
|
66
|
+
private serviceCwd;
|
|
67
|
+
private stateFor;
|
|
68
|
+
private evictOverflow;
|
|
69
|
+
private emit;
|
|
70
|
+
}
|
|
71
|
+
export {};
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from "node:path";
|
|
2
|
+
import { GitManager } from "./git-manager.js";
|
|
3
|
+
/** Lines of surrounding context captured with each incident. */
|
|
4
|
+
const CONTEXT_LINES = 12;
|
|
5
|
+
/** How many follow-up lines after a trigger are absorbed as stack frames. */
|
|
6
|
+
const FRAME_FOLLOW = 12;
|
|
7
|
+
const TITLE_MAX = 240;
|
|
8
|
+
const PROMPT_LOG_LINES = 40;
|
|
9
|
+
/**
|
|
10
|
+
* Watches every log line via {@link LogStore.subscribe}, distils error and
|
|
11
|
+
* stack-trace lines into deduped incidents, and assembles a copy-to-agent
|
|
12
|
+
* prompt (incident + affected-file diff + recent logs) on demand.
|
|
13
|
+
*/
|
|
14
|
+
export class ErrorInbox {
|
|
15
|
+
logStore;
|
|
16
|
+
configStore;
|
|
17
|
+
cwd;
|
|
18
|
+
capacity;
|
|
19
|
+
incidents = [];
|
|
20
|
+
byId = new Map();
|
|
21
|
+
bySignature = new Map();
|
|
22
|
+
stateByService = new Map();
|
|
23
|
+
listeners = new Set();
|
|
24
|
+
nextId = 1;
|
|
25
|
+
unsubscribe;
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.logStore = options.logStore;
|
|
28
|
+
this.configStore = options.configStore;
|
|
29
|
+
this.cwd = options.cwd ?? process.cwd();
|
|
30
|
+
this.capacity = options.capacity ?? 100;
|
|
31
|
+
this.unsubscribe = this.logStore.subscribe((entry) => {
|
|
32
|
+
this.ingest(entry);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/** Stop observing the log store. */
|
|
36
|
+
dispose() {
|
|
37
|
+
this.unsubscribe();
|
|
38
|
+
}
|
|
39
|
+
list(limit = this.capacity) {
|
|
40
|
+
const sorted = [...this.incidents].sort((a, b) => a.lastSeen < b.lastSeen ? 1 : a.lastSeen > b.lastSeen ? -1 : b.id - a.id);
|
|
41
|
+
return sorted.slice(0, limit);
|
|
42
|
+
}
|
|
43
|
+
get(id) {
|
|
44
|
+
return this.byId.get(id);
|
|
45
|
+
}
|
|
46
|
+
subscribe(listener) {
|
|
47
|
+
this.listeners.add(listener);
|
|
48
|
+
return () => {
|
|
49
|
+
this.listeners.delete(listener);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Feed one log line through the detectors. Returns a touched incident, if any. */
|
|
53
|
+
ingest(entry) {
|
|
54
|
+
const text = entry.text;
|
|
55
|
+
const state = this.stateFor(entry.service);
|
|
56
|
+
state.recent.push(text);
|
|
57
|
+
if (state.recent.length > CONTEXT_LINES)
|
|
58
|
+
state.recent.shift();
|
|
59
|
+
const frame = extractFrame(text);
|
|
60
|
+
// Absorb stack frames / continuation lines into the active incident.
|
|
61
|
+
if (state.active && state.active.remaining > 0 && (frame || isStackFrame(text))) {
|
|
62
|
+
const incident = this.byId.get(state.active.id);
|
|
63
|
+
if (incident) {
|
|
64
|
+
incident.logExcerpt.push(text);
|
|
65
|
+
incident.lastSeen = entry.timestamp;
|
|
66
|
+
if (incident.file === undefined && frame) {
|
|
67
|
+
incident.file = frame.file;
|
|
68
|
+
incident.line = frame.line;
|
|
69
|
+
}
|
|
70
|
+
state.active.remaining -= 1;
|
|
71
|
+
this.emit(incident);
|
|
72
|
+
}
|
|
73
|
+
return incident ?? null;
|
|
74
|
+
}
|
|
75
|
+
// Bare frames without a preceding header aren't their own incidents.
|
|
76
|
+
if (isStackFrame(text))
|
|
77
|
+
return null;
|
|
78
|
+
const level = classifyLine(text);
|
|
79
|
+
if (level === null)
|
|
80
|
+
return null;
|
|
81
|
+
return this.recordIncident(entry, level, frame, state);
|
|
82
|
+
}
|
|
83
|
+
recordIncident(entry, level, frame, state) {
|
|
84
|
+
const signature = `${entry.service} ${normalizeSignature(entry.text)}`;
|
|
85
|
+
const existing = this.bySignature.get(signature);
|
|
86
|
+
if (existing) {
|
|
87
|
+
existing.count += 1;
|
|
88
|
+
existing.lastSeen = entry.timestamp;
|
|
89
|
+
existing.level = level;
|
|
90
|
+
existing.logExcerpt = [...state.recent];
|
|
91
|
+
if (frame) {
|
|
92
|
+
existing.file = frame.file;
|
|
93
|
+
existing.line = frame.line;
|
|
94
|
+
}
|
|
95
|
+
state.active = { id: existing.id, remaining: FRAME_FOLLOW };
|
|
96
|
+
this.emit(existing);
|
|
97
|
+
return existing;
|
|
98
|
+
}
|
|
99
|
+
// The header line often has no frame of its own (e.g. a Python
|
|
100
|
+
// `ValueError` printed after its `File "…"` frames). Fall back to the
|
|
101
|
+
// most recent frame in the surrounding context.
|
|
102
|
+
const resolvedFrame = frame ?? lastFrameIn(state.recent);
|
|
103
|
+
const incident = {
|
|
104
|
+
id: this.nextId++,
|
|
105
|
+
service: entry.service,
|
|
106
|
+
level,
|
|
107
|
+
signature,
|
|
108
|
+
title: entry.text.trim().slice(0, TITLE_MAX),
|
|
109
|
+
file: resolvedFrame?.file,
|
|
110
|
+
line: resolvedFrame?.line,
|
|
111
|
+
firstSeen: entry.timestamp,
|
|
112
|
+
lastSeen: entry.timestamp,
|
|
113
|
+
count: 1,
|
|
114
|
+
logExcerpt: [...state.recent],
|
|
115
|
+
};
|
|
116
|
+
this.incidents.push(incident);
|
|
117
|
+
this.byId.set(incident.id, incident);
|
|
118
|
+
this.bySignature.set(signature, incident);
|
|
119
|
+
this.evictOverflow();
|
|
120
|
+
state.active = { id: incident.id, remaining: FRAME_FOLLOW };
|
|
121
|
+
this.emit(incident);
|
|
122
|
+
return incident;
|
|
123
|
+
}
|
|
124
|
+
/** Assemble the copy-to-agent payload for an incident. */
|
|
125
|
+
async buildPrompt(id) {
|
|
126
|
+
const incident = this.byId.get(id);
|
|
127
|
+
if (!incident)
|
|
128
|
+
return null;
|
|
129
|
+
const serviceCwd = await this.serviceCwd(incident.service);
|
|
130
|
+
const resolvedFile = incident.file
|
|
131
|
+
? isAbsolute(incident.file)
|
|
132
|
+
? incident.file
|
|
133
|
+
: resolve(serviceCwd, incident.file)
|
|
134
|
+
: undefined;
|
|
135
|
+
let diff = "";
|
|
136
|
+
if (incident.file) {
|
|
137
|
+
try {
|
|
138
|
+
diff = await new GitManager(serviceCwd).diff(incident.file);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
diff = "";
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const recentLogs = this.logStore
|
|
145
|
+
.read(incident.service, PROMPT_LOG_LINES)
|
|
146
|
+
.map((entry) => entry.text);
|
|
147
|
+
return {
|
|
148
|
+
incident,
|
|
149
|
+
file: resolvedFile,
|
|
150
|
+
prompt: renderPrompt(incident, resolvedFile, diff, recentLogs),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async serviceCwd(service) {
|
|
154
|
+
try {
|
|
155
|
+
const config = await this.configStore.load();
|
|
156
|
+
const definition = config.services.find((item) => item.name === service);
|
|
157
|
+
if (definition?.cwd) {
|
|
158
|
+
return isAbsolute(definition.cwd)
|
|
159
|
+
? definition.cwd
|
|
160
|
+
: resolve(this.cwd, definition.cwd);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// fall through to the workspace root
|
|
165
|
+
}
|
|
166
|
+
return this.cwd;
|
|
167
|
+
}
|
|
168
|
+
stateFor(service) {
|
|
169
|
+
let state = this.stateByService.get(service);
|
|
170
|
+
if (!state) {
|
|
171
|
+
state = { recent: [] };
|
|
172
|
+
this.stateByService.set(service, state);
|
|
173
|
+
}
|
|
174
|
+
return state;
|
|
175
|
+
}
|
|
176
|
+
evictOverflow() {
|
|
177
|
+
while (this.incidents.length > this.capacity) {
|
|
178
|
+
const dropped = this.incidents.shift();
|
|
179
|
+
if (!dropped)
|
|
180
|
+
break;
|
|
181
|
+
this.byId.delete(dropped.id);
|
|
182
|
+
if (this.bySignature.get(dropped.signature) === dropped) {
|
|
183
|
+
this.bySignature.delete(dropped.signature);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
emit(incident) {
|
|
188
|
+
for (const listener of this.listeners) {
|
|
189
|
+
try {
|
|
190
|
+
listener(incident);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// ignore listener errors
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// `traceback` is intentionally absent: it's a stack opener, not the error
|
|
199
|
+
// message itself — the real exception arrives a few lines later (see the
|
|
200
|
+
// look-back in recordIncident, which pulls the frame from those lines).
|
|
201
|
+
const FATAL = /\b(panic|fatal|uncaught|unhandled|EADDRINUSE|ECONNREFUSED|segmentation fault|exception in thread)\b/i;
|
|
202
|
+
// Bare `error` plus typed headers like `TypeError:` / `ValueError` / `Exception`.
|
|
203
|
+
const ERROR_WORD = /\b\w*(?:error|exception)\b/i;
|
|
204
|
+
const NO_ERRORS = /\b0 errors?\b/i;
|
|
205
|
+
const WARN = /\b(warn|warning|deprecated)\b/i;
|
|
206
|
+
function classifyLine(text) {
|
|
207
|
+
if (FATAL.test(text))
|
|
208
|
+
return "error";
|
|
209
|
+
if (ERROR_WORD.test(text) && !NO_ERRORS.test(text))
|
|
210
|
+
return "error";
|
|
211
|
+
if (WARN.test(text))
|
|
212
|
+
return "warning";
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
const PY_FRAME = /File "([^"]+)", line (\d+)/;
|
|
216
|
+
const JS_FRAME = /\(?([^\s()]+\.(?:[cm]?[jt]sx?)):(\d+):\d+\)?/;
|
|
217
|
+
function extractFrame(text) {
|
|
218
|
+
const py = PY_FRAME.exec(text);
|
|
219
|
+
if (py)
|
|
220
|
+
return { file: py[1], line: Number(py[2]) };
|
|
221
|
+
const js = JS_FRAME.exec(text);
|
|
222
|
+
if (js)
|
|
223
|
+
return { file: js[1], line: Number(js[2]) };
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
/** Most recent extractable frame in a context window (newest line last). */
|
|
227
|
+
function lastFrameIn(lines) {
|
|
228
|
+
for (let i = lines.length - 1; i >= 0 && i >= lines.length - 8; i--) {
|
|
229
|
+
const frame = extractFrame(lines[i]);
|
|
230
|
+
if (frame)
|
|
231
|
+
return frame;
|
|
232
|
+
}
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
function isStackFrame(text) {
|
|
236
|
+
return /^\s*(at\s+|File\s+"|Caused by:|\.\.\.\s+\d+\s+more|--- End of)/.test(text);
|
|
237
|
+
}
|
|
238
|
+
/** Collapse volatile bits (timestamps, numbers, hex, quoted values) so repeats dedupe. */
|
|
239
|
+
function normalizeSignature(text) {
|
|
240
|
+
return text
|
|
241
|
+
.trim()
|
|
242
|
+
.replace(/\b\d{4}-\d{2}-\d{2}[t ][\d:.,]+z?\b/gi, "<ts>")
|
|
243
|
+
.replace(/0x[0-9a-f]+/gi, "<hex>")
|
|
244
|
+
.replace(/\b\d+\b/g, "<n>")
|
|
245
|
+
.replace(/\s+/g, " ")
|
|
246
|
+
.slice(0, 200)
|
|
247
|
+
.toLowerCase();
|
|
248
|
+
}
|
|
249
|
+
function renderPrompt(incident, file, diff, recentLogs) {
|
|
250
|
+
const parts = [];
|
|
251
|
+
parts.push(`I hit an error in my **${incident.service}** service. Help me fix it.`);
|
|
252
|
+
parts.push("");
|
|
253
|
+
parts.push("## Error");
|
|
254
|
+
parts.push("```");
|
|
255
|
+
parts.push(...incident.logExcerpt);
|
|
256
|
+
parts.push("```");
|
|
257
|
+
if (file) {
|
|
258
|
+
parts.push("");
|
|
259
|
+
parts.push(`Affected file: \`${file}\`${incident.line ? ` (line ${incident.line})` : ""}`);
|
|
260
|
+
}
|
|
261
|
+
if (diff.trim()) {
|
|
262
|
+
parts.push("");
|
|
263
|
+
parts.push("## Current diff of the affected file");
|
|
264
|
+
parts.push("```diff");
|
|
265
|
+
parts.push(diff.trimEnd());
|
|
266
|
+
parts.push("```");
|
|
267
|
+
}
|
|
268
|
+
if (recentLogs.length) {
|
|
269
|
+
parts.push("");
|
|
270
|
+
parts.push(`## Last ${recentLogs.length} log lines from ${incident.service}`);
|
|
271
|
+
parts.push("```");
|
|
272
|
+
parts.push(...recentLogs);
|
|
273
|
+
parts.push("```");
|
|
274
|
+
}
|
|
275
|
+
return parts.join("\n");
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=error-inbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-inbox.js","sourceRoot":"","sources":["../../src/core/error-inbox.ts"],"names":[],"mappings":"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"}
|
package/dist/core/log-store.d.ts
CHANGED
|
@@ -5,13 +5,18 @@ interface LogStoreOptions {
|
|
|
5
5
|
maxLinesPerService?: number;
|
|
6
6
|
timelineStore?: TimelineStore;
|
|
7
7
|
}
|
|
8
|
+
type LogListener = (entry: LogEntry) => void;
|
|
8
9
|
export declare class LogStore {
|
|
9
10
|
private readonly entriesByService;
|
|
10
11
|
private readonly baseDir;
|
|
11
12
|
private readonly maxLinesPerService;
|
|
12
13
|
private readonly timelineStore?;
|
|
14
|
+
private readonly listeners;
|
|
13
15
|
constructor(options?: LogStoreOptions);
|
|
16
|
+
/** Observe every appended line. Returns an unsubscribe fn. */
|
|
17
|
+
subscribe(listener: LogListener): () => void;
|
|
14
18
|
append(service: string, stream: LogStream, text: string): Promise<LogEntry>;
|
|
19
|
+
private emit;
|
|
15
20
|
read(service: string, limit?: number): LogEntry[];
|
|
16
21
|
private appendTimelineEvent;
|
|
17
22
|
}
|
package/dist/core/log-store.js
CHANGED
|
@@ -5,11 +5,19 @@ export class LogStore {
|
|
|
5
5
|
baseDir;
|
|
6
6
|
maxLinesPerService;
|
|
7
7
|
timelineStore;
|
|
8
|
+
listeners = new Set();
|
|
8
9
|
constructor(options = {}) {
|
|
9
10
|
this.baseDir = options.baseDir ?? ".nomoreide/logs";
|
|
10
11
|
this.maxLinesPerService = options.maxLinesPerService ?? 500;
|
|
11
12
|
this.timelineStore = options.timelineStore;
|
|
12
13
|
}
|
|
14
|
+
/** Observe every appended line. Returns an unsubscribe fn. */
|
|
15
|
+
subscribe(listener) {
|
|
16
|
+
this.listeners.add(listener);
|
|
17
|
+
return () => {
|
|
18
|
+
this.listeners.delete(listener);
|
|
19
|
+
};
|
|
20
|
+
}
|
|
13
21
|
async append(service, stream, text) {
|
|
14
22
|
const entry = {
|
|
15
23
|
service,
|
|
@@ -23,8 +31,19 @@ export class LogStore {
|
|
|
23
31
|
await mkdir(this.baseDir, { recursive: true });
|
|
24
32
|
await appendFile(join(this.baseDir, `${safeFileName(service)}.log`), `${JSON.stringify(entry)}\n`);
|
|
25
33
|
await this.appendTimelineEvent(entry);
|
|
34
|
+
this.emit(entry);
|
|
26
35
|
return entry;
|
|
27
36
|
}
|
|
37
|
+
emit(entry) {
|
|
38
|
+
for (const listener of this.listeners) {
|
|
39
|
+
try {
|
|
40
|
+
listener(entry);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// ignore listener errors
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
28
47
|
read(service, limit = this.maxLinesPerService) {
|
|
29
48
|
return (this.entriesByService.get(service) ?? []).slice(-limit);
|
|
30
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-store.js","sourceRoot":"","sources":["../../src/core/log-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"log-store.js","sourceRoot":"","sources":["../../src/core/log-store.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { FastMCP } from "fastmcp";
|
|
2
2
|
import { ConfigStore } from "../core/config-store.js";
|
|
3
|
+
import { ErrorInbox } from "../core/error-inbox.js";
|
|
3
4
|
import { LogStore } from "../core/log-store.js";
|
|
4
5
|
import { ProcessManager } from "../core/process-manager.js";
|
|
5
6
|
import { ToolCallStore } from "../core/tool-call-store.js";
|
|
6
7
|
import { type UiLifecycleManager } from "../web/ui-lifecycle.js";
|
|
7
|
-
import { NOMOREIDE_TOOL_NAMES } from "./tools.js";
|
|
8
|
-
export { NOMOREIDE_TOOL_NAMES } from "./tools.js";
|
|
8
|
+
import { NOMOREIDE_TOOL_NAMES } from "./tools/index.js";
|
|
9
|
+
export { NOMOREIDE_TOOL_NAMES } from "./tools/index.js";
|
|
9
10
|
interface CreateNoMoreIdeMcpServerOptions {
|
|
10
11
|
configPath?: string;
|
|
11
12
|
logDir?: string;
|
|
@@ -15,6 +16,7 @@ interface CreateNoMoreIdeMcpServerOptions {
|
|
|
15
16
|
export interface NoMoreIdeMcpServer {
|
|
16
17
|
server: FastMCP;
|
|
17
18
|
configStore: ConfigStore;
|
|
19
|
+
errorInbox: ErrorInbox;
|
|
18
20
|
logStore: LogStore;
|
|
19
21
|
manager: ProcessManager;
|
|
20
22
|
uiLifecycle: UiLifecycleManager;
|
package/dist/mcp/server.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { dirname, resolve } from "node:path";
|
|
2
2
|
import { FastMCP } from "fastmcp";
|
|
3
3
|
import { ConfigStore, defaultGlobalConfigPath } from "../core/config-store.js";
|
|
4
|
+
import { ErrorInbox } from "../core/error-inbox.js";
|
|
4
5
|
import { LogStore } from "../core/log-store.js";
|
|
5
6
|
import { ProcessManager } from "../core/process-manager.js";
|
|
6
7
|
import { TimelineStore } from "../core/timeline-store.js";
|
|
7
8
|
import { ToolCallStore } from "../core/tool-call-store.js";
|
|
8
9
|
import { createUiLifecycleManager, } from "../web/ui-lifecycle.js";
|
|
9
|
-
import { NOMOREIDE_TOOL_NAMES, registerNoMoreIdeTools, } from "./tools.js";
|
|
10
|
-
export { NOMOREIDE_TOOL_NAMES } from "./tools.js";
|
|
10
|
+
import { NOMOREIDE_TOOL_NAMES, registerNoMoreIdeTools, } from "./tools/index.js";
|
|
11
|
+
export { NOMOREIDE_TOOL_NAMES } from "./tools/index.js";
|
|
11
12
|
export function createNoMoreIdeMcpServer(options = {}) {
|
|
12
13
|
const configPath = options.configPath ?? defaultGlobalConfigPath();
|
|
13
14
|
const logDir = options.logDir ?? resolve(process.cwd(), ".nomoreide/logs");
|
|
@@ -20,6 +21,7 @@ export function createNoMoreIdeMcpServer(options = {}) {
|
|
|
20
21
|
timelineStore,
|
|
21
22
|
});
|
|
22
23
|
const manager = new ProcessManager({ configStore, logStore, timelineStore });
|
|
24
|
+
const errorInbox = new ErrorInbox({ logStore, configStore });
|
|
23
25
|
const toolCallStore = new ToolCallStore();
|
|
24
26
|
const uiLifecycle = options.uiLifecycle ??
|
|
25
27
|
createUiLifecycleManager({
|
|
@@ -35,6 +37,7 @@ export function createNoMoreIdeMcpServer(options = {}) {
|
|
|
35
37
|
registerNoMoreIdeTools({
|
|
36
38
|
server,
|
|
37
39
|
configStore,
|
|
40
|
+
errorInbox,
|
|
38
41
|
logStore,
|
|
39
42
|
manager,
|
|
40
43
|
timelineStore,
|
|
@@ -44,6 +47,7 @@ export function createNoMoreIdeMcpServer(options = {}) {
|
|
|
44
47
|
return {
|
|
45
48
|
server,
|
|
46
49
|
configStore,
|
|
50
|
+
errorInbox,
|
|
47
51
|
logStore,
|
|
48
52
|
manager,
|
|
49
53
|
uiLifecycle,
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EACL,wBAAwB,GAEzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { stringify } from "./context.js";
|
|
2
|
+
export const AGENT_TOOL_NAMES = [
|
|
3
|
+
"nomoreide_open_ui",
|
|
4
|
+
"nomoreide_close_ui",
|
|
5
|
+
];
|
|
6
|
+
export function registerAgentTools(server, ctx) {
|
|
7
|
+
const { uiLifecycle } = ctx;
|
|
8
|
+
server.addTool({
|
|
9
|
+
name: "nomoreide_open_ui",
|
|
10
|
+
description: "Open or reuse the singleton NoMoreIDE web UI.",
|
|
11
|
+
execute: async () => stringify(await uiLifecycle.ensureStarted()),
|
|
12
|
+
});
|
|
13
|
+
server.addTool({
|
|
14
|
+
name: "nomoreide_close_ui",
|
|
15
|
+
description: "Close the NoMoreIDE web UI owned by this MCP process.",
|
|
16
|
+
execute: async () => stringify(await uiLifecycle.close()),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/mcp/tools/agent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAoB,MAAM,cAAc,CAAC;AAE3D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,mBAAmB;IACnB,oBAAoB;CACZ,CAAC;AAEX,MAAM,UAAU,kBAAkB,CAAC,MAAe,EAAE,GAAgB;IAClE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;IAE5B,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,+CAA+C;QAC5D,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,WAAW,CAAC,aAAa,EAAE,CAAC;KAClE,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC;QACb,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,uDAAuD;QACpE,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC;KAC1D,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { FastMCP } from "fastmcp";
|
|
2
|
+
import type { ConfigStore } from "../../core/config-store.js";
|
|
3
|
+
import type { ErrorInbox } from "../../core/error-inbox.js";
|
|
4
|
+
import { GitManager } from "../../core/git-manager.js";
|
|
5
|
+
import type { LogStore } from "../../core/log-store.js";
|
|
6
|
+
import type { ProcessManager } from "../../core/process-manager.js";
|
|
7
|
+
import type { TimelineStore } from "../../core/timeline-store.js";
|
|
8
|
+
import { type ToolCallStore } from "../../core/tool-call-store.js";
|
|
9
|
+
import type { UiLifecycleManager } from "../../web/ui-lifecycle.js";
|
|
10
|
+
/** Shared stateful services every tool group receives. */
|
|
11
|
+
export interface ToolContext {
|
|
12
|
+
configStore: ConfigStore;
|
|
13
|
+
errorInbox: ErrorInbox;
|
|
14
|
+
logStore: LogStore;
|
|
15
|
+
manager: ProcessManager;
|
|
16
|
+
timelineStore: TimelineStore;
|
|
17
|
+
uiLifecycle: UiLifecycleManager;
|
|
18
|
+
}
|
|
19
|
+
/** Each domain registers its tools onto the (optionally recording) server. */
|
|
20
|
+
export type RegisterTools = (server: FastMCP, ctx: ToolContext) => void;
|
|
21
|
+
export declare function git(cwd?: string): GitManager;
|
|
22
|
+
export declare function stringify(value: unknown): string;
|
|
23
|
+
/**
|
|
24
|
+
* Wrap a FastMCP server so every `addTool` execute is timed and recorded in
|
|
25
|
+
* the tool-call store. The aggregator wraps once, then hands the same wrapped
|
|
26
|
+
* server to each domain's `registerXTools`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function wrapServerForRecording(server: FastMCP, store: ToolCallStore): FastMCP;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { GitManager } from "../../core/git-manager.js";
|
|
2
|
+
import { previewArgs } from "../../core/tool-call-store.js";
|
|
3
|
+
export function git(cwd) {
|
|
4
|
+
return new GitManager(cwd ?? process.cwd());
|
|
5
|
+
}
|
|
6
|
+
export function stringify(value) {
|
|
7
|
+
return JSON.stringify(value, null, 2);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Wrap a FastMCP server so every `addTool` execute is timed and recorded in
|
|
11
|
+
* the tool-call store. The aggregator wraps once, then hands the same wrapped
|
|
12
|
+
* server to each domain's `registerXTools`.
|
|
13
|
+
*/
|
|
14
|
+
export function wrapServerForRecording(server, store) {
|
|
15
|
+
const originalAdd = server.addTool.bind(server);
|
|
16
|
+
const wrapped = (definition) => {
|
|
17
|
+
const originalExecute = definition.execute;
|
|
18
|
+
const recordingDefinition = {
|
|
19
|
+
...definition,
|
|
20
|
+
execute: async (args, context) => {
|
|
21
|
+
const start = Date.now();
|
|
22
|
+
const startedAt = new Date(start).toISOString();
|
|
23
|
+
try {
|
|
24
|
+
const result = await originalExecute(args, context);
|
|
25
|
+
store.record({
|
|
26
|
+
tool: definition.name,
|
|
27
|
+
startedAt,
|
|
28
|
+
durationMs: Date.now() - start,
|
|
29
|
+
status: "ok",
|
|
30
|
+
args: previewArgs(args),
|
|
31
|
+
});
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
store.record({
|
|
36
|
+
tool: definition.name,
|
|
37
|
+
startedAt,
|
|
38
|
+
durationMs: Date.now() - start,
|
|
39
|
+
status: "error",
|
|
40
|
+
args: previewArgs(args),
|
|
41
|
+
error: error instanceof Error ? error.message : String(error),
|
|
42
|
+
});
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
return originalAdd(recordingDefinition);
|
|
48
|
+
};
|
|
49
|
+
return new Proxy(server, {
|
|
50
|
+
get(target, prop, receiver) {
|
|
51
|
+
if (prop === "addTool")
|
|
52
|
+
return wrapped;
|
|
53
|
+
return Reflect.get(target, prop, receiver);
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/mcp/tools/context.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAIvD,OAAO,EAAE,WAAW,EAAsB,MAAM,+BAA+B,CAAC;AAgBhF,MAAM,UAAU,GAAG,CAAC,GAAY;IAC9B,OAAO,IAAI,UAAU,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAe,EACf,KAAoB;IAEpB,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,CAAC,UAA6C,EAAE,EAAE;QAChE,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,CAAC;QAC3C,MAAM,mBAAmB,GAAG;YAC1B,GAAG,UAAU;YACb,OAAO,EAAE,KAAK,EAAE,IAAa,EAAE,OAAgB,EAAE,EAAE;gBACjD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACzB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;gBAChD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAO,eAGA,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;oBACtC,KAAK,CAAC,MAAM,CAAC;wBACX,IAAI,EAAE,UAAU,CAAC,IAAI;wBACrB,SAAS;wBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;wBAC9B,MAAM,EAAE,IAAI;wBACZ,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC;qBACxB,CAAC,CAAC;oBACH,OAAO,MAA4C,CAAC;gBACtD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,KAAK,CAAC,MAAM,CAAC;wBACX,IAAI,EAAE,UAAU,CAAC,IAAI;wBACrB,SAAS;wBACT,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;wBAC9B,MAAM,EAAE,OAAO;wBACf,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC;wBACvB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC9D,CAAC,CAAC;oBACH,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;SACmC,CAAC;QACvC,OAAO,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAC1C,CAAC,CAAC;IACF,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACvB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;YACxB,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,OAAO,CAAC;YACvC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FastMCP } from "fastmcp";
|
|
2
|
+
import { type ToolContext } from "./context.js";
|
|
3
|
+
export declare const ERROR_TOOL_NAMES: readonly ["nomoreide_list_errors", "nomoreide_error_prompt"];
|
|
4
|
+
/** Error Inbox tools: surface detected incidents and their copy-to-agent prompt. */
|
|
5
|
+
export declare function registerErrorTools(server: FastMCP, ctx: ToolContext): void;
|