cntx-ui 3.1.4 → 3.1.6

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.
@@ -286,8 +286,12 @@ export default class APIRouter {
286
286
  }
287
287
  async handlePostSemanticSearch(req, res) {
288
288
  const body = await this.getRequestBody(req);
289
- const { query, limit = 20 } = JSON.parse(body);
290
- const results = await this.vectorStore.search(query, { limit });
289
+ const { query, question, limit = 20 } = JSON.parse(body);
290
+ const searchTerm = query || question;
291
+ if (!searchTerm) {
292
+ return this.sendError(res, 400, 'Missing search term (query or question)');
293
+ }
294
+ const results = await this.vectorStore.search(searchTerm, { limit });
291
295
  this.sendResponse(res, 200, { results });
292
296
  }
293
297
  async handleGetVectorDbStatus(req, res) {
@@ -6,8 +6,10 @@ import { readFileSync } from 'fs';
6
6
  import { join } from 'path';
7
7
  export class MCPServer {
8
8
  cntxServer;
9
- constructor(cntxServer) {
9
+ version;
10
+ constructor(cntxServer, version = '3.0.0') {
10
11
  this.cntxServer = cntxServer;
12
+ this.version = version;
11
13
  // Listen for MCP requests on stdin
12
14
  process.stdin.on('data', (data) => {
13
15
  this.handleInput(data.toString());
@@ -36,7 +38,7 @@ export class MCPServer {
36
38
  resources: {},
37
39
  prompts: {}
38
40
  },
39
- serverInfo: { name: 'cntx-ui', version: '3.0.0' }
41
+ serverInfo: { name: 'cntx-ui', version: this.version }
40
42
  }));
41
43
  case 'tools/list':
42
44
  return this.sendResponse(this.handleListTools(id));
@@ -28,6 +28,7 @@ export default class SemanticSplitter {
28
28
  includeContext: true, // Include imports/types needed
29
29
  minFunctionSize: 40, // Skip tiny functions
30
30
  minStructureSize: 20, // Skip tiny structures
31
+ verbose: options.verbose || false,
31
32
  ...options
32
33
  };
33
34
  // Initialize tree-sitter parsers
@@ -88,7 +89,10 @@ export default class SemanticSplitter {
88
89
  allChunks.push(...fileChunks);
89
90
  }
90
91
  catch (error) {
91
- console.warn(`Failed to process ${filePath}: ${error.message}`);
92
+ console.warn(`⚠️ Failed to process ${filePath}: ${error.message}`);
93
+ if (this.options.verbose) {
94
+ console.error(error.stack);
95
+ }
92
96
  }
93
97
  }
94
98
  console.log(`🧩 Created ${allChunks.length} semantic chunks across project`);
@@ -112,39 +116,48 @@ export default class SemanticSplitter {
112
116
  return [];
113
117
  }
114
118
  const parser = this.getParser(relativePath);
115
- const tree = parser.parse(content);
116
- const root = tree.rootNode;
117
- const ext = extname(relativePath).toLowerCase();
118
- const elements = {
119
- functions: [],
120
- types: [],
121
- imports: []
122
- };
123
- if (['.js', '.jsx', '.ts', '.tsx', '.rs'].includes(ext)) {
124
- elements.imports = this.extractImports(root, content, relativePath);
125
- // Traverse AST for functions and types
126
- this.traverse(root, content, relativePath, elements);
127
- }
128
- else if (ext === '.json') {
129
- this.extractJsonStructures(root, content, relativePath, elements);
130
- }
131
- else if (ext === '.css' || ext === '.scss') {
132
- this.extractCssStructures(root, content, relativePath, elements);
133
- }
134
- else if (ext === '.html') {
135
- this.extractHtmlStructures(root, content, relativePath, elements);
136
- }
137
- else if (ext === '.sql') {
138
- this.extractSqlStructures(root, content, relativePath, elements);
139
- }
140
- else if (ext === '.md') {
141
- this.extractMarkdownStructures(root, content, relativePath, elements);
119
+ try {
120
+ const tree = parser.parse(content);
121
+ const root = tree.rootNode;
122
+ const ext = extname(relativePath).toLowerCase();
123
+ const elements = {
124
+ functions: [],
125
+ types: [],
126
+ imports: []
127
+ };
128
+ if (['.js', '.jsx', '.ts', '.tsx', '.rs'].includes(ext)) {
129
+ elements.imports = this.extractImports(root, content, relativePath);
130
+ // Traverse AST for functions and types
131
+ this.traverse(root, content, relativePath, elements);
132
+ }
133
+ else if (ext === '.json') {
134
+ this.extractJsonStructures(root, content, relativePath, elements);
135
+ }
136
+ else if (ext === '.css' || ext === '.scss') {
137
+ this.extractCssStructures(root, content, relativePath, elements);
138
+ }
139
+ else if (ext === '.html') {
140
+ this.extractHtmlStructures(root, content, relativePath, elements);
141
+ }
142
+ else if (ext === '.sql') {
143
+ this.extractSqlStructures(root, content, relativePath, elements);
144
+ }
145
+ else if (ext === '.md') {
146
+ this.extractMarkdownStructures(root, content, relativePath, elements);
147
+ }
148
+ else if (ext === '.toml') {
149
+ this.extractTomlStructures(root, content, relativePath, elements);
150
+ }
151
+ // Create chunks from elements
152
+ return this.createChunks(elements, content, relativePath);
142
153
  }
143
- else if (ext === '.toml') {
144
- this.extractTomlStructures(root, content, relativePath, elements);
154
+ catch (error) {
155
+ console.warn(`⚠️ Parser failed for ${relativePath}: ${error.message}`);
156
+ if (this.options.verbose) {
157
+ console.error(error.stack);
158
+ }
159
+ return [];
145
160
  }
146
- // Create chunks from elements
147
- return this.createChunks(elements, content, relativePath);
148
161
  }
149
162
  traverse(node, content, filePath, elements) {
150
163
  // Detect Function Declarations (JS/TS)
package/dist/server.js CHANGED
@@ -38,6 +38,7 @@ function getProjectName(cwd) {
38
38
  export class CntxServer {
39
39
  CWD;
40
40
  CNTX_DIR;
41
+ version;
41
42
  verbose;
42
43
  isMcp;
43
44
  mcpServerStarted;
@@ -66,6 +67,20 @@ export class CntxServer {
66
67
  this.mcpServerStarted = false;
67
68
  this.mcpServer = null;
68
69
  this.initMessages = [];
70
+ // Read package version
71
+ try {
72
+ let pkgDir = __dirname;
73
+ let pkgPath = join(pkgDir, 'package.json');
74
+ if (!existsSync(pkgPath)) {
75
+ pkgDir = join(__dirname, '..');
76
+ pkgPath = join(pkgDir, 'package.json');
77
+ }
78
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
79
+ this.version = pkg.version;
80
+ }
81
+ catch {
82
+ this.version = '3.1.5';
83
+ }
69
84
  // Ensure directory exists
70
85
  if (!existsSync(this.CNTX_DIR))
71
86
  mkdirSync(this.CNTX_DIR, { recursive: true });
@@ -80,7 +95,8 @@ export class CntxServer {
80
95
  this.semanticSplitter = new SemanticSplitter({
81
96
  maxChunkSize: 2000,
82
97
  includeContext: true,
83
- minFunctionSize: 50
98
+ minFunctionSize: 50,
99
+ verbose: this.verbose
84
100
  });
85
101
  this.vectorStore = new SimpleVectorStore(this.databaseManager, {
86
102
  modelName: 'Xenova/all-MiniLM-L6-v2',
@@ -201,11 +217,15 @@ export class CntxServer {
201
217
  }
202
218
  startMCPServer() {
203
219
  if (!this.mcpServer) {
204
- this.mcpServer = new MCPServer(this);
220
+ this.mcpServer = new MCPServer(this, this.version);
205
221
  this.mcpServerStarted = true;
206
222
  }
207
223
  }
208
224
  async listen(port = 3333, host = 'localhost') {
225
+ if (this.isMcp) {
226
+ this.log('Mode: MCP (stdio) - Skipping HTTP server start');
227
+ return null;
228
+ }
209
229
  const server = createServer((req, res) => {
210
230
  const url = parse(req.url || '/', true);
211
231
  // Serve static files from web/dist
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cntx-ui",
3
3
  "type": "module",
4
- "version": "3.1.4",
4
+ "version": "3.1.6",
5
5
  "description": "Autonomous Repository Intelligence engine with web UI and MCP server. Unified semantic code understanding, local RAG, and agent working memory.",
6
6
  "keywords": [
7
7
  "repository-intelligence",