coding-agent-adapters 0.11.1 → 0.12.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.cjs +568 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -5
- package/dist/index.d.ts +103 -5
- package/dist/index.js +567 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -335,6 +335,16 @@ function generateAiderApprovalConfig(preset) {
|
|
|
335
335
|
summary: `Aider: ${def.description}`
|
|
336
336
|
};
|
|
337
337
|
}
|
|
338
|
+
function generateHermesApprovalConfig(preset) {
|
|
339
|
+
const def = getPresetDefinition(preset);
|
|
340
|
+
return {
|
|
341
|
+
preset,
|
|
342
|
+
cliFlags: [],
|
|
343
|
+
workspaceFiles: [],
|
|
344
|
+
envVars: {},
|
|
345
|
+
summary: `Hermes Agent: ${def.description}`
|
|
346
|
+
};
|
|
347
|
+
}
|
|
338
348
|
function generateApprovalConfig(adapterType, preset) {
|
|
339
349
|
switch (adapterType) {
|
|
340
350
|
case "claude":
|
|
@@ -345,6 +355,8 @@ function generateApprovalConfig(adapterType, preset) {
|
|
|
345
355
|
return generateCodexApprovalConfig(preset);
|
|
346
356
|
case "aider":
|
|
347
357
|
return generateAiderApprovalConfig(preset);
|
|
358
|
+
case "hermes":
|
|
359
|
+
return generateHermesApprovalConfig(preset);
|
|
348
360
|
default:
|
|
349
361
|
throw new Error(`Unknown adapter type: ${adapterType}`);
|
|
350
362
|
}
|
|
@@ -422,6 +434,13 @@ var BaseCodingAdapter = class extends BaseCLIAdapter {
|
|
|
422
434
|
result = result.replace(/ {2,}/g, " ");
|
|
423
435
|
return result;
|
|
424
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* Generate hook telemetry protocol configuration.
|
|
439
|
+
* Returns null by default — only Claude adapter supports hooks.
|
|
440
|
+
*/
|
|
441
|
+
getHookTelemetryProtocol(_options) {
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
425
444
|
/**
|
|
426
445
|
* Override detectExit to include installation instructions
|
|
427
446
|
*/
|
|
@@ -547,6 +566,7 @@ Docs: ${this.installation.docsUrl}`
|
|
|
547
566
|
};
|
|
548
567
|
|
|
549
568
|
// src/claude-adapter.ts
|
|
569
|
+
var CLAUDE_HOOK_MARKER_PREFIX = "PARALLAX_CLAUDE_HOOK";
|
|
550
570
|
var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
551
571
|
adapterType = "claude";
|
|
552
572
|
displayName = "Claude Code";
|
|
@@ -584,7 +604,8 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
584
604
|
responseType: "keys",
|
|
585
605
|
keys: ["enter"],
|
|
586
606
|
description: "Auto-approve tool permission prompts (file access, MCP tools, etc.)",
|
|
587
|
-
safe: true
|
|
607
|
+
safe: true,
|
|
608
|
+
once: true
|
|
588
609
|
},
|
|
589
610
|
{
|
|
590
611
|
pattern: /update available.*\[y\/n\]/i,
|
|
@@ -693,6 +714,7 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
693
714
|
getEnv(config) {
|
|
694
715
|
const env = {};
|
|
695
716
|
const credentials = this.getCredentials(config);
|
|
717
|
+
const adapterConfig = config.adapterConfig;
|
|
696
718
|
if (credentials.anthropicKey) {
|
|
697
719
|
env.ANTHROPIC_API_KEY = credentials.anthropicKey;
|
|
698
720
|
}
|
|
@@ -702,8 +724,110 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
702
724
|
if (!this.isInteractive(config)) {
|
|
703
725
|
env.CLAUDE_CODE_DISABLE_INTERACTIVE = "true";
|
|
704
726
|
}
|
|
727
|
+
if (adapterConfig?.claudeHookTelemetry) {
|
|
728
|
+
env.PARALLAX_CLAUDE_HOOK_TELEMETRY = "1";
|
|
729
|
+
env.PARALLAX_CLAUDE_HOOK_MARKER_PREFIX = adapterConfig.claudeHookMarkerPrefix || CLAUDE_HOOK_MARKER_PREFIX;
|
|
730
|
+
}
|
|
705
731
|
return env;
|
|
706
732
|
}
|
|
733
|
+
getHookTelemetryProtocol(options) {
|
|
734
|
+
if (options?.httpUrl) {
|
|
735
|
+
const httpHookBase = {
|
|
736
|
+
type: "http",
|
|
737
|
+
url: options.httpUrl,
|
|
738
|
+
timeout: 5
|
|
739
|
+
};
|
|
740
|
+
if (options.sessionId) {
|
|
741
|
+
httpHookBase.headers = { "X-Parallax-Session-Id": options.sessionId };
|
|
742
|
+
}
|
|
743
|
+
const hookEntry2 = [{ matcher: "", hooks: [{ ...httpHookBase }] }];
|
|
744
|
+
const hookEntryNoMatcher = [{ hooks: [{ ...httpHookBase }] }];
|
|
745
|
+
const settingsHooks2 = {
|
|
746
|
+
PermissionRequest: hookEntryNoMatcher,
|
|
747
|
+
PreToolUse: hookEntry2,
|
|
748
|
+
Stop: hookEntryNoMatcher,
|
|
749
|
+
Notification: hookEntry2,
|
|
750
|
+
TaskCompleted: hookEntryNoMatcher
|
|
751
|
+
};
|
|
752
|
+
return {
|
|
753
|
+
markerPrefix: "",
|
|
754
|
+
scriptPath: "",
|
|
755
|
+
scriptContent: "",
|
|
756
|
+
settingsHooks: settingsHooks2
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
const markerPrefix = options?.markerPrefix || CLAUDE_HOOK_MARKER_PREFIX;
|
|
760
|
+
const scriptPath = options?.scriptPath || ".claude/hooks/parallax-hook-telemetry.sh";
|
|
761
|
+
const scriptCommand = `"${"$"}CLAUDE_PROJECT_DIR"/${scriptPath}`;
|
|
762
|
+
const hookEntry = [{ matcher: "", hooks: [{ type: "command", command: scriptCommand }] }];
|
|
763
|
+
const settingsHooks = {
|
|
764
|
+
Notification: hookEntry,
|
|
765
|
+
PreToolUse: hookEntry,
|
|
766
|
+
TaskCompleted: hookEntry,
|
|
767
|
+
SessionEnd: hookEntry
|
|
768
|
+
};
|
|
769
|
+
const scriptContent = `#!/usr/bin/env bash
|
|
770
|
+
set -euo pipefail
|
|
771
|
+
|
|
772
|
+
INPUT="$(cat)"
|
|
773
|
+
[ -z "${"$"}INPUT" ] && exit 0
|
|
774
|
+
|
|
775
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
776
|
+
exit 0
|
|
777
|
+
fi
|
|
778
|
+
|
|
779
|
+
EVENT="$(printf '%s' "${"$"}INPUT" | jq -r '.hook_event_name // empty')"
|
|
780
|
+
[ -z "${"$"}EVENT" ] && exit 0
|
|
781
|
+
|
|
782
|
+
NOTIFICATION_TYPE="$(printf '%s' "${"$"}INPUT" | jq -r '.notification_type // empty')"
|
|
783
|
+
TOOL_NAME="$(printf '%s' "${"$"}INPUT" | jq -r '.tool_name // empty')"
|
|
784
|
+
MESSAGE="$(printf '%s' "${"$"}INPUT" | jq -r '.message // empty')"
|
|
785
|
+
|
|
786
|
+
printf '%s ' '${markerPrefix}'
|
|
787
|
+
jq -nc --arg event "${"$"}EVENT" --arg notification_type "${"$"}NOTIFICATION_TYPE" --arg tool_name "${"$"}TOOL_NAME" --arg message "${"$"}MESSAGE" '({event: $event}
|
|
788
|
+
+ (if $notification_type != "" then {notification_type: $notification_type} else {} end)
|
|
789
|
+
+ (if $tool_name != "" then {tool_name: $tool_name} else {} end)
|
|
790
|
+
+ (if $message != "" then {message: $message} else {} end))'
|
|
791
|
+
`;
|
|
792
|
+
return {
|
|
793
|
+
markerPrefix,
|
|
794
|
+
scriptPath,
|
|
795
|
+
scriptContent,
|
|
796
|
+
settingsHooks
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
getHookMarkers(output) {
|
|
800
|
+
const markers = [];
|
|
801
|
+
const markerRegex = /(?:^|\n)\s*([A-Z0-9_]+)\s+(\{[^\n\r]+\})/g;
|
|
802
|
+
let match;
|
|
803
|
+
while ((match = markerRegex.exec(output)) !== null) {
|
|
804
|
+
const markerToken = match[1];
|
|
805
|
+
if (!markerToken.includes("CLAUDE_HOOK")) {
|
|
806
|
+
continue;
|
|
807
|
+
}
|
|
808
|
+
const payload = match[2];
|
|
809
|
+
try {
|
|
810
|
+
const parsed = JSON.parse(payload);
|
|
811
|
+
const event = typeof parsed.event === "string" ? parsed.event : void 0;
|
|
812
|
+
if (!event) continue;
|
|
813
|
+
markers.push({
|
|
814
|
+
event,
|
|
815
|
+
notification_type: typeof parsed.notification_type === "string" ? parsed.notification_type : void 0,
|
|
816
|
+
tool_name: typeof parsed.tool_name === "string" ? parsed.tool_name : void 0,
|
|
817
|
+
message: typeof parsed.message === "string" ? parsed.message : void 0
|
|
818
|
+
});
|
|
819
|
+
} catch {
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return markers;
|
|
823
|
+
}
|
|
824
|
+
getLatestHookMarker(output) {
|
|
825
|
+
const markers = this.getHookMarkers(output);
|
|
826
|
+
return markers.length > 0 ? markers[markers.length - 1] : null;
|
|
827
|
+
}
|
|
828
|
+
stripHookMarkers(output) {
|
|
829
|
+
return output.replace(/(?:^|\n)\s*[A-Z0-9_]*CLAUDE_HOOK[A-Z0-9_]*\s+\{[^\n\r]+\}\s*/g, "\n");
|
|
830
|
+
}
|
|
707
831
|
detectLogin(output) {
|
|
708
832
|
const stripped = this.stripAnsi(output);
|
|
709
833
|
if (stripped.includes("Not logged in") || stripped.includes("Please run /login") || stripped.includes("please log in") || stripped.includes("run /login")) {
|
|
@@ -736,6 +860,7 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
736
860
|
*/
|
|
737
861
|
detectBlockingPrompt(output) {
|
|
738
862
|
const stripped = this.stripAnsi(output);
|
|
863
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
739
864
|
const loginDetection = this.detectLogin(output);
|
|
740
865
|
if (loginDetection.required) {
|
|
741
866
|
return {
|
|
@@ -747,6 +872,27 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
747
872
|
instructions: loginDetection.instructions
|
|
748
873
|
};
|
|
749
874
|
}
|
|
875
|
+
if (marker?.event === "Notification") {
|
|
876
|
+
if (marker.notification_type === "permission_prompt") {
|
|
877
|
+
return {
|
|
878
|
+
detected: true,
|
|
879
|
+
type: "permission",
|
|
880
|
+
prompt: marker.message || "Claude permission prompt",
|
|
881
|
+
suggestedResponse: "keys:enter",
|
|
882
|
+
canAutoRespond: true,
|
|
883
|
+
instructions: "Claude is waiting for permission approval"
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
if (marker.notification_type === "elicitation_dialog") {
|
|
887
|
+
return {
|
|
888
|
+
detected: true,
|
|
889
|
+
type: "tool_wait",
|
|
890
|
+
prompt: marker.message || "Claude elicitation dialog",
|
|
891
|
+
canAutoRespond: false,
|
|
892
|
+
instructions: "Claude is waiting for required user input"
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
}
|
|
750
896
|
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)) {
|
|
751
897
|
return {
|
|
752
898
|
detected: true,
|
|
@@ -845,7 +991,11 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
845
991
|
*/
|
|
846
992
|
detectLoading(output) {
|
|
847
993
|
const stripped = this.stripAnsi(output);
|
|
994
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
848
995
|
const tail = stripped.slice(-500);
|
|
996
|
+
if (marker?.event === "PreToolUse") {
|
|
997
|
+
return true;
|
|
998
|
+
}
|
|
849
999
|
if (/esc\s+to\s+interrupt/i.test(tail)) {
|
|
850
1000
|
return true;
|
|
851
1001
|
}
|
|
@@ -866,7 +1016,14 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
866
1016
|
*/
|
|
867
1017
|
detectToolRunning(output) {
|
|
868
1018
|
const stripped = this.stripAnsi(output);
|
|
1019
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
869
1020
|
const tail = stripped.slice(-500);
|
|
1021
|
+
if (marker?.event === "PreToolUse" && marker.tool_name) {
|
|
1022
|
+
return {
|
|
1023
|
+
toolName: marker.tool_name.toLowerCase(),
|
|
1024
|
+
description: `${marker.tool_name} (hook)`
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
870
1027
|
const contextualMatch = tail.match(/Claude\s+in\s+([A-Za-z0-9._-]+)\s*\[(\w+_tool)\]/i);
|
|
871
1028
|
if (contextualMatch) {
|
|
872
1029
|
const appName = contextualMatch[1];
|
|
@@ -895,7 +1052,14 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
895
1052
|
*/
|
|
896
1053
|
detectTaskComplete(output) {
|
|
897
1054
|
const stripped = this.stripAnsi(output);
|
|
1055
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
898
1056
|
if (!stripped.trim()) return false;
|
|
1057
|
+
if (marker?.event === "TaskCompleted") {
|
|
1058
|
+
return true;
|
|
1059
|
+
}
|
|
1060
|
+
if (marker?.event === "Notification" && marker.notification_type === "idle_prompt") {
|
|
1061
|
+
return true;
|
|
1062
|
+
}
|
|
899
1063
|
if (/trust.*directory|do you want to|needs? your permission/i.test(stripped)) {
|
|
900
1064
|
return false;
|
|
901
1065
|
}
|
|
@@ -912,7 +1076,16 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
912
1076
|
}
|
|
913
1077
|
detectReady(output) {
|
|
914
1078
|
const stripped = this.stripAnsi(output);
|
|
1079
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
915
1080
|
if (!stripped.trim()) return false;
|
|
1081
|
+
if (marker?.event === "Notification") {
|
|
1082
|
+
if (marker.notification_type === "permission_prompt" || marker.notification_type === "elicitation_dialog") {
|
|
1083
|
+
return false;
|
|
1084
|
+
}
|
|
1085
|
+
if (marker.notification_type === "idle_prompt") {
|
|
1086
|
+
return true;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
916
1089
|
if (/trust.*directory|do you want to|needs? your permission/i.test(stripped)) {
|
|
917
1090
|
return false;
|
|
918
1091
|
}
|
|
@@ -923,7 +1096,8 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
923
1096
|
return hasConversationalReadyText || hasLegacyPrompt || hasShortcutsHint;
|
|
924
1097
|
}
|
|
925
1098
|
parseOutput(output) {
|
|
926
|
-
const
|
|
1099
|
+
const withoutHookMarkers = this.stripHookMarkers(output);
|
|
1100
|
+
const stripped = this.stripAnsi(withoutHookMarkers);
|
|
927
1101
|
const isComplete = this.isResponseComplete(stripped);
|
|
928
1102
|
if (!isComplete) {
|
|
929
1103
|
return null;
|
|
@@ -946,9 +1120,18 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
946
1120
|
getHealthCheckCommand() {
|
|
947
1121
|
return "claude --version";
|
|
948
1122
|
}
|
|
1123
|
+
detectExit(output) {
|
|
1124
|
+
const stripped = this.stripAnsi(output);
|
|
1125
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
1126
|
+
if (marker?.event === "SessionEnd") {
|
|
1127
|
+
return { exited: true, code: 0 };
|
|
1128
|
+
}
|
|
1129
|
+
return super.detectExit(output);
|
|
1130
|
+
}
|
|
949
1131
|
};
|
|
950
1132
|
|
|
951
1133
|
// src/gemini-adapter.ts
|
|
1134
|
+
var GEMINI_HOOK_MARKER_PREFIX = "PARALLAX_GEMINI_HOOK";
|
|
952
1135
|
var GeminiAdapter = class extends BaseCodingAdapter {
|
|
953
1136
|
adapterType = "gemini";
|
|
954
1137
|
displayName = "Google Gemini";
|
|
@@ -1048,6 +1231,7 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1048
1231
|
getEnv(config) {
|
|
1049
1232
|
const env = {};
|
|
1050
1233
|
const credentials = this.getCredentials(config);
|
|
1234
|
+
const adapterConfig = config.adapterConfig;
|
|
1051
1235
|
if (credentials.googleKey) {
|
|
1052
1236
|
env.GOOGLE_API_KEY = credentials.googleKey;
|
|
1053
1237
|
env.GEMINI_API_KEY = credentials.googleKey;
|
|
@@ -1058,8 +1242,96 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1058
1242
|
if (!this.isInteractive(config)) {
|
|
1059
1243
|
env.NO_COLOR = "1";
|
|
1060
1244
|
}
|
|
1245
|
+
if (adapterConfig?.geminiHookTelemetry) {
|
|
1246
|
+
env.PARALLAX_GEMINI_HOOK_TELEMETRY = "1";
|
|
1247
|
+
env.PARALLAX_GEMINI_HOOK_MARKER_PREFIX = adapterConfig.geminiHookMarkerPrefix || GEMINI_HOOK_MARKER_PREFIX;
|
|
1248
|
+
}
|
|
1061
1249
|
return env;
|
|
1062
1250
|
}
|
|
1251
|
+
getHookTelemetryProtocol(options) {
|
|
1252
|
+
const markerPrefix = options?.markerPrefix || GEMINI_HOOK_MARKER_PREFIX;
|
|
1253
|
+
const scriptPath = options?.scriptPath || ".gemini/hooks/parallax-hook-telemetry.sh";
|
|
1254
|
+
const scriptCommand = `"${"$"}GEMINI_PROJECT_ROOT"/${scriptPath}`;
|
|
1255
|
+
const hookEntry = [{ matcher: "", hooks: [{ type: "command", command: scriptCommand }] }];
|
|
1256
|
+
const settingsHooks = {
|
|
1257
|
+
Notification: hookEntry,
|
|
1258
|
+
BeforeTool: hookEntry,
|
|
1259
|
+
AfterAgent: hookEntry,
|
|
1260
|
+
SessionEnd: hookEntry
|
|
1261
|
+
};
|
|
1262
|
+
const scriptContent = `#!/usr/bin/env bash
|
|
1263
|
+
set -euo pipefail
|
|
1264
|
+
|
|
1265
|
+
INPUT="$(cat)"
|
|
1266
|
+
[ -z "${"$"}INPUT" ] && exit 0
|
|
1267
|
+
|
|
1268
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
1269
|
+
# Valid no-op response
|
|
1270
|
+
printf '%s
|
|
1271
|
+
' '{"continue":true}'
|
|
1272
|
+
exit 0
|
|
1273
|
+
fi
|
|
1274
|
+
|
|
1275
|
+
EVENT="$(printf '%s' "${"$"}INPUT" | jq -r '.hookEventName // .hook_event_name // empty')"
|
|
1276
|
+
[ -z "${"$"}EVENT" ] && { printf '%s
|
|
1277
|
+
' '{"continue":true}'; exit 0; }
|
|
1278
|
+
|
|
1279
|
+
NOTIFICATION_TYPE="$(printf '%s' "${"$"}INPUT" | jq -r '.notificationType // .notification_type // empty')"
|
|
1280
|
+
TOOL_NAME="$(printf '%s' "${"$"}INPUT" | jq -r '.toolName // .tool_name // empty')"
|
|
1281
|
+
MESSAGE="$(printf '%s' "${"$"}INPUT" | jq -r '.message // empty')"
|
|
1282
|
+
|
|
1283
|
+
PAYLOAD="$(jq -nc \\
|
|
1284
|
+
--arg event "${"$"}EVENT" \\
|
|
1285
|
+
--arg notification_type "${"$"}NOTIFICATION_TYPE" \\
|
|
1286
|
+
--arg tool_name "${"$"}TOOL_NAME" \\
|
|
1287
|
+
--arg message "${"$"}MESSAGE" \\
|
|
1288
|
+
'({event: $event}
|
|
1289
|
+
+ (if $notification_type != "" then {notification_type: $notification_type} else {} end)
|
|
1290
|
+
+ (if $tool_name != "" then {tool_name: $tool_name} else {} end)
|
|
1291
|
+
+ (if $message != "" then {message: $message} else {} end))')"
|
|
1292
|
+
|
|
1293
|
+
MARKER="${markerPrefix} ${"$"}PAYLOAD"
|
|
1294
|
+
jq -nc --arg m "${"$"}MARKER" '{continue: true, suppressOutput: true, systemMessage: $m}'
|
|
1295
|
+
`;
|
|
1296
|
+
return {
|
|
1297
|
+
markerPrefix,
|
|
1298
|
+
scriptPath,
|
|
1299
|
+
scriptContent,
|
|
1300
|
+
settingsHooks
|
|
1301
|
+
};
|
|
1302
|
+
}
|
|
1303
|
+
getHookMarkers(output) {
|
|
1304
|
+
const markers = [];
|
|
1305
|
+
const markerRegex = /(?:^|\n)\s*([A-Z0-9_]+)\s+(\{[^\n\r]+\})/g;
|
|
1306
|
+
let match;
|
|
1307
|
+
while ((match = markerRegex.exec(output)) !== null) {
|
|
1308
|
+
const markerToken = match[1];
|
|
1309
|
+
if (!markerToken.includes("GEMINI_HOOK")) {
|
|
1310
|
+
continue;
|
|
1311
|
+
}
|
|
1312
|
+
const payload = match[2];
|
|
1313
|
+
try {
|
|
1314
|
+
const parsed = JSON.parse(payload);
|
|
1315
|
+
const event = typeof parsed.event === "string" ? parsed.event : void 0;
|
|
1316
|
+
if (!event) continue;
|
|
1317
|
+
markers.push({
|
|
1318
|
+
event,
|
|
1319
|
+
notification_type: typeof parsed.notification_type === "string" ? parsed.notification_type : void 0,
|
|
1320
|
+
tool_name: typeof parsed.tool_name === "string" ? parsed.tool_name : void 0,
|
|
1321
|
+
message: typeof parsed.message === "string" ? parsed.message : void 0
|
|
1322
|
+
});
|
|
1323
|
+
} catch {
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return markers;
|
|
1327
|
+
}
|
|
1328
|
+
getLatestHookMarker(output) {
|
|
1329
|
+
const markers = this.getHookMarkers(output);
|
|
1330
|
+
return markers.length > 0 ? markers[markers.length - 1] : null;
|
|
1331
|
+
}
|
|
1332
|
+
stripHookMarkers(output) {
|
|
1333
|
+
return output.replace(/(?:^|\n)\s*[A-Z0-9_]*GEMINI_HOOK[A-Z0-9_]*\s+\{[^\n\r]+\}\s*/g, "\n");
|
|
1334
|
+
}
|
|
1063
1335
|
detectLogin(output) {
|
|
1064
1336
|
const stripped = this.stripAnsi(output);
|
|
1065
1337
|
if (stripped.includes("API key not found") || /set (?:GOOGLE_API_KEY|GEMINI_API_KEY)/i.test(stripped) || stripped.includes("authentication required") || stripped.includes("Invalid API key") || stripped.includes("API key is not valid")) {
|
|
@@ -1110,6 +1382,17 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1110
1382
|
}
|
|
1111
1383
|
detectBlockingPrompt(output) {
|
|
1112
1384
|
const stripped = this.stripAnsi(output);
|
|
1385
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
1386
|
+
if (marker?.event === "Notification" && marker.notification_type === "ToolPermission") {
|
|
1387
|
+
return {
|
|
1388
|
+
detected: true,
|
|
1389
|
+
type: "permission",
|
|
1390
|
+
prompt: marker.message || "Gemini tool permission",
|
|
1391
|
+
suggestedResponse: "keys:enter",
|
|
1392
|
+
canAutoRespond: true,
|
|
1393
|
+
instructions: "Gemini is asking to allow a tool action"
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1113
1396
|
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)) {
|
|
1114
1397
|
return {
|
|
1115
1398
|
detected: true,
|
|
@@ -1205,7 +1488,11 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1205
1488
|
*/
|
|
1206
1489
|
detectLoading(output) {
|
|
1207
1490
|
const stripped = this.stripAnsi(output);
|
|
1491
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
1208
1492
|
const tail = stripped.slice(-500);
|
|
1493
|
+
if (marker?.event === "BeforeTool") {
|
|
1494
|
+
return true;
|
|
1495
|
+
}
|
|
1209
1496
|
if (/esc\s+to\s+cancel/i.test(tail)) {
|
|
1210
1497
|
return true;
|
|
1211
1498
|
}
|
|
@@ -1214,6 +1501,17 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1214
1501
|
}
|
|
1215
1502
|
return false;
|
|
1216
1503
|
}
|
|
1504
|
+
detectToolRunning(output) {
|
|
1505
|
+
const stripped = this.stripAnsi(output);
|
|
1506
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
1507
|
+
if (marker?.event === "BeforeTool" && marker.tool_name) {
|
|
1508
|
+
return {
|
|
1509
|
+
toolName: marker.tool_name.toLowerCase(),
|
|
1510
|
+
description: `${marker.tool_name} (hook)`
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
return null;
|
|
1514
|
+
}
|
|
1217
1515
|
/**
|
|
1218
1516
|
* Detect task completion for Gemini CLI.
|
|
1219
1517
|
*
|
|
@@ -1226,6 +1524,10 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1226
1524
|
*/
|
|
1227
1525
|
detectTaskComplete(output) {
|
|
1228
1526
|
const stripped = this.stripAnsi(output);
|
|
1527
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
1528
|
+
if (marker?.event === "AfterAgent") {
|
|
1529
|
+
return true;
|
|
1530
|
+
}
|
|
1229
1531
|
if (/◇\s+Ready/.test(stripped)) {
|
|
1230
1532
|
return true;
|
|
1231
1533
|
}
|
|
@@ -1236,6 +1538,13 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1236
1538
|
}
|
|
1237
1539
|
detectReady(output) {
|
|
1238
1540
|
const stripped = this.stripAnsi(output);
|
|
1541
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
1542
|
+
if (marker?.event === "Notification" && marker.notification_type === "ToolPermission") {
|
|
1543
|
+
return false;
|
|
1544
|
+
}
|
|
1545
|
+
if (marker?.event === "AfterAgent") {
|
|
1546
|
+
return true;
|
|
1547
|
+
}
|
|
1239
1548
|
const hasActiveOverlay = /interactive\s+shell\s+awaiting\s+input|press\s+tab\s+to\s+focus\s+shell/i.test(stripped) || /waiting\s+for\s+user\s+confirmation|apply.?this.?change|allow.?execution|do.?you.?want.?to.?proceed/i.test(stripped) || /do.?you.?want.?to.?continue\s*\([yY]\/[nN]\)\??|are.?you.?sure\??\s*\([yY]\/[nN]\)\??/i.test(stripped) || /enable.?checkpointing.?to.?recover.?your.?session.?after.?a.?crash/i.test(stripped) || /esc\s+to\s+cancel|esc\s+to\s+interrupt/i.test(stripped);
|
|
1240
1549
|
if (hasActiveOverlay) {
|
|
1241
1550
|
return false;
|
|
@@ -1253,7 +1562,8 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1253
1562
|
/gemini>\s*$/i.test(stripped);
|
|
1254
1563
|
}
|
|
1255
1564
|
parseOutput(output) {
|
|
1256
|
-
const
|
|
1565
|
+
const withoutHookMarkers = this.stripHookMarkers(output);
|
|
1566
|
+
const stripped = this.stripAnsi(withoutHookMarkers);
|
|
1257
1567
|
const isComplete = this.isResponseComplete(stripped);
|
|
1258
1568
|
if (!isComplete) {
|
|
1259
1569
|
return null;
|
|
@@ -1277,6 +1587,13 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1277
1587
|
*/
|
|
1278
1588
|
detectExit(output) {
|
|
1279
1589
|
const stripped = this.stripAnsi(output);
|
|
1590
|
+
const marker = this.getLatestHookMarker(stripped);
|
|
1591
|
+
if (marker?.event === "SessionEnd") {
|
|
1592
|
+
return {
|
|
1593
|
+
exited: true,
|
|
1594
|
+
code: 0
|
|
1595
|
+
};
|
|
1596
|
+
}
|
|
1280
1597
|
if (/folder.?trust.?level.?must.?be.?selected.*exiting/i.test(stripped)) {
|
|
1281
1598
|
return {
|
|
1282
1599
|
exited: true,
|
|
@@ -2126,6 +2443,213 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
2126
2443
|
}
|
|
2127
2444
|
};
|
|
2128
2445
|
|
|
2446
|
+
// src/hermes-adapter.ts
|
|
2447
|
+
var HermesAdapter = class extends BaseCodingAdapter {
|
|
2448
|
+
adapterType = "hermes";
|
|
2449
|
+
displayName = "Hermes Agent";
|
|
2450
|
+
/** Prompt-toolkit TUI + spinner rendering needs a slightly longer settle. */
|
|
2451
|
+
readySettleMs = 400;
|
|
2452
|
+
installation = {
|
|
2453
|
+
command: 'pip install "hermes-agent[cli]"',
|
|
2454
|
+
alternatives: [
|
|
2455
|
+
'pipx install "hermes-agent[cli]"',
|
|
2456
|
+
'uv tool install "hermes-agent[cli]"'
|
|
2457
|
+
],
|
|
2458
|
+
docsUrl: "https://github.com/NousResearch/hermes-agent"
|
|
2459
|
+
};
|
|
2460
|
+
getWorkspaceFiles() {
|
|
2461
|
+
return [
|
|
2462
|
+
{
|
|
2463
|
+
relativePath: "AGENTS.md",
|
|
2464
|
+
description: "Project instructions and architecture notes loaded by Hermes context files",
|
|
2465
|
+
autoLoaded: true,
|
|
2466
|
+
type: "memory",
|
|
2467
|
+
format: "markdown"
|
|
2468
|
+
},
|
|
2469
|
+
{
|
|
2470
|
+
relativePath: "SOUL.md",
|
|
2471
|
+
description: "Optional persona/context file auto-injected into Hermes system prompt",
|
|
2472
|
+
autoLoaded: true,
|
|
2473
|
+
type: "memory",
|
|
2474
|
+
format: "markdown"
|
|
2475
|
+
},
|
|
2476
|
+
{
|
|
2477
|
+
relativePath: "cli-config.yaml",
|
|
2478
|
+
description: "Legacy/local Hermes CLI configuration file",
|
|
2479
|
+
autoLoaded: true,
|
|
2480
|
+
type: "config",
|
|
2481
|
+
format: "yaml"
|
|
2482
|
+
}
|
|
2483
|
+
];
|
|
2484
|
+
}
|
|
2485
|
+
getRecommendedModels(_credentials) {
|
|
2486
|
+
return {
|
|
2487
|
+
powerful: "anthropic/claude-opus-4.6",
|
|
2488
|
+
fast: "google/gemini-3-flash-preview"
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
getCommand() {
|
|
2492
|
+
return "hermes";
|
|
2493
|
+
}
|
|
2494
|
+
getArgs(_config) {
|
|
2495
|
+
return ["chat"];
|
|
2496
|
+
}
|
|
2497
|
+
getEnv(config) {
|
|
2498
|
+
const env = {};
|
|
2499
|
+
const credentials = this.getCredentials(config);
|
|
2500
|
+
if (credentials.openaiKey) {
|
|
2501
|
+
env.OPENROUTER_API_KEY = credentials.openaiKey;
|
|
2502
|
+
env.OPENAI_API_KEY = credentials.openaiKey;
|
|
2503
|
+
}
|
|
2504
|
+
if (credentials.anthropicKey) {
|
|
2505
|
+
env.ANTHROPIC_API_KEY = credentials.anthropicKey;
|
|
2506
|
+
}
|
|
2507
|
+
if (credentials.googleKey) {
|
|
2508
|
+
env.GOOGLE_API_KEY = credentials.googleKey;
|
|
2509
|
+
env.GEMINI_API_KEY = credentials.googleKey;
|
|
2510
|
+
}
|
|
2511
|
+
if (!this.isInteractive(config)) {
|
|
2512
|
+
env.HERMES_QUIET = "1";
|
|
2513
|
+
}
|
|
2514
|
+
return env;
|
|
2515
|
+
}
|
|
2516
|
+
detectLogin(output) {
|
|
2517
|
+
const stripped = this.stripAnsi(output);
|
|
2518
|
+
if (/isn.?t configured yet/i.test(stripped) || /no api keys or providers found/i.test(stripped) || /run setup now\?\s*\[y\/n\]/i.test(stripped)) {
|
|
2519
|
+
return {
|
|
2520
|
+
required: true,
|
|
2521
|
+
type: "api_key",
|
|
2522
|
+
instructions: "Hermes requires provider credentials. Run: hermes setup"
|
|
2523
|
+
};
|
|
2524
|
+
}
|
|
2525
|
+
return { required: false };
|
|
2526
|
+
}
|
|
2527
|
+
detectBlockingPrompt(output) {
|
|
2528
|
+
const stripped = this.stripAnsi(output);
|
|
2529
|
+
const loginDetection = this.detectLogin(output);
|
|
2530
|
+
if (loginDetection.required) {
|
|
2531
|
+
return {
|
|
2532
|
+
detected: true,
|
|
2533
|
+
type: "login",
|
|
2534
|
+
prompt: loginDetection.instructions,
|
|
2535
|
+
canAutoRespond: false,
|
|
2536
|
+
instructions: loginDetection.instructions
|
|
2537
|
+
};
|
|
2538
|
+
}
|
|
2539
|
+
if (/Hermes needs your input|Other \(type your answer\)/i.test(stripped)) {
|
|
2540
|
+
return {
|
|
2541
|
+
detected: true,
|
|
2542
|
+
type: "tool_wait",
|
|
2543
|
+
prompt: "Hermes clarify prompt",
|
|
2544
|
+
canAutoRespond: false,
|
|
2545
|
+
instructions: "Hermes is waiting for clarify input (arrow keys + Enter or free text)."
|
|
2546
|
+
};
|
|
2547
|
+
}
|
|
2548
|
+
if (/Sudo Password Required|password hidden|Password \(hidden\):/i.test(stripped)) {
|
|
2549
|
+
return {
|
|
2550
|
+
detected: true,
|
|
2551
|
+
type: "tool_wait",
|
|
2552
|
+
prompt: "Hermes sudo password prompt",
|
|
2553
|
+
canAutoRespond: false,
|
|
2554
|
+
instructions: "Hermes terminal tool is waiting for a sudo password or skip."
|
|
2555
|
+
};
|
|
2556
|
+
}
|
|
2557
|
+
if (/Dangerous Command|Allow once|Allow for this session|permanent allowlist|\bDeny\b/i.test(stripped)) {
|
|
2558
|
+
return {
|
|
2559
|
+
detected: true,
|
|
2560
|
+
type: "permission",
|
|
2561
|
+
prompt: "Hermes dangerous command approval",
|
|
2562
|
+
canAutoRespond: false,
|
|
2563
|
+
instructions: "Choose approval policy (once/session/always/deny)."
|
|
2564
|
+
};
|
|
2565
|
+
}
|
|
2566
|
+
return super.detectBlockingPrompt(output);
|
|
2567
|
+
}
|
|
2568
|
+
detectLoading(output) {
|
|
2569
|
+
const stripped = this.stripAnsi(output);
|
|
2570
|
+
const tail = stripped.slice(-1200);
|
|
2571
|
+
if (/(?:pondering|contemplating|musing|cogitating|ruminating|deliberating|mulling|reflecting|processing|reasoning|analyzing|computing|synthesizing|formulating|brainstorming)\.\.\.\s*\(\d+\.\d+s\)/i.test(tail)) {
|
|
2572
|
+
return true;
|
|
2573
|
+
}
|
|
2574
|
+
if (/\(\d+\.\d+s\)\s*$/.test(tail) && /(?:🔍|📄|💻|⚙️|📖|✍️|🔧|🌐|👆|⌨️|📋|🧠|📚|🎨|🐍|🔀|⚡|💬)/.test(tail)) {
|
|
2575
|
+
return true;
|
|
2576
|
+
}
|
|
2577
|
+
if (/⚕\s*❯\s*$/.test(tail)) {
|
|
2578
|
+
return true;
|
|
2579
|
+
}
|
|
2580
|
+
return false;
|
|
2581
|
+
}
|
|
2582
|
+
detectTaskComplete(output) {
|
|
2583
|
+
if (/╭─\s*⚕\s*Hermes/i.test(output)) {
|
|
2584
|
+
return true;
|
|
2585
|
+
}
|
|
2586
|
+
const stripped = this.stripAnsi(output);
|
|
2587
|
+
if (!stripped.trim()) return false;
|
|
2588
|
+
if (this.detectLoading(stripped)) {
|
|
2589
|
+
return false;
|
|
2590
|
+
}
|
|
2591
|
+
const hasIdlePrompt = /(?:^|\n)\s*❯\s*$/m.test(stripped);
|
|
2592
|
+
const hasToolFeed = /(?:^|\n)\s*┊\s+\S+/m.test(stripped);
|
|
2593
|
+
if (hasIdlePrompt && hasToolFeed) {
|
|
2594
|
+
return true;
|
|
2595
|
+
}
|
|
2596
|
+
return false;
|
|
2597
|
+
}
|
|
2598
|
+
detectReady(output) {
|
|
2599
|
+
const stripped = this.stripAnsi(output);
|
|
2600
|
+
const tail = stripped.slice(-800);
|
|
2601
|
+
if (!tail.trim()) return false;
|
|
2602
|
+
if (this.detectLoading(tail)) {
|
|
2603
|
+
return false;
|
|
2604
|
+
}
|
|
2605
|
+
if (/Hermes needs your input|Sudo Password Required|Dangerous Command/i.test(tail)) {
|
|
2606
|
+
return false;
|
|
2607
|
+
}
|
|
2608
|
+
if (/(?:⚕|⚠|🔐|\?|✎)\s*❯\s*$/.test(tail)) {
|
|
2609
|
+
return false;
|
|
2610
|
+
}
|
|
2611
|
+
return /(?:^|\n)\s*❯\s*$/m.test(tail);
|
|
2612
|
+
}
|
|
2613
|
+
parseOutput(output) {
|
|
2614
|
+
const raw = output;
|
|
2615
|
+
const stripped = this.stripAnsi(output);
|
|
2616
|
+
const complete = this.detectTaskComplete(raw) || this.detectReady(stripped);
|
|
2617
|
+
if (!complete) {
|
|
2618
|
+
return null;
|
|
2619
|
+
}
|
|
2620
|
+
let content = "";
|
|
2621
|
+
const boxMatch = raw.match(/╭─\s*⚕\s*Hermes[^\n]*\n([\s\S]*?)\n\s*╰/i);
|
|
2622
|
+
if (boxMatch?.[1]) {
|
|
2623
|
+
content = boxMatch[1].trim();
|
|
2624
|
+
}
|
|
2625
|
+
if (!content) {
|
|
2626
|
+
content = this.extractContent(stripped, /(?:^|\n)\s*(?:⚕|⚠|🔐|\?|✎)?\s*❯\s*$/gim);
|
|
2627
|
+
}
|
|
2628
|
+
return {
|
|
2629
|
+
type: this.containsQuestion(content) ? "question" : "response",
|
|
2630
|
+
content,
|
|
2631
|
+
isComplete: true,
|
|
2632
|
+
isQuestion: this.containsQuestion(content),
|
|
2633
|
+
metadata: {
|
|
2634
|
+
raw: output
|
|
2635
|
+
}
|
|
2636
|
+
};
|
|
2637
|
+
}
|
|
2638
|
+
getPromptPattern() {
|
|
2639
|
+
return /(?:^|\n)\s*(?:⚕|⚠|🔐|\?|✎)?\s*❯\s*$/i;
|
|
2640
|
+
}
|
|
2641
|
+
detectExit(output) {
|
|
2642
|
+
const stripped = this.stripAnsi(output);
|
|
2643
|
+
if (/Goodbye!\s*⚕/i.test(stripped)) {
|
|
2644
|
+
return { exited: true, code: 0 };
|
|
2645
|
+
}
|
|
2646
|
+
return super.detectExit(output);
|
|
2647
|
+
}
|
|
2648
|
+
getHealthCheckCommand() {
|
|
2649
|
+
return "hermes version";
|
|
2650
|
+
}
|
|
2651
|
+
};
|
|
2652
|
+
|
|
2129
2653
|
// src/pattern-loader.ts
|
|
2130
2654
|
var BASELINE_PATTERNS = {
|
|
2131
2655
|
claude: {
|
|
@@ -2249,6 +2773,41 @@ var BASELINE_PATTERNS = {
|
|
|
2249
2773
|
toolWait: [],
|
|
2250
2774
|
exit: [],
|
|
2251
2775
|
source: "baseline"
|
|
2776
|
+
},
|
|
2777
|
+
hermes: {
|
|
2778
|
+
ready: [
|
|
2779
|
+
"\u276F",
|
|
2780
|
+
"\u2695 Hermes",
|
|
2781
|
+
"Welcome to Hermes Agent"
|
|
2782
|
+
],
|
|
2783
|
+
auth: [
|
|
2784
|
+
"isn't configured yet",
|
|
2785
|
+
"no API keys or providers found",
|
|
2786
|
+
"Run setup now? [Y/n]"
|
|
2787
|
+
],
|
|
2788
|
+
blocking: [
|
|
2789
|
+
"Hermes needs your input",
|
|
2790
|
+
"Sudo Password Required",
|
|
2791
|
+
"Dangerous Command"
|
|
2792
|
+
],
|
|
2793
|
+
loading: [
|
|
2794
|
+
"deliberating...",
|
|
2795
|
+
"(0.0s)",
|
|
2796
|
+
"\u2695 \u276F"
|
|
2797
|
+
],
|
|
2798
|
+
turnComplete: [
|
|
2799
|
+
"\u256D\u2500 \u2695 Hermes",
|
|
2800
|
+
"\u276F"
|
|
2801
|
+
],
|
|
2802
|
+
toolWait: [
|
|
2803
|
+
"Hermes needs your input",
|
|
2804
|
+
"Sudo Password Required",
|
|
2805
|
+
"Dangerous Command"
|
|
2806
|
+
],
|
|
2807
|
+
exit: [
|
|
2808
|
+
"Goodbye! \u2695"
|
|
2809
|
+
],
|
|
2810
|
+
source: "baseline"
|
|
2252
2811
|
}
|
|
2253
2812
|
};
|
|
2254
2813
|
var patternCache = /* @__PURE__ */ new Map();
|
|
@@ -2319,14 +2878,16 @@ function createAllAdapters() {
|
|
|
2319
2878
|
new ClaudeAdapter(),
|
|
2320
2879
|
new GeminiAdapter(),
|
|
2321
2880
|
new CodexAdapter(),
|
|
2322
|
-
new AiderAdapter()
|
|
2881
|
+
new AiderAdapter(),
|
|
2882
|
+
new HermesAdapter()
|
|
2323
2883
|
];
|
|
2324
2884
|
}
|
|
2325
2885
|
var ADAPTER_TYPES = {
|
|
2326
2886
|
claude: ClaudeAdapter,
|
|
2327
2887
|
gemini: GeminiAdapter,
|
|
2328
2888
|
codex: CodexAdapter,
|
|
2329
|
-
aider: AiderAdapter
|
|
2889
|
+
aider: AiderAdapter,
|
|
2890
|
+
hermes: HermesAdapter
|
|
2330
2891
|
};
|
|
2331
2892
|
function createAdapter(type) {
|
|
2332
2893
|
const AdapterClass = ADAPTER_TYPES[type];
|
|
@@ -2373,6 +2934,6 @@ async function printMissingAdapters(types) {
|
|
|
2373
2934
|
}
|
|
2374
2935
|
}
|
|
2375
2936
|
|
|
2376
|
-
export { ADAPTER_TYPES, AIDER_COMMAND_CATEGORIES, AiderAdapter, BaseCodingAdapter, CLAUDE_TOOL_CATEGORIES, CODEX_TOOL_CATEGORIES, ClaudeAdapter, CodexAdapter, GEMINI_TOOL_CATEGORIES, GeminiAdapter, PRESET_DEFINITIONS, TOOL_CATEGORIES, checkAdapters, checkAllAdapters, clearPatternCache, createAdapter, createAllAdapters, generateAiderApprovalConfig, generateApprovalConfig, generateClaudeApprovalConfig, generateCodexApprovalConfig, generateGeminiApprovalConfig, getBaselinePatterns, getPresetDefinition, hasDynamicPatterns, listPresets, loadPatterns, loadPatternsSync, preloadAllPatterns, printMissingAdapters };
|
|
2937
|
+
export { ADAPTER_TYPES, AIDER_COMMAND_CATEGORIES, AiderAdapter, BaseCodingAdapter, CLAUDE_TOOL_CATEGORIES, CODEX_TOOL_CATEGORIES, ClaudeAdapter, CodexAdapter, GEMINI_TOOL_CATEGORIES, GeminiAdapter, HermesAdapter, PRESET_DEFINITIONS, TOOL_CATEGORIES, checkAdapters, checkAllAdapters, clearPatternCache, createAdapter, createAllAdapters, generateAiderApprovalConfig, generateApprovalConfig, generateClaudeApprovalConfig, generateCodexApprovalConfig, generateGeminiApprovalConfig, generateHermesApprovalConfig, getBaselinePatterns, getPresetDefinition, hasDynamicPatterns, listPresets, loadPatterns, loadPatternsSync, preloadAllPatterns, printMissingAdapters };
|
|
2377
2938
|
//# sourceMappingURL=index.js.map
|
|
2378
2939
|
//# sourceMappingURL=index.js.map
|