cntx-ui 2.0.8 → 2.0.10
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/README.md +67 -8
- package/bin/cntx-ui.js +11 -2
- package/lib/mcp-server.js +4 -0
- package/package.json +16 -6
- package/server.js +209 -84
- package/web/dist/assets/index-AIbnyG7t.js +531 -0
- package/web/dist/index.html +1 -1
- package/web/dist/assets/index-Ctn4CHCP.js +0 -531
package/server.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, watch, readdirSync, statSync } from 'fs';
|
|
2
|
-
import { join, dirname, relative, extname } from 'path';
|
|
2
|
+
import { join, dirname, relative, extname, basename } from 'path';
|
|
3
3
|
import { createServer } from 'http';
|
|
4
4
|
import { WebSocketServer } from 'ws';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { startMCPTransport } from './lib/mcp-transport.js';
|
|
8
|
+
import { homedir } from 'os';
|
|
8
9
|
|
|
9
10
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
|
|
@@ -25,9 +26,10 @@ function getContentType(filePath) {
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export class CntxServer {
|
|
28
|
-
constructor(cwd = process.cwd()) {
|
|
29
|
+
constructor(cwd = process.cwd(), options = {}) {
|
|
29
30
|
this.CWD = cwd;
|
|
30
31
|
this.CNTX_DIR = join(cwd, '.cntx');
|
|
32
|
+
this.isQuietMode = options.quiet || false;
|
|
31
33
|
this.CONFIG_FILE = join(this.CNTX_DIR, 'config.json');
|
|
32
34
|
this.BUNDLES_FILE = join(this.CNTX_DIR, 'bundles.json');
|
|
33
35
|
this.HIDDEN_FILES_CONFIG = join(this.CNTX_DIR, 'hidden-files.json');
|
|
@@ -40,6 +42,8 @@ export class CntxServer {
|
|
|
40
42
|
this.watchers = [];
|
|
41
43
|
this.clients = new Set();
|
|
42
44
|
this.isScanning = false;
|
|
45
|
+
this.mcpServer = null;
|
|
46
|
+
this.mcpServerStarted = false;
|
|
43
47
|
|
|
44
48
|
this.hiddenFilesConfig = {
|
|
45
49
|
globalHidden: [], // Files hidden across all bundles
|
|
@@ -95,7 +99,7 @@ export class CntxServer {
|
|
|
95
99
|
const config = JSON.parse(readFileSync(this.HIDDEN_FILES_CONFIG, 'utf8'));
|
|
96
100
|
this.hiddenFilesConfig = { ...this.hiddenFilesConfig, ...config };
|
|
97
101
|
} catch (e) {
|
|
98
|
-
console.warn('Could not load hidden files config:', e.message);
|
|
102
|
+
if (!this.isQuietMode) console.warn('Could not load hidden files config:', e.message);
|
|
99
103
|
}
|
|
100
104
|
}
|
|
101
105
|
}
|
|
@@ -104,7 +108,7 @@ export class CntxServer {
|
|
|
104
108
|
try {
|
|
105
109
|
writeFileSync(this.HIDDEN_FILES_CONFIG, JSON.stringify(this.hiddenFilesConfig, null, 2));
|
|
106
110
|
} catch (e) {
|
|
107
|
-
console.error('Failed to save hidden files config:', e.message);
|
|
111
|
+
if (!this.isQuietMode) console.error('Failed to save hidden files config:', e.message);
|
|
108
112
|
}
|
|
109
113
|
}
|
|
110
114
|
|
|
@@ -340,7 +344,7 @@ export class CntxServer {
|
|
|
340
344
|
}
|
|
341
345
|
});
|
|
342
346
|
} catch (e) {
|
|
343
|
-
console.warn('Could not load bundle states:', e.message);
|
|
347
|
+
if (!this.isQuietMode) console.warn('Could not load bundle states:', e.message);
|
|
344
348
|
}
|
|
345
349
|
}
|
|
346
350
|
}
|
|
@@ -672,7 +676,7 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
672
676
|
const regex = new RegExp('^' + regexPattern + '$');
|
|
673
677
|
return regex.test(path);
|
|
674
678
|
} catch (e) {
|
|
675
|
-
console.log(`Regex error for pattern "${pattern}": ${e.message}`);
|
|
679
|
+
if (!this.isQuietMode) console.log(`Regex error for pattern "${pattern}": ${e.message}`);
|
|
676
680
|
return false;
|
|
677
681
|
}
|
|
678
682
|
}
|
|
@@ -796,7 +800,7 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
796
800
|
if (filename && !this.isScanning) {
|
|
797
801
|
const fullPath = join(this.CWD, filename);
|
|
798
802
|
if (!this.shouldIgnoreFile(fullPath)) {
|
|
799
|
-
console.log(`File ${eventType}: ${filename}`);
|
|
803
|
+
if (!this.isQuietMode) console.log(`File ${eventType}: ${filename}`);
|
|
800
804
|
this.markBundlesChanged(filename.replace(/\\\\/g, '/'));
|
|
801
805
|
this.broadcastUpdate();
|
|
802
806
|
}
|
|
@@ -837,7 +841,7 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
837
841
|
|
|
838
842
|
generateAllBundles() {
|
|
839
843
|
this.isScanning = true;
|
|
840
|
-
console.log('Scanning files and generating bundles...');
|
|
844
|
+
if (!this.isQuietMode) console.log('Scanning files and generating bundles...');
|
|
841
845
|
|
|
842
846
|
this.bundles.forEach((bundle, name) => {
|
|
843
847
|
this.generateBundle(name);
|
|
@@ -845,14 +849,14 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
845
849
|
|
|
846
850
|
this.saveBundleStates();
|
|
847
851
|
this.isScanning = false;
|
|
848
|
-
console.log('Bundle generation complete');
|
|
852
|
+
if (!this.isQuietMode) console.log('Bundle generation complete');
|
|
849
853
|
}
|
|
850
854
|
|
|
851
855
|
generateBundle(name) {
|
|
852
856
|
const bundle = this.bundles.get(name);
|
|
853
857
|
if (!bundle) return;
|
|
854
858
|
|
|
855
|
-
console.log(`Generating bundle: ${name}`);
|
|
859
|
+
if (!this.isQuietMode) console.log(`Generating bundle: ${name}`);
|
|
856
860
|
const allFiles = this.getAllFiles();
|
|
857
861
|
|
|
858
862
|
// Filter files by bundle patterns
|
|
@@ -869,7 +873,7 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
869
873
|
bundle.lastGenerated = new Date().toISOString();
|
|
870
874
|
bundle.size = Buffer.byteLength(bundle.content, 'utf8');
|
|
871
875
|
|
|
872
|
-
console.log(`Generated bundle '${name}' with ${bundle.files.length} files (${(bundle.size / 1024).toFixed(1)}kb)`);
|
|
876
|
+
if (!this.isQuietMode) console.log(`Generated bundle '${name}' with ${bundle.files.length} files (${(bundle.size / 1024).toFixed(1)}kb)`);
|
|
873
877
|
}
|
|
874
878
|
|
|
875
879
|
generateBundleXML(bundleName, files) {
|
|
@@ -1200,7 +1204,7 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
1200
1204
|
res.end(content);
|
|
1201
1205
|
return;
|
|
1202
1206
|
} catch (e) {
|
|
1203
|
-
console.error('Error serving index.html:', e);
|
|
1207
|
+
if (!this.isQuietMode) console.error('Error serving index.html:', e);
|
|
1204
1208
|
}
|
|
1205
1209
|
}
|
|
1206
1210
|
|
|
@@ -1233,6 +1237,9 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
1233
1237
|
<div class="api-link">
|
|
1234
1238
|
<strong>Files:</strong> <a href="/api/files">/api/files</a>
|
|
1235
1239
|
</div>
|
|
1240
|
+
<div class="api-link">
|
|
1241
|
+
<strong>Status:</strong> <a href="/api/status">/api/status</a>
|
|
1242
|
+
</div>
|
|
1236
1243
|
|
|
1237
1244
|
<h2>Web Interface:</h2>
|
|
1238
1245
|
<p>The web interface is not available because it wasn't built when this package was published.</p>
|
|
@@ -1262,7 +1269,7 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
1262
1269
|
res.end(content);
|
|
1263
1270
|
return;
|
|
1264
1271
|
} catch (e) {
|
|
1265
|
-
console.error('Error serving static file:', e);
|
|
1272
|
+
if (!this.isQuietMode) console.error('Error serving static file:', e);
|
|
1266
1273
|
}
|
|
1267
1274
|
}
|
|
1268
1275
|
}
|
|
@@ -1334,20 +1341,20 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
1334
1341
|
req.on('data', chunk => body += chunk);
|
|
1335
1342
|
req.on('end', () => {
|
|
1336
1343
|
try {
|
|
1337
|
-
console.log('🔍 Received config save request');
|
|
1344
|
+
if (!this.isQuietMode) console.log('🔍 Received config save request');
|
|
1338
1345
|
const config = JSON.parse(body);
|
|
1339
|
-
console.log('📝 Config to save:', JSON.stringify(config, null, 2));
|
|
1346
|
+
if (!this.isQuietMode) console.log('📝 Config to save:', JSON.stringify(config, null, 2));
|
|
1340
1347
|
|
|
1341
1348
|
// Ensure .cntx directory exists
|
|
1342
1349
|
if (!existsSync(this.CNTX_DIR)) {
|
|
1343
|
-
console.log('📁 Creating .cntx directory...');
|
|
1350
|
+
if (!this.isQuietMode) console.log('📁 Creating .cntx directory...');
|
|
1344
1351
|
mkdirSync(this.CNTX_DIR, { recursive: true });
|
|
1345
1352
|
}
|
|
1346
1353
|
|
|
1347
1354
|
// Write config file
|
|
1348
|
-
console.log('💾 Writing config to:', this.CONFIG_FILE);
|
|
1355
|
+
if (!this.isQuietMode) console.log('💾 Writing config to:', this.CONFIG_FILE);
|
|
1349
1356
|
writeFileSync(this.CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
1350
|
-
console.log('✅ Config file written successfully');
|
|
1357
|
+
if (!this.isQuietMode) console.log('✅ Config file written successfully');
|
|
1351
1358
|
|
|
1352
1359
|
// Reload configuration
|
|
1353
1360
|
this.loadConfig();
|
|
@@ -1356,17 +1363,17 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
1356
1363
|
|
|
1357
1364
|
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
1358
1365
|
res.end('OK');
|
|
1359
|
-
console.log('✅ Config save response sent');
|
|
1366
|
+
if (!this.isQuietMode) console.log('✅ Config save response sent');
|
|
1360
1367
|
|
|
1361
1368
|
} catch (e) {
|
|
1362
|
-
console.error('❌ Config save error:', e);
|
|
1369
|
+
if (!this.isQuietMode) console.error('❌ Config save error:', e);
|
|
1363
1370
|
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
1364
1371
|
res.end(`Error: ${e.message}`);
|
|
1365
1372
|
}
|
|
1366
1373
|
});
|
|
1367
1374
|
|
|
1368
1375
|
req.on('error', (err) => {
|
|
1369
|
-
console.error('❌ Request error:', err);
|
|
1376
|
+
if (!this.isQuietMode) console.error('❌ Request error:', err);
|
|
1370
1377
|
if (!res.headersSent) {
|
|
1371
1378
|
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
1372
1379
|
res.end('Internal Server Error');
|
|
@@ -1630,6 +1637,34 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
1630
1637
|
});
|
|
1631
1638
|
}
|
|
1632
1639
|
|
|
1640
|
+
} else if (url.pathname === '/api/status') {
|
|
1641
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
1642
|
+
const statusInfo = {
|
|
1643
|
+
server: {
|
|
1644
|
+
version: '2.0.8',
|
|
1645
|
+
workingDirectory: this.CWD,
|
|
1646
|
+
startTime: new Date().toISOString(),
|
|
1647
|
+
isScanning: this.isScanning
|
|
1648
|
+
},
|
|
1649
|
+
bundles: {
|
|
1650
|
+
count: this.bundles.size,
|
|
1651
|
+
names: Array.from(this.bundles.keys()),
|
|
1652
|
+
totalFiles: Array.from(this.bundles.values()).reduce((sum, bundle) => sum + bundle.files.length, 0)
|
|
1653
|
+
},
|
|
1654
|
+
mcp: {
|
|
1655
|
+
available: true,
|
|
1656
|
+
serverStarted: this.mcpServerStarted,
|
|
1657
|
+
command: 'npx cntx-ui mcp',
|
|
1658
|
+
setupScript: './examples/claude-mcp-setup.sh'
|
|
1659
|
+
},
|
|
1660
|
+
files: {
|
|
1661
|
+
total: this.getAllFiles().length,
|
|
1662
|
+
hiddenGlobally: this.hiddenFilesConfig.globalHidden.length,
|
|
1663
|
+
ignorePatterns: this.ignorePatterns.length
|
|
1664
|
+
}
|
|
1665
|
+
};
|
|
1666
|
+
res.end(JSON.stringify(statusInfo, null, 2));
|
|
1667
|
+
|
|
1633
1668
|
} else {
|
|
1634
1669
|
res.writeHead(404);
|
|
1635
1670
|
res.end('Not found');
|
|
@@ -1644,9 +1679,11 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
1644
1679
|
});
|
|
1645
1680
|
|
|
1646
1681
|
server.listen(port, () => {
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1682
|
+
if (!this.isQuietMode) {
|
|
1683
|
+
console.log(`🚀 cntx-ui API running at http://localhost:${port}`);
|
|
1684
|
+
console.log(`📁 Watching: ${this.CWD}`);
|
|
1685
|
+
console.log(`📦 Bundles: ${Array.from(this.bundles.keys()).join(', ')}`);
|
|
1686
|
+
}
|
|
1650
1687
|
});
|
|
1651
1688
|
|
|
1652
1689
|
return server;
|
|
@@ -1678,32 +1715,45 @@ This project uses cntx-ui for bundle management and AI context organization.
|
|
|
1678
1715
|
}
|
|
1679
1716
|
|
|
1680
1717
|
export function startServer(options = {}) {
|
|
1681
|
-
const server = new CntxServer(options.cwd);
|
|
1718
|
+
const server = new CntxServer(options.cwd, { quiet: options.quiet });
|
|
1682
1719
|
server.init();
|
|
1720
|
+
|
|
1721
|
+
if (options.withMcp) {
|
|
1722
|
+
server.mcpServerStarted = true;
|
|
1723
|
+
if (!server.isQuietMode) {
|
|
1724
|
+
console.log('🔗 MCP server tracking enabled - use /api/status to check MCP configuration');
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1683
1728
|
return server.startServer(options.port);
|
|
1684
1729
|
}
|
|
1685
1730
|
|
|
1686
1731
|
export function startMCPServer(options = {}) {
|
|
1687
|
-
const server = new CntxServer(options.cwd);
|
|
1732
|
+
const server = new CntxServer(options.cwd, { quiet: true });
|
|
1688
1733
|
server.init();
|
|
1689
1734
|
startMCPTransport(server);
|
|
1690
1735
|
return server;
|
|
1691
1736
|
}
|
|
1692
1737
|
|
|
1693
|
-
export function generateBundle(name = 'master', cwd = process.cwd()) {
|
|
1694
|
-
const server = new CntxServer(cwd);
|
|
1738
|
+
export function generateBundle(name = 'master', cwd = process.cwd(), options = {}) {
|
|
1739
|
+
const server = new CntxServer(cwd, { quiet: options.quiet });
|
|
1695
1740
|
server.init();
|
|
1696
1741
|
server.generateBundle(name);
|
|
1697
1742
|
server.saveBundleStates();
|
|
1698
1743
|
}
|
|
1699
1744
|
|
|
1700
|
-
export function initConfig(cwd = process.cwd()) {
|
|
1701
|
-
|
|
1702
|
-
|
|
1745
|
+
export function initConfig(cwd = process.cwd(), options = {}) {
|
|
1746
|
+
const isQuiet = options.quiet || false;
|
|
1747
|
+
if (!isQuiet) {
|
|
1748
|
+
console.log('🚀 Starting initConfig...');
|
|
1749
|
+
console.log('📂 Working directory:', cwd);
|
|
1750
|
+
}
|
|
1703
1751
|
|
|
1704
|
-
const server = new CntxServer(cwd);
|
|
1705
|
-
|
|
1706
|
-
|
|
1752
|
+
const server = new CntxServer(cwd, { quiet: isQuiet });
|
|
1753
|
+
if (!isQuiet) {
|
|
1754
|
+
console.log('📁 CNTX_DIR:', server.CNTX_DIR);
|
|
1755
|
+
console.log('📄 CONFIG_FILE path:', server.CONFIG_FILE);
|
|
1756
|
+
}
|
|
1707
1757
|
|
|
1708
1758
|
const defaultConfig = {
|
|
1709
1759
|
bundles: {
|
|
@@ -1713,86 +1763,161 @@ export function initConfig(cwd = process.cwd()) {
|
|
|
1713
1763
|
|
|
1714
1764
|
try {
|
|
1715
1765
|
// Create .cntx directory
|
|
1716
|
-
console.log('🔍 Checking if .cntx directory exists...');
|
|
1766
|
+
if (!isQuiet) console.log('🔍 Checking if .cntx directory exists...');
|
|
1717
1767
|
if (!existsSync(server.CNTX_DIR)) {
|
|
1718
|
-
console.log('📁 Creating .cntx directory...');
|
|
1768
|
+
if (!isQuiet) console.log('📁 Creating .cntx directory...');
|
|
1719
1769
|
mkdirSync(server.CNTX_DIR, { recursive: true });
|
|
1720
|
-
console.log('✅ .cntx directory created');
|
|
1770
|
+
if (!isQuiet) console.log('✅ .cntx directory created');
|
|
1721
1771
|
} else {
|
|
1722
|
-
console.log('✅ .cntx directory already exists');
|
|
1772
|
+
if (!isQuiet) console.log('✅ .cntx directory already exists');
|
|
1723
1773
|
}
|
|
1724
1774
|
|
|
1725
1775
|
// List directory contents before writing config
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1776
|
+
if (!isQuiet) {
|
|
1777
|
+
console.log('📋 Directory contents before writing config:');
|
|
1778
|
+
const beforeFiles = readdirSync(server.CNTX_DIR);
|
|
1779
|
+
console.log('Files:', beforeFiles);
|
|
1780
|
+
}
|
|
1729
1781
|
|
|
1730
1782
|
// Write config.json
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1783
|
+
if (!isQuiet) {
|
|
1784
|
+
console.log('📝 Writing config.json...');
|
|
1785
|
+
console.log('📄 Config content:', JSON.stringify(defaultConfig, null, 2));
|
|
1786
|
+
console.log('📍 Writing to path:', server.CONFIG_FILE);
|
|
1787
|
+
}
|
|
1734
1788
|
|
|
1735
1789
|
writeFileSync(server.CONFIG_FILE, JSON.stringify(defaultConfig, null, 2));
|
|
1736
|
-
console.log('✅ writeFileSync completed');
|
|
1790
|
+
if (!isQuiet) console.log('✅ writeFileSync completed');
|
|
1737
1791
|
|
|
1738
1792
|
// Verify file was created
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1793
|
+
if (!isQuiet) {
|
|
1794
|
+
console.log('🔍 Checking if config.json exists...');
|
|
1795
|
+
const configExists = existsSync(server.CONFIG_FILE);
|
|
1796
|
+
console.log('Config exists?', configExists);
|
|
1797
|
+
|
|
1798
|
+
if (configExists) {
|
|
1799
|
+
const configContent = readFileSync(server.CONFIG_FILE, 'utf8');
|
|
1800
|
+
console.log('✅ Config file created successfully');
|
|
1801
|
+
console.log('📖 Config content:', configContent);
|
|
1802
|
+
} else {
|
|
1803
|
+
console.log('❌ Config file was NOT created');
|
|
1804
|
+
}
|
|
1750
1805
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1806
|
+
// List directory contents after writing config
|
|
1807
|
+
console.log('📋 Directory contents after writing config:');
|
|
1808
|
+
const afterFiles = readdirSync(server.CNTX_DIR);
|
|
1809
|
+
console.log('Files:', afterFiles);
|
|
1810
|
+
}
|
|
1755
1811
|
|
|
1756
1812
|
} catch (error) {
|
|
1757
|
-
|
|
1758
|
-
|
|
1813
|
+
if (!isQuiet) {
|
|
1814
|
+
console.error('❌ Error in initConfig:', error);
|
|
1815
|
+
console.error('Stack trace:', error.stack);
|
|
1816
|
+
}
|
|
1759
1817
|
throw error;
|
|
1760
1818
|
}
|
|
1761
1819
|
|
|
1762
1820
|
// Create cursor rules if they don't exist
|
|
1763
1821
|
try {
|
|
1764
1822
|
if (!existsSync(server.CURSOR_RULES_FILE)) {
|
|
1765
|
-
console.log('📋 Creating cursor rules...');
|
|
1823
|
+
if (!isQuiet) console.log('📋 Creating cursor rules...');
|
|
1766
1824
|
const cursorRules = server.getDefaultCursorRules();
|
|
1767
1825
|
server.saveCursorRules(cursorRules);
|
|
1768
|
-
console.log(`📋 Created ${relative(cwd, server.CURSOR_RULES_FILE)} with project-specific rules`);
|
|
1826
|
+
if (!isQuiet) console.log(`📋 Created ${relative(cwd, server.CURSOR_RULES_FILE)} with project-specific rules`);
|
|
1769
1827
|
}
|
|
1770
1828
|
} catch (error) {
|
|
1771
|
-
console.error('❌ Error creating cursor rules:', error);
|
|
1829
|
+
if (!isQuiet) console.error('❌ Error creating cursor rules:', error);
|
|
1772
1830
|
}
|
|
1773
1831
|
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1832
|
+
if (!isQuiet) {
|
|
1833
|
+
console.log('✅ cntx-ui initialized successfully!');
|
|
1834
|
+
console.log('');
|
|
1835
|
+
console.log('🚀 Next step: Start the web interface');
|
|
1836
|
+
console.log(' Run: cntx-ui watch');
|
|
1837
|
+
console.log('');
|
|
1838
|
+
console.log('📱 Then visit: http://localhost:3333');
|
|
1839
|
+
console.log(' Follow the setup guide to create your first bundles');
|
|
1840
|
+
console.log('');
|
|
1841
|
+
console.log('💡 The web interface handles everything - no manual file editing needed!');
|
|
1842
|
+
}
|
|
1783
1843
|
}
|
|
1784
1844
|
|
|
1785
|
-
export function getStatus(cwd = process.cwd()) {
|
|
1786
|
-
const server = new CntxServer(cwd);
|
|
1845
|
+
export function getStatus(cwd = process.cwd(), options = {}) {
|
|
1846
|
+
const server = new CntxServer(cwd, { quiet: options.quiet });
|
|
1787
1847
|
server.init();
|
|
1788
1848
|
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
});
|
|
1849
|
+
if (!options.quiet) {
|
|
1850
|
+
console.log(`📁 Working directory: ${server.CWD}`);
|
|
1851
|
+
console.log(`📦 Bundles configured: ${server.bundles.size}`);
|
|
1852
|
+
server.bundles.forEach((bundle, name) => {
|
|
1853
|
+
const status = bundle.changed ? '🔄 CHANGED' : '✅ SYNCED';
|
|
1854
|
+
console.log(` ${name}: ${bundle.files.length} files ${status}`);
|
|
1855
|
+
});
|
|
1856
|
+
|
|
1857
|
+
const hasCursorRules = existsSync(server.CURSOR_RULES_FILE);
|
|
1858
|
+
console.log(`🤖 Cursor rules: ${hasCursorRules ? '✅ Configured' : '❌ Not found'}`);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
export function setupMCP(cwd = process.cwd(), options = {}) {
|
|
1863
|
+
const isQuiet = options.quiet || false;
|
|
1864
|
+
const projectDir = cwd;
|
|
1865
|
+
const projectName = basename(projectDir);
|
|
1866
|
+
const configFile = join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
1867
|
+
|
|
1868
|
+
if (!isQuiet) {
|
|
1869
|
+
console.log('🔗 Setting up MCP for Claude Desktop...');
|
|
1870
|
+
console.log(`📁 Project: ${projectName} (${projectDir})`);
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
// Create config directory if it doesn't exist
|
|
1874
|
+
const configDir = dirname(configFile);
|
|
1875
|
+
if (!existsSync(configDir)) {
|
|
1876
|
+
mkdirSync(configDir, { recursive: true });
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
// Read existing config or create empty one
|
|
1880
|
+
let config = { mcpServers: {} };
|
|
1881
|
+
if (existsSync(configFile)) {
|
|
1882
|
+
try {
|
|
1883
|
+
const configContent = readFileSync(configFile, 'utf8');
|
|
1884
|
+
config = JSON.parse(configContent);
|
|
1885
|
+
if (!config.mcpServers) config.mcpServers = {};
|
|
1886
|
+
} catch (error) {
|
|
1887
|
+
if (!isQuiet) console.warn('⚠️ Could not parse existing config, creating new one');
|
|
1888
|
+
config = { mcpServers: {} };
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
// Add this project's MCP server
|
|
1893
|
+
const serverName = `cntx-ui-${projectName}`;
|
|
1894
|
+
config.mcpServers[serverName] = {
|
|
1895
|
+
command: 'npx',
|
|
1896
|
+
args: ['cntx-ui', 'mcp'],
|
|
1897
|
+
cwd: projectDir
|
|
1898
|
+
};
|
|
1795
1899
|
|
|
1796
|
-
|
|
1797
|
-
|
|
1900
|
+
// Write updated config
|
|
1901
|
+
try {
|
|
1902
|
+
writeFileSync(configFile, JSON.stringify(config, null, 2));
|
|
1903
|
+
|
|
1904
|
+
if (!isQuiet) {
|
|
1905
|
+
console.log(`✅ Added MCP server: ${serverName}`);
|
|
1906
|
+
console.log('📋 Your Claude Desktop config now includes:');
|
|
1907
|
+
|
|
1908
|
+
Object.keys(config.mcpServers).forEach(name => {
|
|
1909
|
+
if (name.startsWith('cntx-ui-')) {
|
|
1910
|
+
console.log(` • ${name}: ${config.mcpServers[name].cwd}`);
|
|
1911
|
+
}
|
|
1912
|
+
});
|
|
1913
|
+
|
|
1914
|
+
console.log('🔄 Please restart Claude Desktop to use the updated configuration');
|
|
1915
|
+
}
|
|
1916
|
+
} catch (error) {
|
|
1917
|
+
if (!isQuiet) {
|
|
1918
|
+
console.error('❌ Error writing Claude Desktop config:', error.message);
|
|
1919
|
+
console.error('💡 Make sure Claude Desktop is not running and try again');
|
|
1920
|
+
}
|
|
1921
|
+
throw error;
|
|
1922
|
+
}
|
|
1798
1923
|
}
|