ai-or-die 0.1.46 → 0.1.47
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.
|
@@ -3,7 +3,10 @@ REM Mock devtunnel CLI for E2E testing.
|
|
|
3
3
|
REM Simulates the subcommands used by VSCodeTunnelManager's two-process model.
|
|
4
4
|
|
|
5
5
|
REM --- user show: auth check (exit 0 = authenticated) ---
|
|
6
|
-
if "%1"=="user" if "%2"=="show"
|
|
6
|
+
if "%1"=="user" if "%2"=="show" (
|
|
7
|
+
echo Logged in as mock-user using GitHub.
|
|
8
|
+
exit /b 0
|
|
9
|
+
)
|
|
7
10
|
|
|
8
11
|
REM --- user login: authenticate (exit 0 = success) ---
|
|
9
12
|
if "%1"=="user" if "%2"=="login" exit /b 0
|
package/package.json
CHANGED
package/src/tunnel-manager.js
CHANGED
|
@@ -21,7 +21,9 @@ class TunnelManager {
|
|
|
21
21
|
this.stopping = false;
|
|
22
22
|
this._restarting = false;
|
|
23
23
|
this.retryCount = 0;
|
|
24
|
-
this.
|
|
24
|
+
this._hostnameSlug = os.hostname().toLowerCase().replace(/[^a-z0-9-]/g, '');
|
|
25
|
+
this.tunnelId = `aiordie-${this._hostnameSlug}`;
|
|
26
|
+
this._authProvider = null;
|
|
25
27
|
|
|
26
28
|
// Resilience tracking
|
|
27
29
|
this._lastSpawnTime = null;
|
|
@@ -183,15 +185,20 @@ class TunnelManager {
|
|
|
183
185
|
|
|
184
186
|
/**
|
|
185
187
|
* Check if user is logged in. If not, attempt interactive login.
|
|
188
|
+
* Detects auth provider (GitHub vs Entra) and adjusts tunnel ID to avoid
|
|
189
|
+
* cross-provider name collisions.
|
|
186
190
|
*/
|
|
187
191
|
async _checkLogin() {
|
|
188
|
-
const
|
|
189
|
-
execFile('devtunnel', ['user', 'show'], { timeout: 10000 }, (err) => {
|
|
190
|
-
resolve(!err);
|
|
192
|
+
const result = await new Promise((resolve) => {
|
|
193
|
+
execFile('devtunnel', ['user', 'show'], { timeout: 10000 }, (err, stdout) => {
|
|
194
|
+
resolve({ ok: !err, stdout: (stdout || '').toString() });
|
|
191
195
|
});
|
|
192
196
|
});
|
|
193
197
|
|
|
194
|
-
if (
|
|
198
|
+
if (result.ok) {
|
|
199
|
+
this._applyAuthSuffix(result.stdout);
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
195
202
|
|
|
196
203
|
console.log(' DevTunnel requires authentication. Launching login...\n');
|
|
197
204
|
|
|
@@ -206,6 +213,13 @@ class TunnelManager {
|
|
|
206
213
|
|
|
207
214
|
if (loginOk) {
|
|
208
215
|
console.log('\n Login successful. Connecting tunnel...');
|
|
216
|
+
// Re-check to detect which provider was used
|
|
217
|
+
const recheck = await new Promise((resolve) => {
|
|
218
|
+
execFile('devtunnel', ['user', 'show'], { timeout: 10000 }, (err, stdout) => {
|
|
219
|
+
resolve((stdout || '').toString());
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
this._applyAuthSuffix(recheck);
|
|
209
223
|
return true;
|
|
210
224
|
}
|
|
211
225
|
|
|
@@ -213,6 +227,19 @@ class TunnelManager {
|
|
|
213
227
|
return false;
|
|
214
228
|
}
|
|
215
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Parse auth provider from `devtunnel user show` output and append
|
|
232
|
+
* a suffix to the tunnel ID when using GitHub auth. This prevents
|
|
233
|
+
* name collisions with tunnels created under a different provider.
|
|
234
|
+
*/
|
|
235
|
+
_applyAuthSuffix(userShowOutput) {
|
|
236
|
+
const match = userShowOutput.match(/using\s+(GitHub)/i);
|
|
237
|
+
if (match) {
|
|
238
|
+
this._authProvider = 'github';
|
|
239
|
+
this.tunnelId = `aiordie-${this._hostnameSlug}-gh`;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
216
243
|
/**
|
|
217
244
|
* Create the named tunnel and configure its port.
|
|
218
245
|
* Steps: devtunnel create <id> → devtunnel port create <id> -p <port>
|
package/src/vscode-tunnel.js
CHANGED
|
@@ -45,6 +45,7 @@ class VSCodeTunnelManager {
|
|
|
45
45
|
|
|
46
46
|
this._healthInterval = null;
|
|
47
47
|
this._reservedPorts = new Set();
|
|
48
|
+
this._authProvider = null;
|
|
48
49
|
|
|
49
50
|
// Kick off async command discovery at construction time
|
|
50
51
|
this._initPromise = Promise.all([
|
|
@@ -123,7 +124,7 @@ class VSCodeTunnelManager {
|
|
|
123
124
|
connectionToken,
|
|
124
125
|
localUrl: null,
|
|
125
126
|
publicUrl: null,
|
|
126
|
-
tunnelId: `aiordie-vscode-${sessionId.slice(0, 12).replace(/[^a-z0-9-]/gi, '')}`,
|
|
127
|
+
tunnelId: `aiordie-vscode-${sessionId.slice(0, 12).replace(/[^a-z0-9-]/gi, '')}${this._authProvider === 'github' ? '-gh' : ''}`,
|
|
127
128
|
status: 'starting',
|
|
128
129
|
sessionId,
|
|
129
130
|
workingDir: workingDir || process.cwd(),
|
|
@@ -161,6 +162,13 @@ class VSCodeTunnelManager {
|
|
|
161
162
|
return { success: false, error: 'Authentication failed or was cancelled' };
|
|
162
163
|
}
|
|
163
164
|
console.warn(`[VSCODE-TUNNEL] Session ${sessionId}: devtunnel login successful`);
|
|
165
|
+
// Re-check to detect auth provider after fresh login
|
|
166
|
+
await this._checkDevtunnelAuth();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Update tunnel ID with auth-provider suffix after detection
|
|
170
|
+
if (this._authProvider === 'github') {
|
|
171
|
+
tunnel.tunnelId = `aiordie-vscode-${sessionId.slice(0, 12).replace(/[^a-z0-9-]/gi, '')}-gh`;
|
|
164
172
|
}
|
|
165
173
|
|
|
166
174
|
// Start health check interval (once)
|
|
@@ -241,7 +249,7 @@ class VSCodeTunnelManager {
|
|
|
241
249
|
|
|
242
250
|
// Step 2: Clean up devtunnel (fire-and-forget)
|
|
243
251
|
if (this._devtunnelCommand) {
|
|
244
|
-
execFile(this._devtunnelCommand, ['delete', tunnel.tunnelId, '-
|
|
252
|
+
execFile(this._devtunnelCommand, ['delete', tunnel.tunnelId, '-f'], { timeout: 10000 }, () => {});
|
|
245
253
|
}
|
|
246
254
|
|
|
247
255
|
// Step 3: Kill server process
|
|
@@ -457,12 +465,22 @@ class VSCodeTunnelManager {
|
|
|
457
465
|
|
|
458
466
|
/**
|
|
459
467
|
* Check if user is authenticated with devtunnel (OS-level credential store).
|
|
468
|
+
* Also detects auth provider (GitHub vs Entra) for tunnel name suffixing.
|
|
460
469
|
*/
|
|
461
470
|
async _checkDevtunnelAuth() {
|
|
462
471
|
if (!this._devtunnelCommand) return false;
|
|
463
472
|
return new Promise((resolve) => {
|
|
464
|
-
execFile(this._devtunnelCommand, ['user', 'show'], { timeout: 10000 }, (err) => {
|
|
465
|
-
|
|
473
|
+
execFile(this._devtunnelCommand, ['user', 'show'], { timeout: 10000 }, (err, stdout) => {
|
|
474
|
+
if (err) {
|
|
475
|
+
resolve(false);
|
|
476
|
+
} else {
|
|
477
|
+
const output = (stdout || '').toString();
|
|
478
|
+
const match = output.match(/using\s+(GitHub)/i);
|
|
479
|
+
if (match) {
|
|
480
|
+
this._authProvider = 'github';
|
|
481
|
+
}
|
|
482
|
+
resolve(true);
|
|
483
|
+
}
|
|
466
484
|
});
|
|
467
485
|
});
|
|
468
486
|
}
|