polydev-ai 1.9.23 → 1.9.25
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/lib/cliManager.js +4 -17
- package/mcp/manifest.json +245 -0
- package/mcp/stdio-wrapper.js +62 -9
- package/package.json +1 -1
package/lib/cliManager.js
CHANGED
|
@@ -1180,14 +1180,10 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
|
|
|
1180
1180
|
const parseCodexOutput = (output) => {
|
|
1181
1181
|
if (!output || !output.trim()) return null;
|
|
1182
1182
|
|
|
1183
|
-
// Strip ANSI escape codes first — Codex CLI wraps markers like 'codex' and
|
|
1184
|
-
// 'tokens used' in bold/color codes which break regex matching
|
|
1185
|
-
const cleanOutput = output.replace(/\x1b\[[0-9;]*m/g, '');
|
|
1186
|
-
|
|
1187
1183
|
// First, try to extract the response between "codex" marker and "tokens used"
|
|
1188
1184
|
// IMPORTANT: Use (?:^|\n) to match "codex" only at the start of a line
|
|
1189
1185
|
// This prevents matching "codex" in model names like "gpt-5.2-codex"
|
|
1190
|
-
const codexMarkerMatch =
|
|
1186
|
+
const codexMarkerMatch = output.match(/(?:^|\n)codex\s*\n([\s\S]*?)(?:\n\s*tokens used|\n\s*$)/i);
|
|
1191
1187
|
if (codexMarkerMatch && codexMarkerMatch[1]) {
|
|
1192
1188
|
const extracted = codexMarkerMatch[1].trim();
|
|
1193
1189
|
if (extracted.length > 0 && !extracted.startsWith('ERROR')) {
|
|
@@ -1196,7 +1192,7 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
|
|
|
1196
1192
|
}
|
|
1197
1193
|
|
|
1198
1194
|
// Fallback: Try to find bullet point responses
|
|
1199
|
-
const bulletMatches =
|
|
1195
|
+
const bulletMatches = output.match(/•\s*(.+)/g);
|
|
1200
1196
|
if (bulletMatches && bulletMatches.length > 0) {
|
|
1201
1197
|
const bulletContent = bulletMatches
|
|
1202
1198
|
.map(m => m.replace(/^•\s*/, '').trim())
|
|
@@ -1208,9 +1204,8 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
|
|
|
1208
1204
|
}
|
|
1209
1205
|
|
|
1210
1206
|
// Last resort: Filter out known noise patterns line by line
|
|
1211
|
-
const lines =
|
|
1207
|
+
const lines = output.split('\n');
|
|
1212
1208
|
const contentLines = [];
|
|
1213
|
-
let seenTokensUsed = false;
|
|
1214
1209
|
|
|
1215
1210
|
// Patterns to skip (Codex-specific noise)
|
|
1216
1211
|
const noisePatterns = [
|
|
@@ -1230,6 +1225,7 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
|
|
|
1230
1225
|
/^thinking$/i, // "thinking" marker
|
|
1231
1226
|
/^codex$/i, // "codex" marker
|
|
1232
1227
|
/^tokens used$/i, // Token count header
|
|
1228
|
+
/^[\d,]+$/, // Just numbers (token counts)
|
|
1233
1229
|
/^ERROR:\s*MCP/i, // MCP errors
|
|
1234
1230
|
/MCP client for .* failed/i, // MCP client failures
|
|
1235
1231
|
/handshake.*failed/i, // Handshake errors
|
|
@@ -1244,15 +1240,6 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
|
|
|
1244
1240
|
for (const line of lines) {
|
|
1245
1241
|
const trimmedLine = line.trim();
|
|
1246
1242
|
|
|
1247
|
-
// Track when we've passed the "tokens used" footer
|
|
1248
|
-
if (/^tokens used$/i.test(trimmedLine)) {
|
|
1249
|
-
seenTokensUsed = true;
|
|
1250
|
-
continue;
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
// After "tokens used", skip pure numbers (token counts like "22")
|
|
1254
|
-
if (seenTokensUsed && /^[\d,]+$/.test(trimmedLine)) continue;
|
|
1255
|
-
|
|
1256
1243
|
// Check if line matches any noise pattern
|
|
1257
1244
|
const isNoise = noisePatterns.some(pattern => pattern.test(trimmedLine));
|
|
1258
1245
|
if (isNoise) continue;
|
package/mcp/manifest.json
CHANGED
|
@@ -292,6 +292,251 @@
|
|
|
292
292
|
}
|
|
293
293
|
]
|
|
294
294
|
},
|
|
295
|
+
{
|
|
296
|
+
"name": "force_cli_detection",
|
|
297
|
+
"description": "Force detection and status update for CLI tools (Claude Code, Codex CLI, Gemini CLI). Updates local cache and reports status to MCP server via Supabase.",
|
|
298
|
+
"inputSchema": {
|
|
299
|
+
"type": "object",
|
|
300
|
+
"properties": {
|
|
301
|
+
"user_id": {
|
|
302
|
+
"type": "string",
|
|
303
|
+
"description": "User ID for database status updates (optional for stdio-wrapper)",
|
|
304
|
+
"minLength": 1
|
|
305
|
+
},
|
|
306
|
+
"provider_id": {
|
|
307
|
+
"type": "string",
|
|
308
|
+
"description": "Specific CLI provider to detect (optional, detects all if not provided)",
|
|
309
|
+
"enum": ["claude_code", "codex_cli", "gemini_cli"]
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
"outputSchema": {
|
|
314
|
+
"type": "object",
|
|
315
|
+
"properties": {
|
|
316
|
+
"success": {
|
|
317
|
+
"type": "boolean",
|
|
318
|
+
"description": "Whether detection was successful"
|
|
319
|
+
},
|
|
320
|
+
"results": {
|
|
321
|
+
"type": "object",
|
|
322
|
+
"description": "Detection results for each provider",
|
|
323
|
+
"additionalProperties": {
|
|
324
|
+
"type": "object",
|
|
325
|
+
"properties": {
|
|
326
|
+
"available": {
|
|
327
|
+
"type": "boolean",
|
|
328
|
+
"description": "Whether CLI is available"
|
|
329
|
+
},
|
|
330
|
+
"authenticated": {
|
|
331
|
+
"type": "boolean",
|
|
332
|
+
"description": "Whether CLI is authenticated"
|
|
333
|
+
},
|
|
334
|
+
"version": {
|
|
335
|
+
"type": "string",
|
|
336
|
+
"description": "CLI version if available"
|
|
337
|
+
},
|
|
338
|
+
"path": {
|
|
339
|
+
"type": "string",
|
|
340
|
+
"description": "Path to CLI executable"
|
|
341
|
+
},
|
|
342
|
+
"error": {
|
|
343
|
+
"type": "string",
|
|
344
|
+
"description": "Error message if detection failed"
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
"message": {
|
|
350
|
+
"type": "string",
|
|
351
|
+
"description": "Human-readable result message"
|
|
352
|
+
},
|
|
353
|
+
"timestamp": {
|
|
354
|
+
"type": "string",
|
|
355
|
+
"description": "Detection timestamp"
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
"required": ["success", "results", "message", "timestamp"]
|
|
359
|
+
},
|
|
360
|
+
"examples": [
|
|
361
|
+
{
|
|
362
|
+
"description": "Detect all CLI providers",
|
|
363
|
+
"input": {
|
|
364
|
+
"user_id": "user_123"
|
|
365
|
+
},
|
|
366
|
+
"output": {
|
|
367
|
+
"success": true,
|
|
368
|
+
"results": {
|
|
369
|
+
"claude_code": {
|
|
370
|
+
"available": true,
|
|
371
|
+
"authenticated": true,
|
|
372
|
+
"version": "claude-code v1.2.3",
|
|
373
|
+
"path": "/usr/local/bin/claude"
|
|
374
|
+
},
|
|
375
|
+
"codex_cli": {
|
|
376
|
+
"available": false,
|
|
377
|
+
"authenticated": false,
|
|
378
|
+
"error": "Codex CLI not found in PATH. Install Codex CLI from OpenAI"
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
"message": "CLI detection completed for all providers",
|
|
382
|
+
"timestamp": "2024-01-15T10:30:00Z"
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
]
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"name": "get_cli_status",
|
|
389
|
+
"description": "Get current CLI status with caching support. Returns cached results if available and fresh, otherwise performs new detection.",
|
|
390
|
+
"inputSchema": {
|
|
391
|
+
"type": "object",
|
|
392
|
+
"properties": {
|
|
393
|
+
"user_id": {
|
|
394
|
+
"type": "string",
|
|
395
|
+
"description": "User ID for database status retrieval (optional for stdio-wrapper)",
|
|
396
|
+
"minLength": 1
|
|
397
|
+
},
|
|
398
|
+
"provider_id": {
|
|
399
|
+
"type": "string",
|
|
400
|
+
"description": "Specific CLI provider status to get (optional, gets all if not provided)",
|
|
401
|
+
"enum": ["claude_code", "codex_cli", "gemini_cli"]
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
"outputSchema": {
|
|
406
|
+
"type": "object",
|
|
407
|
+
"properties": {
|
|
408
|
+
"success": {
|
|
409
|
+
"type": "boolean",
|
|
410
|
+
"description": "Whether status retrieval was successful"
|
|
411
|
+
},
|
|
412
|
+
"results": {
|
|
413
|
+
"type": "object",
|
|
414
|
+
"description": "Status results for each provider",
|
|
415
|
+
"additionalProperties": {
|
|
416
|
+
"type": "object",
|
|
417
|
+
"properties": {
|
|
418
|
+
"available": {
|
|
419
|
+
"type": "boolean"
|
|
420
|
+
},
|
|
421
|
+
"authenticated": {
|
|
422
|
+
"type": "boolean"
|
|
423
|
+
},
|
|
424
|
+
"version": {
|
|
425
|
+
"type": "string"
|
|
426
|
+
},
|
|
427
|
+
"lastChecked": {
|
|
428
|
+
"type": "string",
|
|
429
|
+
"description": "Last status check timestamp"
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
"message": {
|
|
435
|
+
"type": "string"
|
|
436
|
+
},
|
|
437
|
+
"timestamp": {
|
|
438
|
+
"type": "string"
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
"required": ["success", "results"]
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
"name": "send_cli_prompt",
|
|
446
|
+
"description": "Send a prompt to a CLI provider and get response. Supports both stdin and argument modes for maximum compatibility.",
|
|
447
|
+
"inputSchema": {
|
|
448
|
+
"type": "object",
|
|
449
|
+
"properties": {
|
|
450
|
+
"provider_id": {
|
|
451
|
+
"type": "string",
|
|
452
|
+
"description": "CLI provider to send prompt to",
|
|
453
|
+
"enum": ["claude_code", "codex_cli", "gemini_cli"]
|
|
454
|
+
},
|
|
455
|
+
"prompt": {
|
|
456
|
+
"type": "string",
|
|
457
|
+
"description": "Prompt to send to the CLI",
|
|
458
|
+
"minLength": 1
|
|
459
|
+
},
|
|
460
|
+
"mode": {
|
|
461
|
+
"type": "string",
|
|
462
|
+
"description": "Prompt sending mode",
|
|
463
|
+
"enum": ["stdin", "args"],
|
|
464
|
+
"default": "args"
|
|
465
|
+
},
|
|
466
|
+
"timeout_ms": {
|
|
467
|
+
"type": "integer",
|
|
468
|
+
"description": "Timeout in milliseconds (90 seconds default for CLI-within-CLI scenarios)",
|
|
469
|
+
"minimum": 1000,
|
|
470
|
+
"maximum": 600000,
|
|
471
|
+
"default": 90000
|
|
472
|
+
},
|
|
473
|
+
"user_id": {
|
|
474
|
+
"type": "string",
|
|
475
|
+
"description": "User ID for usage tracking (optional)",
|
|
476
|
+
"minLength": 1
|
|
477
|
+
}
|
|
478
|
+
},
|
|
479
|
+
"required": ["prompt"]
|
|
480
|
+
},
|
|
481
|
+
"outputSchema": {
|
|
482
|
+
"type": "object",
|
|
483
|
+
"properties": {
|
|
484
|
+
"success": {
|
|
485
|
+
"type": "boolean",
|
|
486
|
+
"description": "Whether the prompt was sent successfully"
|
|
487
|
+
},
|
|
488
|
+
"content": {
|
|
489
|
+
"type": "string",
|
|
490
|
+
"description": "CLI response content"
|
|
491
|
+
},
|
|
492
|
+
"error": {
|
|
493
|
+
"type": "string",
|
|
494
|
+
"description": "Error message if prompt failed"
|
|
495
|
+
},
|
|
496
|
+
"tokens_used": {
|
|
497
|
+
"type": "integer",
|
|
498
|
+
"description": "Number of tokens used"
|
|
499
|
+
},
|
|
500
|
+
"latency_ms": {
|
|
501
|
+
"type": "integer",
|
|
502
|
+
"description": "Response latency in milliseconds"
|
|
503
|
+
},
|
|
504
|
+
"provider": {
|
|
505
|
+
"type": "string",
|
|
506
|
+
"description": "CLI provider used"
|
|
507
|
+
},
|
|
508
|
+
"mode": {
|
|
509
|
+
"type": "string",
|
|
510
|
+
"description": "Mode used for sending"
|
|
511
|
+
},
|
|
512
|
+
"timestamp": {
|
|
513
|
+
"type": "string",
|
|
514
|
+
"description": "Response timestamp"
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
"required": ["success", "provider", "timestamp"]
|
|
518
|
+
},
|
|
519
|
+
"examples": [
|
|
520
|
+
{
|
|
521
|
+
"description": "Send prompt to Claude Code",
|
|
522
|
+
"input": {
|
|
523
|
+
"provider_id": "claude_code",
|
|
524
|
+
"prompt": "Help me debug this TypeScript error: Property 'map' does not exist on type 'string'",
|
|
525
|
+
"mode": "args",
|
|
526
|
+
"user_id": "user_123"
|
|
527
|
+
},
|
|
528
|
+
"output": {
|
|
529
|
+
"success": true,
|
|
530
|
+
"content": "This error occurs when you're trying to use the .map() method on a string variable. The .map() method is an array method, not a string method...",
|
|
531
|
+
"tokens_used": 150,
|
|
532
|
+
"latency_ms": 1200,
|
|
533
|
+
"provider": "claude_code",
|
|
534
|
+
"mode": "args",
|
|
535
|
+
"timestamp": "2024-01-15T10:35:00Z"
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
]
|
|
539
|
+
},
|
|
295
540
|
{
|
|
296
541
|
"name": "enable_status_reporting",
|
|
297
542
|
"description": "Enable automatic CLI status reporting to polydev.ai server. Reports are sent when CLI detection runs and via periodic heartbeat. Requires a Polydev user token.",
|
package/mcp/stdio-wrapper.js
CHANGED
|
@@ -453,11 +453,7 @@ Token will be saved automatically after login.`
|
|
|
453
453
|
}
|
|
454
454
|
|
|
455
455
|
// Handle get_perspectives with local CLIs + remote perspectives
|
|
456
|
-
|
|
457
|
-
// (send_cli_prompt was removed from tool list to prevent AI models from choosing it
|
|
458
|
-
// over get_perspectives, but old clients may still call it)
|
|
459
|
-
if (toolName === 'get_perspectives' || toolName === 'polydev.get_perspectives' ||
|
|
460
|
-
toolName === 'send_cli_prompt' || toolName === 'polydev.send_cli_prompt') {
|
|
456
|
+
if (toolName === 'get_perspectives' || toolName === 'polydev.get_perspectives') {
|
|
461
457
|
return await this.handleGetPerspectivesWithCLIs(params, id);
|
|
462
458
|
}
|
|
463
459
|
|
|
@@ -1634,8 +1630,10 @@ To re-login: /polydev:login`
|
|
|
1634
1630
|
const cliTools = [
|
|
1635
1631
|
'force_cli_detection',
|
|
1636
1632
|
'get_cli_status',
|
|
1633
|
+
'send_cli_prompt',
|
|
1637
1634
|
'polydev.force_cli_detection',
|
|
1638
|
-
'polydev.get_cli_status'
|
|
1635
|
+
'polydev.get_cli_status',
|
|
1636
|
+
'polydev.send_cli_prompt'
|
|
1639
1637
|
];
|
|
1640
1638
|
return cliTools.includes(toolName);
|
|
1641
1639
|
}
|
|
@@ -1723,6 +1721,11 @@ To re-login: /polydev:login`
|
|
|
1723
1721
|
result = await this.localGetCliStatus(args);
|
|
1724
1722
|
break;
|
|
1725
1723
|
|
|
1724
|
+
case 'send_cli_prompt':
|
|
1725
|
+
case 'polydev.send_cli_prompt':
|
|
1726
|
+
result = await this.localSendCliPrompt(args);
|
|
1727
|
+
break;
|
|
1728
|
+
|
|
1726
1729
|
default:
|
|
1727
1730
|
throw new Error(`Unknown CLI tool: ${toolName}`);
|
|
1728
1731
|
}
|
|
@@ -2191,7 +2194,7 @@ To re-login: /polydev:login`
|
|
|
2191
2194
|
if (result.success) successCount++;
|
|
2192
2195
|
completedCount++;
|
|
2193
2196
|
|
|
2194
|
-
// Resolve early if we have enough successes OR all
|
|
2197
|
+
// Resolve early if we have enough successes OR all promises done
|
|
2195
2198
|
if (successCount >= needed || completedCount >= promises.length) {
|
|
2196
2199
|
resolved = true;
|
|
2197
2200
|
resolve([...results]); // Copy to prevent mutation from late arrivals
|
|
@@ -2459,7 +2462,7 @@ To re-login: /polydev:login`
|
|
|
2459
2462
|
user_token: this.userToken,
|
|
2460
2463
|
// Exclude providers that succeeded locally
|
|
2461
2464
|
exclude_providers: excludeProviders,
|
|
2462
|
-
// NEW: Specific providers to request (from API-only
|
|
2465
|
+
// NEW: Specific providers to request (from API-only list)
|
|
2463
2466
|
request_providers: requestProviders.length > 0 ? requestProviders : undefined,
|
|
2464
2467
|
// Pass CLI responses for dashboard logging
|
|
2465
2468
|
cli_responses: cliResponses,
|
|
@@ -2897,6 +2900,25 @@ To re-login: /polydev:login`
|
|
|
2897
2900
|
} else {
|
|
2898
2901
|
return `CLI Response (${result.provider || 'Unknown'} - ${result.mode || 'unknown'} mode)\n\n${result.content}\n\nLatency: ${result.latency_ms || 0}ms | Tokens: ${result.tokens_used || 0} | ${result.timestamp}`;
|
|
2899
2902
|
}
|
|
2903
|
+
} else {
|
|
2904
|
+
// Status/detection response
|
|
2905
|
+
let formatted = `CLI Operation Success\n\n`;
|
|
2906
|
+
formatted += `${result.message}\n\n`;
|
|
2907
|
+
|
|
2908
|
+
if (result.results) {
|
|
2909
|
+
formatted += `Results:\n`;
|
|
2910
|
+
for (const [providerId, status] of Object.entries(result.results)) {
|
|
2911
|
+
const icon = status.available ? '[+]' : '[-]';
|
|
2912
|
+
const authStatus = status.authenticated ? '[auth]' : '[no-auth]';
|
|
2913
|
+
formatted += `- ${icon} ${authStatus} ${providerId}: ${status.available ? 'Available' : 'Not Available'}`;
|
|
2914
|
+
if (status.version) formatted += ` (${status.version})`;
|
|
2915
|
+
if (status.error) formatted += ` - ${status.error}`;
|
|
2916
|
+
formatted += `\n`;
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
formatted += `\n${result.local_only ? 'Local execution' : 'Remote execution'} | ${result.timestamp}`;
|
|
2921
|
+
return formatted;
|
|
2900
2922
|
}
|
|
2901
2923
|
}
|
|
2902
2924
|
|
|
@@ -2941,7 +2963,7 @@ To re-login: /polydev:login`
|
|
|
2941
2963
|
this.userModelPreferences = result.modelPreferences;
|
|
2942
2964
|
this.modelPreferencesCacheTime = Date.now();
|
|
2943
2965
|
|
|
2944
|
-
// Also cache
|
|
2966
|
+
// Also cache perspectives_per_message setting (default 2)
|
|
2945
2967
|
this.perspectivesPerMessage = result.perspectivesPerMessage || 2;
|
|
2946
2968
|
|
|
2947
2969
|
// Cache provider order from user's dashboard (respects display_order)
|
|
@@ -3394,6 +3416,37 @@ function createSandboxServer() {
|
|
|
3394
3416
|
required: ['prompt']
|
|
3395
3417
|
}
|
|
3396
3418
|
},
|
|
3419
|
+
{
|
|
3420
|
+
name: 'get_cli_status',
|
|
3421
|
+
description: 'Check status of local CLI tools (Claude Code, Codex CLI, Gemini CLI)',
|
|
3422
|
+
inputSchema: {
|
|
3423
|
+
type: 'object',
|
|
3424
|
+
properties: {
|
|
3425
|
+
provider_id: {
|
|
3426
|
+
type: 'string',
|
|
3427
|
+
description: 'Optional specific provider to check'
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
},
|
|
3432
|
+
{
|
|
3433
|
+
name: 'force_cli_detection',
|
|
3434
|
+
description: 'Force re-detection of installed local CLI tools',
|
|
3435
|
+
inputSchema: { type: 'object', properties: {} }
|
|
3436
|
+
},
|
|
3437
|
+
{
|
|
3438
|
+
name: 'send_cli_prompt',
|
|
3439
|
+
description: 'Send prompt to local CLI with perspectives fallback',
|
|
3440
|
+
inputSchema: {
|
|
3441
|
+
type: 'object',
|
|
3442
|
+
properties: {
|
|
3443
|
+
provider_id: { type: 'string', description: 'CLI provider ID' },
|
|
3444
|
+
prompt: { type: 'string', description: 'Prompt to send' },
|
|
3445
|
+
mode: { type: 'string', enum: ['args', 'stdin'], default: 'args' }
|
|
3446
|
+
},
|
|
3447
|
+
required: ['provider_id', 'prompt']
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3397
3450
|
]
|
|
3398
3451
|
};
|
|
3399
3452
|
}
|