@1mcp/agent 0.16.0 → 0.17.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.
- package/README.md +37 -2
- package/build/commands/app/backups.d.ts +17 -0
- package/build/commands/app/backups.d.ts.map +1 -0
- package/build/commands/app/backups.js +162 -0
- package/build/commands/app/backups.js.map +1 -0
- package/build/commands/app/consolidate.d.ts +21 -0
- package/build/commands/app/consolidate.d.ts.map +1 -0
- package/build/commands/app/consolidate.js +383 -0
- package/build/commands/app/consolidate.js.map +1 -0
- package/build/commands/app/discover.d.ts +16 -0
- package/build/commands/app/discover.d.ts.map +1 -0
- package/build/commands/app/discover.js +79 -0
- package/build/commands/app/discover.js.map +1 -0
- package/build/commands/app/index.d.ts +12 -0
- package/build/commands/app/index.d.ts.map +1 -0
- package/build/commands/app/index.js +274 -0
- package/build/commands/app/index.js.map +1 -0
- package/build/commands/app/list.d.ts +16 -0
- package/build/commands/app/list.d.ts.map +1 -0
- package/build/commands/app/list.js +95 -0
- package/build/commands/app/list.js.map +1 -0
- package/build/commands/app/restore.d.ts +21 -0
- package/build/commands/app/restore.d.ts.map +1 -0
- package/build/commands/app/restore.js +265 -0
- package/build/commands/app/restore.js.map +1 -0
- package/build/commands/app/status.d.ts +16 -0
- package/build/commands/app/status.d.ts.map +1 -0
- package/build/commands/app/status.js +224 -0
- package/build/commands/app/status.js.map +1 -0
- package/build/commands/mcp/add.d.ts +19 -0
- package/build/commands/mcp/add.d.ts.map +1 -0
- package/build/commands/mcp/add.js +135 -0
- package/build/commands/mcp/add.js.map +1 -0
- package/build/commands/mcp/enable.d.ts +13 -0
- package/build/commands/mcp/enable.d.ts.map +1 -0
- package/build/commands/mcp/enable.js +100 -0
- package/build/commands/mcp/enable.js.map +1 -0
- package/build/commands/mcp/index.d.ts +12 -0
- package/build/commands/mcp/index.d.ts.map +1 -0
- package/build/commands/mcp/index.js +351 -0
- package/build/commands/mcp/index.js.map +1 -0
- package/build/commands/mcp/list.d.ts +11 -0
- package/build/commands/mcp/list.d.ts.map +1 -0
- package/build/commands/mcp/list.js +144 -0
- package/build/commands/mcp/list.js.map +1 -0
- package/build/commands/mcp/remove.d.ts +10 -0
- package/build/commands/mcp/remove.d.ts.map +1 -0
- package/build/commands/mcp/remove.js +89 -0
- package/build/commands/mcp/remove.js.map +1 -0
- package/build/commands/mcp/status.d.ts +10 -0
- package/build/commands/mcp/status.d.ts.map +1 -0
- package/build/commands/mcp/status.js +243 -0
- package/build/commands/mcp/status.js.map +1 -0
- package/build/commands/mcp/update.d.ts +18 -0
- package/build/commands/mcp/update.d.ts.map +1 -0
- package/build/commands/mcp/update.js +157 -0
- package/build/commands/mcp/update.js.map +1 -0
- package/build/commands/mcp/utils/configUtils.d.ts +64 -0
- package/build/commands/mcp/utils/configUtils.d.ts.map +1 -0
- package/build/commands/mcp/utils/configUtils.js +266 -0
- package/build/commands/mcp/utils/configUtils.js.map +1 -0
- package/build/commands/mcp/utils/doubleHyphenParser.d.ts +32 -0
- package/build/commands/mcp/utils/doubleHyphenParser.d.ts.map +1 -0
- package/build/commands/mcp/utils/doubleHyphenParser.js +61 -0
- package/build/commands/mcp/utils/doubleHyphenParser.js.map +1 -0
- package/build/commands/mcp/utils/validation.d.ts +33 -0
- package/build/commands/mcp/utils/validation.d.ts.map +1 -0
- package/build/commands/mcp/utils/validation.js +235 -0
- package/build/commands/mcp/utils/validation.js.map +1 -0
- package/build/constants.d.ts +11 -2
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +15 -2
- package/build/constants.js.map +1 -1
- package/build/core/capabilities/asyncLoadingOrchestrator.d.ts +96 -0
- package/build/core/capabilities/asyncLoadingOrchestrator.d.ts.map +1 -0
- package/build/core/capabilities/asyncLoadingOrchestrator.js +256 -0
- package/build/core/capabilities/asyncLoadingOrchestrator.js.map +1 -0
- package/build/core/capabilities/capabilityAggregator.d.ts +114 -0
- package/build/core/capabilities/capabilityAggregator.d.ts.map +1 -0
- package/build/core/capabilities/capabilityAggregator.js +234 -0
- package/build/core/capabilities/capabilityAggregator.js.map +1 -0
- package/build/core/client/clientManager.d.ts +28 -0
- package/build/core/client/clientManager.d.ts.map +1 -1
- package/build/core/client/clientManager.js +120 -0
- package/build/core/client/clientManager.js.map +1 -1
- package/build/core/loading/loadingStateTracker.d.ts +128 -0
- package/build/core/loading/loadingStateTracker.d.ts.map +1 -0
- package/build/core/loading/loadingStateTracker.js +209 -0
- package/build/core/loading/loadingStateTracker.js.map +1 -0
- package/build/core/loading/mcpLoadingManager.d.ts +139 -0
- package/build/core/loading/mcpLoadingManager.d.ts.map +1 -0
- package/build/core/loading/mcpLoadingManager.js +296 -0
- package/build/core/loading/mcpLoadingManager.js.map +1 -0
- package/build/core/notifications/notificationManager.d.ts +111 -0
- package/build/core/notifications/notificationManager.d.ts.map +1 -0
- package/build/core/notifications/notificationManager.js +232 -0
- package/build/core/notifications/notificationManager.js.map +1 -0
- package/build/core/server/agentConfig.d.ts +50 -0
- package/build/core/server/agentConfig.d.ts.map +1 -1
- package/build/core/server/agentConfig.js +68 -1
- package/build/core/server/agentConfig.js.map +1 -1
- package/build/core/server/serverManager.d.ts +1 -0
- package/build/core/server/serverManager.d.ts.map +1 -1
- package/build/core/server/serverManager.js +3 -0
- package/build/core/server/serverManager.js.map +1 -1
- package/build/index.js +115 -32
- package/build/index.js.map +1 -1
- package/build/server.d.ts +23 -2
- package/build/server.d.ts.map +1 -1
- package/build/server.js +83 -10
- package/build/server.js.map +1 -1
- package/build/transport/http/middlewares/mcpAvailabilityMiddleware.d.ts +79 -0
- package/build/transport/http/middlewares/mcpAvailabilityMiddleware.d.ts.map +1 -0
- package/build/transport/http/middlewares/mcpAvailabilityMiddleware.js +243 -0
- package/build/transport/http/middlewares/mcpAvailabilityMiddleware.js.map +1 -0
- package/build/transport/http/routes/healthRoutes.d.ts +2 -1
- package/build/transport/http/routes/healthRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/healthRoutes.js +170 -1
- package/build/transport/http/routes/healthRoutes.js.map +1 -1
- package/build/transport/http/routes/sseRoutes.d.ts +2 -1
- package/build/transport/http/routes/sseRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/sseRoutes.js +13 -1
- package/build/transport/http/routes/sseRoutes.js.map +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.d.ts +2 -1
- package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -1
- package/build/transport/http/routes/streamableHttpRoutes.js +13 -1
- package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -1
- package/build/transport/http/server.d.ts +7 -1
- package/build/transport/http/server.d.ts.map +1 -1
- package/build/transport/http/server.js +15 -4
- package/build/transport/http/server.js.map +1 -1
- package/build/transport/transportFactory.d.ts +4 -0
- package/build/transport/transportFactory.d.ts.map +1 -1
- package/build/transport/transportFactory.js +1 -1
- package/build/transport/transportFactory.js.map +1 -1
- package/build/utils/appDiscovery.d.ts +75 -0
- package/build/utils/appDiscovery.d.ts.map +1 -0
- package/build/utils/appDiscovery.js +358 -0
- package/build/utils/appDiscovery.js.map +1 -0
- package/build/utils/appPresets.d.ts +88 -0
- package/build/utils/appPresets.d.ts.map +1 -0
- package/build/utils/appPresets.js +430 -0
- package/build/utils/appPresets.js.map +1 -0
- package/build/utils/backupManager.d.ts +61 -0
- package/build/utils/backupManager.d.ts.map +1 -0
- package/build/utils/backupManager.js +314 -0
- package/build/utils/backupManager.js.map +1 -0
- package/build/utils/urlDetection.d.ts +35 -0
- package/build/utils/urlDetection.d.ts.map +1 -0
- package/build/utils/urlDetection.js +115 -0
- package/build/utils/urlDetection.js.map +1 -0
- package/build/utils/validationHelpers.d.ts +62 -0
- package/build/utils/validationHelpers.d.ts.map +1 -0
- package/build/utils/validationHelpers.js +252 -0
- package/build/utils/validationHelpers.js.map +1 -0
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ A unified Model Context Protocol server implementation that aggregates multiple
|
|
|
11
11
|
- [Overview](#overview)
|
|
12
12
|
- [Features](#features)
|
|
13
13
|
- [Quick Start](#quick-start)
|
|
14
|
+
- [Commands](#commands)
|
|
14
15
|
- [Prerequisites](#prerequisites)
|
|
15
16
|
- [Usage](#usage)
|
|
16
17
|
- [Docker](#docker)
|
|
@@ -35,6 +36,7 @@ A unified Model Context Protocol server implementation that aggregates multiple
|
|
|
35
36
|
- **Simplified Configuration**: Simplifies configuration management across different AI assistants.
|
|
36
37
|
- **Standardized Interaction**: Provides a standardized way for AI models to interact with external tools and resources.
|
|
37
38
|
- **Dynamic Configuration**: Supports dynamic configuration reloading without server restart.
|
|
39
|
+
- **Async Loading**: Optional asynchronous server loading with real-time capability updates via listChanged notifications.
|
|
38
40
|
- **Graceful Shutdown**: Handles graceful shutdown and resource cleanup.
|
|
39
41
|
- **Secure**: Includes comprehensive authentication and security features.
|
|
40
42
|
- **Optimized**: Supports advanced filtering, pagination, and request optimization.
|
|
@@ -65,6 +67,37 @@ npx -y @1mcp/agent --config ~/Library/Application\ Support/Claude/claude_desktop
|
|
|
65
67
|
|
|
66
68
|
3. Enjoy it!
|
|
67
69
|
|
|
70
|
+
## Commands
|
|
71
|
+
|
|
72
|
+
1MCP provides several commands to manage your MCP server configuration:
|
|
73
|
+
|
|
74
|
+
### Core Commands
|
|
75
|
+
|
|
76
|
+
- **`npx -y @1mcp/agent [serve]`** - Start the 1MCP server (default command)
|
|
77
|
+
- `--transport` - Choose transport type (stdio, http, sse)
|
|
78
|
+
- `--config` - Use specific config file
|
|
79
|
+
- `--port` - Change HTTP port
|
|
80
|
+
|
|
81
|
+
### MCP Management
|
|
82
|
+
|
|
83
|
+
- **`npx -y @1mcp/agent mcp add <name>`** - Add a new MCP server to configuration
|
|
84
|
+
- **`npx -y @1mcp/agent mcp remove <name>`** - Remove an MCP server
|
|
85
|
+
- **`npx -y @1mcp/agent mcp list`** - List all configured MCP servers
|
|
86
|
+
- **`npx -y @1mcp/agent mcp status [name]`** - Show server status and details
|
|
87
|
+
- **`npx -y @1mcp/agent mcp enable/disable <name>`** - Enable or disable servers
|
|
88
|
+
- **`npx -y @1mcp/agent mcp update <name>`** - Update server configuration
|
|
89
|
+
|
|
90
|
+
### App Integration
|
|
91
|
+
|
|
92
|
+
- **`npx -y @1mcp/agent app consolidate`** - Consolidate configurations from other MCP apps
|
|
93
|
+
- **`npx -y @1mcp/agent app discover`** - Discover MCP servers from installed applications
|
|
94
|
+
- **`npx -y @1mcp/agent app list`** - List discovered applications
|
|
95
|
+
- **`npx -y @1mcp/agent app status`** - Show consolidation status
|
|
96
|
+
|
|
97
|
+
For detailed command usage, run: `1mcp <command> --help`
|
|
98
|
+
|
|
99
|
+
Full documentation: [Commands Reference](https://docs.1mcp.app/commands/)
|
|
100
|
+
|
|
68
101
|
## Prerequisites
|
|
69
102
|
|
|
70
103
|
- [Node.js](https://nodejs.org/) (version 21 or higher)
|
|
@@ -113,8 +146,10 @@ Available options:
|
|
|
113
146
|
| `--session-storage-path` | `ONE_MCP_SESSION_STORAGE_PATH` | Custom session storage directory path (string) | |
|
|
114
147
|
| `--rate-limit-window` | `ONE_MCP_RATE_LIMIT_WINDOW` | OAuth rate limit window in minutes (number) | 15 |
|
|
115
148
|
| `--rate-limit-max` | `ONE_MCP_RATE_LIMIT_MAX` | Maximum requests per OAuth rate limit window (number) | 100 |
|
|
116
|
-
|
|
117
|
-
| `--
|
|
149
|
+
|
|
150
|
+
| `--enable-async-loading` | `ONE_MCP_ENABLE_ASYNC_LOADING` | Enable asynchronous MCP server loading(boolean) | false |
|
|
151
|
+
| `--health-info-level` | `ONE_MCP_HEALTH_INFO_LEVEL` | Health endpoint information detail level ("full", "basic", "minimal") | "minimal" |
|
|
152
|
+
| `--help`, `-h` | | Show help | |
|
|
118
153
|
|
|
119
154
|
## Docker
|
|
120
155
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backups command - Manage and list backup files.
|
|
3
|
+
*
|
|
4
|
+
* Provides backup management functionality including listing,
|
|
5
|
+
* verification, and cleanup of old backup files.
|
|
6
|
+
*/
|
|
7
|
+
interface BackupsOptions {
|
|
8
|
+
'app-name'?: string;
|
|
9
|
+
cleanup?: number;
|
|
10
|
+
verify: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Main backups command handler
|
|
14
|
+
*/
|
|
15
|
+
export declare function backupsCommand(options: BackupsOptions): Promise<void>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=backups.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backups.d.ts","sourceRoot":"","sources":["../../../src/commands/app/backups.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AAEH,UAAU,cAAc;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAW3E"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { listAppBackups, cleanupOldBackups, verifyBackupIntegrity, findBackupByMetaPath, } from '../../utils/backupManager.js';
|
|
2
|
+
import { getAppPreset } from '../../utils/appPresets.js';
|
|
3
|
+
/**
|
|
4
|
+
* Main backups command handler
|
|
5
|
+
*/
|
|
6
|
+
export async function backupsCommand(options) {
|
|
7
|
+
console.log('💾 MCP Configuration Backup Management\n');
|
|
8
|
+
// Cleanup mode
|
|
9
|
+
if (options.cleanup !== undefined) {
|
|
10
|
+
await cleanupBackups(options.cleanup);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
// List and optionally verify backups
|
|
14
|
+
await listBackupsWithDetails(options['app-name'], options.verify);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* List backups with detailed information
|
|
18
|
+
*/
|
|
19
|
+
async function listBackupsWithDetails(appName, verify = false) {
|
|
20
|
+
const backups = listAppBackups(appName);
|
|
21
|
+
if (backups.length === 0) {
|
|
22
|
+
if (appName) {
|
|
23
|
+
console.log(`📭 No backups found for ${appName}.`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
console.log('📭 No backups found.');
|
|
27
|
+
}
|
|
28
|
+
console.log('\n💡 Backups are created automatically during consolidation.');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (appName) {
|
|
32
|
+
const preset = getAppPreset(appName);
|
|
33
|
+
console.log(`📋 Backups for ${preset?.displayName || appName}:\n`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.log('📋 All Available Backups:\n');
|
|
37
|
+
}
|
|
38
|
+
// Group by application
|
|
39
|
+
const groupedBackups = backups.reduce((groups, backup) => {
|
|
40
|
+
if (!groups[backup.app]) {
|
|
41
|
+
groups[backup.app] = [];
|
|
42
|
+
}
|
|
43
|
+
groups[backup.app].push(backup);
|
|
44
|
+
return groups;
|
|
45
|
+
}, {});
|
|
46
|
+
let totalSize = 0;
|
|
47
|
+
let verifiedCount = 0;
|
|
48
|
+
let corruptedCount = 0;
|
|
49
|
+
for (const [app, appBackups] of Object.entries(groupedBackups)) {
|
|
50
|
+
const preset = getAppPreset(app);
|
|
51
|
+
console.log(`📱 ${preset?.displayName || app} (${app}):`);
|
|
52
|
+
for (const backup of appBackups) {
|
|
53
|
+
const backupInfo = findBackupByMetaPath(backup.metaPath);
|
|
54
|
+
console.log(` 🕐 ${backup.age} - ${backup.operation} operation`);
|
|
55
|
+
console.log(` 📁 ${backup.backupPath}`);
|
|
56
|
+
console.log(` 🔧 ${backup.serverCount} servers backed up`);
|
|
57
|
+
if (backupInfo) {
|
|
58
|
+
const fileSizeKB = Math.round(backupInfo.metadata.fileSize / 1024);
|
|
59
|
+
totalSize += backupInfo.metadata.fileSize;
|
|
60
|
+
console.log(` 📊 Size: ${fileSizeKB} KB`);
|
|
61
|
+
// Verify integrity if requested
|
|
62
|
+
if (verify) {
|
|
63
|
+
const isValid = verifyBackupIntegrity(backupInfo);
|
|
64
|
+
if (isValid) {
|
|
65
|
+
console.log(` ✅ Integrity: Valid`);
|
|
66
|
+
verifiedCount++;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.log(` ❌ Integrity: Corrupted`);
|
|
70
|
+
corruptedCount++;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
console.log(` 📝 Metadata: ${backup.metaPath}`);
|
|
75
|
+
console.log();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Summary
|
|
79
|
+
const totalSizeMB = Math.round((totalSize / (1024 * 1024)) * 100) / 100;
|
|
80
|
+
console.log('📊 Backup Summary:');
|
|
81
|
+
console.log(` 📦 Total backups: ${backups.length}`);
|
|
82
|
+
console.log(` 📱 Applications: ${Object.keys(groupedBackups).length}`);
|
|
83
|
+
console.log(` 💽 Total size: ${totalSizeMB} MB`);
|
|
84
|
+
if (verify) {
|
|
85
|
+
console.log(` ✅ Verified: ${verifiedCount}`);
|
|
86
|
+
if (corruptedCount > 0) {
|
|
87
|
+
console.log(` ❌ Corrupted: ${corruptedCount}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Show oldest and newest
|
|
91
|
+
if (backups.length > 1) {
|
|
92
|
+
const oldest = backups[backups.length - 1];
|
|
93
|
+
const newest = backups[0];
|
|
94
|
+
console.log(` 🕐 Oldest: ${oldest.age} (${getAppPreset(oldest.app)?.displayName || oldest.app})`);
|
|
95
|
+
console.log(` 🕐 Newest: ${newest.age} (${getAppPreset(newest.app)?.displayName || newest.app})`);
|
|
96
|
+
}
|
|
97
|
+
// Usage recommendations
|
|
98
|
+
console.log('\n💡 Management Commands:');
|
|
99
|
+
console.log(' 📋 List app backups: npx @1mcp/agent app backups <app-name>');
|
|
100
|
+
console.log(' 🔍 Verify integrity: npx @1mcp/agent app backups --verify');
|
|
101
|
+
console.log(' 🧹 Cleanup old: npx @1mcp/agent app backups --cleanup=30');
|
|
102
|
+
console.log(' 🔄 Restore: npx @1mcp/agent app restore <app-name>');
|
|
103
|
+
if (corruptedCount > 0) {
|
|
104
|
+
console.log('\n⚠️ Warning: Some backups failed integrity verification.');
|
|
105
|
+
console.log(' Consider creating fresh backups for affected applications.');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Cleanup old backups
|
|
110
|
+
*/
|
|
111
|
+
async function cleanupBackups(maxAgeDays) {
|
|
112
|
+
console.log(`🧹 Cleaning up backups older than ${maxAgeDays} days...\n`);
|
|
113
|
+
if (maxAgeDays < 1) {
|
|
114
|
+
console.error('❌ Invalid age: must be at least 1 day.');
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
// Show what will be deleted first
|
|
118
|
+
const allBackups = listAppBackups();
|
|
119
|
+
const cutoffTime = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
|
|
120
|
+
const oldBackups = allBackups.filter((backup) => backup.timestamp < cutoffTime);
|
|
121
|
+
if (oldBackups.length === 0) {
|
|
122
|
+
console.log(`✅ No backups older than ${maxAgeDays} days found.`);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
console.log(`📋 Found ${oldBackups.length} backups to delete:\n`);
|
|
126
|
+
const groupedOld = oldBackups.reduce((groups, backup) => {
|
|
127
|
+
if (!groups[backup.app]) {
|
|
128
|
+
groups[backup.app] = [];
|
|
129
|
+
}
|
|
130
|
+
groups[backup.app].push(backup);
|
|
131
|
+
return groups;
|
|
132
|
+
}, {});
|
|
133
|
+
Object.entries(groupedOld).forEach(([app, appBackups]) => {
|
|
134
|
+
const preset = getAppPreset(app);
|
|
135
|
+
console.log(`📱 ${preset?.displayName || app}: ${appBackups.length} backups`);
|
|
136
|
+
appBackups.forEach((backup) => {
|
|
137
|
+
console.log(` 🕐 ${backup.age} - ${backup.operation}`);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
// Perform cleanup
|
|
141
|
+
console.log('\n🗑️ Deleting old backups...');
|
|
142
|
+
const deletedCount = cleanupOldBackups(maxAgeDays);
|
|
143
|
+
if (deletedCount > 0) {
|
|
144
|
+
console.log(`✅ Successfully deleted ${deletedCount} old backups.`);
|
|
145
|
+
// Show remaining backups
|
|
146
|
+
const remainingBackups = listAppBackups();
|
|
147
|
+
console.log(`📦 Remaining backups: ${remainingBackups.length}`);
|
|
148
|
+
if (remainingBackups.length > 0) {
|
|
149
|
+
const totalSize = remainingBackups.reduce((sum, backup) => {
|
|
150
|
+
const backupInfo = findBackupByMetaPath(backup.metaPath);
|
|
151
|
+
return sum + (backupInfo?.metadata.fileSize || 0);
|
|
152
|
+
}, 0);
|
|
153
|
+
const totalSizeMB = Math.round((totalSize / (1024 * 1024)) * 100) / 100;
|
|
154
|
+
console.log(`💽 Total size: ${totalSizeMB} MB`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
console.log('⚠️ No backups were deleted (they may have been removed already).');
|
|
159
|
+
}
|
|
160
|
+
console.log('\n💡 To see remaining backups: npx @1mcp/agent app backups');
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=backups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backups.js","sourceRoot":"","sources":["../../../src/commands/app/backups.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidate command - Main consolidation logic for MCP servers.
|
|
3
|
+
*
|
|
4
|
+
* Extracts MCP servers from desktop applications and consolidates
|
|
5
|
+
* them into 1mcp with safe backup and validation.
|
|
6
|
+
*/
|
|
7
|
+
interface ConsolidateOptions {
|
|
8
|
+
'app-name': string[];
|
|
9
|
+
url?: string;
|
|
10
|
+
'dry-run': boolean;
|
|
11
|
+
yes: boolean;
|
|
12
|
+
'manual-only': boolean;
|
|
13
|
+
'backup-only': boolean;
|
|
14
|
+
force: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Main consolidate command handler
|
|
18
|
+
*/
|
|
19
|
+
export declare function consolidateCommand(options: ConsolidateOptions): Promise<void>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=consolidate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidate.d.ts","sourceRoot":"","sources":["../../../src/commands/app/consolidate.ts"],"names":[],"mappings":"AAyBA;;;;;GAKG;AAEH,UAAU,kBAAkB;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,OAAO,CAAC;IACb,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAWD;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2GnF"}
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import readline from 'readline';
|
|
4
|
+
import { getServer1mcpUrl, validateServer1mcpUrl } from '../../utils/urlDetection.js';
|
|
5
|
+
import { discoverAppConfigs, handleMultipleConfigs, extractAndFilterServers, generateAppConfig, checkConsolidationStatus, } from '../../utils/appDiscovery.js';
|
|
6
|
+
import { isAppSupported, isAppConfigurable, generateManualInstructions, getAppPreset, showPlatformWarningIfNeeded, } from '../../utils/appPresets.js';
|
|
7
|
+
import { validateOperation, generateOperationPreview } from '../../utils/validationHelpers.js';
|
|
8
|
+
import { createBackup, withFileLock } from '../../utils/backupManager.js';
|
|
9
|
+
import { getAppBackupDir } from '../../constants.js';
|
|
10
|
+
import { McpConfigManager } from '../../config/mcpConfigManager.js';
|
|
11
|
+
import { setServer } from '../mcp/utils/configUtils.js';
|
|
12
|
+
/**
|
|
13
|
+
* Main consolidate command handler
|
|
14
|
+
*/
|
|
15
|
+
export async function consolidateCommand(options) {
|
|
16
|
+
const appNames = options['app-name'];
|
|
17
|
+
// Check if app names were provided
|
|
18
|
+
if (!appNames || appNames.length === 0) {
|
|
19
|
+
console.error('❌ Error: No application names provided.');
|
|
20
|
+
console.log('Please specify at least one application to consolidate.');
|
|
21
|
+
console.log('Example: npx @1mcp/agent app consolidate claude-desktop');
|
|
22
|
+
console.log('Use "npx @1mcp/agent app list" to see supported applications.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
// Show platform warning if needed
|
|
26
|
+
showPlatformWarningIfNeeded();
|
|
27
|
+
console.log('🔍 Starting MCP server consolidation...\n');
|
|
28
|
+
// Validate all app names first
|
|
29
|
+
const invalidApps = appNames.filter((app) => !isAppSupported(app));
|
|
30
|
+
if (invalidApps.length > 0) {
|
|
31
|
+
console.error(`❌ Unsupported applications: ${invalidApps.join(', ')}`);
|
|
32
|
+
console.log('Use "npx @1mcp/agent app list" to see supported applications.');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
// Get 1mcp server URL
|
|
36
|
+
const serverUrl = await getServer1mcpUrl(options.url);
|
|
37
|
+
console.log(`🔗 Using 1mcp server: ${serverUrl}`);
|
|
38
|
+
// Validate server connectivity (unless force mode)
|
|
39
|
+
if (!options.force) {
|
|
40
|
+
const connectivityCheck = await validateServer1mcpUrl(serverUrl);
|
|
41
|
+
if (!connectivityCheck.valid) {
|
|
42
|
+
console.error(`❌ Cannot connect to 1mcp server: ${connectivityCheck.error}`);
|
|
43
|
+
console.log('Make sure the 1mcp server is running or use --force to skip validation.');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
console.log('✅ 1mcp server connectivity verified\n');
|
|
47
|
+
}
|
|
48
|
+
const results = [];
|
|
49
|
+
// Process each app
|
|
50
|
+
for (const appName of appNames) {
|
|
51
|
+
console.log(`\n🔍 Processing ${getAppPreset(appName)?.displayName || appName}...`);
|
|
52
|
+
try {
|
|
53
|
+
const result = await consolidateApp(appName, serverUrl, options);
|
|
54
|
+
results.push(result);
|
|
55
|
+
// Display result
|
|
56
|
+
if (result.status === 'success') {
|
|
57
|
+
console.log(`✅ ${result.message}`);
|
|
58
|
+
if (result.serversImported !== undefined) {
|
|
59
|
+
console.log(`📋 Imported ${result.serversImported} MCP servers`);
|
|
60
|
+
}
|
|
61
|
+
if (result.backupPath) {
|
|
62
|
+
console.log(`💾 Backup created: ${result.backupPath}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (result.status === 'manual') {
|
|
66
|
+
console.log(`🔧 ${result.message}`);
|
|
67
|
+
if (result.manualInstructions) {
|
|
68
|
+
console.log(result.manualInstructions);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else if (result.status === 'skipped') {
|
|
72
|
+
console.log(`⏭️ ${result.message}`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.error(`❌ ${result.message}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
const errorResult = {
|
|
80
|
+
app: appName,
|
|
81
|
+
status: 'failed',
|
|
82
|
+
message: `Failed to consolidate ${appName}: ${error.message}`,
|
|
83
|
+
};
|
|
84
|
+
results.push(errorResult);
|
|
85
|
+
console.error(`❌ ${errorResult.message}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Final summary
|
|
89
|
+
console.log('\n' + '='.repeat(60));
|
|
90
|
+
console.log('📊 Consolidation Summary:');
|
|
91
|
+
const successful = results.filter((r) => r.status === 'success');
|
|
92
|
+
const manual = results.filter((r) => r.status === 'manual');
|
|
93
|
+
const failed = results.filter((r) => r.status === 'failed');
|
|
94
|
+
const skipped = results.filter((r) => r.status === 'skipped');
|
|
95
|
+
console.log(`✅ Successful: ${successful.length}`);
|
|
96
|
+
console.log(`🔧 Manual setup required: ${manual.length}`);
|
|
97
|
+
console.log(`⏭️ Skipped: ${skipped.length}`);
|
|
98
|
+
console.log(`❌ Failed: ${failed.length}`);
|
|
99
|
+
if (successful.length > 0) {
|
|
100
|
+
console.log('\n🔄 Restart the following applications to use consolidated configuration:');
|
|
101
|
+
successful.forEach((result) => {
|
|
102
|
+
console.log(` - ${getAppPreset(result.app)?.displayName || result.app}`);
|
|
103
|
+
});
|
|
104
|
+
console.log('\n💡 To undo consolidation, use:');
|
|
105
|
+
console.log(' npx @1mcp/agent app restore <app-name>');
|
|
106
|
+
}
|
|
107
|
+
if (failed.length > 0) {
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Consolidate a single application
|
|
113
|
+
*/
|
|
114
|
+
async function consolidateApp(appName, serverUrl, options) {
|
|
115
|
+
// Check if app is already consolidated (unless force mode)
|
|
116
|
+
if (!options.force) {
|
|
117
|
+
const consolidationStatus = await checkConsolidationStatus(appName);
|
|
118
|
+
if (consolidationStatus.isConsolidated) {
|
|
119
|
+
return {
|
|
120
|
+
app: appName,
|
|
121
|
+
status: 'skipped',
|
|
122
|
+
message: `Already consolidated to ${consolidationStatus.consolidatedUrl}`,
|
|
123
|
+
serversImported: 0,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Check if app is configurable
|
|
128
|
+
if (!isAppConfigurable(appName)) {
|
|
129
|
+
// Manual setup required
|
|
130
|
+
const instructions = generateManualInstructions(appName, serverUrl);
|
|
131
|
+
return {
|
|
132
|
+
app: appName,
|
|
133
|
+
status: 'manual',
|
|
134
|
+
message: `${getAppPreset(appName)?.displayName || appName} requires manual configuration`,
|
|
135
|
+
manualInstructions: instructions,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
// Manual-only mode
|
|
139
|
+
if (options['manual-only']) {
|
|
140
|
+
const instructions = generateManualInstructions(appName, serverUrl);
|
|
141
|
+
return {
|
|
142
|
+
app: appName,
|
|
143
|
+
status: 'manual',
|
|
144
|
+
message: `Manual setup instructions for ${getAppPreset(appName)?.displayName || appName}`,
|
|
145
|
+
manualInstructions: instructions,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// Discover configurations
|
|
149
|
+
const discovery = await discoverAppConfigs(appName);
|
|
150
|
+
if (discovery.configs.length === 0) {
|
|
151
|
+
return {
|
|
152
|
+
app: appName,
|
|
153
|
+
status: 'skipped',
|
|
154
|
+
message: `No configuration files found for ${getAppPreset(appName)?.displayName || appName}`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
// Handle multiple configs
|
|
158
|
+
const strategy = handleMultipleConfigs(discovery);
|
|
159
|
+
if (strategy.action === 'none') {
|
|
160
|
+
return {
|
|
161
|
+
app: appName,
|
|
162
|
+
status: 'skipped',
|
|
163
|
+
message: `No valid configuration found for ${getAppPreset(appName)?.displayName || appName}`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
let targetConfig = strategy.target;
|
|
167
|
+
// If multiple configs and not in yes mode, ask user to choose
|
|
168
|
+
if (strategy.action === 'choose' && !options.yes && !options['dry-run']) {
|
|
169
|
+
targetConfig = await promptUserChoice(strategy.options);
|
|
170
|
+
}
|
|
171
|
+
// Extract servers
|
|
172
|
+
const servers = extractAndFilterServers(targetConfig.content, getAppPreset(appName)?.configFormat);
|
|
173
|
+
if (servers.length === 0 && !options.force) {
|
|
174
|
+
return {
|
|
175
|
+
app: appName,
|
|
176
|
+
status: 'skipped',
|
|
177
|
+
message: `No MCP servers found in ${getAppPreset(appName)?.displayName || appName} configuration`,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// Validate operation
|
|
181
|
+
if (!options.force) {
|
|
182
|
+
const validation = await validateOperation(targetConfig.path, targetConfig.content, serverUrl);
|
|
183
|
+
if (!validation.canProceed) {
|
|
184
|
+
const errors = [
|
|
185
|
+
...validation.configValidation.errors,
|
|
186
|
+
...validation.permissionValidation.errors,
|
|
187
|
+
...validation.connectivityValidation.errors,
|
|
188
|
+
];
|
|
189
|
+
throw new Error(`Validation failed: ${errors.join(', ')}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Generate preview with correct backup path
|
|
193
|
+
const timestamp = Date.now();
|
|
194
|
+
const dateStr = new Date(timestamp).toISOString().replace(/[:.-]/g, '').slice(0, 15); // YYYYMMDDTHHMMSS
|
|
195
|
+
const appBackupDir = getAppBackupDir(appName);
|
|
196
|
+
const backupFileName = `${dateStr}_consolidate.backup`;
|
|
197
|
+
const backupPath = path.join(appBackupDir, backupFileName);
|
|
198
|
+
const preview = generateOperationPreview(appName, targetConfig.path, servers.map((s) => s.name), serverUrl, backupPath);
|
|
199
|
+
// Show preview and get confirmation
|
|
200
|
+
if (!options.yes && !options['dry-run']) {
|
|
201
|
+
const confirmed = await confirmOperation(preview);
|
|
202
|
+
if (!confirmed) {
|
|
203
|
+
return {
|
|
204
|
+
app: appName,
|
|
205
|
+
status: 'skipped',
|
|
206
|
+
message: `Consolidation cancelled by user for ${getAppPreset(appName)?.displayName || appName}`,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Dry run mode - just show what would happen
|
|
211
|
+
if (options['dry-run']) {
|
|
212
|
+
console.log('\n📋 Dry Run Preview:');
|
|
213
|
+
console.log(`App: ${getAppPreset(appName)?.displayName || appName}`);
|
|
214
|
+
console.log(`Config: ${targetConfig.path}`);
|
|
215
|
+
console.log(`Servers to import: ${servers.map((s) => s.name).join(', ') || 'none'}`);
|
|
216
|
+
console.log(`Replacement URL: ${serverUrl}`);
|
|
217
|
+
console.log(`Backup would be created: ${backupPath}`);
|
|
218
|
+
return {
|
|
219
|
+
app: appName,
|
|
220
|
+
status: 'success',
|
|
221
|
+
message: `Dry run completed for ${getAppPreset(appName)?.displayName || appName}`,
|
|
222
|
+
serversImported: servers.length,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
// Create backup
|
|
226
|
+
const backup = createBackup(targetConfig.path, appName, 'consolidate', servers.length);
|
|
227
|
+
// Backup-only mode
|
|
228
|
+
if (options['backup-only']) {
|
|
229
|
+
return {
|
|
230
|
+
app: appName,
|
|
231
|
+
status: 'success',
|
|
232
|
+
message: `Backup created for ${getAppPreset(appName)?.displayName || appName}`,
|
|
233
|
+
backupPath: backup.backupPath,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
// Perform consolidation with file locking
|
|
237
|
+
await withFileLock(targetConfig.path, async () => {
|
|
238
|
+
try {
|
|
239
|
+
// Import servers to 1mcp
|
|
240
|
+
if (servers.length > 0) {
|
|
241
|
+
await importServersTo1mcp(servers);
|
|
242
|
+
}
|
|
243
|
+
// Generate new config
|
|
244
|
+
const newConfig = generateAppConfig(appName, serverUrl);
|
|
245
|
+
// Write new configuration
|
|
246
|
+
fs.writeFileSync(targetConfig.path, JSON.stringify(newConfig, null, 2));
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
// Rollback on failure
|
|
250
|
+
fs.copyFileSync(backup.backupPath, backup.originalPath);
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
return {
|
|
255
|
+
app: appName,
|
|
256
|
+
status: 'success',
|
|
257
|
+
message: `Successfully consolidated ${getAppPreset(appName)?.displayName || appName}`,
|
|
258
|
+
serversImported: servers.length,
|
|
259
|
+
backupPath: backup.backupPath,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Convert MCPServerConfig to MCPServerParams format
|
|
264
|
+
*/
|
|
265
|
+
function convertToMCPServerParams(server) {
|
|
266
|
+
const params = {
|
|
267
|
+
disabled: false,
|
|
268
|
+
};
|
|
269
|
+
// Determine transport type and set appropriate parameters
|
|
270
|
+
if (server.command) {
|
|
271
|
+
// Stdio transport
|
|
272
|
+
params.type = 'stdio';
|
|
273
|
+
params.command = server.command;
|
|
274
|
+
if (server.args && server.args.length > 0) {
|
|
275
|
+
params.args = server.args;
|
|
276
|
+
}
|
|
277
|
+
if (server.env) {
|
|
278
|
+
params.env = server.env;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else if (server.url) {
|
|
282
|
+
// HTTP transport - determine if SSE or regular HTTP
|
|
283
|
+
if (server.url.includes('/sse') || server.url.includes('text/event-stream')) {
|
|
284
|
+
params.type = 'sse';
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
params.type = 'http';
|
|
288
|
+
}
|
|
289
|
+
params.url = server.url;
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
throw new Error(`Invalid server configuration: ${server.name} has neither command nor url`);
|
|
293
|
+
}
|
|
294
|
+
return params;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Import MCP servers to 1mcp configuration
|
|
298
|
+
*/
|
|
299
|
+
async function importServersTo1mcp(servers) {
|
|
300
|
+
const mcpConfig = McpConfigManager.getInstance();
|
|
301
|
+
// Get current transport config
|
|
302
|
+
const currentConfig = mcpConfig.getTransportConfig();
|
|
303
|
+
for (const server of servers) {
|
|
304
|
+
// Check if server already exists
|
|
305
|
+
if (currentConfig[server.name]) {
|
|
306
|
+
console.log(`⚠️ Server "${server.name}" already exists in 1mcp config - skipping`);
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
try {
|
|
310
|
+
// Convert to proper MCPServerParams format
|
|
311
|
+
const serverParams = convertToMCPServerParams(server);
|
|
312
|
+
// Add server to configuration
|
|
313
|
+
setServer(server.name, serverParams);
|
|
314
|
+
console.log(`✅ Imported server: ${server.name}`);
|
|
315
|
+
// Log what was imported
|
|
316
|
+
if (serverParams.type === 'stdio') {
|
|
317
|
+
console.log(` Type: stdio`);
|
|
318
|
+
console.log(` Command: ${serverParams.command}`);
|
|
319
|
+
if (serverParams.args)
|
|
320
|
+
console.log(` Args: ${serverParams.args.join(' ')}`);
|
|
321
|
+
}
|
|
322
|
+
else if (serverParams.type === 'http' || serverParams.type === 'sse') {
|
|
323
|
+
console.log(` Type: ${serverParams.type}`);
|
|
324
|
+
console.log(` URL: ${serverParams.url}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
console.error(`❌ Failed to import server "${server.name}": ${error.message}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Prompt user to choose from multiple configurations
|
|
334
|
+
*/
|
|
335
|
+
async function promptUserChoice(configs) {
|
|
336
|
+
console.log('\n📋 Multiple configurations found:');
|
|
337
|
+
configs.forEach((config, index) => {
|
|
338
|
+
console.log(`${index + 1}. ${config.path} (${config.level}, ${config.servers.length} servers)`);
|
|
339
|
+
});
|
|
340
|
+
const rl = readline.createInterface({
|
|
341
|
+
input: process.stdin,
|
|
342
|
+
output: process.stdout,
|
|
343
|
+
});
|
|
344
|
+
return new Promise((resolve) => {
|
|
345
|
+
rl.question('\nWhich configuration would you like to use? (number): ', (answer) => {
|
|
346
|
+
rl.close();
|
|
347
|
+
const choice = parseInt(answer, 10);
|
|
348
|
+
if (choice >= 1 && choice <= configs.length) {
|
|
349
|
+
resolve(configs[choice - 1]);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
console.log('Invalid choice, using first option.');
|
|
353
|
+
resolve(configs[0]);
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Confirm operation with user
|
|
360
|
+
*/
|
|
361
|
+
async function confirmOperation(preview) {
|
|
362
|
+
console.log('\n📋 Operation Preview:');
|
|
363
|
+
console.log(`App: ${preview.app}`);
|
|
364
|
+
console.log(`Config: ${preview.configPath}`);
|
|
365
|
+
console.log(`Servers to import: ${preview.serversToImport.join(', ') || 'none'}`);
|
|
366
|
+
console.log(`Replacement URL: ${preview.replacementUrl}`);
|
|
367
|
+
console.log(`Backup will be created: ${preview.backupPath}`);
|
|
368
|
+
if (preview.risks.length > 0) {
|
|
369
|
+
console.log('\n⚠️ Potential Issues:');
|
|
370
|
+
preview.risks.forEach((risk) => console.log(` - ${risk}`));
|
|
371
|
+
}
|
|
372
|
+
const rl = readline.createInterface({
|
|
373
|
+
input: process.stdin,
|
|
374
|
+
output: process.stdout,
|
|
375
|
+
});
|
|
376
|
+
return new Promise((resolve) => {
|
|
377
|
+
rl.question('\nAre you sure you want to proceed? (y/n): ', (answer) => {
|
|
378
|
+
rl.close();
|
|
379
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=consolidate.js.map
|