aptunnel 1.0.1 → 1.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aptunnel",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Cross-platform Aptible tunnel manager — multi-tunnel, auto-discovery, background process management",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,15 +37,16 @@ export async function runInit(args) {
37
37
  console.log('');
38
38
 
39
39
  // 4. Login (interactive — handles 2FA via stdio: inherit)
40
- // Close readline BEFORE spawning aptible so stdin is fully available to the child
40
+ // Do NOT show a spinner here: aptible may prompt for a 2FA OTP code and the
41
+ // spinner output would hide that prompt. Print a plain line instead.
41
42
  closeRL();
42
- const spinner = (await import('ora')).default({ text: 'Logging in to Aptible…' }).start();
43
+ console.log('Logging in to Aptible… (enter 2FA code if prompted)');
43
44
  const ok = await login({ email, password });
44
45
  if (!ok) {
45
- spinner.fail('Login failed. Please check your credentials.');
46
+ logger.error('Login failed. Please check your credentials.');
46
47
  process.exit(1);
47
48
  }
48
- spinner.succeed('Logged in successfully.');
49
+ logger.success('Logged in successfully.');
49
50
  console.log('');
50
51
 
51
52
  // 5. Discover environments
@@ -272,8 +273,9 @@ function closeRL() {
272
273
  _rl.close();
273
274
  _rl = null;
274
275
  }
275
- // Ensure stdin is resumed so child processes can read from it (e.g. aptible 2FA)
276
- process.stdin.resume();
276
+ // Do NOT call process.stdin.resume() here. Flowing mode with no listener
277
+ // discards keystrokes. Child processes (aptible) read from fd 0 directly
278
+ // at OS level regardless of Node.js stream state.
277
279
  }
278
280
 
279
281
  function ask(prompt) {
@@ -303,6 +305,9 @@ function askSecret(prompt) {
303
305
  if (char === '\r' || char === '\n') {
304
306
  process.stdin.removeListener('data', onData);
305
307
  if (isTTY) process.stdin.setRawMode(false);
308
+ // Pause so Node.js stops consuming keystrokes that belong to child
309
+ // processes (e.g. aptible login waiting for a 2FA OTP).
310
+ process.stdin.pause();
306
311
  process.stdout.write('\n');
307
312
  resolve(chars.join(''));
308
313
  return;
@@ -93,7 +93,6 @@ function getRL() {
93
93
  }
94
94
  function closeRL() {
95
95
  if (_rl) { _rl.close(); _rl = null; }
96
- process.stdin.resume();
97
96
  }
98
97
 
99
98
  function ask(prompt) {
@@ -120,6 +119,7 @@ function askSecret(prompt) {
120
119
  if (char === '\r' || char === '\n') {
121
120
  process.stdin.removeListener('data', onData);
122
121
  if (isTTY) process.stdin.setRawMode(false);
122
+ process.stdin.pause();
123
123
  process.stdout.write('\n');
124
124
  resolve(chars.join(''));
125
125
  return;
@@ -58,12 +58,10 @@ export function login({ email, password, lifetime = '7d', otp } = {}) {
58
58
  if (password) args.push(`--password=${password}`);
59
59
  if (otp) args.push(`--otp=${otp}`);
60
60
 
61
- // Resume stdin so aptible can receive input (e.g. 2FA OTP prompt).
62
- // readline.close() pauses process.stdin; we must unpause it before handing
63
- // it to a child process, otherwise the child's read() never returns.
64
- process.stdin.resume();
65
-
66
- // stdio: 'inherit' is critical — aptible prompts for 2FA interactively
61
+ // stdio: 'inherit' aptible reads from fd 0 directly at OS level,
62
+ // independent of Node.js stream state. Do NOT call process.stdin.resume()
63
+ // here: flowing mode with no listener would consume the user's 2FA keystrokes
64
+ // before aptible gets them.
67
65
  const child = spawn('aptible', args, { stdio: 'inherit', ...SHELL_OPT });
68
66
 
69
67
  child.on('close', (code) => resolve(code === 0));