cntx-ui 3.0.5 → 3.0.7

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/server.js CHANGED
@@ -6,9 +6,7 @@
6
6
  import { createServer } from 'http';
7
7
  import { join, dirname, relative, extname } from 'path';
8
8
  import { fileURLToPath } from 'url';
9
- import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, cpSync } from 'fs';
10
- import * as fs from 'fs';
11
- import { homedir } from 'os';
9
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
12
10
 
13
11
  // Import our modular components
14
12
  import ConfigurationManager from './lib/configuration-manager.js';
@@ -17,7 +15,6 @@ import FileSystemManager from './lib/file-system-manager.js';
17
15
  import BundleManager from './lib/bundle-manager.js';
18
16
  import APIRouter from './lib/api-router.js';
19
17
  import WebSocketManager from './lib/websocket-manager.js';
20
- import { AgentRuntime } from './lib/agent-runtime.js';
21
18
 
22
19
  // Import existing lib modules
23
20
  import { startMCPTransport } from './lib/mcp-transport.js';
@@ -51,7 +48,6 @@ export class CntxServer {
51
48
  this.verbose = options.verbose || false;
52
49
  this.mcpServerStarted = false;
53
50
  this.mcpServer = null;
54
- this.initMessages = []; // Track initialization messages
55
51
 
56
52
  // Ensure directory exists early
57
53
  if (!existsSync(this.CNTX_DIR)) mkdirSync(this.CNTX_DIR, { recursive: true });
@@ -78,9 +74,6 @@ export class CntxServer {
78
74
  this.lastSemanticAnalysis = null;
79
75
  this.vectorStoreInitialized = false;
80
76
 
81
- // Initialize Agent Runtime
82
- this.agentRuntime = new AgentRuntime(this);
83
-
84
77
  // Create semantic analysis manager object for API router
85
78
  this.semanticAnalysisManager = {
86
79
  getSemanticAnalysis: () => this.getSemanticAnalysis(),
@@ -89,13 +82,6 @@ export class CntxServer {
89
82
  lastSemanticAnalysis: this.lastSemanticAnalysis
90
83
  };
91
84
 
92
- // Create activity manager placeholder
93
- this.activityManager = {
94
- loadActivities: () => this.loadActivities(),
95
- executeActivity: (id) => this.executeActivity(id),
96
- stopActivity: (id) => this.stopActivity(id)
97
- };
98
-
99
85
  // Initialize API router with all managers
100
86
  this.apiRouter = new APIRouter(
101
87
  this,
@@ -103,8 +89,7 @@ export class CntxServer {
103
89
  this.bundleManager,
104
90
  this.fileSystemManager,
105
91
  this.semanticAnalysisManager,
106
- this.vectorStore,
107
- this.activityManager
92
+ this.vectorStore
108
93
  );
109
94
 
110
95
  // Add references for cross-module communication
@@ -112,87 +97,35 @@ export class CntxServer {
112
97
  this.bundleManager.webSocketManager = this.webSocketManager;
113
98
  }
114
99
 
115
- // Progress bar utility
116
- async showProgressBar(message, minTime = 500) {
117
- const startTime = Date.now();
118
- const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
119
- let frameIndex = 0;
120
-
121
- const interval = setInterval(() => {
122
- process.stdout.write(`\r${frames[frameIndex]} ${message}`);
123
- frameIndex = (frameIndex + 1) % frames.length;
124
- }, 80);
100
+ // === Proxy methods for MCP compatibility ===
125
101
 
126
- return () => {
127
- clearInterval(interval);
128
- const elapsed = Date.now() - startTime;
129
- const remaining = Math.max(0, minTime - elapsed);
102
+ get bundles() {
103
+ return this.configManager.getBundles();
104
+ }
130
105
 
131
- if (remaining > 0) {
132
- return new Promise(resolve => setTimeout(resolve, remaining));
133
- }
134
- return Promise.resolve();
135
- };
106
+ getAllFiles() {
107
+ return this.fileSystemManager.getAllFiles();
136
108
  }
137
109
 
138
- // Single progress bar for initialization
139
- async showInitProgress(steps) {
140
- const totalSteps = steps.length;
141
- let currentStep = 0;
110
+ getFileTree() {
111
+ return this.fileSystemManager.getFileTree();
112
+ }
142
113
 
143
- const updateProgress = (stepName, completed = false) => {
144
- const progress = Math.round((currentStep / totalSteps) * 100);
145
- const barLength = 30;
146
- const filledLength = Math.round((progress / 100) * barLength);
147
- const bar = '█'.repeat(filledLength) + '░'.repeat(barLength - filledLength);
114
+ generateBundle(name) {
115
+ return this.bundleManager.regenerateBundle(name);
116
+ }
148
117
 
149
- // Clear the line and show progress
150
- process.stdout.write(`\r[${bar}] ${progress}% - ${stepName}${' '.repeat(20)}`);
151
- };
118
+ generateAllBundles() {
119
+ return this.bundleManager.generateAllBundles();
120
+ }
152
121
 
153
- // Initialize progress bar
154
- updateProgress(steps[0]);
155
-
156
- return {
157
- next: (stepName, minTime = 800) => {
158
- return new Promise(async (resolve) => {
159
- const startTime = Date.now();
160
-
161
- // Move to next step
162
- currentStep++;
163
-
164
- if (currentStep < totalSteps) {
165
- updateProgress(steps[currentStep]);
166
- }
167
-
168
- // Add random delay between 200-800ms on top of minimum time
169
- const randomDelay = Math.floor(Math.random() * 600) + 200;
170
- const totalDelay = minTime + randomDelay;
171
-
172
- // Wait minimum time + random delay
173
- const elapsed = Date.now() - startTime;
174
- const remaining = Math.max(0, totalDelay - elapsed);
175
- if (remaining > 0) {
176
- await new Promise(resolve => setTimeout(resolve, remaining));
177
- }
178
-
179
- resolve();
180
- });
181
- },
182
- complete: () => {
183
- const progress = 100;
184
- const barLength = 30;
185
- const bar = '█'.repeat(barLength);
186
- process.stdout.write(`\r[${bar}] ${progress}% - Complete${' '.repeat(20)}\n`);
187
- }
188
- };
122
+ saveBundleStates() {
123
+ return this.configManager.saveBundleStates();
189
124
  }
190
125
 
191
- // Helper method to add initialization messages
192
- addInitMessage(message) {
193
- if (this.verbose) {
194
- this.initMessages.push(message);
195
- }
126
+ loadIgnorePatterns() {
127
+ this.configManager.loadIgnorePatterns();
128
+ this.fileSystemManager.setIgnorePatterns(this.configManager.getIgnorePatterns());
196
129
  }
197
130
 
198
131
  // === Initialization ===
@@ -202,55 +135,45 @@ export class CntxServer {
202
135
 
203
136
  const { skipFileWatcher = false, skipBundleGeneration = false } = options;
204
137
 
205
- const steps = skipFileWatcher
206
- ? ['Loading configuration', 'Loading semantic cache']
207
- : ['Loading configuration', 'Setting up file watcher', 'Loading semantic cache', 'Starting file watcher', 'Generating bundles'];
208
-
209
- const progress = await this.showInitProgress(steps);
210
-
211
- // Step 1: Loading configuration
138
+ // Step 1: Load configuration
212
139
  this.configManager.loadConfig();
213
140
  this.configManager.loadHiddenFilesConfig();
214
141
  this.configManager.loadIgnorePatterns();
215
142
  this.configManager.loadBundleStates();
216
- await progress.next(steps[0], 800);
143
+ console.log(' Configuration loaded');
217
144
 
218
145
  if (!skipFileWatcher) {
219
- // Step 2: Setting up file watcher
146
+ // Step 2: Set up file watcher
220
147
  this.fileSystemManager.setIgnorePatterns(this.configManager.getIgnorePatterns());
221
- await progress.next(steps[1], 400);
148
+ console.log(' File watcher configured');
222
149
  }
223
150
 
224
- // Step 3: Loading semantic cache
151
+ // Step 3: Load semantic cache
225
152
  const cacheData = this.configManager.loadSemanticCache();
226
153
  if (cacheData) {
227
154
  this.semanticCache = cacheData.analysis;
228
155
  this.lastSemanticAnalysis = cacheData.timestamp;
156
+ console.log(` Semantic cache loaded (${this.semanticCache.chunks.length} chunks)`);
157
+ } else {
158
+ console.log(' No semantic cache found (will analyze on first request)');
229
159
  }
230
- await progress.next(skipFileWatcher ? steps[1] : steps[2], 800);
231
160
 
232
161
  if (!skipFileWatcher) {
233
- // Step 4: Starting file watcher
162
+ // Step 4: Start file watcher
234
163
  this.startWatching();
235
- await progress.next(steps[3], 600);
164
+ console.log(' File watcher started');
236
165
 
237
166
  // Trigger initial semantic analysis in background if no cache
238
167
  if (!this.semanticCache) {
239
168
  this.getSemanticAnalysis().catch(err => console.error('Initial semantic analysis failed:', err.message));
240
169
  }
241
170
 
242
- // Step 5: Generating bundles
171
+ // Step 5: Generate bundles (awaited to prevent race conditions)
243
172
  if (!skipBundleGeneration) {
244
- this.bundleManager.generateAllBundles();
245
- await progress.next(steps[4], 1200);
173
+ await this.bundleManager.generateAllBundles();
174
+ console.log(' Bundles generated');
246
175
  }
247
176
  }
248
-
249
- // Complete progress bar
250
- progress.complete();
251
-
252
- // Generate Agent Manifest
253
- await this.agentRuntime.generateAgentManifest();
254
177
  }
255
178
 
256
179
  // Display initialization summary
@@ -281,7 +204,7 @@ export class CntxServer {
281
204
  // Display summary
282
205
  if (summary.length > 0) {
283
206
  console.log('Initialization complete:');
284
- summary.forEach(msg => console.log(` ${msg}`));
207
+ summary.forEach(msg => console.log(` - ${msg}`));
285
208
  console.log('');
286
209
  }
287
210
  }
@@ -291,13 +214,13 @@ export class CntxServer {
291
214
  startWatching() {
292
215
  this.fileSystemManager.startWatching(async (eventType, filename) => {
293
216
  if (this.verbose) {
294
- console.log(`📁 File ${eventType}: ${filename}`);
217
+ console.log(`File ${eventType}: ${filename}`);
295
218
  }
296
219
 
297
220
  // Skip processing files in .cntx directory to prevent infinite loops
298
221
  if (filename.startsWith('.cntx/')) {
299
222
  if (this.verbose) {
300
- console.log(`📁 Skipping .cntx file: ${filename}`);
223
+ console.log(`Skipping .cntx file: ${filename}`);
301
224
  }
302
225
  return;
303
226
  }
@@ -337,7 +260,7 @@ export class CntxServer {
337
260
  // Regenerate each affected bundle
338
261
  for (const bundleName of affectedBundles) {
339
262
  if (this.verbose) {
340
- console.log(`🔄 Auto-regenerating bundle: ${bundleName}`);
263
+ console.log(`Auto-regenerating bundle: ${bundleName}`);
341
264
  }
342
265
  await this.bundleManager.regenerateBundle(bundleName);
343
266
  }
@@ -417,16 +340,19 @@ export class CntxServer {
417
340
  // === Semantic Analysis (Legacy methods for compatibility) ===
418
341
 
419
342
  async getSemanticAnalysis() {
343
+ // Return cached result if available
344
+ if (this.semanticCache) {
345
+ return this.semanticCache;
346
+ }
347
+
420
348
  // 1. Try to load from SQLite first
421
349
  try {
422
350
  const dbChunks = this.databaseManager.db.prepare('SELECT * FROM semantic_chunks').all();
423
351
  if (dbChunks.length > 0) {
424
- if (!this.semanticCache) {
425
- this.semanticCache = {
426
- chunks: dbChunks.map(row => this.databaseManager.mapChunkRow(row)),
427
- summary: { totalChunks: dbChunks.length }
428
- };
429
- }
352
+ this.semanticCache = {
353
+ chunks: dbChunks.map(row => this.databaseManager.mapChunkRow(row)),
354
+ summary: { totalChunks: dbChunks.length }
355
+ };
430
356
  return this.semanticCache;
431
357
  }
432
358
  } catch (e) {
@@ -439,7 +365,7 @@ export class CntxServer {
439
365
  const files = this.fileSystemManager.getAllFiles()
440
366
  .filter(f => supportedExtensions.includes(extname(f).toLowerCase()))
441
367
  .map(f => relative(this.CWD, f));
442
-
368
+
443
369
  let bundleConfig = null;
444
370
  if (existsSync(this.configManager.CONFIG_FILE)) {
445
371
  bundleConfig = JSON.parse(readFileSync(this.configManager.CONFIG_FILE, 'utf8'));
@@ -454,7 +380,9 @@ export class CntxServer {
454
380
  }
455
381
 
456
382
  // 4. Trigger background embedding enhancement
457
- this.enhanceSemanticChunksIfNeeded(this.semanticCache);
383
+ this.enhanceSemanticChunksIfNeeded(this.semanticCache).catch(err => {
384
+ console.error('Background embedding enhancement failed:', err.message);
385
+ });
458
386
 
459
387
  return this.semanticCache;
460
388
  } catch (error) {
@@ -464,12 +392,12 @@ export class CntxServer {
464
392
  }
465
393
 
466
394
  async refreshSemanticAnalysis() {
467
- console.log('🔄 Refreshing semantic analysis and database...');
468
-
395
+ console.log('Refreshing semantic analysis and database...');
396
+
469
397
  // Clear the database table but keep other data
470
398
  this.databaseManager.db.prepare('DELETE FROM semantic_chunks').run();
471
399
  this.databaseManager.db.prepare('DELETE FROM vector_embeddings').run();
472
-
400
+
473
401
  this.semanticCache = null;
474
402
  this.lastSemanticAnalysis = null;
475
403
 
@@ -488,11 +416,11 @@ export class CntxServer {
488
416
  }
489
417
 
490
418
  if (chunksNeedingEmbeddings.length === 0) {
491
- console.log('All chunks already have persistent embeddings');
419
+ console.log('All chunks already have persistent embeddings');
492
420
  return;
493
421
  }
494
422
 
495
- console.log(`🔧 Enhancing ${chunksNeedingEmbeddings.length} chunks with persistent embeddings...`);
423
+ console.log(`Enhancing ${chunksNeedingEmbeddings.length} chunks with persistent embeddings...`);
496
424
 
497
425
  // Initialize vector store if needed
498
426
  if (!this.vectorStoreInitialized) {
@@ -508,7 +436,7 @@ export class CntxServer {
508
436
  console.error(`Failed to generate/persist embedding for chunk ${chunk.id}:`, error.message);
509
437
  }
510
438
  }
511
- console.log('Background embedding enhancement complete');
439
+ console.log('Background embedding enhancement complete');
512
440
  }
513
441
 
514
442
  invalidateSemanticCache() {
@@ -527,121 +455,6 @@ export class CntxServer {
527
455
  return this.bundleManager.generateFileXML(chunk.filePath);
528
456
  }
529
457
 
530
- invalidateSemanticCache() {
531
- this.semanticCache = null;
532
- this.lastSemanticAnalysis = null;
533
- }
534
-
535
- // === Activity Management (Placeholder) ===
536
-
537
- async loadActivities() {
538
- try {
539
- const activitiesPath = join(this.CWD, '.cntx', 'activities');
540
- const activitiesJsonPath = join(activitiesPath, 'activities.json');
541
-
542
- console.log('DEBUG: Looking for activities at:', activitiesJsonPath);
543
- console.log('DEBUG: File exists:', fs.existsSync(activitiesJsonPath));
544
- console.log('DEBUG: CWD is:', this.CWD);
545
-
546
- if (!fs.existsSync(activitiesJsonPath)) {
547
- console.log('Activities file not found, returning empty array');
548
- return [];
549
- }
550
-
551
- const activitiesData = JSON.parse(fs.readFileSync(activitiesJsonPath, 'utf8'));
552
-
553
- return activitiesData.map((activity, index) => {
554
- // Extract the actual directory name from the references field
555
- let activityId = activity.title.toLowerCase().replace(/[^a-z0-9]/g, '-');
556
- if (activity.references && activity.references.length > 0) {
557
- // Extract directory name from path like ".cntx/activities/activities/refactor-js-to-ts/README.md"
558
- const refPath = activity.references[0];
559
- const pathParts = refPath.split('/');
560
- if (pathParts.length >= 4) {
561
- activityId = pathParts[3]; // activities/activities/{this-part}/README.md
562
- }
563
- }
564
- const activityDir = join(activitiesPath, 'activities', activityId);
565
-
566
- // Load markdown files
567
- const files = {
568
- readme: this.loadMarkdownFile(join(activityDir, 'README.md')),
569
- progress: this.loadMarkdownFile(join(activityDir, 'progress.md')),
570
- tasks: this.loadMarkdownFile(join(activityDir, 'tasks.md')),
571
- notes: this.loadMarkdownFile(join(activityDir, 'notes.md'))
572
- };
573
-
574
- // Calculate progress from progress.md file
575
- const progress = this.parseProgressFromMarkdown(files.progress);
576
-
577
- return {
578
- id: activityId,
579
- name: activity.title,
580
- description: activity.description,
581
- status: activity.status === 'todo' ? 'pending' : activity.status,
582
- priority: activity.tags?.includes('high') ? 'high' : activity.tags?.includes('low') ? 'low' : 'medium',
583
- progress,
584
- updatedAt: new Date().toISOString(),
585
- category: activity.tags?.[0] || 'general',
586
- files,
587
- tags: activity.tags
588
- };
589
- });
590
- } catch (error) {
591
- console.error('Failed to load activities:', error);
592
- return [];
593
- }
594
- }
595
-
596
- loadMarkdownFile(filePath) {
597
- try {
598
- if (fs.existsSync(filePath)) {
599
- return fs.readFileSync(filePath, 'utf8');
600
- }
601
- return 'No content available';
602
- } catch (error) {
603
- return `Error loading file: ${error.message}`;
604
- }
605
- }
606
-
607
- parseProgressFromMarkdown(progressContent) {
608
- try {
609
- if (!progressContent || progressContent === 'No content available') {
610
- return 0;
611
- }
612
-
613
- // Look for "Overall Completion: XX%" pattern
614
- const overallMatch = progressContent.match(/(?:Overall Completion|Progress):\s*(\d+)%/i);
615
- if (overallMatch) {
616
- return parseInt(overallMatch[1], 10);
617
- }
618
-
619
- // Fallback: count completed tasks vs total tasks in checkbox format
620
- const taskMatches = progressContent.match(/- \[([x✓✅\s])\]/gi);
621
- if (taskMatches && taskMatches.length > 0) {
622
- const completedTasks = taskMatches.filter(match =>
623
- match.includes('[x]') || match.includes('[✓]') || match.includes('[✅]')
624
- ).length;
625
- return Math.round((completedTasks / taskMatches.length) * 100);
626
- }
627
-
628
- return 0;
629
- } catch (error) {
630
- console.error('Error parsing progress:', error);
631
- return 0;
632
- }
633
- }
634
-
635
- async executeActivity(activityId) {
636
- // Placeholder - would execute specific activity
637
- return { success: false, message: 'Activity execution not implemented' };
638
- }
639
-
640
- async stopActivity(activityId) {
641
- // Placeholder - would stop running activity
642
- return { success: false, message: 'Activity stopping not implemented' };
643
- }
644
-
645
458
  // === MCP Server Integration ===
646
459
 
647
460
  startMCPServer() {
@@ -650,7 +463,7 @@ export class CntxServer {
650
463
  this.mcpServerStarted = true;
651
464
 
652
465
  if (this.verbose) {
653
- console.log('🔗 MCP server started');
466
+ console.log('MCP server started');
654
467
  }
655
468
  }
656
469
  }
@@ -668,8 +481,8 @@ export class CntxServer {
668
481
  // Start server and show progress
669
482
  server.listen(port, host, () => {
670
483
  console.log('');
671
- console.log(`🌐 Server running at http://${host}:${port}`);
672
- console.log(`📊 Serving ${this.bundleManager.getAllBundleInfo().length} bundles from your project`);
484
+ console.log(`Server running at http://${host}:${port}`);
485
+ console.log(`Serving ${this.bundleManager.getAllBundleInfo().length} bundles from your project`);
673
486
  console.log('');
674
487
 
675
488
  // Display initialization summary
@@ -678,11 +491,11 @@ export class CntxServer {
678
491
 
679
492
  // Handle graceful shutdown
680
493
  process.on('SIGINT', () => {
681
- console.log('\n🛑 Shutting down server...');
494
+ console.log('\nShutting down server...');
682
495
  this.webSocketManager.close();
683
496
  this.fileSystemManager.destroy();
684
497
  server.close(() => {
685
- console.log('Server stopped');
498
+ console.log('Server stopped');
686
499
  process.exit(0);
687
500
  });
688
501
  });
@@ -691,11 +504,25 @@ export class CntxServer {
691
504
  }
692
505
  }
693
506
 
507
+ // Auto-init and start: checks for .cntx/, runs initConfig() if missing, then starts server
508
+ export async function autoInitAndStart(options = {}) {
509
+ const cwd = options.cwd || process.cwd();
510
+ const cntxDir = join(cwd, '.cntx');
511
+
512
+ if (!existsSync(cntxDir)) {
513
+ console.log('No .cntx directory found, initializing...');
514
+ console.log('');
515
+ await initConfig(cwd);
516
+ console.log('');
517
+ }
518
+
519
+ return startServer(options);
520
+ }
521
+
694
522
  // Export function for CLI compatibility
695
523
  export async function startServer(options = {}) {
696
524
  const server = new CntxServer(options.cwd, { verbose: options.verbose });
697
525
 
698
- // Show ASCII art first
699
526
  const asciiArt = `
700
527
  ██████ ███ ██ ████████ ██ ██ ██ ██ ██
701
528
  ██ ████ ██ ██ ██ ██ ██ ██ ██
@@ -704,12 +531,13 @@ export async function startServer(options = {}) {
704
531
  ██████ ██ ████ ██ ██ ██ ██████ ██
705
532
  `;
706
533
  console.log(asciiArt);
707
- console.log(''); // Add blank line after art
708
534
 
709
- // Now start initialization with progress bar
535
+ // Now start initialization
710
536
  await server.init();
711
537
 
712
- if (options.withMcp) {
538
+ // Enable MCP status tracking by default
539
+ const withMcp = options.withMcp !== false;
540
+ if (withMcp) {
713
541
  server.startMCPServer();
714
542
  }
715
543
 
@@ -723,7 +551,7 @@ export async function startMCPServer(options = {}) {
723
551
  server.startMCPServer();
724
552
 
725
553
  // For MCP mode, we don't start the web server, just keep the process alive
726
- console.log('🔗 MCP server running on stdio...');
554
+ console.log('MCP server running on stdio...');
727
555
  }
728
556
 
729
557
  export async function generateBundle(bundleName = 'master') {
@@ -743,11 +571,11 @@ export async function generateBundle(bundleName = 'master') {
743
571
  // Initialize project configuration
744
572
  export async function initConfig(cwd = process.cwd()) {
745
573
  const server = new CntxServer(cwd);
746
-
574
+
747
575
  // 1. Initialize directory structure
748
576
  if (!existsSync(server.CNTX_DIR)) {
749
577
  mkdirSync(server.CNTX_DIR, { recursive: true });
750
- console.log('📁 Created .cntx directory');
578
+ console.log('Created .cntx directory');
751
579
  }
752
580
 
753
581
  // 2. Create .mcp.json for Claude Code discovery
@@ -762,11 +590,11 @@ export async function initConfig(cwd = process.cwd()) {
762
590
  }
763
591
  };
764
592
  writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), 'utf8');
765
- console.log('📄 Created .mcp.json for agent auto-discovery');
593
+ console.log('Created .mcp.json for MCP auto-discovery');
766
594
 
767
595
  // 3. Initialize basic configuration with better defaults and auto-suggestions
768
596
  server.configManager.loadConfig();
769
-
597
+
770
598
  const suggestedBundles = {
771
599
  master: ['**/*']
772
600
  };
@@ -784,7 +612,7 @@ export async function initConfig(cwd = process.cwd()) {
784
612
  commonDirs.forEach(d => {
785
613
  if (existsSync(join(cwd, d.dir))) {
786
614
  suggestedBundles[d.name] = [`${d.dir}/**`];
787
- console.log(`💡 Suggested bundle: ${d.name} (${d.dir}/**)`);
615
+ console.log(` Suggested bundle: ${d.name} (${d.dir}/**)`);
788
616
  }
789
617
  });
790
618
 
@@ -820,89 +648,10 @@ export async function initConfig(cwd = process.cwd()) {
820
648
  .mcp.json
821
649
  `;
822
650
  writeFileSync(ignorePath, defaultIgnore, 'utf8');
823
- console.log('📄 Created .cntxignore with smart defaults');
824
- }
825
-
826
- console.log('⚙️ Basic configuration initialized');
827
-
828
- // ... (rest of the file remains same)
829
- const templateDir = join(__dirname, 'templates');
830
-
831
- // Copy agent configuration files
832
- const agentFiles = [
833
- 'agent-config.yaml',
834
- 'agent-instructions.md'
835
- ];
836
-
837
- for (const file of agentFiles) {
838
- const sourcePath = join(templateDir, file);
839
- const destPath = join(server.CNTX_DIR, file);
840
-
841
- if (existsSync(sourcePath) && !existsSync(destPath)) {
842
- copyFileSync(sourcePath, destPath);
843
- console.log(`📄 Created ${file}`);
844
- }
845
- }
846
-
847
- // Copy agent-rules directory structure
848
- const agentRulesSource = join(templateDir, 'agent-rules');
849
- const agentRulesDest = join(server.CNTX_DIR, 'agent-rules');
850
-
851
- if (existsSync(agentRulesSource) && !existsSync(agentRulesDest)) {
852
- cpSync(agentRulesSource, agentRulesDest, { recursive: true });
853
- console.log('📁 Created agent-rules directory with templates');
854
- }
855
-
856
- // Copy activities framework
857
- const activitiesDir = join(server.CNTX_DIR, 'activities');
858
- if (!existsSync(activitiesDir)) {
859
- mkdirSync(activitiesDir, { recursive: true });
651
+ console.log('Created .cntxignore with smart defaults');
860
652
  }
861
653
 
862
- // Copy activities README
863
- const activitiesReadmeSource = join(templateDir, 'activities', 'README.md');
864
- const activitiesReadmeDest = join(activitiesDir, 'README.md');
865
-
866
- if (existsSync(activitiesReadmeSource) && !existsSync(activitiesReadmeDest)) {
867
- copyFileSync(activitiesReadmeSource, activitiesReadmeDest);
868
- console.log('📄 Created activities/README.md');
869
- }
870
-
871
- // Copy activities lib directory (MDC templates)
872
- const activitiesLibSource = join(templateDir, 'activities', 'lib');
873
- const activitiesLibDest = join(activitiesDir, 'lib');
874
-
875
- if (existsSync(activitiesLibSource) && !existsSync(activitiesLibDest)) {
876
- cpSync(activitiesLibSource, activitiesLibDest, { recursive: true });
877
- console.log('📁 Created activities/lib with MDC templates');
878
- }
879
-
880
- // Copy activities.json from templates
881
- const activitiesJsonPath = join(activitiesDir, 'activities.json');
882
- const templateActivitiesJsonPath = join(templateDir, 'activities', 'activities.json');
883
- if (!existsSync(activitiesJsonPath) && existsSync(templateActivitiesJsonPath)) {
884
- copyFileSync(templateActivitiesJsonPath, activitiesJsonPath);
885
- console.log('📄 Created activities.json with bundle example activity');
886
- }
887
-
888
- // Copy example activity from templates
889
- const activitiesDestDir = join(activitiesDir, 'activities');
890
- const templateActivitiesDir = join(templateDir, 'activities', 'activities');
891
- if (!existsSync(activitiesDestDir) && existsSync(templateActivitiesDir)) {
892
- cpSync(templateActivitiesDir, activitiesDestDir, { recursive: true });
893
- console.log('📁 Created example activity with templates');
894
- }
895
-
896
- console.log('');
897
- console.log('🎉 cntx-ui initialized with full scaffolding!');
898
- console.log('');
899
- console.log('Next steps:');
900
- console.log(' 1️⃣ Start the server: cntx-ui watch');
901
- console.log(' 2️⃣ Open web UI: http://localhost:3333');
902
- console.log(' 3️⃣ Read .cntx/agent-instructions.md for AI integration');
903
- console.log(' 4️⃣ Explore .cntx/activities/README.md for project management');
904
- console.log('');
905
- console.log('💡 Pro tip: Use "cntx-ui status" to see your project overview');
654
+ console.log('Configuration initialized');
906
655
  }
907
656
 
908
657
  export async function getStatus() {
@@ -912,13 +661,13 @@ export async function getStatus() {
912
661
  const bundles = server.bundleManager.getAllBundleInfo();
913
662
  const totalFiles = server.fileSystemManager.getAllFiles().length;
914
663
 
915
- console.log('📊 cntx-ui Status');
664
+ console.log('cntx-ui Status');
916
665
  console.log('================');
917
666
  console.log(`Total files: ${totalFiles}`);
918
667
  console.log(`Bundles: ${bundles.length}`);
919
668
 
920
669
  bundles.forEach(bundle => {
921
- console.log(` ${bundle.name}: ${bundle.fileCount} files (${Math.round(bundle.size / 1024)}KB)`);
670
+ console.log(` - ${bundle.name}: ${bundle.fileCount} files (${Math.round(bundle.size / 1024)}KB)`);
922
671
  });
923
672
 
924
673
  return {
@@ -928,46 +677,10 @@ export async function getStatus() {
928
677
  };
929
678
  }
930
679
 
931
- export function setupMCP() {
932
- const configPath = join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
933
- const projectPath = process.cwd();
934
-
935
- console.log('🔧 Setting up MCP integration...');
936
- console.log(`Project: ${projectPath}`);
937
- console.log(`Claude config: ${configPath}`);
938
-
939
- try {
940
- let config = {};
941
- if (existsSync(configPath)) {
942
- config = JSON.parse(readFileSync(configPath, 'utf8'));
943
- }
944
-
945
- if (!config.mcpServers) {
946
- config.mcpServers = {};
947
- }
948
-
949
- config.mcpServers['cntx-ui'] = {
950
- command: 'node',
951
- args: [join(projectPath, 'bin', 'cntx-ui.js'), 'mcp'],
952
- env: {}
953
- };
954
-
955
- // Ensure directory exists
956
- mkdirSync(dirname(configPath), { recursive: true });
957
- writeFileSync(configPath, JSON.stringify(config, null, 2));
958
-
959
- console.log('✅ MCP integration configured');
960
- console.log('💡 Restart Claude Desktop to apply changes');
961
- } catch (error) {
962
- console.error('❌ Failed to setup MCP:', error.message);
963
- console.log('💡 You may need to manually add the configuration to Claude Desktop');
964
- }
965
- }
966
-
967
680
  // Auto-start server when run directly
968
681
  const isMainModule = import.meta.url === `file://${process.argv[1]}`;
969
682
  if (isMainModule) {
970
- console.log('🚀 Starting cntx-ui server...');
683
+ console.log('Starting cntx-ui server...');
971
684
  const server = new CntxServer();
972
685
  server.init();
973
686
  server.listen(3333, 'localhost');