@nordsym/apiclaw 2.2.0 → 2.2.1

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.
Files changed (176) hide show
  1. package/README.md +15 -2
  2. package/dist/bin-http.js +0 -0
  3. package/dist/bin.bundled.js +79288 -0
  4. package/dist/gateway-client.d.ts.map +1 -1
  5. package/dist/gateway-client.js +24 -2
  6. package/dist/gateway-client.js.map +1 -1
  7. package/dist/index.bundled.js +61263 -0
  8. package/dist/index.js +2 -2
  9. package/dist/index.js.map +1 -1
  10. package/package.json +7 -2
  11. package/.claude/settings.local.json +0 -13
  12. package/.env.prod +0 -1
  13. package/apiclaw-README.md +0 -494
  14. package/convex/_generated/api.d.ts +0 -145
  15. package/convex/_generated/api.js +0 -23
  16. package/convex/_generated/dataModel.d.ts +0 -60
  17. package/convex/_generated/server.d.ts +0 -143
  18. package/convex/_generated/server.js +0 -93
  19. package/convex/_listWorkspaces.ts +0 -13
  20. package/convex/adminActivate.ts +0 -53
  21. package/convex/adminStats.ts +0 -306
  22. package/convex/agents.ts +0 -939
  23. package/convex/analytics.ts +0 -187
  24. package/convex/apiKeys.ts +0 -220
  25. package/convex/backfillAnalytics.ts +0 -272
  26. package/convex/backfillSearchLogs.ts +0 -35
  27. package/convex/billing.ts +0 -834
  28. package/convex/capabilities.ts +0 -157
  29. package/convex/chains.ts +0 -1318
  30. package/convex/credits.ts +0 -211
  31. package/convex/crons.ts +0 -65
  32. package/convex/debugFilestackLogs.ts +0 -16
  33. package/convex/debugGetToken.ts +0 -18
  34. package/convex/directCall.ts +0 -713
  35. package/convex/earnProgress.ts +0 -753
  36. package/convex/email.ts +0 -329
  37. package/convex/feedback.ts +0 -265
  38. package/convex/funnel.ts +0 -431
  39. package/convex/guards.ts +0 -174
  40. package/convex/http.ts +0 -3756
  41. package/convex/inbound.ts +0 -32
  42. package/convex/logs.ts +0 -701
  43. package/convex/migrateFilestack.ts +0 -81
  44. package/convex/migratePartnersProd.ts +0 -174
  45. package/convex/migratePratham.ts +0 -126
  46. package/convex/migrateProviderWorkspaces.ts +0 -175
  47. package/convex/mou.ts +0 -91
  48. package/convex/nurture.ts +0 -355
  49. package/convex/providerKeys.ts +0 -289
  50. package/convex/providers.ts +0 -1135
  51. package/convex/purchases.ts +0 -183
  52. package/convex/ratelimit.ts +0 -104
  53. package/convex/schema.ts +0 -926
  54. package/convex/searchLogs.ts +0 -265
  55. package/convex/seedAPILayerAPIs.ts +0 -191
  56. package/convex/seedDirectCallConfigs.ts +0 -336
  57. package/convex/seedPratham.ts +0 -149
  58. package/convex/spendAlerts.ts +0 -442
  59. package/convex/stripeActions.ts +0 -607
  60. package/convex/teams.ts +0 -243
  61. package/convex/telemetry.ts +0 -81
  62. package/convex/tsconfig.json +0 -25
  63. package/convex/updateAPIStatus.ts +0 -44
  64. package/convex/usage.ts +0 -260
  65. package/convex/usageReports.ts +0 -357
  66. package/convex/waitlist.ts +0 -55
  67. package/convex/webhooks.ts +0 -494
  68. package/convex/workspaceSettings.ts +0 -143
  69. package/convex/workspaces.ts +0 -1331
  70. package/convex.json +0 -3
  71. package/direct-test.mjs +0 -51
  72. package/email-templates/filestack-provider-outreach.html +0 -162
  73. package/email-templates/partnership-template.html +0 -116
  74. package/email-templates/pratham-draft-preview.txt +0 -57
  75. package/email-templates/pratham-partnership-draft.html +0 -141
  76. package/reports/APIClaw-Session-Report-2026-04-05.pdf +0 -0
  77. package/reports/pipeline/PIPELINE-REPORT.json +0 -153
  78. package/reports/pipeline/acquire_apisguru.json +0 -17
  79. package/reports/pipeline/capabilities.json +0 -38
  80. package/reports/pipeline/discover_azure_recursive.json +0 -1551
  81. package/reports/pipeline/discover_github.json +0 -25
  82. package/reports/pipeline/discover_github_repos.json +0 -49
  83. package/reports/pipeline/discover_swaggerhub.json +0 -24
  84. package/reports/pipeline/discover_well_known.json +0 -23
  85. package/reports/pipeline/fetch_specs.json +0 -19
  86. package/reports/pipeline/generate_providers.json +0 -14
  87. package/reports/pipeline/match_registry.json +0 -11
  88. package/reports/pipeline/parse_specs.json +0 -17
  89. package/reports/pipeline/promote_candidates.json +0 -34
  90. package/reports/pipeline/validate.json +0 -30
  91. package/reports/pipeline/validate_smoke_details.json +0 -3835
  92. package/reports/session-report-2026-04-05.html +0 -433
  93. package/seed-apis-direct.mjs +0 -106
  94. package/src/access-control.ts +0 -174
  95. package/src/adapters/base.ts +0 -364
  96. package/src/adapters/claude-desktop.ts +0 -41
  97. package/src/adapters/cline.ts +0 -88
  98. package/src/adapters/continue.ts +0 -91
  99. package/src/adapters/cursor.ts +0 -43
  100. package/src/adapters/custom.ts +0 -188
  101. package/src/adapters/detect.ts +0 -202
  102. package/src/adapters/index.ts +0 -47
  103. package/src/adapters/windsurf.ts +0 -44
  104. package/src/bin-http.ts +0 -45
  105. package/src/bin.ts +0 -34
  106. package/src/capability-router.ts +0 -331
  107. package/src/chainExecutor.ts +0 -730
  108. package/src/chainResolver.test.ts +0 -246
  109. package/src/chainResolver.ts +0 -658
  110. package/src/cli/commands/demo.ts +0 -109
  111. package/src/cli/commands/doctor.ts +0 -435
  112. package/src/cli/commands/index.ts +0 -9
  113. package/src/cli/commands/login.ts +0 -203
  114. package/src/cli/commands/mcp-install.ts +0 -373
  115. package/src/cli/commands/restore.ts +0 -333
  116. package/src/cli/commands/setup.ts +0 -297
  117. package/src/cli/commands/uninstall.ts +0 -240
  118. package/src/cli/index.ts +0 -148
  119. package/src/cli.ts +0 -370
  120. package/src/confirmation.ts +0 -296
  121. package/src/credentials.ts +0 -455
  122. package/src/credits.ts +0 -329
  123. package/src/crypto.ts +0 -75
  124. package/src/discovery.ts +0 -568
  125. package/src/enterprise/env.ts +0 -156
  126. package/src/enterprise/index.ts +0 -7
  127. package/src/enterprise/script-generator.ts +0 -481
  128. package/src/execute-dynamic.ts +0 -617
  129. package/src/execute.ts +0 -2386
  130. package/src/funnel-client.ts +0 -168
  131. package/src/funnel.test.ts +0 -187
  132. package/src/gateway-client.ts +0 -192
  133. package/src/hivr-whitelist.ts +0 -110
  134. package/src/http-api.ts +0 -286
  135. package/src/http-server-minimal.ts +0 -154
  136. package/src/index.ts +0 -2702
  137. package/src/intelligent-gateway.ts +0 -339
  138. package/src/mcp-analytics.ts +0 -156
  139. package/src/metered.ts +0 -149
  140. package/src/open-apis-generated.ts +0 -157
  141. package/src/open-apis.ts +0 -558
  142. package/src/postinstall.ts +0 -40
  143. package/src/product-whitelist.ts +0 -246
  144. package/src/proxy.ts +0 -36
  145. package/src/registration-guard.ts +0 -117
  146. package/src/session.ts +0 -129
  147. package/src/stripe.ts +0 -497
  148. package/src/telemetry.ts +0 -71
  149. package/src/test.ts +0 -135
  150. package/src/types/convex-api.d.ts +0 -20
  151. package/src/types/convex-api.ts +0 -21
  152. package/src/types.ts +0 -109
  153. package/src/ui/colors.ts +0 -219
  154. package/src/ui/errors.ts +0 -394
  155. package/src/ui/index.ts +0 -17
  156. package/src/ui/prompts.ts +0 -390
  157. package/src/ui/spinner.ts +0 -325
  158. package/src/utils/backup.ts +0 -224
  159. package/src/utils/config.ts +0 -318
  160. package/src/utils/os.ts +0 -124
  161. package/src/utils/paths.ts +0 -203
  162. package/src/webhook.ts +0 -107
  163. package/test-10-working.cjs +0 -97
  164. package/test-14-final.cjs +0 -96
  165. package/test-actual-handlers.ts +0 -92
  166. package/test-apilayer-all-14.ts +0 -249
  167. package/test-apilayer-fixed.ts +0 -248
  168. package/test-direct-endpoints.ts +0 -174
  169. package/test-exact-endpoints.ts +0 -144
  170. package/test-final.ts +0 -83
  171. package/test-full-routing.ts +0 -100
  172. package/test-handlers-correct.ts +0 -217
  173. package/test-numverify-key.ts +0 -41
  174. package/test-via-handlers.ts +0 -92
  175. package/test-worldnews.mjs +0 -26
  176. package/tsconfig.json +0 -20
@@ -1,224 +0,0 @@
1
- /**
2
- * Backup System
3
- * Handles timestamped backups of config files with automatic cleanup
4
- */
5
-
6
- import { existsSync, mkdirSync, readdirSync, unlinkSync, copyFileSync, statSync } from 'fs';
7
- import { dirname, basename, join, extname } from 'path';
8
-
9
- const MAX_BACKUPS = 5;
10
- const BACKUP_PATTERN = /\.backup\.(\d+)\.json$/;
11
-
12
- export interface BackupResult {
13
- success: boolean;
14
- backupPath: string | null;
15
- error?: string;
16
- }
17
-
18
- export interface BackupInfo {
19
- path: string;
20
- timestamp: number;
21
- date: Date;
22
- filename: string;
23
- }
24
-
25
- /**
26
- * Generate backup filename with timestamp
27
- */
28
- function generateBackupFilename(originalPath: string): string {
29
- const dir = dirname(originalPath);
30
- const base = basename(originalPath, '.json');
31
- const timestamp = Date.now();
32
-
33
- return join(dir, `${base}.backup.${timestamp}.json`);
34
- }
35
-
36
- /**
37
- * Create a backup of a config file
38
- */
39
- export function createBackup(configPath: string): BackupResult {
40
- try {
41
- // Check if original file exists
42
- if (!existsSync(configPath)) {
43
- return {
44
- success: true,
45
- backupPath: null,
46
- // No backup needed if file doesn't exist
47
- };
48
- }
49
-
50
- // Ensure backup directory exists
51
- const dir = dirname(configPath);
52
- if (!existsSync(dir)) {
53
- mkdirSync(dir, { recursive: true });
54
- }
55
-
56
- // Generate backup path
57
- const backupPath = generateBackupFilename(configPath);
58
-
59
- // Copy file
60
- copyFileSync(configPath, backupPath);
61
-
62
- // Cleanup old backups
63
- cleanupOldBackups(configPath);
64
-
65
- return {
66
- success: true,
67
- backupPath,
68
- };
69
- } catch (error) {
70
- return {
71
- success: false,
72
- backupPath: null,
73
- error: error instanceof Error ? error.message : 'Unknown error creating backup',
74
- };
75
- }
76
- }
77
-
78
- /**
79
- * List all backups for a config file
80
- */
81
- export function listBackups(configPath: string): BackupInfo[] {
82
- const dir = dirname(configPath);
83
- const baseName = basename(configPath, '.json');
84
-
85
- if (!existsSync(dir)) {
86
- return [];
87
- }
88
-
89
- const files = readdirSync(dir);
90
- const backups: BackupInfo[] = [];
91
-
92
- for (const file of files) {
93
- // Match backup pattern: {basename}.backup.{timestamp}.json
94
- const match = file.match(new RegExp(`^${escapeRegex(baseName)}\\.backup\\.(\\d+)\\.json$`));
95
-
96
- if (match) {
97
- const timestamp = parseInt(match[1], 10);
98
- const fullPath = join(dir, file);
99
-
100
- backups.push({
101
- path: fullPath,
102
- timestamp,
103
- date: new Date(timestamp),
104
- filename: file,
105
- });
106
- }
107
- }
108
-
109
- // Sort by timestamp, newest first
110
- return backups.sort((a, b) => b.timestamp - a.timestamp);
111
- }
112
-
113
- /**
114
- * Get the most recent backup
115
- */
116
- export function getLatestBackup(configPath: string): BackupInfo | null {
117
- const backups = listBackups(configPath);
118
- return backups[0] || null;
119
- }
120
-
121
- /**
122
- * Cleanup old backups, keeping only MAX_BACKUPS most recent
123
- */
124
- export function cleanupOldBackups(configPath: string): number {
125
- const backups = listBackups(configPath);
126
- let deleted = 0;
127
-
128
- // Keep only the first MAX_BACKUPS
129
- const toDelete = backups.slice(MAX_BACKUPS);
130
-
131
- for (const backup of toDelete) {
132
- try {
133
- unlinkSync(backup.path);
134
- deleted++;
135
- } catch {
136
- // Ignore deletion errors
137
- }
138
- }
139
-
140
- return deleted;
141
- }
142
-
143
- /**
144
- * Restore from a backup
145
- */
146
- export function restoreBackup(backupPath: string, targetPath: string): BackupResult {
147
- try {
148
- if (!existsSync(backupPath)) {
149
- return {
150
- success: false,
151
- backupPath: null,
152
- error: `Backup file not found: ${backupPath}`,
153
- };
154
- }
155
-
156
- // Backup current file before restoring
157
- const preRestoreBackup = createBackup(targetPath);
158
-
159
- // Copy backup to target
160
- copyFileSync(backupPath, targetPath);
161
-
162
- return {
163
- success: true,
164
- backupPath: preRestoreBackup.backupPath,
165
- };
166
- } catch (error) {
167
- return {
168
- success: false,
169
- backupPath: null,
170
- error: error instanceof Error ? error.message : 'Unknown error restoring backup',
171
- };
172
- }
173
- }
174
-
175
- /**
176
- * Restore from the most recent backup
177
- */
178
- export function restoreLatestBackup(configPath: string): BackupResult {
179
- const latest = getLatestBackup(configPath);
180
-
181
- if (!latest) {
182
- return {
183
- success: false,
184
- backupPath: null,
185
- error: 'No backups found',
186
- };
187
- }
188
-
189
- return restoreBackup(latest.path, configPath);
190
- }
191
-
192
- /**
193
- * Format backup info for display
194
- */
195
- export function formatBackupInfo(backup: BackupInfo): string {
196
- const date = backup.date.toLocaleString();
197
- return `${backup.filename} (${date})`;
198
- }
199
-
200
- /**
201
- * Escape regex special characters
202
- */
203
- function escapeRegex(str: string): string {
204
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
205
- }
206
-
207
- /**
208
- * Delete all backups for a config file
209
- */
210
- export function deleteAllBackups(configPath: string): number {
211
- const backups = listBackups(configPath);
212
- let deleted = 0;
213
-
214
- for (const backup of backups) {
215
- try {
216
- unlinkSync(backup.path);
217
- deleted++;
218
- } catch {
219
- // Ignore deletion errors
220
- }
221
- }
222
-
223
- return deleted;
224
- }
@@ -1,318 +0,0 @@
1
- /**
2
- * Config Management
3
- * Handles JSON read/write/merge operations for MCP config files
4
- */
5
-
6
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
7
- import { dirname } from 'path';
8
- import { createBackup } from './backup.js';
9
-
10
- export interface MCPServerConfig {
11
- command: string;
12
- args?: string[];
13
- env?: Record<string, string>;
14
- }
15
-
16
- export interface MCPConfig {
17
- mcpServers?: Record<string, MCPServerConfig>;
18
- [key: string]: unknown;
19
- }
20
-
21
- // Continue uses array format for mcpServers
22
- export interface ContinueServerConfig {
23
- name: string;
24
- command: string;
25
- args?: string[];
26
- env?: Record<string, string>;
27
- }
28
-
29
- export interface ContinueConfig {
30
- mcpServers?: ContinueServerConfig[];
31
- [key: string]: unknown;
32
- }
33
-
34
- export interface ConfigReadResult {
35
- success: boolean;
36
- config: MCPConfig | ContinueConfig | null;
37
- error?: string;
38
- isNew?: boolean;
39
- }
40
-
41
- export interface ConfigWriteResult {
42
- success: boolean;
43
- error?: string;
44
- backupPath?: string | null;
45
- }
46
-
47
- export interface MergeOptions {
48
- force?: boolean;
49
- workspace?: string;
50
- serverName?: string;
51
- clientName?: string; // MCP client identifier (e.g., "cursor", "claude-desktop")
52
- }
53
-
54
- /**
55
- * Read and parse a JSON config file
56
- */
57
- export function readConfig(configPath: string): ConfigReadResult {
58
- try {
59
- if (!existsSync(configPath)) {
60
- return {
61
- success: true,
62
- config: {},
63
- isNew: true,
64
- };
65
- }
66
-
67
- const content = readFileSync(configPath, 'utf-8');
68
-
69
- // Handle empty files
70
- if (!content.trim()) {
71
- return {
72
- success: true,
73
- config: {},
74
- isNew: true,
75
- };
76
- }
77
-
78
- const config = JSON.parse(content);
79
-
80
- return {
81
- success: true,
82
- config,
83
- isNew: false,
84
- };
85
- } catch (error) {
86
- if (error instanceof SyntaxError) {
87
- return {
88
- success: false,
89
- config: null,
90
- error: `Invalid JSON in config file: ${error.message}`,
91
- };
92
- }
93
-
94
- return {
95
- success: false,
96
- config: null,
97
- error: error instanceof Error ? error.message : 'Unknown error reading config',
98
- };
99
- }
100
- }
101
-
102
- /**
103
- * Write config to file with backup
104
- */
105
- export function writeConfig(
106
- configPath: string,
107
- config: MCPConfig | ContinueConfig,
108
- createBackupFirst = true
109
- ): ConfigWriteResult {
110
- try {
111
- // Ensure directory exists
112
- const dir = dirname(configPath);
113
- if (!existsSync(dir)) {
114
- mkdirSync(dir, { recursive: true });
115
- }
116
-
117
- // Create backup if file exists and backup requested
118
- let backupPath: string | null = null;
119
- if (createBackupFirst && existsSync(configPath)) {
120
- const backupResult = createBackup(configPath);
121
- if (!backupResult.success) {
122
- return {
123
- success: false,
124
- error: `Failed to create backup: ${backupResult.error}`,
125
- };
126
- }
127
- backupPath = backupResult.backupPath;
128
- }
129
-
130
- // Validate JSON before writing
131
- const content = JSON.stringify(config, null, 2);
132
- JSON.parse(content); // Validation parse
133
-
134
- // Write file
135
- writeFileSync(configPath, content, 'utf-8');
136
-
137
- return {
138
- success: true,
139
- backupPath,
140
- };
141
- } catch (error) {
142
- return {
143
- success: false,
144
- error: error instanceof Error ? error.message : 'Unknown error writing config',
145
- };
146
- }
147
- }
148
-
149
- /**
150
- * Deep merge two objects
151
- */
152
- export function deepMerge<T extends Record<string, unknown>>(
153
- target: T,
154
- source: Partial<T>
155
- ): T {
156
- const result = { ...target };
157
-
158
- for (const key in source) {
159
- const sourceValue = source[key];
160
- const targetValue = result[key];
161
-
162
- if (
163
- sourceValue !== null &&
164
- typeof sourceValue === 'object' &&
165
- !Array.isArray(sourceValue) &&
166
- targetValue !== null &&
167
- typeof targetValue === 'object' &&
168
- !Array.isArray(targetValue)
169
- ) {
170
- // Recursively merge objects
171
- result[key] = deepMerge(
172
- targetValue as Record<string, unknown>,
173
- sourceValue as Record<string, unknown>
174
- ) as T[Extract<keyof T, string>];
175
- } else {
176
- // Overwrite value
177
- result[key] = sourceValue as T[Extract<keyof T, string>];
178
- }
179
- }
180
-
181
- return result;
182
- }
183
-
184
- /**
185
- * Generate APIClaw MCP server configuration
186
- */
187
- export function generateApiclawConfig(options: MergeOptions = {}): MCPServerConfig {
188
- const config: MCPServerConfig = {
189
- command: 'npx',
190
- args: ['-y', '@nordsym/apiclaw'],
191
- };
192
-
193
- const env: Record<string, string> = {};
194
- if (options.workspace) env.APICLAW_WORKSPACE = options.workspace;
195
- if (options.clientName) env.APICLAW_MCP_CLIENT = options.clientName;
196
-
197
- if (Object.keys(env).length > 0) {
198
- config.env = env;
199
- }
200
-
201
- return config;
202
- }
203
-
204
- /**
205
- * Generate APIClaw config for Continue (array format)
206
- */
207
- export function generateApiclawContinueConfig(options: MergeOptions = {}): ContinueServerConfig {
208
- const config: ContinueServerConfig = {
209
- name: options.serverName || 'apiclaw',
210
- command: 'npx',
211
- args: ['-y', '@nordsym/apiclaw'],
212
- };
213
-
214
- if (options.workspace) {
215
- config.env = {
216
- APICLAW_WORKSPACE: options.workspace,
217
- };
218
- }
219
-
220
- return config;
221
- }
222
-
223
- /**
224
- * Check if APIClaw is already configured
225
- */
226
- export function hasApiclawConfig(config: MCPConfig | ContinueConfig, serverName = 'apiclaw'): boolean {
227
- // Handle Continue's array format
228
- if (Array.isArray((config as ContinueConfig).mcpServers)) {
229
- const continueConfig = config as ContinueConfig;
230
- return continueConfig.mcpServers?.some(s => s.name === serverName) || false;
231
- }
232
-
233
- // Handle standard object format
234
- const mcpConfig = config as MCPConfig;
235
- return mcpConfig.mcpServers?.[serverName] !== undefined;
236
- }
237
-
238
- /**
239
- * Merge APIClaw config into existing config (standard format)
240
- */
241
- export function mergeApiclawConfig(
242
- existingConfig: MCPConfig,
243
- options: MergeOptions = {}
244
- ): MCPConfig {
245
- const serverName = options.serverName || 'apiclaw';
246
- const apiclawConfig = generateApiclawConfig(options);
247
-
248
- return deepMerge(existingConfig, {
249
- mcpServers: {
250
- ...existingConfig.mcpServers,
251
- [serverName]: apiclawConfig,
252
- },
253
- });
254
- }
255
-
256
- /**
257
- * Merge APIClaw config into Continue config (array format)
258
- */
259
- export function mergeApiclawContinueConfig(
260
- existingConfig: ContinueConfig,
261
- options: MergeOptions = {}
262
- ): ContinueConfig {
263
- const serverName = options.serverName || 'apiclaw';
264
- const apiclawConfig = generateApiclawContinueConfig(options);
265
-
266
- const existingServers = existingConfig.mcpServers || [];
267
-
268
- // Check if already exists
269
- const existingIndex = existingServers.findIndex(s => s.name === serverName);
270
-
271
- let newServers: ContinueServerConfig[];
272
- if (existingIndex >= 0) {
273
- // Update existing
274
- newServers = [...existingServers];
275
- newServers[existingIndex] = apiclawConfig;
276
- } else {
277
- // Add new
278
- newServers = [...existingServers, apiclawConfig];
279
- }
280
-
281
- return {
282
- ...existingConfig,
283
- mcpServers: newServers,
284
- };
285
- }
286
-
287
- /**
288
- * Remove APIClaw from config
289
- */
290
- export function removeApiclawConfig(
291
- config: MCPConfig | ContinueConfig,
292
- serverName = 'apiclaw'
293
- ): MCPConfig | ContinueConfig {
294
- // Handle Continue's array format
295
- if (Array.isArray((config as ContinueConfig).mcpServers)) {
296
- const continueConfig = config as ContinueConfig;
297
- return {
298
- ...continueConfig,
299
- mcpServers: continueConfig.mcpServers?.filter(s => s.name !== serverName),
300
- };
301
- }
302
-
303
- // Handle standard object format
304
- const mcpConfig = config as MCPConfig;
305
- const { [serverName]: _, ...remainingServers } = mcpConfig.mcpServers || {};
306
-
307
- return {
308
- ...mcpConfig,
309
- mcpServers: remainingServers,
310
- };
311
- }
312
-
313
- /**
314
- * Detect if config uses Continue's array format
315
- */
316
- export function isContinueFormat(config: MCPConfig | ContinueConfig): config is ContinueConfig {
317
- return Array.isArray((config as ContinueConfig).mcpServers);
318
- }
package/src/utils/os.ts DELETED
@@ -1,124 +0,0 @@
1
- /**
2
- * OS Detection Utility
3
- * Detects the operating system and provides platform-specific helpers
4
- */
5
-
6
- import { platform, homedir } from 'os';
7
- import { join } from 'path';
8
-
9
- export type Platform = 'mac' | 'win' | 'linux';
10
-
11
- /**
12
- * Detect the current operating system
13
- */
14
- export function detectOS(): Platform {
15
- const os = platform();
16
-
17
- switch (os) {
18
- case 'darwin':
19
- return 'mac';
20
- case 'win32':
21
- return 'win';
22
- case 'linux':
23
- return 'linux';
24
- default:
25
- // Default to linux for other Unix-like systems
26
- return 'linux';
27
- }
28
- }
29
-
30
- /**
31
- * Get the home directory for the current user
32
- */
33
- export function getHomeDir(): string {
34
- return homedir();
35
- }
36
-
37
- /**
38
- * Get the app data directory based on OS
39
- * - macOS: ~/Library/Application Support
40
- * - Windows: %APPDATA%
41
- * - Linux: ~/.config
42
- */
43
- export function getAppDataDir(): string {
44
- const home = getHomeDir();
45
- const os = detectOS();
46
-
47
- switch (os) {
48
- case 'mac':
49
- return join(home, 'Library', 'Application Support');
50
- case 'win':
51
- return process.env.APPDATA || join(home, 'AppData', 'Roaming');
52
- case 'linux':
53
- return process.env.XDG_CONFIG_HOME || join(home, '.config');
54
- }
55
- }
56
-
57
- /**
58
- * Get the user profile directory (Windows-specific, falls back to home)
59
- */
60
- export function getUserProfileDir(): string {
61
- return process.env.USERPROFILE || getHomeDir();
62
- }
63
-
64
- /**
65
- * Check if running as root/admin
66
- */
67
- export function isElevated(): boolean {
68
- const os = detectOS();
69
-
70
- if (os === 'win') {
71
- // Windows admin check is more complex, skip for now
72
- return false;
73
- }
74
-
75
- // Unix-like: check if UID is 0
76
- return process.getuid?.() === 0;
77
- }
78
-
79
- /**
80
- * Get OS-specific path separator
81
- */
82
- export function getPathSeparator(): string {
83
- return detectOS() === 'win' ? '\\' : '/';
84
- }
85
-
86
- /**
87
- * Normalize path for current OS
88
- */
89
- export function normalizePath(path: string): string {
90
- const os = detectOS();
91
-
92
- if (os === 'win') {
93
- // Convert forward slashes to backslashes on Windows
94
- return path.replace(/\//g, '\\');
95
- }
96
-
97
- return path;
98
- }
99
-
100
- /**
101
- * Expand ~ to home directory
102
- */
103
- export function expandHome(path: string): string {
104
- if (path.startsWith('~')) {
105
- return join(getHomeDir(), path.slice(1));
106
- }
107
- return path;
108
- }
109
-
110
- /**
111
- * Get OS display name
112
- */
113
- export function getOSDisplayName(): string {
114
- const os = detectOS();
115
-
116
- switch (os) {
117
- case 'mac':
118
- return 'macOS';
119
- case 'win':
120
- return 'Windows';
121
- case 'linux':
122
- return 'Linux';
123
- }
124
- }