polydev-ai 1.9.21 → 1.9.23

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 CHANGED
@@ -1180,10 +1180,14 @@ 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
+
1183
1187
  // First, try to extract the response between "codex" marker and "tokens used"
1184
1188
  // IMPORTANT: Use (?:^|\n) to match "codex" only at the start of a line
1185
1189
  // This prevents matching "codex" in model names like "gpt-5.2-codex"
1186
- const codexMarkerMatch = output.match(/(?:^|\n)codex\s*\n([\s\S]*?)(?:\n\s*tokens used|\n\s*$)/i);
1190
+ const codexMarkerMatch = cleanOutput.match(/(?:^|\n)codex\s*\n([\s\S]*?)(?:\n\s*tokens used|\n\s*$)/i);
1187
1191
  if (codexMarkerMatch && codexMarkerMatch[1]) {
1188
1192
  const extracted = codexMarkerMatch[1].trim();
1189
1193
  if (extracted.length > 0 && !extracted.startsWith('ERROR')) {
@@ -1192,7 +1196,7 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
1192
1196
  }
1193
1197
 
1194
1198
  // Fallback: Try to find bullet point responses
1195
- const bulletMatches = output.match(/•\s*(.+)/g);
1199
+ const bulletMatches = cleanOutput.match(/•\s*(.+)/g);
1196
1200
  if (bulletMatches && bulletMatches.length > 0) {
1197
1201
  const bulletContent = bulletMatches
1198
1202
  .map(m => m.replace(/^•\s*/, '').trim())
@@ -1204,8 +1208,9 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
1204
1208
  }
1205
1209
 
1206
1210
  // Last resort: Filter out known noise patterns line by line
1207
- const lines = output.split('\n');
1211
+ const lines = cleanOutput.split('\n');
1208
1212
  const contentLines = [];
1213
+ let seenTokensUsed = false;
1209
1214
 
1210
1215
  // Patterns to skip (Codex-specific noise)
1211
1216
  const noisePatterns = [
@@ -1225,7 +1230,6 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
1225
1230
  /^thinking$/i, // "thinking" marker
1226
1231
  /^codex$/i, // "codex" marker
1227
1232
  /^tokens used$/i, // Token count header
1228
- /^[\d,]+$/, // Just numbers (token counts)
1229
1233
  /^ERROR:\s*MCP/i, // MCP errors
1230
1234
  /MCP client for .* failed/i, // MCP client failures
1231
1235
  /handshake.*failed/i, // Handshake errors
@@ -1240,6 +1244,15 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
1240
1244
  for (const line of lines) {
1241
1245
  const trimmedLine = line.trim();
1242
1246
 
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
+
1243
1256
  // Check if line matches any noise pattern
1244
1257
  const isNoise = noisePatterns.some(pattern => pattern.test(trimmedLine));
1245
1258
  if (isNoise) continue;
package/mcp/manifest.json CHANGED
@@ -292,251 +292,6 @@
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
- },
540
295
  {
541
296
  "name": "enable_status_reporting",
542
297
  "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.",
@@ -453,7 +453,11 @@ Token will be saved automatically after login.`
453
453
  }
454
454
 
455
455
  // Handle get_perspectives with local CLIs + remote perspectives
456
- if (toolName === 'get_perspectives' || toolName === 'polydev.get_perspectives') {
456
+ // Also redirect send_cli_prompt get_perspectives for backward compat
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') {
457
461
  return await this.handleGetPerspectivesWithCLIs(params, id);
458
462
  }
459
463
 
@@ -1630,10 +1634,8 @@ To re-login: /polydev:login`
1630
1634
  const cliTools = [
1631
1635
  'force_cli_detection',
1632
1636
  'get_cli_status',
1633
- 'send_cli_prompt',
1634
1637
  'polydev.force_cli_detection',
1635
- 'polydev.get_cli_status',
1636
- 'polydev.send_cli_prompt'
1638
+ 'polydev.get_cli_status'
1637
1639
  ];
1638
1640
  return cliTools.includes(toolName);
1639
1641
  }
@@ -1721,11 +1723,6 @@ To re-login: /polydev:login`
1721
1723
  result = await this.localGetCliStatus(args);
1722
1724
  break;
1723
1725
 
1724
- case 'send_cli_prompt':
1725
- case 'polydev.send_cli_prompt':
1726
- result = await this.localSendCliPrompt(args);
1727
- break;
1728
-
1729
1726
  default:
1730
1727
  throw new Error(`Unknown CLI tool: ${toolName}`);
1731
1728
  }
@@ -2194,7 +2191,7 @@ To re-login: /polydev:login`
2194
2191
  if (result.success) successCount++;
2195
2192
  completedCount++;
2196
2193
 
2197
- // Resolve early if we have enough successes OR all promises done
2194
+ // Resolve early if we have enough successes OR all complete
2198
2195
  if (successCount >= needed || completedCount >= promises.length) {
2199
2196
  resolved = true;
2200
2197
  resolve([...results]); // Copy to prevent mutation from late arrivals
@@ -2462,7 +2459,7 @@ To re-login: /polydev:login`
2462
2459
  user_token: this.userToken,
2463
2460
  // Exclude providers that succeeded locally
2464
2461
  exclude_providers: excludeProviders,
2465
- // NEW: Specific providers to request (from API-only list)
2462
+ // NEW: Specific providers to request (from API-only providers)
2466
2463
  request_providers: requestProviders.length > 0 ? requestProviders : undefined,
2467
2464
  // Pass CLI responses for dashboard logging
2468
2465
  cli_responses: cliResponses,
@@ -2900,25 +2897,6 @@ To re-login: /polydev:login`
2900
2897
  } else {
2901
2898
  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}`;
2902
2899
  }
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;
2922
2900
  }
2923
2901
  }
2924
2902
 
@@ -2963,7 +2941,7 @@ To re-login: /polydev:login`
2963
2941
  this.userModelPreferences = result.modelPreferences;
2964
2942
  this.modelPreferencesCacheTime = Date.now();
2965
2943
 
2966
- // Also cache perspectives_per_message setting (default 2)
2944
+ // Also cache perspectivesPerMessage setting (default 2)
2967
2945
  this.perspectivesPerMessage = result.perspectivesPerMessage || 2;
2968
2946
 
2969
2947
  // Cache provider order from user's dashboard (respects display_order)
@@ -3416,37 +3394,6 @@ function createSandboxServer() {
3416
3394
  required: ['prompt']
3417
3395
  }
3418
3396
  },
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
- }
3450
3397
  ]
3451
3398
  };
3452
3399
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polydev-ai",
3
- "version": "1.9.21",
3
+ "version": "1.9.23",
4
4
  "engines": {
5
5
  "node": ">=20.x <=22.x"
6
6
  },