coder-link 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +31 -13
  2. package/dist/cli.js +214 -76
  3. package/dist/cli.js.map +1 -1
  4. package/dist/lib/claude-code-manager.d.ts +8 -1
  5. package/dist/lib/claude-code-manager.d.ts.map +1 -1
  6. package/dist/lib/claude-code-manager.js +84 -118
  7. package/dist/lib/claude-code-manager.js.map +1 -1
  8. package/dist/lib/codex-manager.d.ts +34 -0
  9. package/dist/lib/codex-manager.d.ts.map +1 -0
  10. package/dist/lib/codex-manager.js +223 -0
  11. package/dist/lib/codex-manager.js.map +1 -0
  12. package/dist/lib/config-io.d.ts +5 -0
  13. package/dist/lib/config-io.d.ts.map +1 -0
  14. package/dist/lib/config-io.js +50 -0
  15. package/dist/lib/config-io.js.map +1 -0
  16. package/dist/lib/crush-manager.d.ts +1 -2
  17. package/dist/lib/crush-manager.d.ts.map +1 -1
  18. package/dist/lib/crush-manager.js +20 -58
  19. package/dist/lib/crush-manager.js.map +1 -1
  20. package/dist/lib/factory-droid-manager.d.ts +8 -2
  21. package/dist/lib/factory-droid-manager.d.ts.map +1 -1
  22. package/dist/lib/factory-droid-manager.js +193 -260
  23. package/dist/lib/factory-droid-manager.js.map +1 -1
  24. package/dist/lib/kimi-manager.d.ts.map +1 -1
  25. package/dist/lib/kimi-manager.js +19 -30
  26. package/dist/lib/kimi-manager.js.map +1 -1
  27. package/dist/lib/opencode-manager.d.ts +1 -1
  28. package/dist/lib/opencode-manager.d.ts.map +1 -1
  29. package/dist/lib/opencode-manager.js +187 -63
  30. package/dist/lib/opencode-manager.js.map +1 -1
  31. package/dist/lib/pi-manager.d.ts +0 -1
  32. package/dist/lib/pi-manager.d.ts.map +1 -1
  33. package/dist/lib/pi-manager.js +18 -41
  34. package/dist/lib/pi-manager.js.map +1 -1
  35. package/dist/lib/provider-registry.d.ts +200 -0
  36. package/dist/lib/provider-registry.d.ts.map +1 -0
  37. package/dist/lib/provider-registry.js +581 -0
  38. package/dist/lib/provider-registry.js.map +1 -0
  39. package/dist/lib/tool-manager.d.ts +42 -3
  40. package/dist/lib/tool-manager.d.ts.map +1 -1
  41. package/dist/lib/tool-manager.js +155 -34
  42. package/dist/lib/tool-manager.js.map +1 -1
  43. package/dist/mcp-services.d.ts.map +1 -1
  44. package/dist/mcp-services.js +57 -3
  45. package/dist/mcp-services.js.map +1 -1
  46. package/dist/{menu.d.ts → menu/main-menu.d.ts} +1 -1
  47. package/dist/menu/main-menu.d.ts.map +1 -0
  48. package/dist/menu/main-menu.js +90 -0
  49. package/dist/menu/main-menu.js.map +1 -0
  50. package/dist/menu/mcp-menu.d.ts +2 -0
  51. package/dist/menu/mcp-menu.d.ts.map +1 -0
  52. package/dist/menu/mcp-menu.js +136 -0
  53. package/dist/menu/mcp-menu.js.map +1 -0
  54. package/dist/menu/provider-menu.d.ts +4 -0
  55. package/dist/menu/provider-menu.d.ts.map +1 -0
  56. package/dist/menu/provider-menu.js +623 -0
  57. package/dist/menu/provider-menu.js.map +1 -0
  58. package/dist/menu/shared.d.ts +17 -0
  59. package/dist/menu/shared.d.ts.map +1 -0
  60. package/dist/menu/shared.js +255 -0
  61. package/dist/menu/shared.js.map +1 -0
  62. package/dist/menu/system-menu.d.ts +3 -0
  63. package/dist/menu/system-menu.d.ts.map +1 -0
  64. package/dist/menu/system-menu.js +111 -0
  65. package/dist/menu/system-menu.js.map +1 -0
  66. package/dist/menu/tool-menu.d.ts +3 -0
  67. package/dist/menu/tool-menu.d.ts.map +1 -0
  68. package/dist/menu/tool-menu.js +619 -0
  69. package/dist/menu/tool-menu.js.map +1 -0
  70. package/dist/utils/api-test.d.ts +6 -0
  71. package/dist/utils/api-test.d.ts.map +1 -1
  72. package/dist/utils/api-test.js +66 -0
  73. package/dist/utils/api-test.js.map +1 -1
  74. package/dist/utils/brand.d.ts.map +1 -1
  75. package/dist/utils/brand.js +14 -0
  76. package/dist/utils/brand.js.map +1 -1
  77. package/dist/utils/config.d.ts +29 -4
  78. package/dist/utils/config.d.ts.map +1 -1
  79. package/dist/utils/config.js +194 -68
  80. package/dist/utils/config.js.map +1 -1
  81. package/dist/utils/providers.d.ts +32 -0
  82. package/dist/utils/providers.d.ts.map +1 -0
  83. package/dist/utils/providers.js +63 -0
  84. package/dist/utils/providers.js.map +1 -0
  85. package/dist/wizard.d.ts.map +1 -1
  86. package/dist/wizard.js +123 -35
  87. package/dist/wizard.js.map +1 -1
  88. package/package.json +1 -1
  89. package/dist/menu.d.ts.map +0 -1
  90. package/dist/menu.js +0 -1226
  91. package/dist/menu.js.map +0 -1
@@ -0,0 +1,581 @@
1
+ /**
2
+ * Centralized Provider Configuration Registry
3
+ *
4
+ * This module serves as the single source of truth for all provider-related
5
+ * configurations including base URLs, default models, display names, and
6
+ * detection patterns.
7
+ *
8
+ * Benefits:
9
+ * - Eliminates duplication across manager files
10
+ * - Makes adding new providers easier (add once, works everywhere)
11
+ * - Ensures consistency across all tools
12
+ * - Simplifies maintenance and updates
13
+ */
14
+ // ============================================================================
15
+ // Provider Configurations
16
+ // ============================================================================
17
+ export const PROVIDER_CONFIGS = {
18
+ glm_coding_plan_global: {
19
+ id: 'glm_coding_plan_global',
20
+ displayName: 'GLM Coding Plan (Global)',
21
+ shortName: 'GLM_Global',
22
+ urls: {
23
+ openai: 'https://api.z.ai/api/coding/paas/v4',
24
+ anthropic: 'https://api.z.ai/api/anthropic',
25
+ },
26
+ defaultModel: 'glm-5',
27
+ commonModels: ['glm-5', 'glm-4.7', 'glm-4.7-flash', 'glm-4-plus'],
28
+ detectionPatterns: ['api.z.ai'],
29
+ supportsThinking: true,
30
+ maxContextSize: 128000,
31
+ maxOutputTokens: 131072,
32
+ },
33
+ glm_coding_plan_china: {
34
+ id: 'glm_coding_plan_china',
35
+ displayName: 'GLM Coding Plan (China)',
36
+ shortName: 'GLM_China',
37
+ urls: {
38
+ openai: 'https://open.bigmodel.cn/api/coding/paas/v4',
39
+ anthropic: 'https://open.bigmodel.cn/api/anthropic',
40
+ },
41
+ defaultModel: 'glm-5',
42
+ commonModels: ['glm-5', 'glm-4.7', 'glm-4.7-flash', 'glm-4-plus'],
43
+ detectionPatterns: ['open.bigmodel.cn'],
44
+ supportsThinking: true,
45
+ maxContextSize: 128000,
46
+ maxOutputTokens: 131072,
47
+ },
48
+ kimi: {
49
+ id: 'kimi',
50
+ displayName: 'Kimi (Moonshot)',
51
+ shortName: 'Kimi',
52
+ urls: {
53
+ openai: 'https://api.moonshot.ai/v1',
54
+ // Kimi does not support Anthropic protocol
55
+ },
56
+ defaultModel: 'moonshot-ai/kimi-k2.5',
57
+ commonModels: ['moonshot-ai/kimi-k2.5', 'moonshot-ai/kimi-k2-thinking'],
58
+ detectionPatterns: ['api.moonshot.ai', 'moonshot'],
59
+ supportsThinking: true,
60
+ maxContextSize: 262144,
61
+ maxOutputTokens: 131072,
62
+ },
63
+ openrouter: {
64
+ id: 'openrouter',
65
+ displayName: 'OpenRouter',
66
+ shortName: 'OpenRouter',
67
+ urls: {
68
+ openai: 'https://openrouter.ai/api/v1',
69
+ anthropic: 'https://openrouter.ai/api',
70
+ },
71
+ defaultModel: 'kimi-k2.5',
72
+ commonModels: ['openrouter/pony-alpha', 'anthropic/claude-opus-4.6', 'qwen/qwen3-coder-next'],
73
+ detectionPatterns: ['openrouter.ai'],
74
+ supportsThinking: false,
75
+ maxContextSize: 16384,
76
+ maxOutputTokens: 131072,
77
+ },
78
+ nvidia: {
79
+ id: 'nvidia',
80
+ displayName: 'NVIDIA NIM',
81
+ shortName: 'NVIDIA',
82
+ urls: {
83
+ openai: 'https://integrate.api.nvidia.com/v1',
84
+ // NVIDIA does not support Anthropic protocol
85
+ },
86
+ defaultModel: 'moonshotai/kimi-k2.5',
87
+ commonModels: [
88
+ 'moonshotai/kimi-k2.5',
89
+ 'deepseek-ai/deepseek-v3.2',
90
+ 'meta/llama-3.3-70b-instruct',
91
+ 'meta/llama-4-maverick-17b-128e-instruct',
92
+ 'qwen/qwen3-coder-480b-a35b-instruct',
93
+ 'z-ai/glm4.7',
94
+ 'nvidia/llama-3.3-nemotron-super-49b-v1.5',
95
+ ],
96
+ detectionPatterns: ['integrate.api.nvidia.com', 'nvidia.com'],
97
+ supportsThinking: false,
98
+ maxContextSize: 4096,
99
+ maxOutputTokens: 131072,
100
+ },
101
+ lmstudio: {
102
+ id: 'lmstudio',
103
+ displayName: 'LM Studio (Local)',
104
+ shortName: 'LM_Studio',
105
+ urls: {
106
+ openai: 'http://localhost:1234/v1',
107
+ anthropic: 'http://localhost:1234',
108
+ },
109
+ defaultModel: 'lmstudio-community',
110
+ commonModels: ['lmstudio-community', 'deepseek-coder-v3', 'codellama/13b', 'mistral-7b-instruct', 'qwen2.5-coder-7b'],
111
+ detectionPatterns: ['localhost:1234', 'localhost:1235', '127.0.0.1:1234', '127.0.0.1:1235'],
112
+ supportsThinking: false,
113
+ maxContextSize: 262144,
114
+ maxOutputTokens: 131072,
115
+ // Configurable defaults for LM Studio (Recommendation #4)
116
+ configurableDefaults: {
117
+ defaultPorts: [1234, 1235],
118
+ allowCustomBaseUrl: true,
119
+ },
120
+ // Requires healthcheck on startup (Recommendation #1)
121
+ requiresHealthCheck: true,
122
+ },
123
+ alibaba: {
124
+ id: 'alibaba',
125
+ displayName: 'Alibaba Coding Plan',
126
+ shortName: 'Alibaba_Coding',
127
+ urls: {
128
+ openai: 'https://coding-intl.dashscope.aliyuncs.com/v1',
129
+ anthropic: 'https://coding-intl.dashscope.aliyuncs.com/apps/anthropic',
130
+ },
131
+ defaultModel: 'qwen3-coder-plus',
132
+ commonModels: ['qwen3-coder-plus', 'qwen3-max', 'qwen3-max-preview', 'qwen-plus', 'qwen-flash', 'qwen-turbo', 'qwen3-coder-flash'],
133
+ detectionPatterns: ['coding-intl.dashscope.aliyuncs.com'],
134
+ supportsThinking: false,
135
+ maxContextSize: 262144,
136
+ maxOutputTokens: 131072,
137
+ },
138
+ alibaba_api: {
139
+ id: 'alibaba_api',
140
+ displayName: 'Alibaba Model Studio API (Singapore)',
141
+ shortName: 'Alibaba_API',
142
+ urls: {
143
+ openai: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',
144
+ anthropic: 'https://dashscope-intl.aliyuncs.com/apps/anthropic',
145
+ },
146
+ defaultModel: 'qwen3-max-2026-01-23',
147
+ commonModels: ['qwen3-max-2026-01-23', 'qwen3-max', 'qwen-plus', 'qwen-turbo', 'qwen3-coder-plus'],
148
+ detectionPatterns: ['dashscope-intl.aliyuncs.com', 'dashscope.aliyuncs.com/compatible-mode'],
149
+ supportsThinking: false,
150
+ maxContextSize: 262144,
151
+ maxOutputTokens: 65536, // qwen3-max has lower limit
152
+ },
153
+ };
154
+ // ============================================================================
155
+ // Helper Functions
156
+ // ============================================================================
157
+ /**
158
+ * Get the provider configuration for a given plan
159
+ */
160
+ export function getProviderConfig(plan) {
161
+ return PROVIDER_CONFIGS[plan];
162
+ }
163
+ /**
164
+ * Get the base URL for a specific plan and protocol
165
+ */
166
+ export function getBaseUrl(plan, protocol) {
167
+ const config = PROVIDER_CONFIGS[plan];
168
+ if (protocol === 'anthropic') {
169
+ return config.urls.anthropic || config.urls.openai;
170
+ }
171
+ return config.urls.openai;
172
+ }
173
+ /**
174
+ * Check if a provider supports a specific protocol
175
+ */
176
+ export function supportsProtocol(plan, protocol) {
177
+ const config = PROVIDER_CONFIGS[plan];
178
+ if (protocol === 'anthropic') {
179
+ return config.urls.anthropic !== undefined;
180
+ }
181
+ return true; // All providers support OpenAI
182
+ }
183
+ /**
184
+ * Detect the plan from a base URL
185
+ */
186
+ export function detectPlanFromUrl(baseUrl) {
187
+ if (!baseUrl)
188
+ return null;
189
+ const normalized = baseUrl.toLowerCase().replace(/\/+$/g, '');
190
+ if (!normalized)
191
+ return null;
192
+ for (const [planId, config] of Object.entries(PROVIDER_CONFIGS)) {
193
+ for (const pattern of config.detectionPatterns) {
194
+ if (normalized.includes(pattern.toLowerCase())) {
195
+ return planId;
196
+ }
197
+ }
198
+ }
199
+ return null;
200
+ }
201
+ /**
202
+ * Get the default model for a plan
203
+ */
204
+ export function getDefaultModel(plan) {
205
+ return PROVIDER_CONFIGS[plan].defaultModel;
206
+ }
207
+ /**
208
+ * Get max output tokens for a model (handles special cases like qwen3-max)
209
+ */
210
+ export function getMaxOutputTokens(plan, model) {
211
+ const config = PROVIDER_CONFIGS[plan];
212
+ // qwen3-max models have lower limit
213
+ if (model?.includes('qwen3-max')) {
214
+ return 65536;
215
+ }
216
+ return config.maxOutputTokens;
217
+ }
218
+ /**
219
+ * Get max context size for a plan
220
+ */
221
+ export function getMaxContextSize(plan) {
222
+ return PROVIDER_CONFIGS[plan].maxContextSize;
223
+ }
224
+ /**
225
+ * Check if a provider requires healthcheck on startup
226
+ */
227
+ export function requiresHealthCheck(plan) {
228
+ return PROVIDER_CONFIGS[plan].requiresHealthCheck === true;
229
+ }
230
+ /**
231
+ * Get configurable defaults for a provider
232
+ */
233
+ export function getConfigurableDefaults(plan) {
234
+ return PROVIDER_CONFIGS[plan].configurableDefaults;
235
+ }
236
+ // ============================================================================
237
+ // Protocol-Agnostic URL Resolution (Recommendation #2)
238
+ // ============================================================================
239
+ /**
240
+ * Resolve provider base URL for a specific protocol.
241
+ * This is a generic, protocol-agnostic function that handles URL normalization
242
+ * for all providers without requiring separate cases for each protocol extension.
243
+ *
244
+ * @param plan - The provider plan
245
+ * @param protocol - The target protocol ('openai' or 'anthropic')
246
+ * @param options - Optional base URL overrides
247
+ * @returns The resolved and normalized base URL
248
+ */
249
+ export function resolveProviderBaseUrl(plan, protocol, options) {
250
+ const config = PROVIDER_CONFIGS[plan];
251
+ // Priority: protocol-specific override > generic override > default
252
+ if (protocol === 'anthropic' && options?.anthropicBaseUrl?.trim()) {
253
+ return normalizeProviderUrl(options.anthropicBaseUrl.trim(), plan, protocol);
254
+ }
255
+ if (options?.baseUrl?.trim()) {
256
+ return normalizeProviderUrl(options.baseUrl.trim(), plan, protocol);
257
+ }
258
+ return getBaseUrl(plan, protocol);
259
+ }
260
+ /**
261
+ * Normalize a user-provided URL based on provider-specific rules.
262
+ * This is the core normalization function that handles all providers
263
+ * in a protocol-agnostic way.
264
+ */
265
+ function normalizeProviderUrl(url, plan, protocol) {
266
+ const config = PROVIDER_CONFIGS[plan];
267
+ const normalized = url.replace(/\/+$/g, '');
268
+ const lower = normalized.toLowerCase();
269
+ switch (plan) {
270
+ case 'glm_coding_plan_global':
271
+ case 'glm_coding_plan_china':
272
+ return normalizeGLMUrl(normalized, lower, protocol, config);
273
+ case 'openrouter':
274
+ return normalizeOpenRouterUrl(normalized, lower, protocol);
275
+ case 'lmstudio':
276
+ // Use centralized LM Studio normalization
277
+ return normalizeLMStudioUrl(normalized, protocol);
278
+ case 'alibaba':
279
+ case 'alibaba_api':
280
+ return normalizeAlibabaUrl(normalized, lower, protocol, config);
281
+ default:
282
+ return normalized;
283
+ }
284
+ }
285
+ /**
286
+ * Normalize GLM (Zhipu AI) URLs
287
+ */
288
+ function normalizeGLMUrl(normalized, lower, protocol, config) {
289
+ if (protocol === 'anthropic') {
290
+ if (lower.endsWith('/api/anthropic'))
291
+ return normalized;
292
+ if (lower.endsWith('/api/coding/paas/v4')) {
293
+ return normalized.replace(/\/api\/coding\/paas\/v4$/i, '/api/anthropic');
294
+ }
295
+ return config.urls.anthropic || normalized;
296
+ }
297
+ return normalized;
298
+ }
299
+ /**
300
+ * Normalize OpenRouter URLs
301
+ */
302
+ function normalizeOpenRouterUrl(normalized, lower, protocol) {
303
+ if (protocol === 'anthropic') {
304
+ if (lower.endsWith('/api/v1'))
305
+ return normalized.replace(/\/api\/v1$/i, '/api');
306
+ if (lower.endsWith('/v1'))
307
+ return normalized.replace(/\/v1$/i, '');
308
+ if (lower.endsWith('/api'))
309
+ return normalized;
310
+ return lower.includes('openrouter.ai') ? `${normalized}/api` : normalized;
311
+ }
312
+ return normalized;
313
+ }
314
+ /**
315
+ * Normalize Alibaba/DashScope URLs
316
+ */
317
+ function normalizeAlibabaUrl(normalized, lower, protocol, config) {
318
+ if (protocol === 'anthropic') {
319
+ if (lower.includes('/apps/anthropic'))
320
+ return normalized;
321
+ if (lower.includes('/compatible-mode/v1')) {
322
+ return normalized.replace(/\/compatible-mode\/v1$/i, '/apps/anthropic');
323
+ }
324
+ if (lower.endsWith('/v1')) {
325
+ return normalized.replace(/\/v1$/i, '/apps/anthropic');
326
+ }
327
+ return config.urls.anthropic || normalized;
328
+ }
329
+ return normalized;
330
+ }
331
+ /**
332
+ * Resolve the effective base URL, handling user overrides and URL normalization
333
+ * @deprecated Use resolveProviderBaseUrl instead for better protocol-agnostic handling
334
+ */
335
+ export function resolveBaseUrl(plan, protocol, options) {
336
+ // Delegate to the new protocol-agnostic resolver
337
+ return resolveProviderBaseUrl(plan, protocol, options);
338
+ }
339
+ /**
340
+ * Normalize a user-provided URL based on provider-specific rules (protocol-agnostic)
341
+ * @deprecated Internal function, use resolveProviderBaseUrl instead
342
+ */
343
+ function normalizeUrl(url, plan, protocol) {
344
+ return normalizeProviderUrl(url, plan, protocol);
345
+ }
346
+ /**
347
+ * Normalize LM Studio URL for a specific protocol (protocol-agnostic)
348
+ * This is a dedicated function to handle LM Studio's URL conventions.
349
+ */
350
+ export function normalizeLMStudioUrl(url, protocol) {
351
+ const normalized = url.replace(/\/+$/g, '');
352
+ const lower = normalized.toLowerCase();
353
+ // For Anthropic protocol, LM Studio expects base URL without /v1
354
+ if (protocol === 'anthropic') {
355
+ return lower.endsWith('/v1') ? normalized.replace(/\/v1$/i, '') : normalized;
356
+ }
357
+ // For OpenAI protocol, ensure /v1 suffix
358
+ if (protocol === 'openai') {
359
+ return lower.endsWith('/v1') ? normalized : `${normalized}/v1`;
360
+ }
361
+ return normalized;
362
+ }
363
+ /**
364
+ * Get all provider plans as an array
365
+ */
366
+ export function getAllPlans() {
367
+ return Object.keys(PROVIDER_CONFIGS);
368
+ }
369
+ /**
370
+ * Get provider display name
371
+ */
372
+ export function getProviderDisplayName(plan) {
373
+ return PROVIDER_CONFIGS[plan].displayName;
374
+ }
375
+ /**
376
+ * Get provider short name (for config keys)
377
+ */
378
+ export function getProviderShortName(plan) {
379
+ return PROVIDER_CONFIGS[plan].shortName;
380
+ }
381
+ /**
382
+ * Check if a provider supports extended thinking
383
+ */
384
+ export function supportsThinking(plan, source) {
385
+ const config = PROVIDER_CONFIGS[plan];
386
+ if (!config.supportsThinking)
387
+ return false;
388
+ // For Kimi, only native Moonshot API supports thinking
389
+ if (plan === 'kimi') {
390
+ return !source || source === '' || source.toLowerCase() === 'moonshot';
391
+ }
392
+ return true;
393
+ }
394
+ /** Default health check timeout in milliseconds */
395
+ const LM_STUDIO_HEALTH_TIMEOUT = 3000;
396
+ /**
397
+ * Get default ports for LM Studio from configuration
398
+ */
399
+ function getLMStudioConfiguredPorts() {
400
+ const config = PROVIDER_CONFIGS.lmstudio;
401
+ return config.configurableDefaults?.defaultPorts || [1234, 1235];
402
+ }
403
+ /**
404
+ * Build health check URL from base URL
405
+ */
406
+ function buildHealthUrl(baseUrl) {
407
+ const normalized = baseUrl.replace(/\/$/, '');
408
+ // LM Studio health endpoint is at root
409
+ return normalized;
410
+ }
411
+ /**
412
+ * Build models endpoint URL from base URL (protocol-agnostic)
413
+ */
414
+ function buildModelsUrl(baseUrl) {
415
+ const normalized = baseUrl.replace(/\/+$/, '');
416
+ // For OpenAI-compatible endpoint, models are at /v1/models
417
+ if (normalized.endsWith('/v1')) {
418
+ return `${normalized}/models`;
419
+ }
420
+ return `${normalized}/v1/models`;
421
+ }
422
+ /**
423
+ * Check if LM Studio server is reachable
424
+ * Returns the actual base URL that responded, or null if unreachable
425
+ */
426
+ export async function checkLMStudioHealth(baseUrl, options) {
427
+ const timeout = options?.timeoutMs ?? LM_STUDIO_HEALTH_TIMEOUT;
428
+ const defaultPorts = getLMStudioConfiguredPorts();
429
+ // If specific URL provided, try only that
430
+ const urlsToTry = baseUrl
431
+ ? [baseUrl.replace(/\/+$/, '')]
432
+ : defaultPorts.map(port => `http://localhost:${port}`);
433
+ for (const url of urlsToTry) {
434
+ try {
435
+ const controller = new AbortController();
436
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
437
+ // Try health endpoint first (root), fallback to models endpoint
438
+ const healthUrl = buildHealthUrl(url);
439
+ const response = await fetch(healthUrl, {
440
+ method: 'GET',
441
+ signal: options?.signal ?? controller.signal,
442
+ });
443
+ clearTimeout(timeoutId);
444
+ if (response.ok || response.status === 200) {
445
+ // Try to parse version info if available
446
+ let version;
447
+ try {
448
+ const data = await response.json();
449
+ version = data.version;
450
+ }
451
+ catch {
452
+ // Health endpoint might return plain text or no body
453
+ }
454
+ return { reachable: true, url, version };
455
+ }
456
+ }
457
+ catch {
458
+ // Try next URL
459
+ continue;
460
+ }
461
+ }
462
+ return { reachable: false };
463
+ }
464
+ /**
465
+ * Fetch the currently loaded model from LM Studio
466
+ * Returns the model ID if available, null otherwise
467
+ */
468
+ export async function fetchLMStudioModel(baseUrl, options) {
469
+ const timeout = options?.timeoutMs ?? LM_STUDIO_HEALTH_TIMEOUT;
470
+ const defaultPorts = getLMStudioConfiguredPorts();
471
+ // Build URLs to try
472
+ let urlsToTry;
473
+ if (baseUrl) {
474
+ urlsToTry = [buildModelsUrl(baseUrl.replace(/\/+$/, ''))];
475
+ }
476
+ else if (options?.port) {
477
+ urlsToTry = [buildModelsUrl(`http://localhost:${options.port}`)];
478
+ }
479
+ else {
480
+ urlsToTry = defaultPorts.map(port => buildModelsUrl(`http://localhost:${port}`));
481
+ }
482
+ for (const modelsUrl of urlsToTry) {
483
+ try {
484
+ const controller = new AbortController();
485
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
486
+ const response = await fetch(modelsUrl, {
487
+ method: 'GET',
488
+ signal: options?.signal ?? controller.signal,
489
+ });
490
+ clearTimeout(timeoutId);
491
+ if (!response.ok) {
492
+ continue;
493
+ }
494
+ const data = await response.json();
495
+ if (data.data && data.data.length > 0) {
496
+ // Return the first (usually only) loaded model
497
+ return data.data[0].id;
498
+ }
499
+ }
500
+ catch {
501
+ // Try next URL
502
+ continue;
503
+ }
504
+ }
505
+ return null;
506
+ }
507
+ /**
508
+ * Check if LM Studio is running and has a model loaded
509
+ * Now includes health check and uses refactored URL building
510
+ */
511
+ export async function checkLMStudioStatus(baseUrl, options) {
512
+ const timeout = options?.timeoutMs ?? LM_STUDIO_HEALTH_TIMEOUT;
513
+ // First check if server is reachable
514
+ const health = await checkLMStudioHealth(baseUrl, { timeoutMs: timeout });
515
+ if (!health.reachable) {
516
+ return {
517
+ running: false,
518
+ reachable: false,
519
+ modelLoaded: false,
520
+ };
521
+ }
522
+ // Then check for loaded model
523
+ const modelId = await fetchLMStudioModel(health.url, { timeoutMs: timeout, port: options?.port });
524
+ return {
525
+ running: modelId !== null,
526
+ reachable: true,
527
+ modelLoaded: modelId !== null,
528
+ modelId: modelId || undefined,
529
+ actualUrl: health.url,
530
+ version: health.version,
531
+ };
532
+ }
533
+ /**
534
+ * Get the effective base URL for LM Studio, considering custom port configuration
535
+ */
536
+ export function getLMStudioBaseUrl(options) {
537
+ if (options?.baseUrl) {
538
+ return options.baseUrl.replace(/\/+$/, '');
539
+ }
540
+ if (options?.port) {
541
+ return `http://localhost:${options.port}`;
542
+ }
543
+ // Default to first configured port
544
+ const defaultPorts = getLMStudioConfiguredPorts();
545
+ return `http://localhost:${defaultPorts[0]}`;
546
+ }
547
+ /**
548
+ * Get default LM Studio ports from configuration
549
+ */
550
+ export function getLMStudioDefaultPorts() {
551
+ return [...getLMStudioConfiguredPorts()];
552
+ }
553
+ /**
554
+ * Perform health check for any provider that requires it.
555
+ * This is a generic function that can be extended for other local providers.
556
+ */
557
+ export async function checkProviderHealth(plan, options) {
558
+ const config = PROVIDER_CONFIGS[plan];
559
+ if (!config.requiresHealthCheck) {
560
+ // Provider doesn't require health check, assume reachable
561
+ return {
562
+ reachable: true,
563
+ url: options?.baseUrl || getBaseUrl(plan, 'openai')
564
+ };
565
+ }
566
+ // Currently only LM Studio requires health check
567
+ // This can be extended for other local providers
568
+ if (plan === 'lmstudio') {
569
+ const result = await checkLMStudioHealth(options?.baseUrl, {
570
+ timeoutMs: options?.timeoutMs,
571
+ signal: options?.signal,
572
+ });
573
+ return {
574
+ reachable: result.reachable,
575
+ url: result.url,
576
+ metadata: result.version ? { version: result.version } : undefined,
577
+ };
578
+ }
579
+ return { reachable: true };
580
+ }
581
+ //# sourceMappingURL=provider-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-registry.js","sourceRoot":"","sources":["../../src/lib/provider-registry.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { Plan } from '../utils/config.js';
1
2
  export interface MCPService {
2
3
  id: string;
3
4
  name: string;
@@ -11,21 +12,59 @@ export interface MCPService {
11
12
  urlTemplate?: Record<string, string>;
12
13
  headers?: Record<string, string>;
13
14
  requiresAuth?: boolean;
15
+ authEnvVar?: string;
16
+ authHeader?: string;
17
+ authScheme?: 'Bearer' | 'raw';
14
18
  }
15
19
  export interface ProviderOptions {
16
20
  baseUrl?: string;
21
+ anthropicBaseUrl?: string;
17
22
  model?: string;
23
+ anthropicModel?: string;
18
24
  providerId?: string;
19
25
  source?: string;
20
26
  maxContextSize?: number;
21
27
  }
28
+ export type ToolName = 'claude-code' | 'opencode' | 'crush' | 'factory-droid' | 'kimi' | 'amp' | 'pi' | 'codex';
29
+ export interface ToolCapabilities {
30
+ supportsProviderConfig: boolean;
31
+ supportsMcp: boolean;
32
+ supportsModelSelection: boolean;
33
+ supportedPlans: Plan[];
34
+ notes?: string;
35
+ }
36
+ export interface ToolAdapter {
37
+ detectCurrentConfig(): Promise<{
38
+ plan: string | null;
39
+ apiKey: string | null;
40
+ model?: string;
41
+ }>;
42
+ loadConfig(plan: string, apiKey: string, options?: ProviderOptions): Promise<void>;
43
+ unloadConfig(): Promise<void>;
44
+ isMCPInstalled(mcpId: string): boolean;
45
+ installMCP(mcp: MCPService, apiKey: string, plan: string): Promise<void>;
46
+ uninstallMCP(mcpId: string): Promise<void>;
47
+ getInstalledMCPs(): string[];
48
+ getMCPStatus(mcpServices: MCPService[]): Map<string, boolean>;
49
+ getOtherMCPs(builtinIds: string[]): Array<{
50
+ id: string;
51
+ config: unknown;
52
+ }>;
53
+ getAllMCPServers(): Record<string, unknown>;
54
+ }
22
55
  export declare class ToolManager {
23
56
  static instance: ToolManager | null;
24
57
  private managers;
58
+ private static readonly CAPABILITIES;
59
+ private readonly managerLoaders;
25
60
  constructor();
26
61
  static getInstance(): ToolManager;
62
+ isSupportedTool(tool: string): tool is ToolName;
63
+ getSupportedTools(): ToolName[];
64
+ getCapabilities(tool: string): ToolCapabilities;
65
+ isPlanSupported(tool: string, plan: string): boolean;
66
+ private assertTool;
27
67
  private getManager;
28
- getSupportedTools(): string[];
29
68
  isConfigured(tool: string): Promise<boolean>;
30
69
  loadConfig(tool: string, plan: string, apiKey: string, overrides?: Partial<ProviderOptions>): Promise<void>;
31
70
  unloadConfig(tool: string): Promise<void>;
@@ -38,9 +77,9 @@ export declare class ToolManager {
38
77
  getMCPStatus(tool: string, mcpServices: MCPService[]): Promise<Map<string, boolean>>;
39
78
  getOtherMCPs(tool: string, builtinIds: string[]): Promise<Array<{
40
79
  id: string;
41
- config: any;
80
+ config: unknown;
42
81
  }>>;
43
- getAllMCPServers(tool: string): Promise<Record<string, any>>;
82
+ getAllMCPServers(tool: string): Promise<Record<string, unknown>>;
44
83
  detectCurrentConfig(tool: string): Promise<{
45
84
  plan: string | null;
46
85
  apiKey: string | null;