neuronlayer 0.1.9 → 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.
Potentially problematic release.
This version of neuronlayer might be problematic. Click here for more details.
- package/README.md +3 -2
- package/dist/index.js +172 -90
- package/dist/index.js.map +7 -0
- package/package.json +6 -1
- package/esbuild.config.js +0 -26
- package/src/cli/commands.ts +0 -573
- package/src/core/adr-exporter.ts +0 -253
- package/src/core/architecture/architecture-enforcement.ts +0 -228
- package/src/core/architecture/duplicate-detector.ts +0 -288
- package/src/core/architecture/index.ts +0 -6
- package/src/core/architecture/pattern-learner.ts +0 -306
- package/src/core/architecture/pattern-library.ts +0 -403
- package/src/core/architecture/pattern-validator.ts +0 -324
- package/src/core/change-intelligence/bug-correlator.ts +0 -544
- package/src/core/change-intelligence/change-intelligence.ts +0 -264
- package/src/core/change-intelligence/change-tracker.ts +0 -334
- package/src/core/change-intelligence/fix-suggester.ts +0 -340
- package/src/core/change-intelligence/index.ts +0 -5
- package/src/core/code-verifier.ts +0 -843
- package/src/core/confidence/confidence-scorer.ts +0 -251
- package/src/core/confidence/conflict-checker.ts +0 -289
- package/src/core/confidence/index.ts +0 -5
- package/src/core/confidence/source-tracker.ts +0 -263
- package/src/core/confidence/warning-detector.ts +0 -241
- package/src/core/context-rot/compaction.ts +0 -284
- package/src/core/context-rot/context-health.ts +0 -243
- package/src/core/context-rot/context-rot-prevention.ts +0 -213
- package/src/core/context-rot/critical-context.ts +0 -221
- package/src/core/context-rot/drift-detector.ts +0 -255
- package/src/core/context-rot/index.ts +0 -7
- package/src/core/context.ts +0 -263
- package/src/core/decision-extractor.ts +0 -339
- package/src/core/decisions.ts +0 -69
- package/src/core/deja-vu.ts +0 -421
- package/src/core/engine.ts +0 -1646
- package/src/core/feature-context.ts +0 -726
- package/src/core/ghost-mode.ts +0 -465
- package/src/core/learning.ts +0 -519
- package/src/core/living-docs/activity-tracker.ts +0 -296
- package/src/core/living-docs/architecture-generator.ts +0 -428
- package/src/core/living-docs/changelog-generator.ts +0 -348
- package/src/core/living-docs/component-generator.ts +0 -230
- package/src/core/living-docs/doc-engine.ts +0 -134
- package/src/core/living-docs/doc-validator.ts +0 -282
- package/src/core/living-docs/index.ts +0 -8
- package/src/core/project-manager.ts +0 -301
- package/src/core/refresh/activity-gate.ts +0 -256
- package/src/core/refresh/git-staleness-checker.ts +0 -108
- package/src/core/refresh/index.ts +0 -27
- package/src/core/summarizer.ts +0 -290
- package/src/core/test-awareness/change-validator.ts +0 -499
- package/src/core/test-awareness/index.ts +0 -5
- package/src/index.ts +0 -90
- package/src/indexing/ast.ts +0 -868
- package/src/indexing/embeddings.ts +0 -85
- package/src/indexing/indexer.ts +0 -270
- package/src/indexing/watcher.ts +0 -78
- package/src/server/gateways/aggregator.ts +0 -374
- package/src/server/gateways/index.ts +0 -473
- package/src/server/gateways/memory-ghost.ts +0 -343
- package/src/server/gateways/memory-query.ts +0 -452
- package/src/server/gateways/memory-record.ts +0 -346
- package/src/server/gateways/memory-review.ts +0 -410
- package/src/server/gateways/memory-status.ts +0 -517
- package/src/server/gateways/memory-verify.ts +0 -392
- package/src/server/gateways/router.ts +0 -434
- package/src/server/gateways/types.ts +0 -610
- package/src/server/http.ts +0 -228
- package/src/server/mcp.ts +0 -154
- package/src/server/resources.ts +0 -85
- package/src/server/tools.ts +0 -2460
- package/src/storage/database.ts +0 -271
- package/src/storage/tier1.ts +0 -135
- package/src/storage/tier2.ts +0 -972
- package/src/storage/tier3.ts +0 -123
- package/src/types/documentation.ts +0 -619
- package/src/types/index.ts +0 -222
- package/src/utils/config.ts +0 -194
- package/src/utils/files.ts +0 -117
- package/src/utils/time.ts +0 -37
- package/src/utils/tokens.ts +0 -52
package/src/server/http.ts
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HTTP API Server for NeuronLayer
|
|
3
|
-
*
|
|
4
|
-
* Provides REST endpoints for tools that don't support MCP.
|
|
5
|
-
* Runs alongside or instead of the MCP server.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { createServer, IncomingMessage, ServerResponse } from 'http';
|
|
9
|
-
import { NeuronLayerEngine } from '../core/engine.js';
|
|
10
|
-
import type { NeuronLayerConfig } from '../types/index.js';
|
|
11
|
-
|
|
12
|
-
export class HTTPServer {
|
|
13
|
-
private engine: NeuronLayerEngine;
|
|
14
|
-
private server: ReturnType<typeof createServer> | null = null;
|
|
15
|
-
private port: number;
|
|
16
|
-
|
|
17
|
-
constructor(config: NeuronLayerConfig, port: number = 3333) {
|
|
18
|
-
this.engine = new NeuronLayerEngine(config);
|
|
19
|
-
this.port = port;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async start(): Promise<void> {
|
|
23
|
-
// Initialize the engine first
|
|
24
|
-
await this.engine.initialize();
|
|
25
|
-
|
|
26
|
-
this.server = createServer((req, res) => {
|
|
27
|
-
this.handleRequest(req, res);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
this.server.listen(this.port, () => {
|
|
31
|
-
console.log(`NeuronLayer HTTP API running at http://localhost:${this.port}`);
|
|
32
|
-
console.log('');
|
|
33
|
-
console.log('Endpoints:');
|
|
34
|
-
console.log(' GET /status - Project status and stats');
|
|
35
|
-
console.log(' GET /search?q=... - Search code semantically');
|
|
36
|
-
console.log(' GET /dependencies?file= - Get file dependencies');
|
|
37
|
-
console.log(' GET /impact?file= - Impact analysis');
|
|
38
|
-
console.log(' GET /circular - Find circular dependencies');
|
|
39
|
-
console.log(' GET /decisions - List all decisions');
|
|
40
|
-
console.log(' POST /decisions - Record a new decision');
|
|
41
|
-
console.log(' GET /symbols?file= - Get symbols in a file');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Handle shutdown
|
|
45
|
-
process.on('SIGINT', () => {
|
|
46
|
-
this.shutdown();
|
|
47
|
-
process.exit(0);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
process.on('SIGTERM', () => {
|
|
51
|
-
this.shutdown();
|
|
52
|
-
process.exit(0);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {
|
|
57
|
-
// Enable CORS for all origins
|
|
58
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
59
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
60
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
61
|
-
|
|
62
|
-
if (req.method === 'OPTIONS') {
|
|
63
|
-
res.writeHead(200);
|
|
64
|
-
res.end();
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const url = new URL(req.url || '/', `http://localhost:${this.port}`);
|
|
69
|
-
const path = url.pathname;
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
let result: unknown;
|
|
73
|
-
|
|
74
|
-
switch (path) {
|
|
75
|
-
case '/':
|
|
76
|
-
case '/status': {
|
|
77
|
-
const summary = this.engine.getProjectSummary();
|
|
78
|
-
const status = this.engine.getInitializationStatus();
|
|
79
|
-
result = {
|
|
80
|
-
project: summary.name,
|
|
81
|
-
status: status.status,
|
|
82
|
-
files: summary.totalFiles,
|
|
83
|
-
lines: summary.totalLines,
|
|
84
|
-
languages: summary.languages,
|
|
85
|
-
decisions: summary.recentDecisions.length
|
|
86
|
-
};
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
case '/search': {
|
|
91
|
-
const query = url.searchParams.get('q');
|
|
92
|
-
if (!query) {
|
|
93
|
-
this.sendError(res, 400, 'Missing query parameter: q');
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const limit = parseInt(url.searchParams.get('limit') || '10');
|
|
97
|
-
const results = await this.engine.search(query, limit);
|
|
98
|
-
result = results.map(r => ({
|
|
99
|
-
file: r.file,
|
|
100
|
-
preview: r.preview,
|
|
101
|
-
similarity: r.similarity,
|
|
102
|
-
lines: `${r.lineStart}-${r.lineEnd}`
|
|
103
|
-
}));
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
case '/dependencies': {
|
|
108
|
-
const file = url.searchParams.get('file');
|
|
109
|
-
if (!file) {
|
|
110
|
-
this.sendError(res, 400, 'Missing query parameter: file');
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
const deps = this.engine.getFileDependencies(file);
|
|
114
|
-
result = deps;
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
case '/impact': {
|
|
119
|
-
const file = url.searchParams.get('file');
|
|
120
|
-
if (!file) {
|
|
121
|
-
this.sendError(res, 400, 'Missing query parameter: file');
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
const depth = parseInt(url.searchParams.get('depth') || '3');
|
|
125
|
-
const dependents = this.engine.getTransitiveDependents(file, depth);
|
|
126
|
-
const circular = this.engine.findCircularDependencies();
|
|
127
|
-
const fileCircular = circular.filter(chain => chain.includes(file));
|
|
128
|
-
|
|
129
|
-
result = {
|
|
130
|
-
file,
|
|
131
|
-
direct_dependents: dependents.filter(d => d.depth === 1).length,
|
|
132
|
-
total_affected: dependents.length,
|
|
133
|
-
risk_level: dependents.length > 10 ? 'high' : dependents.length > 5 ? 'medium' : 'low',
|
|
134
|
-
affected_files: dependents.slice(0, 20),
|
|
135
|
-
circular_dependencies: fileCircular
|
|
136
|
-
};
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
case '/circular': {
|
|
141
|
-
const chains = this.engine.findCircularDependencies();
|
|
142
|
-
result = {
|
|
143
|
-
count: chains.length,
|
|
144
|
-
chains: chains.slice(0, 10)
|
|
145
|
-
};
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
case '/decisions': {
|
|
150
|
-
if (req.method === 'POST') {
|
|
151
|
-
const body = await this.readBody(req);
|
|
152
|
-
const data = JSON.parse(body);
|
|
153
|
-
if (!data.title || !data.description) {
|
|
154
|
-
this.sendError(res, 400, 'Missing required fields: title, description');
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
const decision = await this.engine.recordDecision(
|
|
158
|
-
data.title,
|
|
159
|
-
data.description,
|
|
160
|
-
data.files || [],
|
|
161
|
-
data.tags || []
|
|
162
|
-
);
|
|
163
|
-
result = decision;
|
|
164
|
-
} else {
|
|
165
|
-
const decisions = this.engine.getRecentDecisions(50);
|
|
166
|
-
result = decisions.map(d => ({
|
|
167
|
-
id: d.id,
|
|
168
|
-
title: d.title,
|
|
169
|
-
description: d.description,
|
|
170
|
-
files: d.files,
|
|
171
|
-
tags: d.tags,
|
|
172
|
-
created: d.createdAt,
|
|
173
|
-
status: d.status
|
|
174
|
-
}));
|
|
175
|
-
}
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
case '/symbols': {
|
|
180
|
-
const file = url.searchParams.get('file');
|
|
181
|
-
if (!file) {
|
|
182
|
-
this.sendError(res, 400, 'Missing query parameter: file');
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
const symbols = this.engine.getSymbols(file);
|
|
186
|
-
result = symbols;
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
default:
|
|
191
|
-
this.sendError(res, 404, `Unknown endpoint: ${path}`);
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
this.sendJSON(res, 200, result);
|
|
196
|
-
} catch (error) {
|
|
197
|
-
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
198
|
-
this.sendError(res, 500, message);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
private readBody(req: IncomingMessage): Promise<string> {
|
|
203
|
-
return new Promise((resolve, reject) => {
|
|
204
|
-
let body = '';
|
|
205
|
-
req.on('data', chunk => { body += chunk; });
|
|
206
|
-
req.on('end', () => resolve(body));
|
|
207
|
-
req.on('error', reject);
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
private sendJSON(res: ServerResponse, status: number, data: unknown): void {
|
|
212
|
-
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
213
|
-
res.end(JSON.stringify(data, null, 2));
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
private sendError(res: ServerResponse, status: number, message: string): void {
|
|
217
|
-
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
218
|
-
res.end(JSON.stringify({ error: message }));
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
shutdown(): void {
|
|
222
|
-
console.log('Shutting down HTTP server...');
|
|
223
|
-
this.engine.shutdown();
|
|
224
|
-
if (this.server) {
|
|
225
|
-
this.server.close();
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
package/src/server/mcp.ts
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
-
import {
|
|
4
|
-
CallToolRequestSchema,
|
|
5
|
-
ListToolsRequestSchema,
|
|
6
|
-
ListResourcesRequestSchema,
|
|
7
|
-
ReadResourceRequestSchema,
|
|
8
|
-
} from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
-
import { NeuronLayerEngine } from '../core/engine.js';
|
|
10
|
-
import {
|
|
11
|
-
allToolDefinitions,
|
|
12
|
-
handleGatewayCall,
|
|
13
|
-
isGatewayTool,
|
|
14
|
-
} from './gateways/index.js';
|
|
15
|
-
import { handleToolCall } from './tools.js';
|
|
16
|
-
import { resourceDefinitions, handleResourceRead } from './resources.js';
|
|
17
|
-
import type { NeuronLayerConfig } from '../types/index.js';
|
|
18
|
-
|
|
19
|
-
export class MCPServer {
|
|
20
|
-
private server: Server;
|
|
21
|
-
private engine: NeuronLayerEngine;
|
|
22
|
-
|
|
23
|
-
constructor(config: NeuronLayerConfig) {
|
|
24
|
-
this.engine = new NeuronLayerEngine(config);
|
|
25
|
-
|
|
26
|
-
this.server = new Server(
|
|
27
|
-
{
|
|
28
|
-
name: 'neuronlayer',
|
|
29
|
-
version: '0.1.0'
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
capabilities: {
|
|
33
|
-
tools: {},
|
|
34
|
-
resources: {}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
this.setupHandlers();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private setupHandlers(): void {
|
|
43
|
-
// List available tools - now using gateway pattern (10 tools instead of 51)
|
|
44
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
45
|
-
return {
|
|
46
|
-
tools: allToolDefinitions.map(t => ({
|
|
47
|
-
name: t.name,
|
|
48
|
-
description: t.description,
|
|
49
|
-
inputSchema: t.inputSchema
|
|
50
|
-
}))
|
|
51
|
-
};
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// Handle tool calls - route to gateways or standalone handlers
|
|
55
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
56
|
-
const { name, arguments: args } = request.params;
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
let result;
|
|
60
|
-
|
|
61
|
-
// Check if it's a gateway tool
|
|
62
|
-
if (isGatewayTool(name)) {
|
|
63
|
-
result = await handleGatewayCall(this.engine, name, args || {});
|
|
64
|
-
} else {
|
|
65
|
-
// Standalone tools route to existing handler
|
|
66
|
-
result = await handleToolCall(this.engine, name, args || {});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return {
|
|
70
|
-
content: [
|
|
71
|
-
{
|
|
72
|
-
type: 'text',
|
|
73
|
-
text: JSON.stringify(result, null, 2)
|
|
74
|
-
}
|
|
75
|
-
]
|
|
76
|
-
};
|
|
77
|
-
} catch (error) {
|
|
78
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
79
|
-
return {
|
|
80
|
-
content: [
|
|
81
|
-
{
|
|
82
|
-
type: 'text',
|
|
83
|
-
text: JSON.stringify({ error: errorMessage })
|
|
84
|
-
}
|
|
85
|
-
],
|
|
86
|
-
isError: true
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// List available resources
|
|
92
|
-
this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
93
|
-
return {
|
|
94
|
-
resources: resourceDefinitions.map(r => ({
|
|
95
|
-
uri: r.uri,
|
|
96
|
-
name: r.name,
|
|
97
|
-
description: r.description,
|
|
98
|
-
mimeType: r.mimeType
|
|
99
|
-
}))
|
|
100
|
-
};
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Read resource content
|
|
104
|
-
this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
105
|
-
const { uri } = request.params;
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
const result = await handleResourceRead(this.engine, uri);
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
contents: [
|
|
112
|
-
{
|
|
113
|
-
uri,
|
|
114
|
-
mimeType: result.mimeType,
|
|
115
|
-
text: result.contents
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
};
|
|
119
|
-
} catch (error) {
|
|
120
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
121
|
-
throw new Error(errorMessage);
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async start(): Promise<void> {
|
|
127
|
-
// Connect to stdio transport FIRST (so we can respond to MCP immediately)
|
|
128
|
-
const transport = new StdioServerTransport();
|
|
129
|
-
await this.server.connect(transport);
|
|
130
|
-
|
|
131
|
-
console.error('NeuronLayer MCP server started');
|
|
132
|
-
|
|
133
|
-
// Initialize the engine in the background (indexing, etc.)
|
|
134
|
-
// This allows MCP to respond while indexing happens
|
|
135
|
-
this.engine.initialize().catch(err => {
|
|
136
|
-
console.error('Engine initialization error:', err);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
// Handle shutdown
|
|
140
|
-
process.on('SIGINT', () => {
|
|
141
|
-
this.shutdown();
|
|
142
|
-
process.exit(0);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
process.on('SIGTERM', () => {
|
|
146
|
-
this.shutdown();
|
|
147
|
-
process.exit(0);
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
shutdown(): void {
|
|
152
|
-
this.engine.shutdown();
|
|
153
|
-
}
|
|
154
|
-
}
|
package/src/server/resources.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import type { NeuronLayerEngine } from '../core/engine.js';
|
|
2
|
-
|
|
3
|
-
export interface ResourceDefinition {
|
|
4
|
-
uri: string;
|
|
5
|
-
name: string;
|
|
6
|
-
description: string;
|
|
7
|
-
mimeType: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const resourceDefinitions: ResourceDefinition[] = [
|
|
11
|
-
{
|
|
12
|
-
uri: 'neuronlayer://decisions/recent',
|
|
13
|
-
name: 'Recent Decisions',
|
|
14
|
-
description: 'Last 10 architectural decisions made in this project',
|
|
15
|
-
mimeType: 'application/json'
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
uri: 'neuronlayer://project/overview',
|
|
19
|
-
name: 'Project Overview',
|
|
20
|
-
description: 'High-level project summary including languages, files, and structure',
|
|
21
|
-
mimeType: 'text/markdown'
|
|
22
|
-
}
|
|
23
|
-
];
|
|
24
|
-
|
|
25
|
-
export async function handleResourceRead(
|
|
26
|
-
engine: NeuronLayerEngine,
|
|
27
|
-
uri: string
|
|
28
|
-
): Promise<{ contents: string; mimeType: string }> {
|
|
29
|
-
switch (uri) {
|
|
30
|
-
case 'neuronlayer://decisions/recent': {
|
|
31
|
-
const decisions = engine.getRecentDecisions(10);
|
|
32
|
-
|
|
33
|
-
const contents = JSON.stringify(
|
|
34
|
-
decisions.map(d => ({
|
|
35
|
-
id: d.id,
|
|
36
|
-
title: d.title,
|
|
37
|
-
description: d.description,
|
|
38
|
-
files: d.files,
|
|
39
|
-
tags: d.tags,
|
|
40
|
-
created_at: d.createdAt.toISOString()
|
|
41
|
-
})),
|
|
42
|
-
null,
|
|
43
|
-
2
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
return { contents, mimeType: 'application/json' };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
case 'neuronlayer://project/overview': {
|
|
50
|
-
const summary = engine.getProjectSummary();
|
|
51
|
-
|
|
52
|
-
const markdown = `# ${summary.name}
|
|
53
|
-
|
|
54
|
-
${summary.description || 'No description available.'}
|
|
55
|
-
|
|
56
|
-
## Statistics
|
|
57
|
-
- **Total Files**: ${summary.totalFiles}
|
|
58
|
-
- **Total Lines**: ${summary.totalLines.toLocaleString()}
|
|
59
|
-
- **Languages**: ${summary.languages.join(', ') || 'Unknown'}
|
|
60
|
-
|
|
61
|
-
## Key Directories
|
|
62
|
-
${summary.keyDirectories.map(d => `- \`${d}/\``).join('\n') || 'None detected'}
|
|
63
|
-
|
|
64
|
-
## Dependencies
|
|
65
|
-
${summary.dependencies.slice(0, 10).map(d => `- ${d}`).join('\n') || 'None detected'}
|
|
66
|
-
${summary.dependencies.length > 10 ? `\n... and ${summary.dependencies.length - 10} more` : ''}
|
|
67
|
-
|
|
68
|
-
## Recent Decisions
|
|
69
|
-
${summary.recentDecisions.length > 0
|
|
70
|
-
? summary.recentDecisions.map(d => `### ${d.title}
|
|
71
|
-
${d.description}
|
|
72
|
-
_${d.createdAt.toLocaleDateString()}_
|
|
73
|
-
`).join('\n')
|
|
74
|
-
: 'No decisions recorded yet.'}
|
|
75
|
-
|
|
76
|
-
${summary.architectureNotes ? `## Architecture Notes\n${summary.architectureNotes}` : ''}
|
|
77
|
-
`;
|
|
78
|
-
|
|
79
|
-
return { contents: markdown, mimeType: 'text/markdown' };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
default:
|
|
83
|
-
throw new Error(`Unknown resource: ${uri}`);
|
|
84
|
-
}
|
|
85
|
-
}
|