@nordsym/apiclaw 1.3.7 → 1.3.8

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 (189) hide show
  1. package/README.md +420 -200
  2. package/convex/_generated/api.d.ts +4 -0
  3. package/convex/agents.ts +403 -0
  4. package/convex/directCall.ts +80 -0
  5. package/convex/earnProgress.ts +753 -0
  6. package/convex/logs.ts +17 -0
  7. package/convex/providerKeys.ts +82 -2
  8. package/convex/schema.ts +71 -2
  9. package/convex/workspaces.ts +84 -2
  10. package/dist/adapters/base.d.ts +112 -0
  11. package/dist/adapters/base.d.ts.map +1 -0
  12. package/dist/adapters/base.js +247 -0
  13. package/dist/adapters/base.js.map +1 -0
  14. package/dist/adapters/claude-desktop.d.ts +12 -0
  15. package/dist/adapters/claude-desktop.d.ts.map +1 -0
  16. package/dist/adapters/claude-desktop.js +36 -0
  17. package/dist/adapters/claude-desktop.js.map +1 -0
  18. package/dist/adapters/cline.d.ts +20 -0
  19. package/dist/adapters/cline.d.ts.map +1 -0
  20. package/dist/adapters/cline.js +77 -0
  21. package/dist/adapters/cline.js.map +1 -0
  22. package/dist/adapters/continue.d.ts +26 -0
  23. package/dist/adapters/continue.d.ts.map +1 -0
  24. package/dist/adapters/continue.js +68 -0
  25. package/dist/adapters/continue.js.map +1 -0
  26. package/dist/adapters/cursor.d.ts +12 -0
  27. package/dist/adapters/cursor.d.ts.map +1 -0
  28. package/dist/adapters/cursor.js +38 -0
  29. package/dist/adapters/cursor.js.map +1 -0
  30. package/dist/adapters/custom.d.ts +47 -0
  31. package/dist/adapters/custom.d.ts.map +1 -0
  32. package/dist/adapters/custom.js +146 -0
  33. package/dist/adapters/custom.js.map +1 -0
  34. package/dist/adapters/detect.d.ts +69 -0
  35. package/dist/adapters/detect.d.ts.map +1 -0
  36. package/dist/adapters/detect.js +158 -0
  37. package/dist/adapters/detect.js.map +1 -0
  38. package/dist/adapters/index.d.ts +21 -0
  39. package/dist/adapters/index.d.ts.map +1 -0
  40. package/dist/adapters/index.js +23 -0
  41. package/dist/adapters/index.js.map +1 -0
  42. package/dist/adapters/windsurf.d.ts +12 -0
  43. package/dist/adapters/windsurf.d.ts.map +1 -0
  44. package/dist/adapters/windsurf.js +39 -0
  45. package/dist/adapters/windsurf.js.map +1 -0
  46. package/dist/bin.d.ts +9 -0
  47. package/dist/bin.d.ts.map +1 -0
  48. package/dist/bin.js +19 -0
  49. package/dist/bin.js.map +1 -0
  50. package/dist/cli/commands/doctor.d.ts +34 -0
  51. package/dist/cli/commands/doctor.d.ts.map +1 -0
  52. package/dist/cli/commands/doctor.js +312 -0
  53. package/dist/cli/commands/doctor.js.map +1 -0
  54. package/dist/cli/commands/index.d.ts +9 -0
  55. package/dist/cli/commands/index.d.ts.map +1 -0
  56. package/dist/cli/commands/index.js +9 -0
  57. package/dist/cli/commands/index.js.map +1 -0
  58. package/dist/cli/commands/restore.d.ts +50 -0
  59. package/dist/cli/commands/restore.d.ts.map +1 -0
  60. package/dist/cli/commands/restore.js +260 -0
  61. package/dist/cli/commands/restore.js.map +1 -0
  62. package/dist/cli/commands/setup.d.ts +19 -0
  63. package/dist/cli/commands/setup.d.ts.map +1 -0
  64. package/dist/cli/commands/setup.js +206 -0
  65. package/dist/cli/commands/setup.js.map +1 -0
  66. package/dist/cli/commands/uninstall.d.ts +37 -0
  67. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  68. package/dist/cli/commands/uninstall.js +189 -0
  69. package/dist/cli/commands/uninstall.js.map +1 -0
  70. package/dist/cli/index.d.ts +7 -0
  71. package/dist/cli/index.d.ts.map +1 -0
  72. package/dist/cli/index.js +97 -0
  73. package/dist/cli/index.js.map +1 -0
  74. package/dist/discovery.d.ts +6 -2
  75. package/dist/discovery.d.ts.map +1 -1
  76. package/dist/discovery.js +296 -2
  77. package/dist/discovery.js.map +1 -1
  78. package/dist/enterprise/env.d.ts +56 -0
  79. package/dist/enterprise/env.d.ts.map +1 -0
  80. package/dist/enterprise/env.js +124 -0
  81. package/dist/enterprise/env.js.map +1 -0
  82. package/dist/enterprise/index.d.ts +7 -0
  83. package/dist/enterprise/index.d.ts.map +1 -0
  84. package/dist/enterprise/index.js +7 -0
  85. package/dist/enterprise/index.js.map +1 -0
  86. package/dist/enterprise/script-generator.d.ts +32 -0
  87. package/dist/enterprise/script-generator.d.ts.map +1 -0
  88. package/dist/enterprise/script-generator.js +461 -0
  89. package/dist/enterprise/script-generator.js.map +1 -0
  90. package/dist/execute.d.ts +21 -0
  91. package/dist/execute.d.ts.map +1 -1
  92. package/dist/execute.js +231 -0
  93. package/dist/execute.js.map +1 -1
  94. package/dist/index.js +79 -7
  95. package/dist/index.js.map +1 -1
  96. package/dist/stripe.d.ts +1 -1
  97. package/dist/stripe.js +1 -1
  98. package/dist/stripe.js.map +1 -1
  99. package/dist/types.d.ts +29 -0
  100. package/dist/types.d.ts.map +1 -1
  101. package/dist/ui/colors.d.ts +111 -0
  102. package/dist/ui/colors.d.ts.map +1 -0
  103. package/dist/ui/colors.js +185 -0
  104. package/dist/ui/colors.js.map +1 -0
  105. package/dist/ui/errors.d.ts +69 -0
  106. package/dist/ui/errors.d.ts.map +1 -0
  107. package/dist/ui/errors.js +334 -0
  108. package/dist/ui/errors.js.map +1 -0
  109. package/dist/ui/index.d.ts +10 -0
  110. package/dist/ui/index.d.ts.map +1 -0
  111. package/dist/ui/index.js +14 -0
  112. package/dist/ui/index.js.map +1 -0
  113. package/dist/ui/prompts.d.ts +88 -0
  114. package/dist/ui/prompts.d.ts.map +1 -0
  115. package/dist/ui/prompts.js +295 -0
  116. package/dist/ui/prompts.js.map +1 -0
  117. package/dist/ui/spinner.d.ts +112 -0
  118. package/dist/ui/spinner.d.ts.map +1 -0
  119. package/dist/ui/spinner.js +229 -0
  120. package/dist/ui/spinner.js.map +1 -0
  121. package/dist/utils/backup.d.ts +48 -0
  122. package/dist/utils/backup.d.ts.map +1 -0
  123. package/dist/utils/backup.js +182 -0
  124. package/dist/utils/backup.js.map +1 -0
  125. package/dist/utils/config.d.ts +80 -0
  126. package/dist/utils/config.d.ts.map +1 -0
  127. package/dist/utils/config.js +221 -0
  128. package/dist/utils/config.js.map +1 -0
  129. package/dist/utils/os.d.ts +45 -0
  130. package/dist/utils/os.d.ts.map +1 -0
  131. package/dist/utils/os.js +106 -0
  132. package/dist/utils/os.js.map +1 -0
  133. package/dist/utils/paths.d.ts +38 -0
  134. package/dist/utils/paths.d.ts.map +1 -0
  135. package/dist/utils/paths.js +160 -0
  136. package/dist/utils/paths.js.map +1 -0
  137. package/docs/PRD-BILLING.md +226 -0
  138. package/docs/PRD-EARN-SYSTEM.md +261 -0
  139. package/docs/PRD-MCP-AUTO-SETUP.md +623 -0
  140. package/docs/enterprise-deployment.md +728 -0
  141. package/landing/next.config.mjs +14 -0
  142. package/landing/public/stats.json +4 -2
  143. package/landing/scripts/generate-stats.js +12 -0
  144. package/landing/src/app/api/workspace-auth/magic-link/route.ts +6 -3
  145. package/landing/src/app/auth/verify/page.tsx +11 -4
  146. package/landing/src/app/docs/page.tsx +1 -1
  147. package/landing/src/app/join/page.tsx +49 -0
  148. package/landing/src/app/login/page.tsx +7 -1
  149. package/landing/src/app/page.tsx +13 -28
  150. package/landing/src/app/providers/register/page.tsx +1 -1
  151. package/landing/src/app/workspace/page.tsx +483 -710
  152. package/landing/src/components/CheckoutButton.tsx +1 -1
  153. package/landing/src/components/EarnCreditsTab.tsx +842 -0
  154. package/landing/src/lib/stats.json +3 -1
  155. package/package.json +9 -2
  156. package/src/adapters/base.ts +363 -0
  157. package/src/adapters/claude-desktop.ts +41 -0
  158. package/src/adapters/cline.ts +88 -0
  159. package/src/adapters/continue.ts +91 -0
  160. package/src/adapters/cursor.ts +43 -0
  161. package/src/adapters/custom.ts +188 -0
  162. package/src/adapters/detect.ts +202 -0
  163. package/src/adapters/index.ts +47 -0
  164. package/src/adapters/windsurf.ts +44 -0
  165. package/src/bin.ts +19 -0
  166. package/src/cli/commands/doctor.ts +367 -0
  167. package/src/cli/commands/index.ts +9 -0
  168. package/src/cli/commands/restore.ts +333 -0
  169. package/src/cli/commands/setup.ts +276 -0
  170. package/src/cli/commands/uninstall.ts +240 -0
  171. package/src/cli/index.ts +107 -0
  172. package/src/discovery.ts +328 -3
  173. package/src/enterprise/env.ts +156 -0
  174. package/src/enterprise/index.ts +7 -0
  175. package/src/enterprise/script-generator.ts +481 -0
  176. package/src/execute.ts +256 -0
  177. package/src/index.ts +85 -7
  178. package/src/stripe.ts +1 -1
  179. package/src/types.ts +32 -0
  180. package/src/ui/colors.ts +219 -0
  181. package/src/ui/errors.ts +394 -0
  182. package/src/ui/index.ts +17 -0
  183. package/src/ui/prompts.ts +390 -0
  184. package/src/ui/spinner.ts +325 -0
  185. package/src/utils/backup.ts +224 -0
  186. package/src/utils/config.ts +315 -0
  187. package/src/utils/os.ts +124 -0
  188. package/src/utils/paths.ts +203 -0
  189. package/landing/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,481 @@
1
+ /**
2
+ * Enterprise Script Generator
3
+ * Generates self-contained deployment scripts for bash and PowerShell
4
+ */
5
+
6
+ import { ApiclawEnvConfig, ENV_VARS, DEFAULT_API_URL } from './env.js';
7
+
8
+ export interface ScriptOptions {
9
+ workspace?: string;
10
+ apiUrl?: string;
11
+ disableTelemetry?: boolean;
12
+ serverName?: string;
13
+ verbose?: boolean;
14
+ }
15
+
16
+ // Env var names as strings for embedding in scripts
17
+ const WORKSPACE_VAR = ENV_VARS.WORKSPACE;
18
+ const API_URL_VAR = ENV_VARS.API_URL;
19
+ const TELEMETRY_VAR = ENV_VARS.DISABLE_TELEMETRY;
20
+
21
+ /**
22
+ * Generate self-contained bash deployment script
23
+ */
24
+ export function generateBashScript(options: ScriptOptions = {}): string {
25
+ const serverName = options.serverName || 'apiclaw';
26
+ const workspaceVal = options.workspace || '';
27
+ const apiUrlVal = options.apiUrl || DEFAULT_API_URL;
28
+ const disableTelemetry = options.disableTelemetry ? 'true' : '';
29
+ const verbose = options.verbose ? '1' : '';
30
+
31
+ return `#!/usr/bin/env bash
32
+ #
33
+ # APIClaw MCP Auto-Setup Script
34
+ # Generated by: npx @nordsym/apiclaw setup --enterprise
35
+ #
36
+ # This script automatically configures APIClaw for all detected MCP clients.
37
+ # Supports: Claude Desktop, Cursor, Windsurf, Cline, Continue
38
+ #
39
+
40
+ set -e
41
+
42
+ # Configuration
43
+ SERVER_NAME="${serverName}"
44
+ WORKSPACE="${workspaceVal}"
45
+ API_URL="${apiUrlVal}"
46
+ DEFAULT_API_URL="${DEFAULT_API_URL}"
47
+ DISABLE_TELEMETRY="${disableTelemetry}"
48
+ VERBOSE="${verbose}"
49
+
50
+ # Environment variable names
51
+ ENV_WORKSPACE="${WORKSPACE_VAR}"
52
+ ENV_API_URL="${API_URL_VAR}"
53
+ ENV_TELEMETRY="${TELEMETRY_VAR}"
54
+
55
+ # Colors
56
+ RED='\\033[0;31m'
57
+ GREEN='\\033[0;32m'
58
+ YELLOW='\\033[1;33m'
59
+ BLUE='\\033[0;34m'
60
+ NC='\\033[0m' # No Color
61
+
62
+ log_info() { echo -e "\${BLUE}ℹ\${NC} $1"; }
63
+ log_success() { echo -e "\${GREEN}✓\${NC} $1"; }
64
+ log_warn() { echo -e "\${YELLOW}⚠\${NC} $1"; }
65
+ log_error() { echo -e "\${RED}✗\${NC} $1"; }
66
+ log_verbose() { [[ -n "$VERBOSE" ]] && echo -e " $1"; }
67
+
68
+ # Detect OS
69
+ detect_os() {
70
+ case "$(uname -s)" in
71
+ Darwin*) echo "mac" ;;
72
+ Linux*) echo "linux" ;;
73
+ MINGW*|MSYS*|CYGWIN*) echo "win" ;;
74
+ *) echo "linux" ;;
75
+ esac
76
+ }
77
+
78
+ OS=$(detect_os)
79
+ HOME_DIR="$HOME"
80
+
81
+ # Set paths based on OS
82
+ case "$OS" in
83
+ mac)
84
+ APP_DATA="$HOME_DIR/Library/Application Support"
85
+ ;;
86
+ linux)
87
+ APP_DATA="\${XDG_CONFIG_HOME:-$HOME_DIR/.config}"
88
+ ;;
89
+ win)
90
+ APP_DATA="\${APPDATA:-$HOME_DIR/AppData/Roaming}"
91
+ ;;
92
+ esac
93
+
94
+ echo ""
95
+ echo "🔧 APIClaw MCP Auto-Setup"
96
+ echo "========================="
97
+ echo ""
98
+ log_info "Detected OS: $OS"
99
+
100
+ # Check for Node.js
101
+ if ! command -v node &> /dev/null; then
102
+ log_error "Node.js is required but not installed."
103
+ exit 1
104
+ fi
105
+ log_success "Node.js $(node --version) found"
106
+
107
+ # Check for npx
108
+ if ! command -v npx &> /dev/null; then
109
+ log_error "npx is required but not installed."
110
+ exit 1
111
+ fi
112
+ log_success "npx available"
113
+
114
+ # Generate APIClaw server config JSON
115
+ generate_config() {
116
+ local env_block=""
117
+
118
+ if [[ -n "$WORKSPACE" ]] || [[ -n "$API_URL" && "$API_URL" != "$DEFAULT_API_URL" ]] || [[ -n "$DISABLE_TELEMETRY" ]]; then
119
+ env_block='"env": {'
120
+ local first=true
121
+
122
+ if [[ -n "$WORKSPACE" ]]; then
123
+ env_block+="\\"$ENV_WORKSPACE\\": \\"$WORKSPACE\\""
124
+ first=false
125
+ fi
126
+
127
+ if [[ -n "$API_URL" && "$API_URL" != "$DEFAULT_API_URL" ]]; then
128
+ [[ "$first" == "false" ]] && env_block+=','
129
+ env_block+="\\"$ENV_API_URL\\": \\"$API_URL\\""
130
+ first=false
131
+ fi
132
+
133
+ if [[ -n "$DISABLE_TELEMETRY" ]]; then
134
+ [[ "$first" == "false" ]] && env_block+=','
135
+ env_block+="\\"$ENV_TELEMETRY\\": \\"true\\""
136
+ fi
137
+
138
+ env_block+='},'
139
+ fi
140
+
141
+ if [[ -n "$env_block" ]]; then
142
+ echo "{\\"command\\": \\"npx\\", \\"args\\": [\\"-y\\", \\"@nordsym/apiclaw\\"], $env_block}"
143
+ else
144
+ echo "{\\"command\\": \\"npx\\", \\"args\\": [\\"-y\\", \\"@nordsym/apiclaw\\"]}"
145
+ fi
146
+ }
147
+
148
+ # Merge APIClaw into existing config using Node.js
149
+ merge_config() {
150
+ local config_path="$1"
151
+ local apiclaw_config
152
+ apiclaw_config=$(generate_config)
153
+
154
+ if [[ -f "$config_path" ]]; then
155
+ # Backup existing
156
+ cp "$config_path" "$config_path.backup.$(date +%s).json"
157
+
158
+ # Read existing config
159
+ local existing
160
+ existing=$(cat "$config_path")
161
+
162
+ # Use node to merge JSON
163
+ node -e "
164
+ const fs = require('fs');
165
+ const existing = JSON.parse(process.argv[1] || '{}');
166
+ const apiclaw = JSON.parse(process.argv[2]);
167
+
168
+ if (!existing.mcpServers) existing.mcpServers = {};
169
+ existing.mcpServers['$SERVER_NAME'] = apiclaw;
170
+
171
+ fs.writeFileSync('$config_path', JSON.stringify(existing, null, 2));
172
+ " "$existing" "$apiclaw_config"
173
+ else
174
+ # Create new config
175
+ mkdir -p "$(dirname "$config_path")"
176
+ node -e "
177
+ const fs = require('fs');
178
+ const apiclaw = JSON.parse(process.argv[1]);
179
+ const config = { mcpServers: { '$SERVER_NAME': apiclaw } };
180
+ fs.writeFileSync('$config_path', JSON.stringify(config, null, 2));
181
+ " "$apiclaw_config"
182
+ fi
183
+ }
184
+
185
+ # Client config paths
186
+ declare -A CLIENT_PATHS
187
+
188
+ case "$OS" in
189
+ mac)
190
+ CLIENT_PATHS=(
191
+ ["Claude Desktop"]="$APP_DATA/Claude/claude_desktop_config.json"
192
+ ["Cursor"]="$APP_DATA/Cursor/User/globalStorage/cursor.mcp/config.json"
193
+ ["Windsurf"]="$HOME_DIR/.codeium/windsurf/mcp_config.json"
194
+ ["Cline"]="$APP_DATA/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json"
195
+ ["Continue"]="$HOME_DIR/.continue/config.json"
196
+ )
197
+ ;;
198
+ linux)
199
+ CLIENT_PATHS=(
200
+ ["Claude Desktop"]="$APP_DATA/Claude/claude_desktop_config.json"
201
+ ["Cursor"]="$APP_DATA/Cursor/User/globalStorage/cursor.mcp/config.json"
202
+ ["Windsurf"]="$HOME_DIR/.codeium/windsurf/mcp_config.json"
203
+ ["Cline"]="$APP_DATA/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json"
204
+ ["Continue"]="$HOME_DIR/.continue/config.json"
205
+ )
206
+ ;;
207
+ win)
208
+ CLIENT_PATHS=(
209
+ ["Claude Desktop"]="$APP_DATA/Claude/claude_desktop_config.json"
210
+ ["Cursor"]="$APP_DATA/Cursor/User/globalStorage/cursor.mcp/config.json"
211
+ ["Windsurf"]="$USERPROFILE/.codeium/windsurf/mcp_config.json"
212
+ ["Cline"]="$APP_DATA/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json"
213
+ ["Continue"]="$USERPROFILE/.continue/config.json"
214
+ )
215
+ ;;
216
+ esac
217
+
218
+ # Configure each client
219
+ echo ""
220
+ log_info "Scanning for MCP clients..."
221
+ echo ""
222
+
223
+ configured=0
224
+ skipped=0
225
+
226
+ for client in "\${!CLIENT_PATHS[@]}"; do
227
+ config_path="\${CLIENT_PATHS[$client]}"
228
+ config_dir=$(dirname "$config_path")
229
+
230
+ # Check if client is installed (config dir exists or we can create it)
231
+ if [[ -d "$config_dir" ]] || [[ -f "$config_path" ]]; then
232
+ log_info "Configuring $client..."
233
+
234
+ if merge_config "$config_path"; then
235
+ log_success "$client configured"
236
+ ((configured++))
237
+ else
238
+ log_error "Failed to configure $client"
239
+ fi
240
+ else
241
+ log_verbose "$client not detected (no config directory)"
242
+ ((skipped++))
243
+ fi
244
+ done
245
+
246
+ # Summary
247
+ echo ""
248
+ echo "========================="
249
+ echo ""
250
+
251
+ if [[ $configured -gt 0 ]]; then
252
+ log_success "Configured $configured client(s)"
253
+ echo ""
254
+ echo "🎉 APIClaw is ready! Restart your MCP clients to activate."
255
+ else
256
+ log_warn "No MCP clients were detected."
257
+ echo ""
258
+ echo "Install one of these clients first:"
259
+ echo " • Claude Desktop: https://claude.ai/download"
260
+ echo " • Cursor: https://cursor.sh"
261
+ echo " • Windsurf: https://codeium.com/windsurf"
262
+ fi
263
+
264
+ echo ""
265
+ `;
266
+ }
267
+
268
+ /**
269
+ * Generate self-contained PowerShell deployment script
270
+ */
271
+ export function generatePowerShellScript(options: ScriptOptions = {}): string {
272
+ const serverName = options.serverName || 'apiclaw';
273
+ const workspaceVal = options.workspace || '';
274
+ const apiUrlVal = options.apiUrl || DEFAULT_API_URL;
275
+ const disableTelemetry = options.disableTelemetry;
276
+ const verbose = options.verbose;
277
+
278
+ return `#Requires -Version 5.1
279
+ <#
280
+ .SYNOPSIS
281
+ APIClaw MCP Auto-Setup Script
282
+
283
+ .DESCRIPTION
284
+ Automatically configures APIClaw for all detected MCP clients.
285
+ Supports: Claude Desktop, Cursor, Windsurf, Cline, Continue
286
+
287
+ .NOTES
288
+ Generated by: npx @nordsym/apiclaw setup --enterprise
289
+ #>
290
+
291
+ [CmdletBinding()]
292
+ param()
293
+
294
+ $ErrorActionPreference = "Stop"
295
+
296
+ # Configuration
297
+ $ServerName = "${serverName}"
298
+ $Workspace = "${workspaceVal}"
299
+ $ApiUrl = "${apiUrlVal}"
300
+ $DefaultApiUrl = "${DEFAULT_API_URL}"
301
+ $DisableTelemetry = $${disableTelemetry ? 'true' : 'false'}
302
+ $VerboseMode = $${verbose ? 'true' : 'false'}
303
+
304
+ # Env var names
305
+ $EnvWorkspace = "${WORKSPACE_VAR}"
306
+ $EnvApiUrl = "${API_URL_VAR}"
307
+ $EnvTelemetry = "${TELEMETRY_VAR}"
308
+
309
+ # Helper functions
310
+ function Write-Info { param($Message) Write-Host "ℹ $Message" -ForegroundColor Blue }
311
+ function Write-Success { param($Message) Write-Host "✓ $Message" -ForegroundColor Green }
312
+ function Write-Warn { param($Message) Write-Host "⚠ $Message" -ForegroundColor Yellow }
313
+ function Write-Err { param($Message) Write-Host "✗ $Message" -ForegroundColor Red }
314
+
315
+ Write-Host ""
316
+ Write-Host "🔧 APIClaw MCP Auto-Setup" -ForegroundColor Cyan
317
+ Write-Host "=========================" -ForegroundColor Cyan
318
+ Write-Host ""
319
+
320
+ # Check for Node.js
321
+ try {
322
+ $nodeVersion = & node --version 2>$null
323
+ Write-Success "Node.js $nodeVersion found"
324
+ } catch {
325
+ Write-Err "Node.js is required but not installed."
326
+ exit 1
327
+ }
328
+
329
+ # Check for npx
330
+ try {
331
+ $null = & npx --version 2>$null
332
+ Write-Success "npx available"
333
+ } catch {
334
+ Write-Err "npx is required but not installed."
335
+ exit 1
336
+ }
337
+
338
+ # Generate APIClaw config
339
+ function Get-ApiclawConfig {
340
+ $config = @{
341
+ command = "npx"
342
+ args = @("-y", "@nordsym/apiclaw")
343
+ }
344
+
345
+ $env = @{}
346
+ if ($Workspace) { $env[$EnvWorkspace] = $Workspace }
347
+ if ($ApiUrl -and $ApiUrl -ne $DefaultApiUrl) { $env[$EnvApiUrl] = $ApiUrl }
348
+ if ($DisableTelemetry) { $env[$EnvTelemetry] = "true" }
349
+
350
+ if ($env.Count -gt 0) {
351
+ $config["env"] = $env
352
+ }
353
+
354
+ return $config
355
+ }
356
+
357
+ # Merge config into existing file
358
+ function Merge-Config {
359
+ param(
360
+ [string]$ConfigPath
361
+ )
362
+
363
+ $configDir = Split-Path -Parent $ConfigPath
364
+
365
+ # Ensure directory exists
366
+ if (!(Test-Path $configDir)) {
367
+ New-Item -ItemType Directory -Path $configDir -Force | Out-Null
368
+ }
369
+
370
+ # Read existing or create new
371
+ if (Test-Path $ConfigPath) {
372
+ # Backup existing
373
+ $backupPath = "$ConfigPath.backup.$([DateTimeOffset]::UtcNow.ToUnixTimeSeconds()).json"
374
+ Copy-Item $ConfigPath $backupPath
375
+
376
+ $existing = Get-Content $ConfigPath -Raw | ConvertFrom-Json -AsHashtable
377
+ } else {
378
+ $existing = @{}
379
+ }
380
+
381
+ # Ensure mcpServers exists
382
+ if (!$existing.ContainsKey("mcpServers")) {
383
+ $existing["mcpServers"] = @{}
384
+ }
385
+
386
+ # Add APIClaw
387
+ $existing["mcpServers"][$ServerName] = Get-ApiclawConfig
388
+
389
+ # Write back
390
+ $existing | ConvertTo-Json -Depth 10 | Set-Content $ConfigPath -Encoding UTF8
391
+ }
392
+
393
+ # Client paths
394
+ $AppData = $env:APPDATA
395
+ $UserProfile = $env:USERPROFILE
396
+
397
+ $ClientPaths = @{
398
+ "Claude Desktop" = "$AppData\\Claude\\claude_desktop_config.json"
399
+ "Cursor" = "$AppData\\Cursor\\User\\globalStorage\\cursor.mcp\\config.json"
400
+ "Windsurf" = "$UserProfile\\.codeium\\windsurf\\mcp_config.json"
401
+ "Cline" = "$AppData\\Code\\User\\globalStorage\\saoudrizwan.claude-dev\\settings\\cline_mcp_settings.json"
402
+ "Continue" = "$UserProfile\\.continue\\config.json"
403
+ }
404
+
405
+ Write-Host ""
406
+ Write-Info "Scanning for MCP clients..."
407
+ Write-Host ""
408
+
409
+ $configured = 0
410
+
411
+ foreach ($client in $ClientPaths.Keys) {
412
+ $configPath = $ClientPaths[$client]
413
+ $configDir = Split-Path -Parent $configPath
414
+
415
+ if ((Test-Path $configDir) -or (Test-Path $configPath)) {
416
+ Write-Info "Configuring $client..."
417
+
418
+ try {
419
+ Merge-Config -ConfigPath $configPath
420
+ Write-Success "$client configured"
421
+ $configured++
422
+ } catch {
423
+ Write-Err "Failed to configure $client: $_"
424
+ }
425
+ }
426
+ }
427
+
428
+ Write-Host ""
429
+ Write-Host "=========================" -ForegroundColor Cyan
430
+ Write-Host ""
431
+
432
+ if ($configured -gt 0) {
433
+ Write-Success "Configured $configured client(s)"
434
+ Write-Host ""
435
+ Write-Host "🎉 APIClaw is ready! Restart your MCP clients to activate." -ForegroundColor Green
436
+ } else {
437
+ Write-Warn "No MCP clients were detected."
438
+ Write-Host ""
439
+ Write-Host "Install one of these clients first:"
440
+ Write-Host " • Claude Desktop: https://claude.ai/download"
441
+ Write-Host " • Cursor: https://cursor.sh"
442
+ Write-Host " • Windsurf: https://codeium.com/windsurf"
443
+ }
444
+
445
+ Write-Host ""
446
+ `;
447
+ }
448
+
449
+ /**
450
+ * Generate script based on target platform
451
+ */
452
+ export function generateScript(
453
+ platform: 'bash' | 'powershell' | 'auto',
454
+ options: ScriptOptions = {}
455
+ ): { script: string; filename: string; platform: 'bash' | 'powershell' } {
456
+ // Auto-detect platform
457
+ let targetPlatform: 'bash' | 'powershell' = platform === 'auto'
458
+ ? (process.platform === 'win32' ? 'powershell' : 'bash')
459
+ : platform;
460
+
461
+ if (targetPlatform === 'powershell') {
462
+ return {
463
+ script: generatePowerShellScript(options),
464
+ filename: 'apiclaw-setup.ps1',
465
+ platform: 'powershell',
466
+ };
467
+ }
468
+
469
+ return {
470
+ script: generateBashScript(options),
471
+ filename: 'apiclaw-setup.sh',
472
+ platform: 'bash',
473
+ };
474
+ }
475
+
476
+ /**
477
+ * Get file extension for platform
478
+ */
479
+ export function getScriptExtension(platform: 'bash' | 'powershell'): string {
480
+ return platform === 'powershell' ? '.ps1' : '.sh';
481
+ }