pty-manager 1.6.8 → 1.7.0

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/dist/index.d.mts CHANGED
@@ -48,6 +48,10 @@ interface SpawnConfig {
48
48
  * - null value disables that rule entirely
49
49
  * - Object value merges fields into the matching adapter rule */
50
50
  ruleOverrides?: Record<string, Partial<Omit<AutoResponseRule, 'pattern'>> | null>;
51
+ /** When true, adapter detectBlockingPrompt() results with suggestedResponse
52
+ * are emitted as autoResponded=false instead of being auto-responded.
53
+ * Auto-response rules (ruleOverrides) are unaffected. */
54
+ skipAdapterAutoResponse?: boolean;
51
55
  }
52
56
  /**
53
57
  * Handle to a running session
@@ -99,8 +103,23 @@ interface LoginDetection {
99
103
  required: boolean;
100
104
  type?: 'api_key' | 'oauth' | 'browser' | 'device_code';
101
105
  url?: string;
106
+ deviceCode?: string;
102
107
  instructions?: string;
103
108
  }
109
+ /**
110
+ * Normalized authentication methods for runtime event consumers.
111
+ */
112
+ type AuthRequiredMethod = 'api_key' | 'oauth_browser' | 'device_code' | 'unknown';
113
+ /**
114
+ * Structured authentication-required payload emitted by PTY session/manager.
115
+ */
116
+ interface AuthRequiredInfo {
117
+ method: AuthRequiredMethod;
118
+ url?: string;
119
+ deviceCode?: string;
120
+ instructions?: string;
121
+ promptSnippet?: string;
122
+ }
104
123
  /**
105
124
  * Types of blocking prompts that can occur
106
125
  */
@@ -425,6 +444,7 @@ interface PTYSessionEvents {
425
444
  output: (data: string) => void;
426
445
  ready: () => void;
427
446
  login_required: (instructions?: string, url?: string) => void;
447
+ auth_required: (info: AuthRequiredInfo) => void;
428
448
  blocking_prompt: (prompt: BlockingPromptInfo, autoResponded: boolean) => void;
429
449
  message: (message: SessionMessage) => void;
430
450
  question: (question: string) => void;
@@ -527,6 +547,10 @@ declare class PTYSession extends EventEmitter {
527
547
  * Simple string hash for deduplication.
528
548
  */
529
549
  private simpleHash;
550
+ private mapLoginTypeToAuthMethod;
551
+ private extractDeviceCode;
552
+ private getPromptSnippet;
553
+ private emitAuthRequired;
530
554
  /**
531
555
  * Strip ANSI codes, cursor movement, box-drawing, and spinner characters.
532
556
  * Used for stall detection hashing and auto-response pattern matching.
@@ -697,6 +721,7 @@ interface PTYManagerEvents {
697
721
  session_stopped: (session: SessionHandle, reason: string) => void;
698
722
  session_error: (session: SessionHandle, error: string) => void;
699
723
  login_required: (session: SessionHandle, instructions?: string, url?: string) => void;
724
+ auth_required: (session: SessionHandle, info: AuthRequiredInfo) => void;
700
725
  blocking_prompt: (session: SessionHandle, promptInfo: BlockingPromptInfo, autoResponded: boolean) => void;
701
726
  message: (message: SessionMessage) => void;
702
727
  question: (session: SessionHandle, question: string) => void;
@@ -1156,4 +1181,4 @@ declare function isBun(): boolean;
1156
1181
  */
1157
1182
  declare function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager;
1158
1183
 
1159
- export { type AdapterFactoryConfig, AdapterRegistry, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type BuildTimelineOptions, BunCompatiblePTYManager, type BunPTYManagerOptions, type CLIAdapter, type LogOptions, type Logger, type LoginDetection, type MessageType, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, type ParsedOutput, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type SpawnConfig, type StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type WorkerSessionHandle, buildTaskCompletionTimeline, createAdapter, createPTYManager, extractTaskCompletionTraceRecords, isBun };
1184
+ export { type AdapterFactoryConfig, AdapterRegistry, type AuthRequiredInfo, type AuthRequiredMethod, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type BuildTimelineOptions, BunCompatiblePTYManager, type BunPTYManagerOptions, type CLIAdapter, type LogOptions, type Logger, type LoginDetection, type MessageType, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, type ParsedOutput, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type SpawnConfig, type StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type WorkerSessionHandle, buildTaskCompletionTimeline, createAdapter, createPTYManager, extractTaskCompletionTraceRecords, isBun };
package/dist/index.d.ts CHANGED
@@ -48,6 +48,10 @@ interface SpawnConfig {
48
48
  * - null value disables that rule entirely
49
49
  * - Object value merges fields into the matching adapter rule */
50
50
  ruleOverrides?: Record<string, Partial<Omit<AutoResponseRule, 'pattern'>> | null>;
51
+ /** When true, adapter detectBlockingPrompt() results with suggestedResponse
52
+ * are emitted as autoResponded=false instead of being auto-responded.
53
+ * Auto-response rules (ruleOverrides) are unaffected. */
54
+ skipAdapterAutoResponse?: boolean;
51
55
  }
52
56
  /**
53
57
  * Handle to a running session
@@ -99,8 +103,23 @@ interface LoginDetection {
99
103
  required: boolean;
100
104
  type?: 'api_key' | 'oauth' | 'browser' | 'device_code';
101
105
  url?: string;
106
+ deviceCode?: string;
102
107
  instructions?: string;
103
108
  }
109
+ /**
110
+ * Normalized authentication methods for runtime event consumers.
111
+ */
112
+ type AuthRequiredMethod = 'api_key' | 'oauth_browser' | 'device_code' | 'unknown';
113
+ /**
114
+ * Structured authentication-required payload emitted by PTY session/manager.
115
+ */
116
+ interface AuthRequiredInfo {
117
+ method: AuthRequiredMethod;
118
+ url?: string;
119
+ deviceCode?: string;
120
+ instructions?: string;
121
+ promptSnippet?: string;
122
+ }
104
123
  /**
105
124
  * Types of blocking prompts that can occur
106
125
  */
@@ -425,6 +444,7 @@ interface PTYSessionEvents {
425
444
  output: (data: string) => void;
426
445
  ready: () => void;
427
446
  login_required: (instructions?: string, url?: string) => void;
447
+ auth_required: (info: AuthRequiredInfo) => void;
428
448
  blocking_prompt: (prompt: BlockingPromptInfo, autoResponded: boolean) => void;
429
449
  message: (message: SessionMessage) => void;
430
450
  question: (question: string) => void;
@@ -527,6 +547,10 @@ declare class PTYSession extends EventEmitter {
527
547
  * Simple string hash for deduplication.
528
548
  */
529
549
  private simpleHash;
550
+ private mapLoginTypeToAuthMethod;
551
+ private extractDeviceCode;
552
+ private getPromptSnippet;
553
+ private emitAuthRequired;
530
554
  /**
531
555
  * Strip ANSI codes, cursor movement, box-drawing, and spinner characters.
532
556
  * Used for stall detection hashing and auto-response pattern matching.
@@ -697,6 +721,7 @@ interface PTYManagerEvents {
697
721
  session_stopped: (session: SessionHandle, reason: string) => void;
698
722
  session_error: (session: SessionHandle, error: string) => void;
699
723
  login_required: (session: SessionHandle, instructions?: string, url?: string) => void;
724
+ auth_required: (session: SessionHandle, info: AuthRequiredInfo) => void;
700
725
  blocking_prompt: (session: SessionHandle, promptInfo: BlockingPromptInfo, autoResponded: boolean) => void;
701
726
  message: (message: SessionMessage) => void;
702
727
  question: (session: SessionHandle, question: string) => void;
@@ -1156,4 +1181,4 @@ declare function isBun(): boolean;
1156
1181
  */
1157
1182
  declare function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager;
1158
1183
 
1159
- export { type AdapterFactoryConfig, AdapterRegistry, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type BuildTimelineOptions, BunCompatiblePTYManager, type BunPTYManagerOptions, type CLIAdapter, type LogOptions, type Logger, type LoginDetection, type MessageType, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, type ParsedOutput, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type SpawnConfig, type StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type WorkerSessionHandle, buildTaskCompletionTimeline, createAdapter, createPTYManager, extractTaskCompletionTraceRecords, isBun };
1184
+ export { type AdapterFactoryConfig, AdapterRegistry, type AuthRequiredInfo, type AuthRequiredMethod, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type BuildTimelineOptions, BunCompatiblePTYManager, type BunPTYManagerOptions, type CLIAdapter, type LogOptions, type Logger, type LoginDetection, type MessageType, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, type ParsedOutput, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type SpawnConfig, type StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type WorkerSessionHandle, buildTaskCompletionTimeline, createAdapter, createPTYManager, extractTaskCompletionTraceRecords, isBun };
package/dist/index.js CHANGED
@@ -98,19 +98,8 @@ var AdapterRegistry = class {
98
98
  // src/pty-session.ts
99
99
  var import_events = require("events");
100
100
  var import_crypto = require("crypto");
101
- var ptyCache = null;
102
- function loadPty() {
103
- if (!ptyCache) {
104
- try {
105
- ptyCache = require("node-pty");
106
- } catch {
107
- throw new Error(
108
- "node-pty is required but not installed. Run: npm install node-pty"
109
- );
110
- }
111
- }
112
- return ptyCache;
113
- }
101
+
102
+ // src/logger.ts
114
103
  var consoleLogger = {
115
104
  debug: (...args) => {
116
105
  if (typeof args[0] === "string") {
@@ -141,6 +130,21 @@ var consoleLogger = {
141
130
  }
142
131
  }
143
132
  };
133
+
134
+ // src/pty-session.ts
135
+ var ptyCache = null;
136
+ function loadPty() {
137
+ if (!ptyCache) {
138
+ try {
139
+ ptyCache = require("node-pty");
140
+ } catch {
141
+ throw new Error(
142
+ "node-pty is required but not installed. Run: npm install node-pty"
143
+ );
144
+ }
145
+ }
146
+ return ptyCache;
147
+ }
144
148
  function generateId() {
145
149
  return `pty-${Date.now()}-${(0, import_crypto.randomUUID)().slice(0, 8)}`;
146
150
  }
@@ -575,6 +579,51 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
575
579
  }
576
580
  return hash.toString(36);
577
581
  }
582
+ mapLoginTypeToAuthMethod(type) {
583
+ switch (type) {
584
+ case "api_key":
585
+ return "api_key";
586
+ case "device_code":
587
+ return "device_code";
588
+ case "oauth":
589
+ case "browser":
590
+ return "oauth_browser";
591
+ default:
592
+ return "unknown";
593
+ }
594
+ }
595
+ extractDeviceCode(text) {
596
+ const stripped = this.stripAnsiForClassifier(text);
597
+ const explicitMatch = stripped.match(
598
+ /(?:one-time|one time|device)?\s*code[:\s]+([A-Z0-9]{3,}(?:-[A-Z0-9]{3,})+)/i
599
+ );
600
+ if (explicitMatch?.[1]) {
601
+ return explicitMatch[1].toUpperCase();
602
+ }
603
+ if (!/code/i.test(stripped)) {
604
+ return void 0;
605
+ }
606
+ const fallbackMatch = stripped.match(/\b([A-Z0-9]{3,}(?:-[A-Z0-9]{3,})+)\b/);
607
+ return fallbackMatch?.[1]?.toUpperCase();
608
+ }
609
+ getPromptSnippet(maxChars = 280) {
610
+ const normalized = this.stripAnsiForClassifier(this.outputBuffer).replace(/\s+/g, " ").trim();
611
+ if (!normalized) {
612
+ return void 0;
613
+ }
614
+ return normalized.length <= maxChars ? normalized : normalized.slice(-maxChars);
615
+ }
616
+ emitAuthRequired(details) {
617
+ const info = {
618
+ method: this.mapLoginTypeToAuthMethod(details.type),
619
+ url: details.url,
620
+ deviceCode: details.deviceCode ?? this.extractDeviceCode(this.outputBuffer),
621
+ instructions: details.instructions,
622
+ promptSnippet: this.getPromptSnippet()
623
+ };
624
+ this.emit("auth_required", info);
625
+ this.emit("login_required", info.instructions, info.url);
626
+ }
578
627
  /**
579
628
  * Strip ANSI codes, cursor movement, box-drawing, and spinner characters.
580
629
  * Used for stall detection hashing and auto-response pattern matching.
@@ -934,7 +983,12 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
934
983
  if (loginDetection.required && this._status !== "authenticating") {
935
984
  this._status = "authenticating";
936
985
  this.clearStallTimer();
937
- this.emit("login_required", loginDetection.instructions, loginDetection.url);
986
+ this.emitAuthRequired({
987
+ type: loginDetection.type,
988
+ url: loginDetection.url,
989
+ deviceCode: loginDetection.deviceCode,
990
+ instructions: loginDetection.instructions
991
+ });
938
992
  this.logger.warn(
939
993
  { sessionId: this.id, loginType: loginDetection.type },
940
994
  "Login required"
@@ -977,7 +1031,7 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
977
1031
  instructions: detection.instructions,
978
1032
  url: detection.url
979
1033
  };
980
- if (detection.canAutoRespond && detection.suggestedResponse) {
1034
+ if (detection.canAutoRespond && detection.suggestedResponse && !this.config.skipAdapterAutoResponse) {
981
1035
  this.logger.info(
982
1036
  {
983
1037
  sessionId: this.id,
@@ -1000,7 +1054,13 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
1000
1054
  }
1001
1055
  if (detection.type === "login") {
1002
1056
  this._status = "authenticating";
1003
- this.emit("login_required", detection.instructions, detection.url);
1057
+ const inferred = this.adapter.detectLogin(this.outputBuffer);
1058
+ this.emitAuthRequired({
1059
+ type: inferred.required ? inferred.type : void 0,
1060
+ url: detection.url ?? inferred.url,
1061
+ deviceCode: inferred.required ? inferred.deviceCode : void 0,
1062
+ instructions: detection.instructions ?? inferred.instructions
1063
+ });
1004
1064
  }
1005
1065
  this.logger.warn(
1006
1066
  {
@@ -1289,36 +1349,6 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
1289
1349
  };
1290
1350
 
1291
1351
  // src/pty-manager.ts
1292
- var consoleLogger2 = {
1293
- debug: (...args) => {
1294
- if (typeof args[0] === "string") {
1295
- console.debug(args[0], args[1]);
1296
- } else {
1297
- console.debug(args[1], args[0]);
1298
- }
1299
- },
1300
- info: (...args) => {
1301
- if (typeof args[0] === "string") {
1302
- console.info(args[0], args[1]);
1303
- } else {
1304
- console.info(args[1], args[0]);
1305
- }
1306
- },
1307
- warn: (...args) => {
1308
- if (typeof args[0] === "string") {
1309
- console.warn(args[0], args[1]);
1310
- } else {
1311
- console.warn(args[1], args[0]);
1312
- }
1313
- },
1314
- error: (...args) => {
1315
- if (typeof args[0] === "string") {
1316
- console.error(args[0], args[1]);
1317
- } else {
1318
- console.error(args[1], args[0]);
1319
- }
1320
- }
1321
- };
1322
1352
  var PTYManager = class extends import_events2.EventEmitter {
1323
1353
  sessions = /* @__PURE__ */ new Map();
1324
1354
  outputLogs = /* @__PURE__ */ new Map();
@@ -1332,7 +1362,7 @@ var PTYManager = class extends import_events2.EventEmitter {
1332
1362
  constructor(config = {}) {
1333
1363
  super();
1334
1364
  this.adapters = new AdapterRegistry();
1335
- this.logger = config.logger || consoleLogger2;
1365
+ this.logger = config.logger || consoleLogger;
1336
1366
  this.maxLogLines = config.maxLogLines || 1e3;
1337
1367
  this._stallDetectionEnabled = config.stallDetectionEnabled ?? false;
1338
1368
  this._stallTimeoutMs = config.stallTimeoutMs ?? 8e3;
@@ -1393,6 +1423,9 @@ var PTYManager = class extends import_events2.EventEmitter {
1393
1423
  session.on("login_required", (instructions, url) => {
1394
1424
  this.emit("login_required", session.toHandle(), instructions, url);
1395
1425
  });
1426
+ session.on("auth_required", (info) => {
1427
+ this.emit("auth_required", session.toHandle(), info);
1428
+ });
1396
1429
  session.on("blocking_prompt", (promptInfo, autoResponded) => {
1397
1430
  this.emit("blocking_prompt", session.toHandle(), promptInfo, autoResponded);
1398
1431
  });
@@ -2430,6 +2463,14 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
2430
2463
  }
2431
2464
  break;
2432
2465
  }
2466
+ case "auth_required": {
2467
+ const session = this.sessions.get(id);
2468
+ if (session) {
2469
+ session.status = "authenticating";
2470
+ this.emit("auth_required", session, event.info);
2471
+ }
2472
+ break;
2473
+ }
2433
2474
  case "message": {
2434
2475
  const msg = event.message;
2435
2476
  this.emit("message", {