@runuai/host 0.9.50 → 0.9.51

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.
@@ -413,17 +413,35 @@ export class EngineLoginManager {
413
413
  /** Consume Claude's one-time code exactly once. */
414
414
  input(opId: string, text: string): boolean {
415
415
  const operation = this.operations.get(opId);
416
- if (
417
- !operation ||
418
- !this.isCurrent(operation) ||
419
- operation.engine !== "claude" ||
420
- operation.stage !== "awaiting_input" ||
421
- operation.inputUsed ||
422
- operation.finishing
423
- ) {
416
+ // Every rejection names itself in the host log: a silently dropped code
417
+ // reads as "Waiting for the host…" forever on the cloud pane (live
418
+ // 2026-08-20, the guard chain gave the operator nothing to act on).
419
+ // Never log `text` — it is one-time OAuth material.
420
+ if (!operation) {
421
+ console.warn(`[engine-login] input dropped: unknown opId ${opId}`);
422
+ return false;
423
+ }
424
+ const rejection = !this.isCurrent(operation)
425
+ ? "operation belongs to a previous bridge generation"
426
+ : operation.engine !== "claude"
427
+ ? `engine is ${operation.engine}, not claude`
428
+ : operation.stage !== "awaiting_input"
429
+ ? `stage is ${operation.stage}, not awaiting_input`
430
+ : operation.inputUsed
431
+ ? "a code was already submitted for this operation"
432
+ : operation.finishing
433
+ ? "the operation is already finishing"
434
+ : null;
435
+ if (rejection !== null) {
436
+ console.warn(
437
+ `[engine-login] input dropped for ${opId}: ${rejection}`,
438
+ );
424
439
  return false;
425
440
  }
426
441
  if (!isValidOneTimeInput(text)) {
442
+ console.warn(
443
+ `[engine-login] input rejected for ${opId}: failed one-time-input validation (length ${text.length})`,
444
+ );
427
445
  void this.fail(
428
446
  operation,
429
447
  "invalid_input",
@@ -431,6 +449,9 @@ export class EngineLoginManager {
431
449
  );
432
450
  return false;
433
451
  }
452
+ console.log(
453
+ `[engine-login] input accepted for ${opId} (${text.length} chars)`,
454
+ );
434
455
  operation.inputUsed = true;
435
456
  operation.outputTail = "";
436
457
  // CARRIAGE RETURN, not newline: `claude setup-token` is an Ink raw-mode
@@ -441,13 +462,20 @@ export class EngineLoginManager {
441
462
  // hung on exactly this.
442
463
  const value = `${text}\r`;
443
464
  if (!operation.process) {
465
+ console.log(
466
+ `[engine-login] input buffered for ${opId} (login process still starting)`,
467
+ );
444
468
  operation.pendingInput = value;
445
469
  return true;
446
470
  }
447
471
  try {
448
472
  operation.process.writeInput(value);
473
+ console.log(`[engine-login] input written to the login process for ${opId}`);
449
474
  return true;
450
475
  } catch {
476
+ console.warn(
477
+ `[engine-login] input write FAILED for ${opId}: the login process rejected stdin`,
478
+ );
451
479
  void this.fail(
452
480
  operation,
453
481
  "invalid_input",
@@ -643,6 +671,9 @@ export class EngineLoginManager {
643
671
  ? extractClaudeOAuthToken(operation.outputTail)
644
672
  : null;
645
673
  if (token) {
674
+ console.log(
675
+ `[engine-login] token detected in CLI output for ${operation.opId}; persisting`,
676
+ );
646
677
  operation.outputTail = "";
647
678
  this.beginClaudeFinish(operation, token);
648
679
  return;
@@ -650,6 +681,9 @@ export class EngineLoginManager {
650
681
  if (operation.stage === "starting") {
651
682
  const authorizeUrl = findSafeHttpsUrl(operation.outputTail);
652
683
  if (authorizeUrl) {
684
+ console.log(
685
+ `[engine-login] authorize URL found for ${operation.opId}; awaiting the one-time code`,
686
+ );
653
687
  operation.stage = "awaiting_input";
654
688
  safeEmit(operation.emit, authorizeEvent(operation, authorizeUrl));
655
689
  safeEmit(operation.emit, {
@@ -694,12 +728,17 @@ export class EngineLoginManager {
694
728
  if (operation.finishPromise) await operation.finishPromise;
695
729
  return;
696
730
  }
731
+ const evidence = lastSignificantOutputLine(operation.outputTail);
732
+ console.warn(
733
+ `[engine-login] login process for ${operation.opId} ended (exit ${result.code ?? "spawn-failed"}) before completion` +
734
+ (evidence ? `; last output: ${evidence}` : ""),
735
+ );
697
736
  await this.fail(
698
737
  operation,
699
738
  result.spawnFailed ? "unavailable" : "start_failed",
700
739
  result.spawnFailed
701
740
  ? "The login runtime is unavailable."
702
- : `${engineLabel(operation.engine)} login did not complete.`,
741
+ : `${engineLabel(operation.engine)} login did not complete.${evidence ? ` Last output: ${evidence}` : ""}`,
703
742
  );
704
743
  }
705
744
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runuai/host",
3
- "version": "0.9.50",
3
+ "version": "0.9.51",
4
4
  "description": "Uai host — runs ephemeral AI tasks in containers on a machine you control.",
5
5
  "license": "MIT",
6
6
  "author": "Uai Tech <team@runuai.com>",