coding-agent-adapters 0.2.12 → 0.2.15
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/README.md +137 -85
- package/dist/index.cjs +410 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -4
- package/dist/index.d.ts +45 -4
- package/dist/index.js +410 -25
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -121,13 +121,14 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
121
121
|
*/
|
|
122
122
|
autoResponseRules = [
|
|
123
123
|
{
|
|
124
|
-
pattern: /trust.*folder|safety
|
|
124
|
+
pattern: /trust.*folder|safety.?check|project.you.created/i,
|
|
125
125
|
type: "permission",
|
|
126
126
|
response: "",
|
|
127
127
|
responseType: "keys",
|
|
128
128
|
keys: ["enter"],
|
|
129
129
|
description: "Accept trust prompt for working directory",
|
|
130
|
-
safe: true
|
|
130
|
+
safe: true,
|
|
131
|
+
once: true
|
|
131
132
|
},
|
|
132
133
|
{
|
|
133
134
|
pattern: /update available.*\[y\/n\]/i,
|
|
@@ -336,6 +337,43 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
336
337
|
],
|
|
337
338
|
docsUrl: "https://github.com/anthropics/gemini-cli#installation"
|
|
338
339
|
};
|
|
340
|
+
/**
|
|
341
|
+
* Auto-response rules for Gemini CLI.
|
|
342
|
+
* Gemini uses Ink/React TUI with arrow-key radio menus.
|
|
343
|
+
* Source: FolderTrustDialog.tsx, MultiFolderTrustDialog.tsx, CloudFreePrivacyNotice.tsx
|
|
344
|
+
*/
|
|
345
|
+
autoResponseRules = [
|
|
346
|
+
{
|
|
347
|
+
pattern: /do.?you.?trust.?this.?folder|trust.?folder|trust.?parent.?folder/i,
|
|
348
|
+
type: "permission",
|
|
349
|
+
response: "",
|
|
350
|
+
responseType: "keys",
|
|
351
|
+
keys: ["enter"],
|
|
352
|
+
description: "Trust current folder (default selection in radio menu)",
|
|
353
|
+
safe: true,
|
|
354
|
+
once: true
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
pattern: /trust.?the.?following.?folders.*(added|workspace)/i,
|
|
358
|
+
type: "permission",
|
|
359
|
+
response: "",
|
|
360
|
+
responseType: "keys",
|
|
361
|
+
keys: ["enter"],
|
|
362
|
+
description: "Trust multiple folders being added to workspace",
|
|
363
|
+
safe: true,
|
|
364
|
+
once: true
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
pattern: /allow.?google.?to.?use.?this.?data/i,
|
|
368
|
+
type: "config",
|
|
369
|
+
response: "",
|
|
370
|
+
responseType: "keys",
|
|
371
|
+
keys: ["down", "enter"],
|
|
372
|
+
description: 'Decline Google data collection (select "No")',
|
|
373
|
+
safe: true,
|
|
374
|
+
once: true
|
|
375
|
+
}
|
|
376
|
+
];
|
|
339
377
|
getRecommendedModels(_credentials) {
|
|
340
378
|
return {
|
|
341
379
|
powerful: "gemini-3-pro",
|
|
@@ -380,6 +418,27 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
380
418
|
instructions: "Set GOOGLE_API_KEY or GEMINI_API_KEY environment variable"
|
|
381
419
|
};
|
|
382
420
|
}
|
|
421
|
+
if (/enter.?gemini.?api.?key/i.test(stripped)) {
|
|
422
|
+
return {
|
|
423
|
+
required: true,
|
|
424
|
+
type: "api_key",
|
|
425
|
+
instructions: "Enter a Gemini API key or set GEMINI_API_KEY environment variable"
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
if (/how.?would.?you.?like.?to.?authenticate/i.test(stripped) || /get.?started/i.test(stripped) && /login.?with.?google|use.?gemini.?api.?key|vertex/i.test(stripped)) {
|
|
429
|
+
return {
|
|
430
|
+
required: true,
|
|
431
|
+
type: "oauth",
|
|
432
|
+
instructions: "Gemini CLI authentication required \u2014 select an auth method"
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
if (/waiting.?for.?auth/i.test(stripped)) {
|
|
436
|
+
return {
|
|
437
|
+
required: true,
|
|
438
|
+
type: "oauth",
|
|
439
|
+
instructions: "Waiting for browser authentication to complete"
|
|
440
|
+
};
|
|
441
|
+
}
|
|
383
442
|
if (stripped.includes("Sign in with Google") || stripped.includes("OAuth") || stripped.includes("accounts.google.com")) {
|
|
384
443
|
const urlMatch = stripped.match(/https?:\/\/[^\s]+/);
|
|
385
444
|
return {
|
|
@@ -400,7 +459,7 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
400
459
|
}
|
|
401
460
|
detectBlockingPrompt(output) {
|
|
402
461
|
const stripped = this.stripAnsi(output);
|
|
403
|
-
if (/
|
|
462
|
+
if (/apply.?this.?change\??/i.test(stripped) || /allow.?execution.?of/i.test(stripped) || /do.?you.?want.?to.?proceed\??/i.test(stripped) || /waiting.?for.?user.?confirmation/i.test(stripped)) {
|
|
404
463
|
return {
|
|
405
464
|
detected: true,
|
|
406
465
|
type: "permission",
|
|
@@ -421,6 +480,15 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
421
480
|
instructions: loginDetection.instructions
|
|
422
481
|
};
|
|
423
482
|
}
|
|
483
|
+
if (/further.?action.?is.?required/i.test(stripped) || /verify.?your.?account/i.test(stripped) || /waiting.?for.?verification/i.test(stripped)) {
|
|
484
|
+
return {
|
|
485
|
+
detected: true,
|
|
486
|
+
type: "config",
|
|
487
|
+
prompt: "Account verification required",
|
|
488
|
+
canAutoRespond: false,
|
|
489
|
+
instructions: "Your Gemini account requires verification before continuing"
|
|
490
|
+
};
|
|
491
|
+
}
|
|
424
492
|
if (/select.*model|choose.*model|gemini-/i.test(stripped) && /\d+\)/i.test(stripped)) {
|
|
425
493
|
return {
|
|
426
494
|
detected: true,
|
|
@@ -452,7 +520,16 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
452
520
|
}
|
|
453
521
|
detectReady(output) {
|
|
454
522
|
const stripped = this.stripAnsi(output);
|
|
455
|
-
|
|
523
|
+
if (/do.?you.?trust.?this.?folder/i.test(stripped) || /how.?would.?you.?like.?to.?authenticate/i.test(stripped) || /waiting.?for.?auth/i.test(stripped) || /allow.?google.?to.?use.?this.?data/i.test(stripped)) {
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
if (/type.?your.?message/i.test(stripped)) {
|
|
527
|
+
return true;
|
|
528
|
+
}
|
|
529
|
+
if (/^\s*[>!*]\s+/m.test(stripped) || /\(r:\)/.test(stripped)) {
|
|
530
|
+
return true;
|
|
531
|
+
}
|
|
532
|
+
return stripped.includes("How can I help") || stripped.includes("What would you like") || // Match "gemini> " prompt specifically, not bare ">"
|
|
456
533
|
/gemini>\s*$/i.test(stripped);
|
|
457
534
|
}
|
|
458
535
|
parseOutput(output) {
|
|
@@ -474,6 +551,27 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
474
551
|
}
|
|
475
552
|
};
|
|
476
553
|
}
|
|
554
|
+
/**
|
|
555
|
+
* Detect exit conditions specific to Gemini CLI.
|
|
556
|
+
* Source: FolderTrustDialog.tsx:127, LogoutConfirmationDialog.tsx:64
|
|
557
|
+
*/
|
|
558
|
+
detectExit(output) {
|
|
559
|
+
const stripped = this.stripAnsi(output);
|
|
560
|
+
if (/folder.?trust.?level.?must.?be.?selected.*exiting/i.test(stripped)) {
|
|
561
|
+
return {
|
|
562
|
+
exited: true,
|
|
563
|
+
code: 1,
|
|
564
|
+
error: "Gemini CLI exited because no folder trust level was selected"
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
if (/you are now logged out/i.test(stripped)) {
|
|
568
|
+
return {
|
|
569
|
+
exited: true,
|
|
570
|
+
code: 0
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
return super.detectExit(output);
|
|
574
|
+
}
|
|
477
575
|
getPromptPattern() {
|
|
478
576
|
return /gemini>\s*$/i;
|
|
479
577
|
}
|
|
@@ -495,11 +593,12 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
495
593
|
};
|
|
496
594
|
/**
|
|
497
595
|
* Auto-response rules for OpenAI Codex CLI.
|
|
498
|
-
* Codex uses
|
|
596
|
+
* Codex uses ratatui/crossterm full-screen TUI with arrow-key menus.
|
|
597
|
+
* Source: trust_directory.rs, update_prompt.rs, model_migration.rs, cwd_prompt.rs, chatwidget.rs, main.rs
|
|
499
598
|
*/
|
|
500
599
|
autoResponseRules = [
|
|
501
600
|
{
|
|
502
|
-
pattern: /
|
|
601
|
+
pattern: /update.?available.*->|update.?now|skip.?until.?next.?version/i,
|
|
503
602
|
type: "config",
|
|
504
603
|
response: "",
|
|
505
604
|
responseType: "keys",
|
|
@@ -508,12 +607,50 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
508
607
|
safe: true
|
|
509
608
|
},
|
|
510
609
|
{
|
|
511
|
-
pattern: /trust
|
|
610
|
+
pattern: /do.?you.?trust.?the.?contents|trust.?this.?directory|yes,?.?continue|prompt.?injection/i,
|
|
512
611
|
type: "permission",
|
|
513
612
|
response: "",
|
|
514
613
|
responseType: "keys",
|
|
515
614
|
keys: ["enter"],
|
|
516
|
-
description:
|
|
615
|
+
description: 'Trust directory contents (default: "Yes, continue")',
|
|
616
|
+
safe: true,
|
|
617
|
+
once: true
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
pattern: /choose.?how.?you.?d.?like.?codex.?to.?proceed|try.?new.?model|use.?existing.?model/i,
|
|
621
|
+
type: "config",
|
|
622
|
+
response: "",
|
|
623
|
+
responseType: "keys",
|
|
624
|
+
keys: ["enter"],
|
|
625
|
+
description: 'Accept model migration (default: "Try new model")',
|
|
626
|
+
safe: true,
|
|
627
|
+
once: true
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
pattern: /choose.?working.?directory.?to.?(resume|fork)/i,
|
|
631
|
+
type: "config",
|
|
632
|
+
response: "",
|
|
633
|
+
responseType: "keys",
|
|
634
|
+
keys: ["enter"],
|
|
635
|
+
description: "Accept default working directory for session resume",
|
|
636
|
+
safe: true
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
pattern: /enable.?full.?access\??/i,
|
|
640
|
+
type: "permission",
|
|
641
|
+
response: "",
|
|
642
|
+
responseType: "keys",
|
|
643
|
+
keys: ["enter"],
|
|
644
|
+
description: 'Confirm full access mode (default: "Yes, continue anyway")',
|
|
645
|
+
safe: true,
|
|
646
|
+
once: true
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
pattern: /continue.?anyway\?\s*\[y\/N\]/i,
|
|
650
|
+
type: "config",
|
|
651
|
+
response: "y",
|
|
652
|
+
responseType: "text",
|
|
653
|
+
description: "Confirm dumb terminal continuation",
|
|
517
654
|
safe: true
|
|
518
655
|
}
|
|
519
656
|
];
|
|
@@ -559,6 +696,23 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
559
696
|
instructions: "Set OPENAI_API_KEY environment variable or provide credentials in adapterConfig"
|
|
560
697
|
};
|
|
561
698
|
}
|
|
699
|
+
if (/sign.?in.?with.?chatgpt/i.test(stripped) || /sign.?in.?with.?device.?code/i.test(stripped) && !/open.?this.?link/i.test(stripped) || /provide.?your.?own.?api.?key/i.test(stripped)) {
|
|
700
|
+
return {
|
|
701
|
+
required: true,
|
|
702
|
+
type: "oauth",
|
|
703
|
+
instructions: "Codex authentication required \u2014 select a sign-in method or provide an API key"
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
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)) {
|
|
707
|
+
const codeMatch = stripped.match(/code[:\s]+([A-Z0-9-]+)/i);
|
|
708
|
+
const urlMatch = stripped.match(/https?:\/\/[^\s]+/);
|
|
709
|
+
return {
|
|
710
|
+
required: true,
|
|
711
|
+
type: "device_code",
|
|
712
|
+
url: urlMatch ? urlMatch[0] : void 0,
|
|
713
|
+
instructions: codeMatch ? `Enter code ${codeMatch[1]} at the URL` : "Device code authentication in progress \u2014 complete in browser"
|
|
714
|
+
};
|
|
715
|
+
}
|
|
562
716
|
if (stripped.includes("device code") || stripped.includes("Enter the code")) {
|
|
563
717
|
const codeMatch = stripped.match(/code[:\s]+([A-Z0-9-]+)/i);
|
|
564
718
|
const urlMatch = stripped.match(/https?:\/\/[^\s]+/);
|
|
@@ -572,10 +726,21 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
572
726
|
return { required: false };
|
|
573
727
|
}
|
|
574
728
|
/**
|
|
575
|
-
* Detect blocking prompts specific to OpenAI Codex CLI
|
|
729
|
+
* Detect blocking prompts specific to OpenAI Codex CLI.
|
|
730
|
+
* Source: approval_overlay.rs, chatwidget.rs, request_user_input/mod.rs
|
|
576
731
|
*/
|
|
577
732
|
detectBlockingPrompt(output) {
|
|
578
733
|
const stripped = this.stripAnsi(output);
|
|
734
|
+
if (/would.?you.?like.?to.?run.?the.?following.?command/i.test(stripped) || /do.?you.?want.?to.?approve.?access/i.test(stripped) || /would.?you.?like.?to.?make.?the.?following.?edits/i.test(stripped) || /press.?enter.?to.?confirm/i.test(stripped) && /esc.?to.?cancel/i.test(stripped)) {
|
|
735
|
+
return {
|
|
736
|
+
detected: true,
|
|
737
|
+
type: "permission",
|
|
738
|
+
prompt: "Codex tool approval",
|
|
739
|
+
suggestedResponse: "keys:enter",
|
|
740
|
+
canAutoRespond: true,
|
|
741
|
+
instructions: "Codex is asking permission to execute a command, approve access, or apply edits"
|
|
742
|
+
};
|
|
743
|
+
}
|
|
579
744
|
const loginDetection = this.detectLogin(output);
|
|
580
745
|
if (loginDetection.required) {
|
|
581
746
|
return {
|
|
@@ -587,6 +752,24 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
587
752
|
instructions: loginDetection.instructions
|
|
588
753
|
};
|
|
589
754
|
}
|
|
755
|
+
if (/set.?up.?default.?sandbox/i.test(stripped) || /use.?non-admin.?sandbox/i.test(stripped)) {
|
|
756
|
+
return {
|
|
757
|
+
detected: true,
|
|
758
|
+
type: "config",
|
|
759
|
+
prompt: "Windows sandbox setup",
|
|
760
|
+
canAutoRespond: false,
|
|
761
|
+
instructions: "Codex needs a sandbox configuration on Windows"
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
if (/type.?your.?answer/i.test(stripped) && /select.?an.?option/i.test(stripped)) {
|
|
765
|
+
return {
|
|
766
|
+
detected: true,
|
|
767
|
+
type: "unknown",
|
|
768
|
+
prompt: "Codex requesting structured user input",
|
|
769
|
+
canAutoRespond: false,
|
|
770
|
+
instructions: "Codex model is asking multi-step questions that require user input"
|
|
771
|
+
};
|
|
772
|
+
}
|
|
590
773
|
if (/select.*model|choose.*model|gpt-4|gpt-3\.5/i.test(stripped) && /\d+\)/i.test(stripped)) {
|
|
591
774
|
return {
|
|
592
775
|
detected: true,
|
|
@@ -618,7 +801,16 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
618
801
|
}
|
|
619
802
|
detectReady(output) {
|
|
620
803
|
const stripped = this.stripAnsi(output);
|
|
621
|
-
|
|
804
|
+
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)) {
|
|
805
|
+
return false;
|
|
806
|
+
}
|
|
807
|
+
if (/›\s+/m.test(stripped)) {
|
|
808
|
+
return true;
|
|
809
|
+
}
|
|
810
|
+
if (/explain this codebase|summarize recent commits|find and fix a bug/i.test(stripped)) {
|
|
811
|
+
return true;
|
|
812
|
+
}
|
|
813
|
+
return stripped.includes("How can I help") || /(?:codex|>)\s*$/i.test(stripped);
|
|
622
814
|
}
|
|
623
815
|
parseOutput(output) {
|
|
624
816
|
const stripped = this.stripAnsi(output);
|
|
@@ -638,6 +830,24 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
638
830
|
}
|
|
639
831
|
};
|
|
640
832
|
}
|
|
833
|
+
/**
|
|
834
|
+
* Detect exit conditions specific to Codex CLI.
|
|
835
|
+
* Source: main.rs:404, main.rs:414, main.rs:461
|
|
836
|
+
*/
|
|
837
|
+
detectExit(output) {
|
|
838
|
+
const stripped = this.stripAnsi(output);
|
|
839
|
+
if (/to.?continue.?this.?session,?.?run/i.test(stripped)) {
|
|
840
|
+
return { exited: true, code: 0 };
|
|
841
|
+
}
|
|
842
|
+
if (/update.?ran.?successfully.*restart.?codex/i.test(stripped)) {
|
|
843
|
+
return {
|
|
844
|
+
exited: true,
|
|
845
|
+
code: 0,
|
|
846
|
+
error: "Codex updated successfully \u2014 restart required"
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
return super.detectExit(output);
|
|
850
|
+
}
|
|
641
851
|
getPromptPattern() {
|
|
642
852
|
return /(?:codex|>)\s*$/i;
|
|
643
853
|
}
|
|
@@ -665,12 +875,42 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
665
875
|
};
|
|
666
876
|
/**
|
|
667
877
|
* Auto-response rules for Aider CLI.
|
|
668
|
-
* Aider uses plain text
|
|
669
|
-
*
|
|
878
|
+
* Aider uses plain text prompts via io.py:832 with (Y)es/(N)o format.
|
|
879
|
+
* All rules are responseType: 'text' — Aider never uses TUI menus.
|
|
880
|
+
*
|
|
881
|
+
* Decline rules come first to override the generic accept patterns.
|
|
670
882
|
*/
|
|
671
883
|
autoResponseRules = [
|
|
884
|
+
// ── Decline rules (specific, checked first) ────────────────────────
|
|
885
|
+
{
|
|
886
|
+
pattern: /allow collection of anonymous analytics/i,
|
|
887
|
+
type: "config",
|
|
888
|
+
response: "n",
|
|
889
|
+
responseType: "text",
|
|
890
|
+
description: "Decline Aider telemetry opt-in",
|
|
891
|
+
safe: true,
|
|
892
|
+
once: true
|
|
893
|
+
},
|
|
672
894
|
{
|
|
673
|
-
pattern: /
|
|
895
|
+
pattern: /would you like to see what.?s new in this version/i,
|
|
896
|
+
type: "config",
|
|
897
|
+
response: "n",
|
|
898
|
+
responseType: "text",
|
|
899
|
+
description: "Decline release notes offer",
|
|
900
|
+
safe: true,
|
|
901
|
+
once: true
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
pattern: /open a github issue pre-filled/i,
|
|
905
|
+
type: "config",
|
|
906
|
+
response: "n",
|
|
907
|
+
responseType: "text",
|
|
908
|
+
description: "Decline automatic bug report",
|
|
909
|
+
safe: true
|
|
910
|
+
},
|
|
911
|
+
// ── File / edit operations ──────────────────────────────────────────
|
|
912
|
+
{
|
|
913
|
+
pattern: /add .+ to the chat\?/i,
|
|
674
914
|
type: "permission",
|
|
675
915
|
response: "y",
|
|
676
916
|
responseType: "text",
|
|
@@ -678,7 +918,15 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
678
918
|
safe: true
|
|
679
919
|
},
|
|
680
920
|
{
|
|
681
|
-
pattern: /
|
|
921
|
+
pattern: /add url to the chat\?/i,
|
|
922
|
+
type: "permission",
|
|
923
|
+
response: "y",
|
|
924
|
+
responseType: "text",
|
|
925
|
+
description: "Allow Aider to add URL content to chat",
|
|
926
|
+
safe: true
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
pattern: /create new file\?/i,
|
|
682
930
|
type: "permission",
|
|
683
931
|
response: "y",
|
|
684
932
|
responseType: "text",
|
|
@@ -686,11 +934,96 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
686
934
|
safe: true
|
|
687
935
|
},
|
|
688
936
|
{
|
|
689
|
-
pattern: /
|
|
937
|
+
pattern: /allow edits to file/i,
|
|
938
|
+
type: "permission",
|
|
939
|
+
response: "y",
|
|
940
|
+
responseType: "text",
|
|
941
|
+
description: "Allow edits to file not yet in chat",
|
|
942
|
+
safe: true
|
|
943
|
+
},
|
|
944
|
+
{
|
|
945
|
+
pattern: /edit the files\?/i,
|
|
946
|
+
type: "permission",
|
|
947
|
+
response: "y",
|
|
948
|
+
responseType: "text",
|
|
949
|
+
description: "Accept architect mode edits",
|
|
950
|
+
safe: true
|
|
951
|
+
},
|
|
952
|
+
// ── Shell operations ────────────────────────────────────────────────
|
|
953
|
+
{
|
|
954
|
+
pattern: /run shell commands?\?/i,
|
|
955
|
+
type: "permission",
|
|
956
|
+
response: "y",
|
|
957
|
+
responseType: "text",
|
|
958
|
+
description: "Allow Aider to run shell commands",
|
|
959
|
+
safe: true
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
pattern: /add command output to the chat\?/i,
|
|
963
|
+
type: "permission",
|
|
964
|
+
response: "y",
|
|
965
|
+
responseType: "text",
|
|
966
|
+
description: "Add shell command output to chat context",
|
|
967
|
+
safe: true
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
pattern: /add \d+.*tokens of command output to the chat\?/i,
|
|
971
|
+
type: "permission",
|
|
972
|
+
response: "y",
|
|
973
|
+
responseType: "text",
|
|
974
|
+
description: "Add /run command output to chat context",
|
|
975
|
+
safe: true
|
|
976
|
+
},
|
|
977
|
+
// ── Setup / maintenance ─────────────────────────────────────────────
|
|
978
|
+
{
|
|
979
|
+
pattern: /no git repo found.*create one/i,
|
|
980
|
+
type: "config",
|
|
981
|
+
response: "y",
|
|
982
|
+
responseType: "text",
|
|
983
|
+
description: "Create git repo for change tracking",
|
|
984
|
+
safe: true,
|
|
985
|
+
once: true
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
pattern: /add .+ to \.gitignore/i,
|
|
989
|
+
type: "config",
|
|
990
|
+
response: "y",
|
|
991
|
+
responseType: "text",
|
|
992
|
+
description: "Update .gitignore with Aider patterns",
|
|
993
|
+
safe: true,
|
|
994
|
+
once: true
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
pattern: /run pip install\?/i,
|
|
998
|
+
type: "config",
|
|
999
|
+
response: "y",
|
|
1000
|
+
responseType: "text",
|
|
1001
|
+
description: "Install missing Python dependencies",
|
|
1002
|
+
safe: true
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
pattern: /install playwright\?/i,
|
|
1006
|
+
type: "config",
|
|
1007
|
+
response: "y",
|
|
1008
|
+
responseType: "text",
|
|
1009
|
+
description: "Install Playwright for web scraping",
|
|
1010
|
+
safe: true
|
|
1011
|
+
},
|
|
1012
|
+
// ── Other safe confirmations ────────────────────────────────────────
|
|
1013
|
+
{
|
|
1014
|
+
pattern: /fix lint errors in/i,
|
|
690
1015
|
type: "permission",
|
|
691
1016
|
response: "y",
|
|
692
1017
|
responseType: "text",
|
|
693
|
-
description: "
|
|
1018
|
+
description: "Accept lint error fix suggestion",
|
|
1019
|
+
safe: true
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
pattern: /try to proceed anyway\?/i,
|
|
1023
|
+
type: "config",
|
|
1024
|
+
response: "y",
|
|
1025
|
+
responseType: "text",
|
|
1026
|
+
description: "Continue despite context limit warning",
|
|
694
1027
|
safe: true
|
|
695
1028
|
}
|
|
696
1029
|
];
|
|
@@ -770,8 +1103,28 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
770
1103
|
instructions: "API key is invalid - please check your credentials"
|
|
771
1104
|
};
|
|
772
1105
|
}
|
|
1106
|
+
if (/login to openrouter or create a free account/i.test(stripped)) {
|
|
1107
|
+
return {
|
|
1108
|
+
required: true,
|
|
1109
|
+
type: "oauth",
|
|
1110
|
+
instructions: "Aider offering OpenRouter OAuth login \u2014 provide API keys to skip"
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
if (/please open this url in your browser to connect aider with openrouter/i.test(stripped) || /waiting up to 5 minutes for you to finish in the browser/i.test(stripped)) {
|
|
1114
|
+
const urlMatch = stripped.match(/https?:\/\/[^\s]+/);
|
|
1115
|
+
return {
|
|
1116
|
+
required: true,
|
|
1117
|
+
type: "browser",
|
|
1118
|
+
url: urlMatch ? urlMatch[0] : void 0,
|
|
1119
|
+
instructions: "Complete OpenRouter authentication in browser"
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
773
1122
|
return { required: false };
|
|
774
1123
|
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Detect blocking prompts specific to Aider CLI.
|
|
1126
|
+
* Source: io.py, onboarding.py, base_coder.py, report.py
|
|
1127
|
+
*/
|
|
775
1128
|
detectBlockingPrompt(output) {
|
|
776
1129
|
const stripped = this.stripAnsi(output);
|
|
777
1130
|
const loginDetection = this.detectLogin(output);
|
|
@@ -780,6 +1133,7 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
780
1133
|
detected: true,
|
|
781
1134
|
type: "login",
|
|
782
1135
|
prompt: loginDetection.instructions,
|
|
1136
|
+
url: loginDetection.url,
|
|
783
1137
|
canAutoRespond: false,
|
|
784
1138
|
instructions: loginDetection.instructions
|
|
785
1139
|
};
|
|
@@ -793,16 +1147,16 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
793
1147
|
instructions: "Please select a model or set AIDER_MODEL env var"
|
|
794
1148
|
};
|
|
795
1149
|
}
|
|
796
|
-
if (/
|
|
1150
|
+
if (/please answer with one of:/i.test(stripped)) {
|
|
797
1151
|
return {
|
|
798
1152
|
detected: true,
|
|
799
|
-
type: "
|
|
800
|
-
prompt: "
|
|
1153
|
+
type: "unknown",
|
|
1154
|
+
prompt: "Invalid confirmation input",
|
|
801
1155
|
canAutoRespond: false,
|
|
802
|
-
instructions: "Aider
|
|
1156
|
+
instructions: "Aider received an invalid response to a confirmation prompt"
|
|
803
1157
|
};
|
|
804
1158
|
}
|
|
805
|
-
if (/delete|remove|overwrite/i.test(stripped) && /\[y\/n\]/i.test(stripped)) {
|
|
1159
|
+
if (/delete|remove|overwrite/i.test(stripped) && (/\[y\/n\]/i.test(stripped) || /\(Y\)es\/\(N\)o/i.test(stripped))) {
|
|
806
1160
|
return {
|
|
807
1161
|
detected: true,
|
|
808
1162
|
type: "permission",
|
|
@@ -816,9 +1170,22 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
816
1170
|
}
|
|
817
1171
|
detectReady(output) {
|
|
818
1172
|
const stripped = this.stripAnsi(output);
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
1173
|
+
if (/login to openrouter/i.test(stripped) || /open this url in your browser/i.test(stripped) || /waiting up to 5 minutes/i.test(stripped)) {
|
|
1174
|
+
return false;
|
|
1175
|
+
}
|
|
1176
|
+
if (/(?:ask|code|architect|help)(?:\s+multi)?>\s*$/m.test(stripped) || /^multi>\s*$/m.test(stripped)) {
|
|
1177
|
+
return true;
|
|
1178
|
+
}
|
|
1179
|
+
if (/^Aider v\d+/m.test(stripped)) {
|
|
1180
|
+
return true;
|
|
1181
|
+
}
|
|
1182
|
+
if (/^(?:Readonly|Editable):/m.test(stripped)) {
|
|
1183
|
+
return true;
|
|
1184
|
+
}
|
|
1185
|
+
return (
|
|
1186
|
+
// Legacy prompt patterns
|
|
1187
|
+
stripped.includes("aider>") || /Added.*to the chat/i.test(stripped) || />\s*$/.test(stripped)
|
|
1188
|
+
);
|
|
822
1189
|
}
|
|
823
1190
|
parseOutput(output) {
|
|
824
1191
|
const stripped = this.stripAnsi(output);
|
|
@@ -839,8 +1206,26 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
839
1206
|
}
|
|
840
1207
|
};
|
|
841
1208
|
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Detect exit conditions specific to Aider.
|
|
1211
|
+
* Source: base_coder.py:994, base_coder.py:998, report.py:77, versioncheck.py:58
|
|
1212
|
+
*/
|
|
1213
|
+
detectExit(output) {
|
|
1214
|
+
const stripped = this.stripAnsi(output);
|
|
1215
|
+
if (/\^C again to exit/i.test(stripped) || /\^C KeyboardInterrupt/i.test(stripped)) {
|
|
1216
|
+
return { exited: true, code: 130 };
|
|
1217
|
+
}
|
|
1218
|
+
if (/re-run aider to use new version/i.test(stripped)) {
|
|
1219
|
+
return {
|
|
1220
|
+
exited: true,
|
|
1221
|
+
code: 0,
|
|
1222
|
+
error: "Aider updated \u2014 restart required"
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
return super.detectExit(output);
|
|
1226
|
+
}
|
|
842
1227
|
getPromptPattern() {
|
|
843
|
-
return /(?:aider
|
|
1228
|
+
return /(?:ask|code|architect|help|aider|multi)(?:\s+multi)?>\s*$/i;
|
|
844
1229
|
}
|
|
845
1230
|
getHealthCheckCommand() {
|
|
846
1231
|
return "aider --version";
|