@nordsym/apiclaw 2.1.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 (185) 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/funnel-client.d.ts +24 -0
  5. package/dist/funnel-client.d.ts.map +1 -0
  6. package/dist/funnel-client.js +131 -0
  7. package/dist/funnel-client.js.map +1 -0
  8. package/dist/funnel.test.d.ts +2 -0
  9. package/dist/funnel.test.d.ts.map +1 -0
  10. package/dist/funnel.test.js +145 -0
  11. package/dist/funnel.test.js.map +1 -0
  12. package/dist/gateway-client.d.ts.map +1 -1
  13. package/dist/gateway-client.js +24 -2
  14. package/dist/gateway-client.js.map +1 -1
  15. package/dist/index.bundled.js +61263 -0
  16. package/dist/index.js +161 -74
  17. package/dist/index.js.map +1 -1
  18. package/dist/postinstall.d.ts +0 -5
  19. package/dist/postinstall.d.ts.map +1 -1
  20. package/dist/postinstall.js +24 -3
  21. package/dist/postinstall.js.map +1 -1
  22. package/dist/registration-guard.d.ts +29 -0
  23. package/dist/registration-guard.d.ts.map +1 -0
  24. package/dist/registration-guard.js +87 -0
  25. package/dist/registration-guard.js.map +1 -0
  26. package/package.json +7 -2
  27. package/.claude/settings.local.json +0 -9
  28. package/.env.prod +0 -1
  29. package/apiclaw-README.md +0 -494
  30. package/convex/_generated/api.d.ts +0 -137
  31. package/convex/_generated/api.js +0 -23
  32. package/convex/_generated/dataModel.d.ts +0 -60
  33. package/convex/_generated/server.d.ts +0 -143
  34. package/convex/_generated/server.js +0 -93
  35. package/convex/adminActivate.ts +0 -53
  36. package/convex/adminStats.ts +0 -306
  37. package/convex/agents.ts +0 -939
  38. package/convex/analytics.ts +0 -187
  39. package/convex/apiKeys.ts +0 -220
  40. package/convex/backfillAnalytics.ts +0 -272
  41. package/convex/backfillSearchLogs.ts +0 -35
  42. package/convex/billing.ts +0 -834
  43. package/convex/capabilities.ts +0 -157
  44. package/convex/chains.ts +0 -1318
  45. package/convex/credits.ts +0 -211
  46. package/convex/crons.ts +0 -50
  47. package/convex/debugFilestackLogs.ts +0 -16
  48. package/convex/debugGetToken.ts +0 -18
  49. package/convex/directCall.ts +0 -713
  50. package/convex/earnProgress.ts +0 -753
  51. package/convex/email.ts +0 -329
  52. package/convex/feedback.ts +0 -265
  53. package/convex/http.ts +0 -3430
  54. package/convex/inbound.ts +0 -32
  55. package/convex/logs.ts +0 -701
  56. package/convex/migrateFilestack.ts +0 -81
  57. package/convex/migratePartnersProd.ts +0 -174
  58. package/convex/migratePratham.ts +0 -126
  59. package/convex/migrateProviderWorkspaces.ts +0 -175
  60. package/convex/mou.ts +0 -91
  61. package/convex/providerKeys.ts +0 -289
  62. package/convex/providers.ts +0 -1135
  63. package/convex/purchases.ts +0 -183
  64. package/convex/ratelimit.ts +0 -104
  65. package/convex/schema.ts +0 -869
  66. package/convex/searchLogs.ts +0 -265
  67. package/convex/seedAPILayerAPIs.ts +0 -191
  68. package/convex/seedDirectCallConfigs.ts +0 -336
  69. package/convex/seedPratham.ts +0 -149
  70. package/convex/spendAlerts.ts +0 -442
  71. package/convex/stripeActions.ts +0 -607
  72. package/convex/teams.ts +0 -243
  73. package/convex/telemetry.ts +0 -81
  74. package/convex/tsconfig.json +0 -25
  75. package/convex/updateAPIStatus.ts +0 -44
  76. package/convex/usage.ts +0 -260
  77. package/convex/usageReports.ts +0 -357
  78. package/convex/waitlist.ts +0 -55
  79. package/convex/webhooks.ts +0 -494
  80. package/convex/workspaceSettings.ts +0 -143
  81. package/convex/workspaces.ts +0 -1331
  82. package/convex.json +0 -3
  83. package/direct-test.mjs +0 -51
  84. package/email-templates/filestack-provider-outreach.html +0 -162
  85. package/email-templates/partnership-template.html +0 -116
  86. package/email-templates/pratham-draft-preview.txt +0 -57
  87. package/email-templates/pratham-partnership-draft.html +0 -141
  88. package/reports/APIClaw-Session-Report-2026-04-05.pdf +0 -0
  89. package/reports/pipeline/PIPELINE-REPORT.json +0 -153
  90. package/reports/pipeline/acquire_apisguru.json +0 -17
  91. package/reports/pipeline/capabilities.json +0 -38
  92. package/reports/pipeline/discover_azure_recursive.json +0 -1551
  93. package/reports/pipeline/discover_github.json +0 -25
  94. package/reports/pipeline/discover_github_repos.json +0 -49
  95. package/reports/pipeline/discover_swaggerhub.json +0 -24
  96. package/reports/pipeline/discover_well_known.json +0 -23
  97. package/reports/pipeline/fetch_specs.json +0 -19
  98. package/reports/pipeline/generate_providers.json +0 -14
  99. package/reports/pipeline/match_registry.json +0 -11
  100. package/reports/pipeline/parse_specs.json +0 -17
  101. package/reports/pipeline/promote_candidates.json +0 -34
  102. package/reports/pipeline/validate.json +0 -30
  103. package/reports/pipeline/validate_smoke_details.json +0 -3835
  104. package/reports/session-report-2026-04-05.html +0 -433
  105. package/seed-apis-direct.mjs +0 -106
  106. package/src/access-control.ts +0 -174
  107. package/src/adapters/base.ts +0 -364
  108. package/src/adapters/claude-desktop.ts +0 -41
  109. package/src/adapters/cline.ts +0 -88
  110. package/src/adapters/continue.ts +0 -91
  111. package/src/adapters/cursor.ts +0 -43
  112. package/src/adapters/custom.ts +0 -188
  113. package/src/adapters/detect.ts +0 -202
  114. package/src/adapters/index.ts +0 -47
  115. package/src/adapters/windsurf.ts +0 -44
  116. package/src/bin-http.ts +0 -45
  117. package/src/bin.ts +0 -34
  118. package/src/capability-router.ts +0 -331
  119. package/src/chainExecutor.ts +0 -730
  120. package/src/chainResolver.test.ts +0 -246
  121. package/src/chainResolver.ts +0 -658
  122. package/src/cli/commands/demo.ts +0 -109
  123. package/src/cli/commands/doctor.ts +0 -435
  124. package/src/cli/commands/index.ts +0 -9
  125. package/src/cli/commands/login.ts +0 -203
  126. package/src/cli/commands/mcp-install.ts +0 -373
  127. package/src/cli/commands/restore.ts +0 -333
  128. package/src/cli/commands/setup.ts +0 -297
  129. package/src/cli/commands/uninstall.ts +0 -240
  130. package/src/cli/index.ts +0 -148
  131. package/src/cli.ts +0 -370
  132. package/src/confirmation.ts +0 -296
  133. package/src/credentials.ts +0 -455
  134. package/src/credits.ts +0 -329
  135. package/src/crypto.ts +0 -75
  136. package/src/discovery.ts +0 -568
  137. package/src/enterprise/env.ts +0 -156
  138. package/src/enterprise/index.ts +0 -7
  139. package/src/enterprise/script-generator.ts +0 -481
  140. package/src/execute-dynamic.ts +0 -617
  141. package/src/execute.ts +0 -2386
  142. package/src/gateway-client.ts +0 -192
  143. package/src/hivr-whitelist.ts +0 -110
  144. package/src/http-api.ts +0 -286
  145. package/src/http-server-minimal.ts +0 -154
  146. package/src/index.ts +0 -2611
  147. package/src/intelligent-gateway.ts +0 -339
  148. package/src/mcp-analytics.ts +0 -156
  149. package/src/metered.ts +0 -149
  150. package/src/open-apis-generated.ts +0 -157
  151. package/src/open-apis.ts +0 -558
  152. package/src/postinstall.ts +0 -18
  153. package/src/product-whitelist.ts +0 -246
  154. package/src/proxy.ts +0 -36
  155. package/src/session.ts +0 -129
  156. package/src/stripe.ts +0 -497
  157. package/src/telemetry.ts +0 -71
  158. package/src/test.ts +0 -135
  159. package/src/types/convex-api.d.ts +0 -20
  160. package/src/types/convex-api.ts +0 -21
  161. package/src/types.ts +0 -109
  162. package/src/ui/colors.ts +0 -219
  163. package/src/ui/errors.ts +0 -394
  164. package/src/ui/index.ts +0 -17
  165. package/src/ui/prompts.ts +0 -390
  166. package/src/ui/spinner.ts +0 -325
  167. package/src/utils/backup.ts +0 -224
  168. package/src/utils/config.ts +0 -318
  169. package/src/utils/os.ts +0 -124
  170. package/src/utils/paths.ts +0 -203
  171. package/src/webhook.ts +0 -107
  172. package/test-10-working.cjs +0 -97
  173. package/test-14-final.cjs +0 -96
  174. package/test-actual-handlers.ts +0 -92
  175. package/test-apilayer-all-14.ts +0 -249
  176. package/test-apilayer-fixed.ts +0 -248
  177. package/test-direct-endpoints.ts +0 -174
  178. package/test-exact-endpoints.ts +0 -144
  179. package/test-final.ts +0 -83
  180. package/test-full-routing.ts +0 -100
  181. package/test-handlers-correct.ts +0 -217
  182. package/test-numverify-key.ts +0 -41
  183. package/test-via-handlers.ts +0 -92
  184. package/test-worldnews.mjs +0 -26
  185. 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
- }