@nordsym/apiclaw 1.7.2 ā 1.7.4
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/convex/_generated/api.d.ts +115 -0
- package/convex/_generated/api.js +23 -0
- package/convex/_generated/dataModel.d.ts +60 -0
- package/convex/_generated/server.d.ts +143 -0
- package/convex/_generated/server.js +93 -0
- package/convex/adminActivate.d.ts +3 -0
- package/convex/adminActivate.d.ts.map +1 -0
- package/convex/adminActivate.js +47 -0
- package/convex/adminActivate.js.map +1 -0
- package/convex/adminActivate.ts +54 -0
- package/convex/adminStats.d.ts +3 -0
- package/convex/adminStats.d.ts.map +1 -0
- package/convex/adminStats.js +42 -0
- package/convex/adminStats.js.map +1 -0
- package/convex/adminStats.ts +44 -0
- package/convex/agents.d.ts +76 -0
- package/convex/agents.d.ts.map +1 -0
- package/convex/agents.js +699 -0
- package/convex/agents.js.map +1 -0
- package/convex/agents.ts +814 -0
- package/convex/analytics.d.ts +5 -0
- package/convex/analytics.d.ts.map +1 -0
- package/convex/analytics.js +166 -0
- package/convex/analytics.js.map +1 -0
- package/convex/analytics.ts +186 -0
- package/convex/billing.d.ts +88 -0
- package/convex/billing.d.ts.map +1 -0
- package/convex/billing.js +655 -0
- package/convex/billing.js.map +1 -0
- package/convex/billing.ts +791 -0
- package/convex/capabilities.d.ts +9 -0
- package/convex/capabilities.d.ts.map +1 -0
- package/convex/capabilities.js +145 -0
- package/convex/capabilities.js.map +1 -0
- package/convex/capabilities.ts +157 -0
- package/convex/chains.d.ts +68 -0
- package/convex/chains.d.ts.map +1 -0
- package/convex/chains.js +1105 -0
- package/convex/chains.js.map +1 -0
- package/convex/chains.ts +1318 -0
- package/convex/credits.d.ts +25 -0
- package/convex/credits.d.ts.map +1 -0
- package/convex/credits.js +186 -0
- package/convex/credits.js.map +1 -0
- package/convex/credits.ts +211 -0
- package/convex/crons.d.ts +3 -0
- package/convex/crons.d.ts.map +1 -0
- package/convex/crons.js +17 -0
- package/convex/crons.js.map +1 -0
- package/convex/crons.ts +28 -0
- package/convex/directCall.d.ts +72 -0
- package/convex/directCall.d.ts.map +1 -0
- package/convex/directCall.js +627 -0
- package/convex/directCall.js.map +1 -0
- package/convex/directCall.ts +678 -0
- package/convex/earnProgress.d.ts +58 -0
- package/convex/earnProgress.d.ts.map +1 -0
- package/convex/earnProgress.js +649 -0
- package/convex/earnProgress.js.map +1 -0
- package/convex/earnProgress.ts +753 -0
- package/convex/email.d.ts +14 -0
- package/convex/email.d.ts.map +1 -0
- package/convex/email.js +300 -0
- package/convex/email.js.map +1 -0
- package/convex/email.ts +329 -0
- package/convex/feedback.d.ts +7 -0
- package/convex/feedback.d.ts.map +1 -0
- package/convex/feedback.js +227 -0
- package/convex/feedback.js.map +1 -0
- package/convex/feedback.ts +265 -0
- package/convex/http.d.ts +3 -0
- package/convex/http.d.ts.map +1 -0
- package/convex/http.js +1405 -0
- package/convex/http.js.map +1 -0
- package/convex/http.ts +1577 -0
- package/convex/inbound.d.ts +2 -0
- package/convex/inbound.d.ts.map +1 -0
- package/convex/inbound.js +32 -0
- package/convex/inbound.js.map +1 -0
- package/convex/inbound.ts +32 -0
- package/convex/logs.d.ts +38 -0
- package/convex/logs.d.ts.map +1 -0
- package/convex/logs.js +487 -0
- package/convex/logs.js.map +1 -0
- package/convex/logs.ts +550 -0
- package/convex/mou.d.ts +6 -0
- package/convex/mou.d.ts.map +1 -0
- package/convex/mou.js +82 -0
- package/convex/mou.js.map +1 -0
- package/convex/mou.ts +91 -0
- package/convex/providerKeys.d.ts +31 -0
- package/convex/providerKeys.d.ts.map +1 -0
- package/convex/providerKeys.js +257 -0
- package/convex/providerKeys.js.map +1 -0
- package/convex/providerKeys.ts +289 -0
- package/convex/providers.d.ts +32 -0
- package/convex/providers.d.ts.map +1 -0
- package/convex/providers.js +814 -0
- package/convex/providers.js.map +1 -0
- package/convex/providers.ts +909 -0
- package/convex/purchases.d.ts +7 -0
- package/convex/purchases.d.ts.map +1 -0
- package/convex/purchases.js +157 -0
- package/convex/purchases.js.map +1 -0
- package/convex/purchases.ts +183 -0
- package/convex/ratelimit.d.ts +4 -0
- package/convex/ratelimit.d.ts.map +1 -0
- package/convex/ratelimit.js +91 -0
- package/convex/ratelimit.js.map +1 -0
- package/convex/ratelimit.ts +104 -0
- package/convex/schema.ts +802 -0
- package/convex/searchLogs.d.ts +4 -0
- package/convex/searchLogs.d.ts.map +1 -0
- package/convex/searchLogs.js +129 -0
- package/convex/searchLogs.js.map +1 -0
- package/convex/searchLogs.ts +146 -0
- package/convex/seedAPILayerAPIs.d.ts +7 -0
- package/convex/seedAPILayerAPIs.d.ts.map +1 -0
- package/convex/seedAPILayerAPIs.js +177 -0
- package/convex/seedAPILayerAPIs.js.map +1 -0
- package/convex/seedAPILayerAPIs.ts +191 -0
- package/convex/seedDirectCallConfigs.d.ts +2 -0
- package/convex/seedDirectCallConfigs.d.ts.map +1 -0
- package/convex/seedDirectCallConfigs.js +324 -0
- package/convex/seedDirectCallConfigs.js.map +1 -0
- package/convex/seedDirectCallConfigs.ts +336 -0
- package/convex/seedPratham.d.ts +6 -0
- package/convex/seedPratham.d.ts.map +1 -0
- package/convex/seedPratham.js +150 -0
- package/convex/seedPratham.js.map +1 -0
- package/convex/seedPratham.ts +161 -0
- package/convex/spendAlerts.d.ts +36 -0
- package/convex/spendAlerts.d.ts.map +1 -0
- package/convex/spendAlerts.js +380 -0
- package/convex/spendAlerts.js.map +1 -0
- package/convex/spendAlerts.ts +442 -0
- package/convex/stripeActions.d.ts +19 -0
- package/convex/stripeActions.d.ts.map +1 -0
- package/convex/stripeActions.js +411 -0
- package/convex/stripeActions.js.map +1 -0
- package/convex/stripeActions.ts +512 -0
- package/convex/teams.d.ts +21 -0
- package/convex/teams.d.ts.map +1 -0
- package/convex/teams.js +215 -0
- package/convex/teams.js.map +1 -0
- package/convex/teams.ts +243 -0
- package/convex/telemetry.d.ts +4 -0
- package/convex/telemetry.d.ts.map +1 -0
- package/convex/telemetry.js +74 -0
- package/convex/telemetry.js.map +1 -0
- package/convex/telemetry.ts +81 -0
- package/convex/tsconfig.json +25 -0
- package/convex/updateAPIStatus.d.ts +6 -0
- package/convex/updateAPIStatus.d.ts.map +1 -0
- package/convex/updateAPIStatus.js +40 -0
- package/convex/updateAPIStatus.js.map +1 -0
- package/convex/updateAPIStatus.ts +45 -0
- package/convex/usage.d.ts +27 -0
- package/convex/usage.d.ts.map +1 -0
- package/convex/usage.js +229 -0
- package/convex/usage.js.map +1 -0
- package/convex/usage.ts +260 -0
- package/convex/waitlist.d.ts +4 -0
- package/convex/waitlist.d.ts.map +1 -0
- package/convex/waitlist.js +49 -0
- package/convex/waitlist.js.map +1 -0
- package/convex/waitlist.ts +55 -0
- package/convex/webhooks.d.ts +12 -0
- package/convex/webhooks.d.ts.map +1 -0
- package/convex/webhooks.js +410 -0
- package/convex/webhooks.js.map +1 -0
- package/convex/webhooks.ts +494 -0
- package/convex/workspaces.d.ts +31 -0
- package/convex/workspaces.d.ts.map +1 -0
- package/convex/workspaces.js +975 -0
- package/convex/workspaces.js.map +1 -0
- package/convex/workspaces.ts +1130 -0
- package/dist/bin.js +0 -0
- package/dist/capability-router.js +1 -1
- package/dist/capability-router.js.map +1 -1
- package/dist/execute.d.ts +2 -0
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +18 -4
- package/dist/execute.js.map +1 -1
- package/dist/http-api.js +1 -1
- package/dist/http-api.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-analytics.d.ts +32 -0
- package/dist/mcp-analytics.d.ts.map +1 -0
- package/dist/mcp-analytics.js +130 -0
- package/dist/mcp-analytics.js.map +1 -0
- package/package.json +1 -1
- package/dist/chain-types.d.ts +0 -187
- package/dist/chain-types.d.ts.map +0 -1
- package/dist/chain-types.js +0 -33
- package/dist/chain-types.js.map +0 -1
- package/dist/registry/apis.json.bak +0 -248811
- package/dist/src/bin.js +0 -17
- package/dist/src/capability-router.js +0 -240
- package/dist/src/chainExecutor.js +0 -451
- package/dist/src/chainResolver.js +0 -518
- package/dist/src/cli/commands/doctor.js +0 -324
- package/dist/src/cli/commands/mcp-install.js +0 -255
- package/dist/src/cli/commands/restore.js +0 -259
- package/dist/src/cli/commands/setup.js +0 -205
- package/dist/src/cli/commands/uninstall.js +0 -188
- package/dist/src/cli/index.js +0 -111
- package/dist/src/cli.js +0 -302
- package/dist/src/confirmation.js +0 -240
- package/dist/src/credentials.js +0 -357
- package/dist/src/credits.js +0 -260
- package/dist/src/crypto.js +0 -66
- package/dist/src/discovery.js +0 -504
- package/dist/src/enterprise/env.js +0 -123
- package/dist/src/enterprise/script-generator.js +0 -460
- package/dist/src/execute-dynamic.js +0 -473
- package/dist/src/execute.js +0 -1727
- package/dist/src/index.js +0 -2062
- package/dist/src/metered.js +0 -80
- package/dist/src/open-apis.js +0 -276
- package/dist/src/proxy.js +0 -28
- package/dist/src/session.js +0 -86
- package/dist/src/stripe.js +0 -407
- package/dist/src/telemetry.js +0 -49
- package/dist/src/types.js +0 -2
- package/dist/src/utils/backup.js +0 -181
- package/dist/src/utils/config.js +0 -220
- package/dist/src/utils/os.js +0 -105
- package/dist/src/utils/paths.js +0 -159
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Doctor Command
|
|
3
|
-
* Health check for APIClaw installation and MCP client configurations
|
|
4
|
-
*/
|
|
5
|
-
import { existsSync } from 'fs';
|
|
6
|
-
import { execSync } from 'child_process';
|
|
7
|
-
import { getAllClients, getClientConfig } from '../../utils/paths.js';
|
|
8
|
-
import { readConfig, hasApiclawConfig } from '../../utils/config.js';
|
|
9
|
-
import { getApiUrl, readEnvConfig, ENV_VARS } from '../../enterprise/env.js';
|
|
10
|
-
/**
|
|
11
|
-
* Check Node.js availability and version
|
|
12
|
-
*/
|
|
13
|
-
function checkNode() {
|
|
14
|
-
try {
|
|
15
|
-
const version = execSync('node --version', { encoding: 'utf-8' }).trim();
|
|
16
|
-
const major = parseInt(version.replace('v', '').split('.')[0], 10);
|
|
17
|
-
if (major < 18) {
|
|
18
|
-
return {
|
|
19
|
-
category: 'System',
|
|
20
|
-
name: 'Node.js',
|
|
21
|
-
status: 'warn',
|
|
22
|
-
message: `${version} (recommend v18+)`,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
return {
|
|
26
|
-
category: 'System',
|
|
27
|
-
name: 'Node.js',
|
|
28
|
-
status: 'pass',
|
|
29
|
-
message: version,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
return {
|
|
34
|
-
category: 'System',
|
|
35
|
-
name: 'Node.js',
|
|
36
|
-
status: 'fail',
|
|
37
|
-
message: 'Not found',
|
|
38
|
-
details: 'Node.js is required. Install from https://nodejs.org',
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Check npm availability
|
|
44
|
-
*/
|
|
45
|
-
function checkNpm() {
|
|
46
|
-
try {
|
|
47
|
-
const version = execSync('npm --version', { encoding: 'utf-8' }).trim();
|
|
48
|
-
return {
|
|
49
|
-
category: 'System',
|
|
50
|
-
name: 'npm',
|
|
51
|
-
status: 'pass',
|
|
52
|
-
message: `v${version}`,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return {
|
|
57
|
-
category: 'System',
|
|
58
|
-
name: 'npm',
|
|
59
|
-
status: 'fail',
|
|
60
|
-
message: 'Not found',
|
|
61
|
-
details: 'npm is required for npx to work',
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Check npx availability
|
|
67
|
-
*/
|
|
68
|
-
function checkNpx() {
|
|
69
|
-
try {
|
|
70
|
-
execSync('npx --version', { encoding: 'utf-8', stdio: 'pipe' });
|
|
71
|
-
return {
|
|
72
|
-
category: 'System',
|
|
73
|
-
name: 'npx',
|
|
74
|
-
status: 'pass',
|
|
75
|
-
message: 'Available',
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
return {
|
|
80
|
-
category: 'System',
|
|
81
|
-
name: 'npx',
|
|
82
|
-
status: 'fail',
|
|
83
|
-
message: 'Not found',
|
|
84
|
-
details: 'npx is required for MCP server execution',
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Check MCP client configuration
|
|
90
|
-
*/
|
|
91
|
-
function checkClient(client, serverName = 'apiclaw') {
|
|
92
|
-
const config = getClientConfig(client);
|
|
93
|
-
const configPath = config.configPath;
|
|
94
|
-
// Check if config file exists
|
|
95
|
-
if (!existsSync(configPath)) {
|
|
96
|
-
// Check if config directory exists (client might be installed but not configured)
|
|
97
|
-
const dirExists = existsSync(config.configDir);
|
|
98
|
-
if (dirExists) {
|
|
99
|
-
return {
|
|
100
|
-
category: 'MCP Clients',
|
|
101
|
-
name: config.displayName,
|
|
102
|
-
status: 'warn',
|
|
103
|
-
message: 'Installed but not configured',
|
|
104
|
-
details: `Config file: ${configPath}`,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
category: 'MCP Clients',
|
|
109
|
-
name: config.displayName,
|
|
110
|
-
status: 'skip',
|
|
111
|
-
message: 'Not installed',
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
// Read and check config
|
|
115
|
-
const readResult = readConfig(configPath);
|
|
116
|
-
if (!readResult.success) {
|
|
117
|
-
return {
|
|
118
|
-
category: 'MCP Clients',
|
|
119
|
-
name: config.displayName,
|
|
120
|
-
status: 'fail',
|
|
121
|
-
message: 'Invalid config',
|
|
122
|
-
details: readResult.error,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
// Check if APIClaw is configured
|
|
126
|
-
if (readResult.config && hasApiclawConfig(readResult.config, serverName)) {
|
|
127
|
-
return {
|
|
128
|
-
category: 'MCP Clients',
|
|
129
|
-
name: config.displayName,
|
|
130
|
-
status: 'pass',
|
|
131
|
-
message: 'Configured',
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
return {
|
|
135
|
-
category: 'MCP Clients',
|
|
136
|
-
name: config.displayName,
|
|
137
|
-
status: 'warn',
|
|
138
|
-
message: 'APIClaw not configured',
|
|
139
|
-
details: `Run: npx @nordsym/apiclaw setup --client ${client}`,
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Check API connectivity
|
|
144
|
-
*/
|
|
145
|
-
async function checkConnectivity() {
|
|
146
|
-
const apiUrl = getApiUrl();
|
|
147
|
-
const convexUrl = process.env.CONVEX_URL || 'https://brilliant-puffin-712.eu-west-1.convex.cloud';
|
|
148
|
-
const candidates = [
|
|
149
|
-
`${apiUrl}/health`,
|
|
150
|
-
'https://apiclaw.nordsym.com',
|
|
151
|
-
`${convexUrl.replace('.cloud', '.site')}/workspace/poll`,
|
|
152
|
-
];
|
|
153
|
-
const failures = [];
|
|
154
|
-
for (const testUrl of candidates) {
|
|
155
|
-
try {
|
|
156
|
-
const controller = new AbortController();
|
|
157
|
-
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
158
|
-
const response = await fetch(testUrl, {
|
|
159
|
-
method: 'GET',
|
|
160
|
-
signal: controller.signal,
|
|
161
|
-
});
|
|
162
|
-
clearTimeout(timeout);
|
|
163
|
-
// Any HTTP response proves network + host reachability.
|
|
164
|
-
if (response.ok) {
|
|
165
|
-
return {
|
|
166
|
-
category: 'Connectivity',
|
|
167
|
-
name: 'API Server',
|
|
168
|
-
status: 'pass',
|
|
169
|
-
message: `${testUrl} reachable`,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
if (testUrl.includes('/workspace/poll') && response.status === 400) {
|
|
173
|
-
return {
|
|
174
|
-
category: 'Connectivity',
|
|
175
|
-
name: 'API Server',
|
|
176
|
-
status: 'pass',
|
|
177
|
-
message: `${testUrl} reachable (auth endpoint responding)`,
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
failures.push(`${testUrl} -> HTTP ${response.status}`);
|
|
181
|
-
}
|
|
182
|
-
catch (error) {
|
|
183
|
-
const reason = error instanceof Error ? error.message : 'Unknown error';
|
|
184
|
-
failures.push(`${testUrl} -> ${reason}`);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return {
|
|
188
|
-
category: 'Connectivity',
|
|
189
|
-
name: 'API Server',
|
|
190
|
-
status: 'skip',
|
|
191
|
-
message: 'Could not reach API (offline or DNS/TLS issue?)',
|
|
192
|
-
details: failures.join(' | '),
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Check environment variables
|
|
197
|
-
*/
|
|
198
|
-
function checkEnvVars() {
|
|
199
|
-
const envConfig = readEnvConfig();
|
|
200
|
-
const results = [];
|
|
201
|
-
if (envConfig.workspace) {
|
|
202
|
-
results.push({
|
|
203
|
-
category: 'Environment',
|
|
204
|
-
name: ENV_VARS.WORKSPACE,
|
|
205
|
-
status: 'pass',
|
|
206
|
-
message: envConfig.workspace,
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
if (envConfig.apiUrl) {
|
|
210
|
-
results.push({
|
|
211
|
-
category: 'Environment',
|
|
212
|
-
name: ENV_VARS.API_URL,
|
|
213
|
-
status: 'pass',
|
|
214
|
-
message: envConfig.apiUrl,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
if (envConfig.disableTelemetry) {
|
|
218
|
-
results.push({
|
|
219
|
-
category: 'Environment',
|
|
220
|
-
name: ENV_VARS.DISABLE_TELEMETRY,
|
|
221
|
-
status: 'pass',
|
|
222
|
-
message: 'true',
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
return results;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Run all health checks
|
|
229
|
-
*/
|
|
230
|
-
export async function runDoctor(options = {}) {
|
|
231
|
-
const checks = [];
|
|
232
|
-
const serverName = options.serverName || 'apiclaw';
|
|
233
|
-
// System checks
|
|
234
|
-
checks.push(checkNode());
|
|
235
|
-
checks.push(checkNpm());
|
|
236
|
-
checks.push(checkNpx());
|
|
237
|
-
// Client checks
|
|
238
|
-
for (const client of getAllClients()) {
|
|
239
|
-
checks.push(checkClient(client, serverName));
|
|
240
|
-
}
|
|
241
|
-
// Connectivity check
|
|
242
|
-
checks.push(await checkConnectivity());
|
|
243
|
-
// Environment checks
|
|
244
|
-
checks.push(...checkEnvVars());
|
|
245
|
-
// Calculate health status
|
|
246
|
-
const failures = checks.filter(c => c.status === 'fail');
|
|
247
|
-
const warnings = checks.filter(c => c.status === 'warn');
|
|
248
|
-
const passes = checks.filter(c => c.status === 'pass');
|
|
249
|
-
let healthy = failures.length === 0;
|
|
250
|
-
let summary;
|
|
251
|
-
if (failures.length > 0) {
|
|
252
|
-
summary = `${failures.length} issue(s) found`;
|
|
253
|
-
}
|
|
254
|
-
else if (warnings.length > 0) {
|
|
255
|
-
summary = `All systems operational (${warnings.length} warning(s))`;
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
summary = 'All systems operational ā';
|
|
259
|
-
}
|
|
260
|
-
return { healthy, checks, summary };
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Format doctor results for display
|
|
264
|
-
*/
|
|
265
|
-
export function formatDoctorOutput(result) {
|
|
266
|
-
const lines = [];
|
|
267
|
-
lines.push('');
|
|
268
|
-
lines.push('š APIClaw Health Check');
|
|
269
|
-
lines.push('========================');
|
|
270
|
-
lines.push('');
|
|
271
|
-
// Group checks by category
|
|
272
|
-
const categories = new Map();
|
|
273
|
-
for (const check of result.checks) {
|
|
274
|
-
const existing = categories.get(check.category) || [];
|
|
275
|
-
existing.push(check);
|
|
276
|
-
categories.set(check.category, existing);
|
|
277
|
-
}
|
|
278
|
-
// Format each category
|
|
279
|
-
for (const [category, checks] of categories) {
|
|
280
|
-
// Skip empty categories
|
|
281
|
-
if (checks.length === 0)
|
|
282
|
-
continue;
|
|
283
|
-
lines.push(`${category}:`);
|
|
284
|
-
for (const check of checks) {
|
|
285
|
-
const icon = getStatusIcon(check.status);
|
|
286
|
-
lines.push(` ${icon} ${check.name} - ${check.message}`);
|
|
287
|
-
if (check.details && (check.status === 'fail' || check.status === 'warn')) {
|
|
288
|
-
lines.push(` ${check.details}`);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
lines.push('');
|
|
292
|
-
}
|
|
293
|
-
// Summary
|
|
294
|
-
lines.push(`Status: ${result.summary}`);
|
|
295
|
-
lines.push('');
|
|
296
|
-
return lines.join('\n');
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Get icon for status
|
|
300
|
-
*/
|
|
301
|
-
function getStatusIcon(status) {
|
|
302
|
-
switch (status) {
|
|
303
|
-
case 'pass': return 'ā';
|
|
304
|
-
case 'fail': return 'ā';
|
|
305
|
-
case 'warn': return 'ā ';
|
|
306
|
-
case 'skip': return 'ā';
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Doctor command handler
|
|
311
|
-
*/
|
|
312
|
-
export async function doctorCommand(options = {}) {
|
|
313
|
-
const result = await runDoctor(options);
|
|
314
|
-
if (options.json) {
|
|
315
|
-
console.log(JSON.stringify(result, null, 2));
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
console.log(formatDoctorOutput(result));
|
|
319
|
-
}
|
|
320
|
-
// Exit with error code if unhealthy
|
|
321
|
-
if (!result.healthy) {
|
|
322
|
-
process.exit(1);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Install Command
|
|
3
|
-
* Simple, focused command to install APIClaw into MCP config files
|
|
4
|
-
* Supports Claude Desktop and Claude Code
|
|
5
|
-
*/
|
|
6
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
-
import { dirname, join } from 'path';
|
|
8
|
-
import { platform, homedir } from 'os';
|
|
9
|
-
import chalk from 'chalk';
|
|
10
|
-
/**
|
|
11
|
-
* Detect operating system
|
|
12
|
-
*/
|
|
13
|
-
function detectOS() {
|
|
14
|
-
const os = platform();
|
|
15
|
-
switch (os) {
|
|
16
|
-
case 'darwin': return 'mac';
|
|
17
|
-
case 'win32': return 'win';
|
|
18
|
-
default: return 'linux';
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Get home directory
|
|
23
|
-
*/
|
|
24
|
-
function getHome() {
|
|
25
|
-
return homedir();
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Get config paths for supported clients
|
|
29
|
-
*/
|
|
30
|
-
function getClientConfigs() {
|
|
31
|
-
const os = detectOS();
|
|
32
|
-
const home = getHome();
|
|
33
|
-
const clients = [
|
|
34
|
-
{
|
|
35
|
-
name: 'claude-desktop',
|
|
36
|
-
displayName: 'Claude Desktop',
|
|
37
|
-
configKey: 'mcpServers',
|
|
38
|
-
getConfigPath: () => {
|
|
39
|
-
switch (os) {
|
|
40
|
-
case 'mac':
|
|
41
|
-
return join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
|
|
42
|
-
case 'win':
|
|
43
|
-
return join(process.env.APPDATA || join(home, 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json');
|
|
44
|
-
case 'linux':
|
|
45
|
-
return join(home, '.config', 'Claude', 'claude_desktop_config.json');
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
name: 'claude-code',
|
|
51
|
-
displayName: 'Claude Code',
|
|
52
|
-
configKey: 'mcpServers',
|
|
53
|
-
getConfigPath: () => {
|
|
54
|
-
// Claude Code uses ~/.claude.json on all platforms
|
|
55
|
-
return join(home, '.claude.json');
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
return clients;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* APIClaw MCP server configuration
|
|
63
|
-
*/
|
|
64
|
-
const APICLAW_CONFIG = {
|
|
65
|
-
command: 'npx',
|
|
66
|
-
args: ['-y', '@nordsym/apiclaw', 'serve'],
|
|
67
|
-
};
|
|
68
|
-
/**
|
|
69
|
-
* Read JSON config file
|
|
70
|
-
*/
|
|
71
|
-
function readConfig(path) {
|
|
72
|
-
try {
|
|
73
|
-
if (!existsSync(path)) {
|
|
74
|
-
return { success: true, config: {}, isNew: true };
|
|
75
|
-
}
|
|
76
|
-
const content = readFileSync(path, 'utf-8');
|
|
77
|
-
if (!content.trim()) {
|
|
78
|
-
return { success: true, config: {}, isNew: true };
|
|
79
|
-
}
|
|
80
|
-
return { success: true, config: JSON.parse(content), isNew: false };
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
return {
|
|
84
|
-
success: false,
|
|
85
|
-
config: null,
|
|
86
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Write JSON config file with backup
|
|
92
|
-
*/
|
|
93
|
-
function writeConfig(path, config, createBackup = true) {
|
|
94
|
-
try {
|
|
95
|
-
const dir = dirname(path);
|
|
96
|
-
if (!existsSync(dir)) {
|
|
97
|
-
mkdirSync(dir, { recursive: true });
|
|
98
|
-
}
|
|
99
|
-
// Create backup if file exists
|
|
100
|
-
if (createBackup && existsSync(path)) {
|
|
101
|
-
const backupPath = `${path}.backup.${Date.now()}.json`;
|
|
102
|
-
const existing = readFileSync(path, 'utf-8');
|
|
103
|
-
writeFileSync(backupPath, existing, 'utf-8');
|
|
104
|
-
}
|
|
105
|
-
writeFileSync(path, JSON.stringify(config, null, 2), 'utf-8');
|
|
106
|
-
return { success: true };
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
return {
|
|
110
|
-
success: false,
|
|
111
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Install APIClaw into a client config
|
|
117
|
-
*/
|
|
118
|
-
function installToClient(client, dryRun) {
|
|
119
|
-
const configPath = client.getConfigPath();
|
|
120
|
-
// Read existing config
|
|
121
|
-
const readResult = readConfig(configPath);
|
|
122
|
-
if (!readResult.success) {
|
|
123
|
-
return { success: false, message: `Failed to read config: ${readResult.error}` };
|
|
124
|
-
}
|
|
125
|
-
const config = readResult.config;
|
|
126
|
-
// Initialize mcpServers if not present
|
|
127
|
-
if (!config.mcpServers) {
|
|
128
|
-
config.mcpServers = {};
|
|
129
|
-
}
|
|
130
|
-
// Check if already installed
|
|
131
|
-
if (config.mcpServers.apiclaw) {
|
|
132
|
-
return { success: true, message: 'Already installed', skipped: true };
|
|
133
|
-
}
|
|
134
|
-
// Add APIClaw config
|
|
135
|
-
config.mcpServers.apiclaw = APICLAW_CONFIG;
|
|
136
|
-
if (dryRun) {
|
|
137
|
-
console.log(chalk.cyan(`\n Would add to ${configPath}:`));
|
|
138
|
-
console.log(chalk.gray(JSON.stringify({ apiclaw: APICLAW_CONFIG }, null, 4)));
|
|
139
|
-
return { success: true, message: 'Dry run - no changes made', skipped: true };
|
|
140
|
-
}
|
|
141
|
-
// Write config
|
|
142
|
-
const writeResult = writeConfig(configPath, config);
|
|
143
|
-
if (!writeResult.success) {
|
|
144
|
-
return { success: false, message: `Failed to write config: ${writeResult.error}` };
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
success: true,
|
|
148
|
-
message: readResult.isNew ? 'Created new config' : 'Updated config'
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Main mcp-install command handler
|
|
153
|
-
*/
|
|
154
|
-
export async function mcpInstallCommand(options) {
|
|
155
|
-
const os = detectOS();
|
|
156
|
-
const osName = os === 'mac' ? 'macOS' : os === 'win' ? 'Windows' : 'Linux';
|
|
157
|
-
console.log(chalk.bold('\nš¦ APIClaw MCP Install\n'));
|
|
158
|
-
console.log(`Platform: ${osName}\n`);
|
|
159
|
-
const clients = getClientConfigs();
|
|
160
|
-
let targetClients = clients;
|
|
161
|
-
// Filter to specific client if requested
|
|
162
|
-
if (options.client) {
|
|
163
|
-
const normalizedClient = options.client.toLowerCase().replace(/[_\s]/g, '-');
|
|
164
|
-
const aliases = {
|
|
165
|
-
'claude': 'claude-desktop',
|
|
166
|
-
'claude-desktop': 'claude-desktop',
|
|
167
|
-
'claudedesktop': 'claude-desktop',
|
|
168
|
-
'desktop': 'claude-desktop',
|
|
169
|
-
'code': 'claude-code',
|
|
170
|
-
'claude-code': 'claude-code',
|
|
171
|
-
'claudecode': 'claude-code',
|
|
172
|
-
};
|
|
173
|
-
const targetName = aliases[normalizedClient];
|
|
174
|
-
if (!targetName) {
|
|
175
|
-
console.log(chalk.red(`ā Unknown client: ${options.client}`));
|
|
176
|
-
console.log(' Supported: claude-desktop, claude-code');
|
|
177
|
-
process.exit(1);
|
|
178
|
-
}
|
|
179
|
-
targetClients = clients.filter(c => c.name === targetName);
|
|
180
|
-
}
|
|
181
|
-
// Detect which clients exist
|
|
182
|
-
console.log('š Detecting MCP clients...\n');
|
|
183
|
-
const detectedClients = [];
|
|
184
|
-
for (const client of targetClients) {
|
|
185
|
-
const configPath = client.getConfigPath();
|
|
186
|
-
const configDir = dirname(configPath);
|
|
187
|
-
const exists = existsSync(configPath) || existsSync(configDir);
|
|
188
|
-
const icon = exists ? chalk.green('ā') : chalk.gray('ā');
|
|
189
|
-
const status = exists ? 'found' : 'not found';
|
|
190
|
-
console.log(` ${icon} ${client.displayName} ${status}`);
|
|
191
|
-
if (exists) {
|
|
192
|
-
detectedClients.push(client);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
console.log('');
|
|
196
|
-
if (detectedClients.length === 0) {
|
|
197
|
-
console.log(chalk.yellow('ā ļø No MCP clients detected.'));
|
|
198
|
-
console.log(' Install Claude Desktop or Claude Code first.\n');
|
|
199
|
-
process.exit(0);
|
|
200
|
-
}
|
|
201
|
-
// Install to each detected client
|
|
202
|
-
let successCount = 0;
|
|
203
|
-
let skipCount = 0;
|
|
204
|
-
let failCount = 0;
|
|
205
|
-
for (const client of detectedClients) {
|
|
206
|
-
const result = installToClient(client, options.dryRun || false);
|
|
207
|
-
if (result.success) {
|
|
208
|
-
if (result.skipped) {
|
|
209
|
-
skipCount++;
|
|
210
|
-
console.log(chalk.yellow(`āļø ${client.displayName}: ${result.message}`));
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
successCount++;
|
|
214
|
-
console.log(chalk.green(`ā ${client.displayName}: ${result.message}`));
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
failCount++;
|
|
219
|
-
console.log(chalk.red(`ā ${client.displayName}: ${result.message}`));
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
// Summary
|
|
223
|
-
console.log('\n' + 'ā'.repeat(50));
|
|
224
|
-
if (failCount === 0) {
|
|
225
|
-
if (options.dryRun) {
|
|
226
|
-
console.log(chalk.cyan('\nā
Dry run complete! Run without --dry-run to apply changes.\n'));
|
|
227
|
-
}
|
|
228
|
-
else if (successCount > 0) {
|
|
229
|
-
console.log(chalk.green('\nā
APIClaw installed successfully!\n'));
|
|
230
|
-
console.log(chalk.bold('What you get:\n'));
|
|
231
|
-
console.log(chalk.cyan(' š Search') + ' 22,000+ APIs to discover');
|
|
232
|
-
console.log(chalk.cyan(' š Open APIs') + ' 1,600 free APIs');
|
|
233
|
-
console.log(chalk.cyan(' š Direct Call') + ' 1,500+ premium (APIClaw manages keys)');
|
|
234
|
-
console.log('');
|
|
235
|
-
console.log('Next:');
|
|
236
|
-
console.log(' 1. Restart your MCP client');
|
|
237
|
-
console.log(' 2. Try: "Find weather APIs"');
|
|
238
|
-
console.log('');
|
|
239
|
-
console.log('Docs: https://apiclaw.com/docs\n');
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
console.log(chalk.yellow('\nā
APIClaw already installed in all clients.\n'));
|
|
243
|
-
console.log(chalk.bold('What you have:\n'));
|
|
244
|
-
console.log(chalk.cyan(' š Search') + ' 22,000+ APIs to discover');
|
|
245
|
-
console.log(chalk.cyan(' š Open APIs') + ' 1,600 free APIs');
|
|
246
|
-
console.log(chalk.cyan(' š Direct Call') + ' 1,500+ premium (APIClaw manages keys)');
|
|
247
|
-
console.log('');
|
|
248
|
-
console.log('Run with --force to reinstall (coming soon).\n');
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
console.log(chalk.red(`\nā ļø Installation completed with ${failCount} error(s).\n`));
|
|
253
|
-
process.exit(1);
|
|
254
|
-
}
|
|
255
|
-
}
|