coding-agent-adapters 0.7.3 → 0.7.5

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.cts CHANGED
@@ -1,13 +1,5 @@
1
1
  import { BaseCLIAdapter, SpawnConfig, AutoResponseRule, LoginDetection, BlockingPromptDetection, ParsedOutput } from 'pty-manager';
2
2
 
3
- /**
4
- * Shared types for coding-agent-adapters
5
- */
6
- /**
7
- * Supported adapter types
8
- */
9
- type AdapterType = 'claude' | 'gemini' | 'codex' | 'aider';
10
-
11
3
  /**
12
4
  * Approval Presets
13
5
  *
@@ -63,6 +55,10 @@ declare function getPresetDefinition(preset: ApprovalPreset): PresetDefinition;
63
55
  * for AI coding agents.
64
56
  */
65
57
 
58
+ /**
59
+ * Supported adapter types
60
+ */
61
+ type AdapterType = 'claude' | 'gemini' | 'codex' | 'aider';
66
62
  /**
67
63
  * Credentials that can be passed via SpawnConfig.adapterConfig
68
64
  */
package/dist/index.d.ts CHANGED
@@ -1,13 +1,5 @@
1
1
  import { BaseCLIAdapter, SpawnConfig, AutoResponseRule, LoginDetection, BlockingPromptDetection, ParsedOutput } from 'pty-manager';
2
2
 
3
- /**
4
- * Shared types for coding-agent-adapters
5
- */
6
- /**
7
- * Supported adapter types
8
- */
9
- type AdapterType = 'claude' | 'gemini' | 'codex' | 'aider';
10
-
11
3
  /**
12
4
  * Approval Presets
13
5
  *
@@ -63,6 +55,10 @@ declare function getPresetDefinition(preset: ApprovalPreset): PresetDefinition;
63
55
  * for AI coding agents.
64
56
  */
65
57
 
58
+ /**
59
+ * Supported adapter types
60
+ */
61
+ type AdapterType = 'claude' | 'gemini' | 'codex' | 'aider';
66
62
  /**
67
63
  * Credentials that can be passed via SpawnConfig.adapterConfig
68
64
  */
package/dist/index.js CHANGED
@@ -609,6 +609,15 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
609
609
  description: "Decline anonymous usage data",
610
610
  safe: true
611
611
  },
612
+ {
613
+ pattern: /how is claude doing this session\?\s*\(optional\)|1:\s*bad\s+2:\s*fine\s+3:\s*good\s+0:\s*dismiss/i,
614
+ type: "config",
615
+ response: "0",
616
+ responseType: "text",
617
+ description: "Dismiss optional Claude session survey",
618
+ safe: true,
619
+ once: true
620
+ },
612
621
  {
613
622
  pattern: /continue without.*\[y\/n\]/i,
614
623
  type: "config",
@@ -654,12 +663,18 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
654
663
  }
655
664
  getArgs(config) {
656
665
  const args = [];
666
+ const adapterConfig = config.adapterConfig;
657
667
  if (!this.isInteractive(config)) {
658
668
  args.push("--print");
659
669
  if (config.workdir) {
660
670
  args.push("--cwd", config.workdir);
661
671
  }
662
672
  }
673
+ if (adapterConfig?.resume) {
674
+ args.push("--resume", adapterConfig.resume);
675
+ } else if (adapterConfig?.continue) {
676
+ args.push("--continue");
677
+ }
663
678
  const approvalConfig = this.getApprovalConfig(config);
664
679
  if (approvalConfig) {
665
680
  args.push(...approvalConfig.cliFlags);
@@ -704,9 +719,6 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
704
719
  * Detect blocking prompts specific to Claude Code CLI
705
720
  */
706
721
  detectBlockingPrompt(output) {
707
- if (this.detectReady(output)) {
708
- return { detected: false };
709
- }
710
722
  const stripped = this.stripAnsi(output);
711
723
  const loginDetection = this.detectLogin(output);
712
724
  if (loginDetection.required) {
@@ -719,6 +731,39 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
719
731
  instructions: loginDetection.instructions
720
732
  };
721
733
  }
734
+ if (/how is claude doing this session\?\s*\(optional\)|1:\s*bad\s+2:\s*fine\s+3:\s*good\s+0:\s*dismiss/i.test(stripped)) {
735
+ return {
736
+ detected: true,
737
+ type: "config",
738
+ prompt: "Claude session survey",
739
+ options: ["1", "2", "3", "0"],
740
+ suggestedResponse: "0",
741
+ canAutoRespond: true,
742
+ instructions: "Optional survey prompt; reply 0 to dismiss"
743
+ };
744
+ }
745
+ if (/enter\/tab\/space to toggle.*esc to cancel|enter to confirm.*esc to cancel|esc to close/i.test(stripped)) {
746
+ return {
747
+ detected: true,
748
+ type: "config",
749
+ prompt: "Claude dialog awaiting navigation",
750
+ options: ["keys:enter", "keys:esc", "keys:down,enter"],
751
+ suggestedResponse: "keys:esc",
752
+ canAutoRespond: false,
753
+ instructions: "Use Enter/Esc or arrow keys to navigate this dialog"
754
+ };
755
+ }
756
+ if (/\/agents\b|\/chrome\b|\/config\b|\/tasks\b|\/skills\b|\/remote-env\b|press .* to navigate .* enter .* esc/i.test(stripped)) {
757
+ return {
758
+ detected: true,
759
+ type: "config",
760
+ prompt: "Claude menu navigation required",
761
+ options: ["keys:esc", "keys:enter", "keys:down,enter"],
762
+ suggestedResponse: "keys:esc",
763
+ canAutoRespond: false,
764
+ instructions: "Claude is showing an interactive menu; use arrow keys + Enter or Esc"
765
+ };
766
+ }
722
767
  if (/Do you want to|wants? (your )?permission|needs your permission/i.test(stripped)) {
723
768
  return {
724
769
  detected: true,
@@ -767,6 +812,9 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
767
812
  instructions: "Claude Code requesting file access permission"
768
813
  };
769
814
  }
815
+ if (this.detectReady(output)) {
816
+ return { detected: false };
817
+ }
770
818
  return super.detectBlockingPrompt(output);
771
819
  }
772
820
  /**
@@ -800,6 +848,10 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
800
848
  */
801
849
  detectTaskComplete(output) {
802
850
  const stripped = this.stripAnsi(output);
851
+ if (!stripped.trim()) return false;
852
+ if (/trust.*directory|do you want to|needs? your permission/i.test(stripped)) {
853
+ return false;
854
+ }
803
855
  const hasDuration = /[A-Z][A-Za-z' -]{2,40}\s+for\s+\d+(?:h\s+\d{1,2}m\s+\d{1,2}s|m\s+\d{1,2}s|s)/.test(stripped);
804
856
  const tail = stripped.slice(-300);
805
857
  const hasIdlePrompt = /❯/.test(tail);
@@ -813,14 +865,15 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
813
865
  }
814
866
  detectReady(output) {
815
867
  const stripped = this.stripAnsi(output);
868
+ if (!stripped.trim()) return false;
816
869
  if (/trust.*directory|do you want to|needs? your permission/i.test(stripped)) {
817
870
  return false;
818
871
  }
819
872
  const tail = stripped.slice(-300);
820
- return stripped.includes("How can I help") || stripped.includes("What would you like") || // v2.1+ shows "for shortcuts" hint when ready
821
- stripped.includes("for shortcuts") || // Match "claude> " or similar specific prompts, not bare ">"
822
- /claude>/i.test(tail) || // v2.1+ uses ❯ as the input prompt
823
- /❯/.test(tail);
873
+ const hasConversationalReadyText = stripped.includes("How can I help") || stripped.includes("What would you like");
874
+ const hasLegacyPrompt = /claude>/i.test(tail);
875
+ const hasShortcutsHint = stripped.includes("for shortcuts");
876
+ return hasConversationalReadyText || hasLegacyPrompt || hasShortcutsHint;
824
877
  }
825
878
  parseOutput(output) {
826
879
  const stripped = this.stripAnsi(output);
@@ -1338,22 +1391,26 @@ var CodexAdapter = class extends BaseCodingAdapter {
1338
1391
  }
1339
1392
  if (/preparing.?device.?code.?login/i.test(stripped) || /open.?this.?link.?in.?your.?browser/i.test(stripped) || /enter.?this.?one-time.?code/i.test(stripped)) {
1340
1393
  const codeMatch = stripped.match(/code[:\s]+([A-Z0-9-]+)/i);
1394
+ const deviceCode = codeMatch ? codeMatch[1] : void 0;
1341
1395
  const urlMatch = stripped.match(/https?:\/\/[^\s]+/);
1342
1396
  return {
1343
1397
  required: true,
1344
1398
  type: "device_code",
1345
1399
  url: urlMatch ? urlMatch[0] : void 0,
1346
- instructions: codeMatch ? `Enter code ${codeMatch[1]} at the URL` : "Device code authentication in progress \u2014 complete in browser"
1400
+ deviceCode,
1401
+ instructions: deviceCode ? `Enter code ${deviceCode} at the URL` : "Device code authentication in progress \u2014 complete in browser"
1347
1402
  };
1348
1403
  }
1349
1404
  if (stripped.includes("device code") || stripped.includes("Enter the code")) {
1350
1405
  const codeMatch = stripped.match(/code[:\s]+([A-Z0-9-]+)/i);
1406
+ const deviceCode = codeMatch ? codeMatch[1] : void 0;
1351
1407
  const urlMatch = stripped.match(/https?:\/\/[^\s]+/);
1352
1408
  return {
1353
1409
  required: true,
1354
1410
  type: "device_code",
1355
1411
  url: urlMatch ? urlMatch[0] : void 0,
1356
- instructions: codeMatch ? `Enter code ${codeMatch[1]} at the URL` : "Device code authentication required"
1412
+ deviceCode,
1413
+ instructions: deviceCode ? `Enter code ${deviceCode} at the URL` : "Device code authentication required"
1357
1414
  };
1358
1415
  }
1359
1416
  return { required: false };
@@ -1467,27 +1524,33 @@ var CodexAdapter = class extends BaseCodingAdapter {
1467
1524
  */
1468
1525
  detectTaskComplete(output) {
1469
1526
  const stripped = this.stripAnsi(output);
1527
+ if (!stripped.trim()) return false;
1470
1528
  const hasWorkedFor = /Worked\s+for\s+\d+(?:h\s+\d{2}m\s+\d{2}s|m\s+\d{2}s|s)/.test(stripped);
1471
- const hasReadyPrompt = /›\s+Ask\s+Codex\s+to\s+do\s+anything/.test(stripped);
1472
- if (hasWorkedFor && hasReadyPrompt) {
1529
+ const hasComposerPrompt = /›\s+Ask\s+Codex\s+to\s+do\s+anything/.test(stripped) || /^\s*›\s*(?!\d+\.)\S.*$/m.test(stripped);
1530
+ const hasIdleFooterHints = /\?\s+for\s+shortcuts/i.test(stripped) || /context\s+left/i.test(stripped) || /tab\s+to\s+queue\s+message/i.test(stripped);
1531
+ if (hasWorkedFor && (hasComposerPrompt || hasIdleFooterHints)) {
1473
1532
  return true;
1474
1533
  }
1475
- if (hasReadyPrompt) {
1534
+ if (hasComposerPrompt) {
1476
1535
  return true;
1477
1536
  }
1478
- if (hasWorkedFor && /›\s+/m.test(stripped)) {
1537
+ if (hasWorkedFor && hasIdleFooterHints) {
1479
1538
  return true;
1480
1539
  }
1481
1540
  return false;
1482
1541
  }
1483
1542
  detectReady(output) {
1484
1543
  const stripped = this.stripAnsi(output);
1544
+ if (!stripped.trim()) return false;
1545
+ const tail = stripped.slice(-1200);
1546
+ const hasComposerPrompt = /^\s*›\s*(?!\d+\.)\S.*$/m.test(tail) || /›\s+Ask\s+Codex\s+to\s+do\s+anything/.test(tail);
1547
+ const hasComposerFooter = /\?\s+for\s+shortcuts/i.test(tail) || /context\s+left/i.test(tail) || /tab\s+to\s+queue\s+message/i.test(tail) || /shift\s*\+\s*enter\s+for\s+newline/i.test(tail);
1548
+ if (hasComposerPrompt || hasComposerFooter) {
1549
+ return true;
1550
+ }
1485
1551
  if (/do.?you.?trust.?the.?contents/i.test(stripped) || /sign.?in.?with.?chatgpt/i.test(stripped) || /update.?available/i.test(stripped) || /enable.?full.?access/i.test(stripped) || /choose.?working.?directory/i.test(stripped)) {
1486
1552
  return false;
1487
1553
  }
1488
- if (/›\s+/m.test(stripped)) {
1489
- return true;
1490
- }
1491
1554
  if (/explain this codebase|summarize recent commits|find and fix a bug/i.test(stripped)) {
1492
1555
  return true;
1493
1556
  }