polydev-ai 1.9.27 → 1.9.29
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/mcp/stdio-wrapper.js +75 -148
- package/package.json +1 -1
package/mcp/stdio-wrapper.js
CHANGED
|
@@ -155,9 +155,6 @@ if (writableTmp) {
|
|
|
155
155
|
* Strips: provider info, approval, sandbox, reasoning, session id, MCP errors, etc.
|
|
156
156
|
*
|
|
157
157
|
* Codex CLI output structure:
|
|
158
|
-
* [metadata] → user → [echoed prompt] → thinking → [status] → codex → [RESPONSE] → tokens used → [count]
|
|
159
|
-
*
|
|
160
|
-
* Claude Code output structure:
|
|
161
158
|
* [may include JSON or plain text response]
|
|
162
159
|
*/
|
|
163
160
|
function cleanCliResponse(content) {
|
|
@@ -1046,9 +1043,28 @@ To authenticate, pass your token directly:
|
|
|
1046
1043
|
};
|
|
1047
1044
|
}
|
|
1048
1045
|
|
|
1049
|
-
// Not sandboxed — auto-
|
|
1050
|
-
console.error('[Polydev] No token found,
|
|
1051
|
-
return
|
|
1046
|
+
// Not sandboxed — tell user to use login tool (don't auto-open browser)
|
|
1047
|
+
console.error('[Polydev] No token found, prompting user to login');
|
|
1048
|
+
return {
|
|
1049
|
+
jsonrpc: '2.0',
|
|
1050
|
+
id,
|
|
1051
|
+
result: {
|
|
1052
|
+
content: [{
|
|
1053
|
+
type: 'text',
|
|
1054
|
+
text: `POLYDEV STATUS
|
|
1055
|
+
==============
|
|
1056
|
+
|
|
1057
|
+
Authentication: Not connected
|
|
1058
|
+
|
|
1059
|
+
To login:
|
|
1060
|
+
1. Use the "login" tool (opens browser)
|
|
1061
|
+
2. Or run: npx polydev-ai
|
|
1062
|
+
|
|
1063
|
+
Token will be saved automatically after login.`
|
|
1064
|
+
}],
|
|
1065
|
+
isError: true
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1052
1068
|
}
|
|
1053
1069
|
|
|
1054
1070
|
try {
|
|
@@ -1138,9 +1154,26 @@ Configure: https://polydev.ai/dashboard/models`
|
|
|
1138
1154
|
}
|
|
1139
1155
|
};
|
|
1140
1156
|
} else {
|
|
1141
|
-
// Token invalid/expired - auto-
|
|
1142
|
-
console.error('[Polydev] Auth status: token invalid/expired
|
|
1143
|
-
return
|
|
1157
|
+
// Token invalid/expired - tell user to re-login (don't auto-open browser)
|
|
1158
|
+
console.error('[Polydev] Auth status: token invalid/expired');
|
|
1159
|
+
return {
|
|
1160
|
+
jsonrpc: '2.0',
|
|
1161
|
+
id,
|
|
1162
|
+
result: {
|
|
1163
|
+
content: [{
|
|
1164
|
+
type: 'text',
|
|
1165
|
+
text: `POLYDEV STATUS
|
|
1166
|
+
==============
|
|
1167
|
+
|
|
1168
|
+
Authentication: Token invalid or expired
|
|
1169
|
+
|
|
1170
|
+
To re-authenticate:
|
|
1171
|
+
1. Use the "login" tool (opens browser)
|
|
1172
|
+
2. Or run: npx polydev-ai`
|
|
1173
|
+
}],
|
|
1174
|
+
isError: true
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1144
1177
|
}
|
|
1145
1178
|
} catch (error) {
|
|
1146
1179
|
// Categorize the error for clearer user messaging
|
|
@@ -1600,8 +1633,7 @@ To re-login: /polydev:login`
|
|
|
1600
1633
|
|
|
1601
1634
|
/**
|
|
1602
1635
|
* Start a periodic progress heartbeat to prevent client-side timeouts.
|
|
1603
|
-
* Sends a progress notification every intervalMs to
|
|
1604
|
-
* Compatible MCP clients will reset their timeout clock on each notification.
|
|
1636
|
+
* Sends a progress notification every intervalMs to keep the connection alive
|
|
1605
1637
|
* @param {string|number} progressToken - Token from request's _meta.progressToken
|
|
1606
1638
|
* @param {number} intervalMs - Heartbeat interval in milliseconds (default: 10s)
|
|
1607
1639
|
* @returns {{ stop: Function, tick: Function }} Controller to stop heartbeat and manually tick progress
|
|
@@ -1687,11 +1719,24 @@ To re-login: /polydev:login`
|
|
|
1687
1719
|
heartbeat.stop(); // Always clean up heartbeat
|
|
1688
1720
|
console.error(`[Stdio Wrapper] get_perspectives error:`, error);
|
|
1689
1721
|
|
|
1690
|
-
// Check if error is
|
|
1722
|
+
// Check if error is specifically an HTTP 401 unauthorized
|
|
1723
|
+
// IMPORTANT: Don't match generic 'token' or 'auth' strings — they appear in
|
|
1724
|
+
// unrelated errors like "Unexpected token" (JSON parse) or "authentication" (CLI output)
|
|
1691
1725
|
const errMsg = (error.message || '').toLowerCase();
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1726
|
+
const isHttp401 = errMsg.includes('401') || errMsg.includes('unauthorized');
|
|
1727
|
+
if (isHttp401) {
|
|
1728
|
+
console.error('[Polydev] Perspectives auth error (401), suggesting re-login');
|
|
1729
|
+
return {
|
|
1730
|
+
jsonrpc: '2.0',
|
|
1731
|
+
id,
|
|
1732
|
+
result: {
|
|
1733
|
+
content: [{
|
|
1734
|
+
type: 'text',
|
|
1735
|
+
text: `Authentication error: ${error.message}\n\nPlease re-authenticate using the "login" tool or run: npx polydev-ai`
|
|
1736
|
+
}],
|
|
1737
|
+
isError: true
|
|
1738
|
+
}
|
|
1739
|
+
};
|
|
1695
1740
|
}
|
|
1696
1741
|
|
|
1697
1742
|
return {
|
|
@@ -2676,8 +2721,8 @@ To re-login: /polydev:login`
|
|
|
2676
2721
|
const statusFile = path.join(polydevevDir, 'cli-status.json');
|
|
2677
2722
|
|
|
2678
2723
|
// Ensure directory exists
|
|
2679
|
-
if (!fs.existsSync(
|
|
2680
|
-
fs.mkdirSync(
|
|
2724
|
+
if (!fs.existsSync(polydeveevDir)) {
|
|
2725
|
+
fs.mkdirSync(polydeveevDir, { recursive: true });
|
|
2681
2726
|
}
|
|
2682
2727
|
|
|
2683
2728
|
// Save status with timestamp
|
|
@@ -3141,28 +3186,24 @@ To re-login: /polydev:login`
|
|
|
3141
3186
|
}
|
|
3142
3187
|
|
|
3143
3188
|
/**
|
|
3144
|
-
* Run startup flow -
|
|
3189
|
+
* Run startup flow - verify token if present, show instructions if not
|
|
3190
|
+
* NEVER auto-opens browser — only the explicit "login" tool should do that
|
|
3145
3191
|
*/
|
|
3146
3192
|
async runStartupFlow() {
|
|
3193
|
+
// Last-chance token reload before deciding
|
|
3194
|
+
if (!this.userToken) {
|
|
3195
|
+
this.reloadTokenFromFiles();
|
|
3196
|
+
}
|
|
3197
|
+
|
|
3147
3198
|
if (!this.userToken) {
|
|
3148
|
-
// No token
|
|
3199
|
+
// No token found — just log instructions, don't open browser
|
|
3149
3200
|
console.error('─'.repeat(50));
|
|
3150
|
-
console.error('Polydev -
|
|
3201
|
+
console.error('Polydev - Authentication Required');
|
|
3151
3202
|
console.error('─'.repeat(50));
|
|
3152
|
-
console.error('
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
console.error('[Polydev] Login completed, running CLI detection...');
|
|
3157
|
-
// After login, run CLI detection
|
|
3158
|
-
return this.localForceCliDetection({});
|
|
3159
|
-
}).then(() => {
|
|
3160
|
-
this._cliDetectionComplete = true;
|
|
3161
|
-
// Display CLI status after detection
|
|
3162
|
-
return this.displayCliStatus();
|
|
3163
|
-
}).catch((error) => {
|
|
3164
|
-
console.error('[Polydev] Auto-login flow error:', error.message);
|
|
3165
|
-
});
|
|
3203
|
+
console.error('No token found. To authenticate:');
|
|
3204
|
+
console.error(' 1. Use the "login" tool');
|
|
3205
|
+
console.error(' 2. Or run: npx polydev-ai');
|
|
3206
|
+
console.error('─'.repeat(50) + '\n');
|
|
3166
3207
|
} else {
|
|
3167
3208
|
// Has token - verify it (also non-blocking)
|
|
3168
3209
|
this.verifyAndDisplayAuth().catch((error) => {
|
|
@@ -3171,117 +3212,6 @@ To re-login: /polydev:login`
|
|
|
3171
3212
|
}
|
|
3172
3213
|
}
|
|
3173
3214
|
|
|
3174
|
-
/**
|
|
3175
|
-
* Auto-login on startup (opens browser automatically)
|
|
3176
|
-
*/
|
|
3177
|
-
async autoLoginOnStartup() {
|
|
3178
|
-
const http = require('http');
|
|
3179
|
-
const { spawn } = require('child_process');
|
|
3180
|
-
|
|
3181
|
-
return new Promise((resolve) => {
|
|
3182
|
-
const server = http.createServer((req, res) => {
|
|
3183
|
-
const url = new URL(req.url, `http://localhost`);
|
|
3184
|
-
|
|
3185
|
-
if (req.method === 'OPTIONS') {
|
|
3186
|
-
res.writeHead(204, {
|
|
3187
|
-
'Access-Control-Allow-Origin': '*',
|
|
3188
|
-
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
3189
|
-
'Access-Control-Allow-Headers': 'Content-Type'
|
|
3190
|
-
});
|
|
3191
|
-
res.end();
|
|
3192
|
-
return;
|
|
3193
|
-
}
|
|
3194
|
-
|
|
3195
|
-
if (url.pathname === '/callback') {
|
|
3196
|
-
const token = url.searchParams.get('token');
|
|
3197
|
-
|
|
3198
|
-
if (token && token.startsWith('pd_')) {
|
|
3199
|
-
this.saveTokenToFiles(token);
|
|
3200
|
-
this.userToken = token;
|
|
3201
|
-
this.isAuthenticated = true;
|
|
3202
|
-
this._freshLogin = true; // Flag for opening models page after CLI detection
|
|
3203
|
-
|
|
3204
|
-
res.writeHead(200, {
|
|
3205
|
-
'Content-Type': 'text/html; charset=utf-8',
|
|
3206
|
-
'Access-Control-Allow-Origin': '*'
|
|
3207
|
-
});
|
|
3208
|
-
res.end(this.getLoginSuccessHTML());
|
|
3209
|
-
|
|
3210
|
-
console.error('[Polydev] Login successful, token saved');
|
|
3211
|
-
|
|
3212
|
-
// Wait 7 seconds before closing server (gives time for 5s auto-close countdown + buffer)
|
|
3213
|
-
setTimeout(() => {
|
|
3214
|
-
server.close();
|
|
3215
|
-
resolve({
|
|
3216
|
-
jsonrpc: '2.0',
|
|
3217
|
-
id,
|
|
3218
|
-
result: {
|
|
3219
|
-
content: [{
|
|
3220
|
-
type: 'text',
|
|
3221
|
-
text: `LOGIN SUCCESSFUL
|
|
3222
|
-
================
|
|
3223
|
-
|
|
3224
|
-
Token saved to:
|
|
3225
|
-
~/.polydev.env
|
|
3226
|
-
~/.zshrc
|
|
3227
|
-
|
|
3228
|
-
IMPORTANT: Restart your IDE to activate.
|
|
3229
|
-
|
|
3230
|
-
After restart, you can:
|
|
3231
|
-
/polydev:ask Query multiple AI models
|
|
3232
|
-
/polydev:auth Check status & credits
|
|
3233
|
-
|
|
3234
|
-
Dashboard: https://polydev.ai/dashboard`
|
|
3235
|
-
}]
|
|
3236
|
-
}
|
|
3237
|
-
});
|
|
3238
|
-
}, 7000);
|
|
3239
|
-
} else {
|
|
3240
|
-
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
3241
|
-
res.end('Invalid or missing token');
|
|
3242
|
-
}
|
|
3243
|
-
} else {
|
|
3244
|
-
res.writeHead(404);
|
|
3245
|
-
res.end('Not found');
|
|
3246
|
-
}
|
|
3247
|
-
});
|
|
3248
|
-
|
|
3249
|
-
server.listen(0, 'localhost', () => {
|
|
3250
|
-
const port = server.address().port;
|
|
3251
|
-
const callbackUrl = `http://localhost:${port}/callback`;
|
|
3252
|
-
const authUrl = `https://polydev.ai/auth?callback=${encodeURIComponent(callbackUrl)}&redirect=ide-plugin&auto=true`;
|
|
3253
|
-
|
|
3254
|
-
console.error('If browser does not open, visit:');
|
|
3255
|
-
console.error(authUrl);
|
|
3256
|
-
console.error('');
|
|
3257
|
-
|
|
3258
|
-
// Best-in-class browser opening using 'open' package (cross-platform)
|
|
3259
|
-
// Falls back to platform-specific commands if package fails
|
|
3260
|
-
this.openBrowser(authUrl).catch(() => {
|
|
3261
|
-
console.error('[Polydev] All browser open methods failed');
|
|
3262
|
-
console.error('[Polydev] Please open this URL manually:', authUrl);
|
|
3263
|
-
});
|
|
3264
|
-
|
|
3265
|
-
// Don't block forever - resolve after timeout
|
|
3266
|
-
setTimeout(() => {
|
|
3267
|
-
if (!this.isAuthenticated) {
|
|
3268
|
-
console.error('[!] Login timeout - use "login" tool to try again');
|
|
3269
|
-
console.error('─'.repeat(50) + '\n');
|
|
3270
|
-
}
|
|
3271
|
-
server.close();
|
|
3272
|
-
resolve(false);
|
|
3273
|
-
}, 2 * 60 * 1000); // 2 minute timeout for startup
|
|
3274
|
-
});
|
|
3275
|
-
|
|
3276
|
-
server.on('error', (err) => {
|
|
3277
|
-
console.error('[!] Could not start login server:', err.message);
|
|
3278
|
-
console.error(' Use "login" tool or run: npx polydev-ai login');
|
|
3279
|
-
console.error('─'.repeat(50) + '\n');
|
|
3280
|
-
resolve(false);
|
|
3281
|
-
});
|
|
3282
|
-
});
|
|
3283
|
-
}
|
|
3284
|
-
|
|
3285
3215
|
/**
|
|
3286
3216
|
* Verify token and display auth status
|
|
3287
3217
|
*/
|
|
@@ -3309,9 +3239,6 @@ Dashboard: https://polydev.ai/dashboard`
|
|
|
3309
3239
|
console.error(`Credits: ${credits} | Tier: ${tier}`);
|
|
3310
3240
|
console.error('─'.repeat(50) + '\n');
|
|
3311
3241
|
} else {
|
|
3312
|
-
// Don't clear isAuthenticated here — handleGetAuthStatus has its own
|
|
3313
|
-
// verification and triggerReAuth logic. Clearing here causes a race condition
|
|
3314
|
-
// where startup verification can invalidate auth before the user checks status.
|
|
3315
3242
|
console.error('─'.repeat(50));
|
|
3316
3243
|
console.error('Polydev - Token may be invalid');
|
|
3317
3244
|
console.error('─'.repeat(50));
|