@raindrop-ai/claude-code 0.0.4 → 0.0.6
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 +20 -0
- package/dist/cli.js +713 -39
- package/dist/index.cjs +705 -26
- package/dist/index.d.cts +119 -2
- package/dist/index.d.ts +119 -2
- package/dist/index.js +690 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -645,7 +645,7 @@ globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
|
645
645
|
|
|
646
646
|
// src/package-info.ts
|
|
647
647
|
var PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
648
|
-
var PACKAGE_VERSION = "0.0.
|
|
648
|
+
var PACKAGE_VERSION = "0.0.6";
|
|
649
649
|
|
|
650
650
|
// src/shipper.ts
|
|
651
651
|
var EventShipper2 = class extends EventShipper {
|
|
@@ -714,6 +714,17 @@ function loadConfig() {
|
|
|
714
714
|
} catch (e) {
|
|
715
715
|
}
|
|
716
716
|
}
|
|
717
|
+
let selfDiagnostics = file.self_diagnostics;
|
|
718
|
+
const envDiag = process.env["RAINDROP_SELF_DIAGNOSTICS"];
|
|
719
|
+
if (envDiag) {
|
|
720
|
+
try {
|
|
721
|
+
const parsed = JSON.parse(envDiag);
|
|
722
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
723
|
+
selfDiagnostics = parsed;
|
|
724
|
+
}
|
|
725
|
+
} catch (e) {
|
|
726
|
+
}
|
|
727
|
+
}
|
|
717
728
|
return {
|
|
718
729
|
writeKey: (_c = (_b = process.env["RAINDROP_WRITE_KEY"]) != null ? _b : file.write_key) != null ? _c : "",
|
|
719
730
|
endpoint: (_e = (_d = process.env["RAINDROP_API_URL"]) != null ? _d : file.api_url) != null ? _e : "https://api.raindrop.ai/v1",
|
|
@@ -721,7 +732,8 @@ function loadConfig() {
|
|
|
721
732
|
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_h = file.debug) != null ? _h : false,
|
|
722
733
|
enabled: (_i = file.enabled) != null ? _i : true,
|
|
723
734
|
eventName: (_k = (_j = process.env["RAINDROP_EVENT_NAME"]) != null ? _j : file.event_name) != null ? _k : "claude_code_session",
|
|
724
|
-
customProperties
|
|
735
|
+
customProperties,
|
|
736
|
+
selfDiagnostics
|
|
725
737
|
};
|
|
726
738
|
}
|
|
727
739
|
function getConfigPath() {
|
|
@@ -741,10 +753,145 @@ function updateConfig(patch) {
|
|
|
741
753
|
}
|
|
742
754
|
|
|
743
755
|
// src/event-mapper.ts
|
|
744
|
-
import { existsSync as
|
|
756
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
757
|
+
import { execSync } from "child_process";
|
|
745
758
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
746
759
|
import { tmpdir } from "os";
|
|
747
760
|
import { join as join2 } from "path";
|
|
761
|
+
|
|
762
|
+
// src/transcript.ts
|
|
763
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
764
|
+
function parseTranscript(transcriptPath) {
|
|
765
|
+
var _a, _b, _c, _d, _e;
|
|
766
|
+
try {
|
|
767
|
+
if (!existsSync2(transcriptPath)) return void 0;
|
|
768
|
+
const content = readFileSync2(transcriptPath, "utf-8");
|
|
769
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
770
|
+
const summary = {
|
|
771
|
+
totalInputTokens: 0,
|
|
772
|
+
totalOutputTokens: 0,
|
|
773
|
+
totalCacheReadTokens: 0,
|
|
774
|
+
totalCacheCreationTokens: 0,
|
|
775
|
+
turnCount: 0,
|
|
776
|
+
toolsUsed: [],
|
|
777
|
+
hasThinking: false
|
|
778
|
+
};
|
|
779
|
+
const toolNames = /* @__PURE__ */ new Set();
|
|
780
|
+
let lastUsage;
|
|
781
|
+
for (const line of lines) {
|
|
782
|
+
let entry;
|
|
783
|
+
try {
|
|
784
|
+
entry = JSON.parse(line);
|
|
785
|
+
} catch (e) {
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
if (entry.type === "system" && entry.subtype === "turn_duration") {
|
|
789
|
+
const durationMs = entry["durationMs"];
|
|
790
|
+
if (typeof durationMs === "number") {
|
|
791
|
+
summary.totalDurationMs = ((_a = summary.totalDurationMs) != null ? _a : 0) + durationMs;
|
|
792
|
+
}
|
|
793
|
+
const version = entry["version"];
|
|
794
|
+
if (typeof version === "string") {
|
|
795
|
+
summary.codeVersion = version;
|
|
796
|
+
}
|
|
797
|
+
const branch = entry["gitBranch"];
|
|
798
|
+
if (typeof branch === "string") {
|
|
799
|
+
summary.gitBranch = branch;
|
|
800
|
+
}
|
|
801
|
+
continue;
|
|
802
|
+
}
|
|
803
|
+
if (entry.type !== "assistant") continue;
|
|
804
|
+
const msg = entry.message;
|
|
805
|
+
if (!msg) continue;
|
|
806
|
+
summary.turnCount++;
|
|
807
|
+
if (msg.model) {
|
|
808
|
+
summary.model = msg.model;
|
|
809
|
+
}
|
|
810
|
+
if (msg.stop_reason) {
|
|
811
|
+
summary.stopReason = msg.stop_reason;
|
|
812
|
+
}
|
|
813
|
+
const entryVersion = entry["version"];
|
|
814
|
+
if (typeof entryVersion === "string") {
|
|
815
|
+
summary.codeVersion = entryVersion;
|
|
816
|
+
}
|
|
817
|
+
const entryBranch = entry["gitBranch"];
|
|
818
|
+
if (typeof entryBranch === "string") {
|
|
819
|
+
summary.gitBranch = entryBranch;
|
|
820
|
+
}
|
|
821
|
+
if (msg.usage) {
|
|
822
|
+
const u = msg.usage;
|
|
823
|
+
summary.totalInputTokens += (_b = u.input_tokens) != null ? _b : 0;
|
|
824
|
+
summary.totalOutputTokens += (_c = u.output_tokens) != null ? _c : 0;
|
|
825
|
+
summary.totalCacheReadTokens += (_d = u.cache_read_input_tokens) != null ? _d : 0;
|
|
826
|
+
summary.totalCacheCreationTokens += (_e = u.cache_creation_input_tokens) != null ? _e : 0;
|
|
827
|
+
if (u.service_tier) {
|
|
828
|
+
summary.serviceTier = u.service_tier;
|
|
829
|
+
}
|
|
830
|
+
lastUsage = u;
|
|
831
|
+
}
|
|
832
|
+
if (Array.isArray(msg.content)) {
|
|
833
|
+
for (const block of msg.content) {
|
|
834
|
+
if (block.type === "tool_use" && block.name) {
|
|
835
|
+
toolNames.add(block.name);
|
|
836
|
+
}
|
|
837
|
+
if (block.type === "thinking") {
|
|
838
|
+
summary.hasThinking = true;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
if (lastUsage) {
|
|
844
|
+
summary.lastTurnInputTokens = lastUsage.input_tokens;
|
|
845
|
+
summary.lastTurnOutputTokens = lastUsage.output_tokens;
|
|
846
|
+
summary.lastTurnCacheReadTokens = lastUsage.cache_read_input_tokens;
|
|
847
|
+
}
|
|
848
|
+
summary.toolsUsed = [...toolNames].sort();
|
|
849
|
+
return summary;
|
|
850
|
+
} catch (e) {
|
|
851
|
+
return void 0;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
function transcriptToProperties(summary) {
|
|
855
|
+
var _a, _b;
|
|
856
|
+
const props = {};
|
|
857
|
+
props["ai.usage.prompt_tokens"] = (_a = summary.lastTurnInputTokens) != null ? _a : summary.totalInputTokens;
|
|
858
|
+
props["ai.usage.completion_tokens"] = (_b = summary.lastTurnOutputTokens) != null ? _b : summary.totalOutputTokens;
|
|
859
|
+
if (summary.lastTurnCacheReadTokens !== void 0) {
|
|
860
|
+
props["ai.usage.cache_read_tokens"] = summary.lastTurnCacheReadTokens;
|
|
861
|
+
}
|
|
862
|
+
props["ai.usage.session_total.prompt_tokens"] = summary.totalInputTokens;
|
|
863
|
+
props["ai.usage.session_total.completion_tokens"] = summary.totalOutputTokens;
|
|
864
|
+
props["ai.usage.session_total.cache_read_tokens"] = summary.totalCacheReadTokens;
|
|
865
|
+
props["ai.usage.session_total.cache_creation_tokens"] = summary.totalCacheCreationTokens;
|
|
866
|
+
if (summary.model) {
|
|
867
|
+
props["ai.model"] = summary.model;
|
|
868
|
+
}
|
|
869
|
+
if (summary.serviceTier) {
|
|
870
|
+
props["ai.service_tier"] = summary.serviceTier;
|
|
871
|
+
}
|
|
872
|
+
if (summary.stopReason) {
|
|
873
|
+
props["ai.stop_reason"] = summary.stopReason;
|
|
874
|
+
}
|
|
875
|
+
if (summary.toolsUsed.length > 0) {
|
|
876
|
+
props["ai.tools_used"] = summary.toolsUsed.join(", ");
|
|
877
|
+
}
|
|
878
|
+
props["ai.turn_count"] = summary.turnCount;
|
|
879
|
+
if (summary.totalDurationMs !== void 0) {
|
|
880
|
+
props["ai.duration_ms"] = summary.totalDurationMs;
|
|
881
|
+
}
|
|
882
|
+
if (summary.codeVersion) {
|
|
883
|
+
props["claude_code.version"] = summary.codeVersion;
|
|
884
|
+
}
|
|
885
|
+
if (summary.gitBranch) {
|
|
886
|
+
props["git.branch"] = summary.gitBranch;
|
|
887
|
+
}
|
|
888
|
+
if (summary.hasThinking) {
|
|
889
|
+
props["ai.has_thinking"] = true;
|
|
890
|
+
}
|
|
891
|
+
return props;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
// src/event-mapper.ts
|
|
748
895
|
var MAX_ATTR_LENGTH = 32768;
|
|
749
896
|
function truncate(value) {
|
|
750
897
|
if (value === void 0) return void 0;
|
|
@@ -788,8 +935,8 @@ function writeState(key, value) {
|
|
|
788
935
|
function readState(key) {
|
|
789
936
|
try {
|
|
790
937
|
const filePath = statePath(key);
|
|
791
|
-
if (!
|
|
792
|
-
return
|
|
938
|
+
if (!existsSync3(filePath)) return void 0;
|
|
939
|
+
return readFileSync3(filePath, "utf-8");
|
|
793
940
|
} catch (e) {
|
|
794
941
|
return void 0;
|
|
795
942
|
}
|
|
@@ -854,12 +1001,15 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
854
1001
|
cwd: payload.cwd,
|
|
855
1002
|
permission_mode: payload.permission_mode,
|
|
856
1003
|
plugin_version: PACKAGE_VERSION,
|
|
1004
|
+
sdk: PACKAGE_NAME,
|
|
1005
|
+
sdk_version: PACKAGE_VERSION,
|
|
857
1006
|
...payload.agent_id ? { agent_id: payload.agent_id } : {},
|
|
858
1007
|
...payload.agent_type ? { agent_type: payload.agent_type } : {}
|
|
859
1008
|
};
|
|
860
1009
|
switch (payload.hook_event_name) {
|
|
861
1010
|
case "SessionStart":
|
|
862
1011
|
writeState(`model_${payload.session_id}`, (_a = payload.model) != null ? _a : "");
|
|
1012
|
+
tryCaptureAppendSystemPrompt(payload.session_id);
|
|
863
1013
|
break;
|
|
864
1014
|
case "UserPromptSubmit":
|
|
865
1015
|
await handleUserPromptSubmit(payload, convoId, config, baseProperties, eventShipper, traceShipper);
|
|
@@ -874,10 +1024,13 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
874
1024
|
handlePostToolUseFailure(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
875
1025
|
break;
|
|
876
1026
|
case "Stop":
|
|
877
|
-
await
|
|
1027
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper);
|
|
878
1028
|
break;
|
|
879
1029
|
case "StopFailure":
|
|
880
|
-
await
|
|
1030
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper, {
|
|
1031
|
+
error: payload.error,
|
|
1032
|
+
error_details: payload.error_details
|
|
1033
|
+
});
|
|
881
1034
|
break;
|
|
882
1035
|
case "SubagentStart":
|
|
883
1036
|
handleSubagentStart(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
@@ -888,6 +1041,9 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
888
1041
|
case "PermissionDenied":
|
|
889
1042
|
handlePermissionDenied(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
890
1043
|
break;
|
|
1044
|
+
case "InstructionsLoaded":
|
|
1045
|
+
handleInstructionsLoaded(payload);
|
|
1046
|
+
break;
|
|
891
1047
|
case "PostCompact":
|
|
892
1048
|
await handlePostCompact(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper);
|
|
893
1049
|
break;
|
|
@@ -896,6 +1052,8 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
896
1052
|
deleteState(turnEventKey(payload.session_id));
|
|
897
1053
|
deleteState(rootSpanKey(payload.session_id));
|
|
898
1054
|
deleteState(`model_${payload.session_id}`);
|
|
1055
|
+
deleteState(appendSystemPromptKey(payload.session_id));
|
|
1056
|
+
cleanupInstructions(payload.session_id);
|
|
899
1057
|
break;
|
|
900
1058
|
default:
|
|
901
1059
|
if (config.debug) {
|
|
@@ -1053,25 +1211,243 @@ async function handlePostCompact(payload, eventId, config, properties, eventShip
|
|
|
1053
1211
|
}
|
|
1054
1212
|
});
|
|
1055
1213
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1214
|
+
function handleInstructionsLoaded(payload) {
|
|
1215
|
+
var _a;
|
|
1216
|
+
if (!payload.file_path || !payload.session_id) return;
|
|
1217
|
+
try {
|
|
1218
|
+
if (existsSync3(payload.file_path)) {
|
|
1219
|
+
const content = readFileSync3(payload.file_path, "utf-8");
|
|
1220
|
+
const MAX_INSTRUCTIONS_LENGTH = 8192;
|
|
1221
|
+
const truncated = content.length > MAX_INSTRUCTIONS_LENGTH ? content.slice(0, MAX_INSTRUCTIONS_LENGTH) + "\n...[truncated]" : content;
|
|
1222
|
+
const fileKey = safeKey(payload.file_path);
|
|
1223
|
+
const header = `# ${(_a = payload.memory_type) != null ? _a : "instructions"}: ${payload.file_path}
|
|
1224
|
+
`;
|
|
1225
|
+
writeState(
|
|
1226
|
+
`instr_${payload.session_id}_${fileKey}`,
|
|
1227
|
+
header + truncated
|
|
1228
|
+
);
|
|
1229
|
+
}
|
|
1230
|
+
} catch (e) {
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
function gatherInstructions(sessionId) {
|
|
1234
|
+
try {
|
|
1235
|
+
if (!existsSync3(STATE_DIR)) return void 0;
|
|
1236
|
+
const prefix = safeKey(`instr_${sessionId}_`);
|
|
1237
|
+
const files = readdirSync(STATE_DIR).filter((f) => f.startsWith(prefix));
|
|
1238
|
+
if (files.length === 0) return void 0;
|
|
1239
|
+
const parts = [];
|
|
1240
|
+
for (const file of files.sort()) {
|
|
1241
|
+
try {
|
|
1242
|
+
parts.push(readFileSync3(join2(STATE_DIR, file), "utf-8"));
|
|
1243
|
+
} catch (e) {
|
|
1244
|
+
continue;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return parts.length > 0 ? parts.join("\n\n---\n\n") : void 0;
|
|
1248
|
+
} catch (e) {
|
|
1249
|
+
return void 0;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
function cleanupInstructions(sessionId) {
|
|
1253
|
+
try {
|
|
1254
|
+
if (!existsSync3(STATE_DIR)) return;
|
|
1255
|
+
const prefix = safeKey(`instr_${sessionId}_`);
|
|
1256
|
+
for (const file of readdirSync(STATE_DIR).filter((f) => f.startsWith(prefix))) {
|
|
1257
|
+
try {
|
|
1258
|
+
unlinkSync(join2(STATE_DIR, file));
|
|
1259
|
+
} catch (e) {
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
} catch (e) {
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
var APPEND_FLAG = "--append-system-prompt";
|
|
1266
|
+
var APPEND_FILE_FLAG = "--append-system-prompt-file";
|
|
1267
|
+
var MAX_ANCESTOR_DEPTH = 15;
|
|
1268
|
+
var PS_TIMEOUT_MS = 3e3;
|
|
1269
|
+
function appendSystemPromptKey(sessionId) {
|
|
1270
|
+
return `append_sysprompt_${sessionId}`;
|
|
1271
|
+
}
|
|
1272
|
+
function tryCaptureAppendSystemPrompt(sessionId) {
|
|
1273
|
+
try {
|
|
1274
|
+
const content = readAncestorAppendSystemPrompt();
|
|
1275
|
+
if (content) {
|
|
1276
|
+
writeState(appendSystemPromptKey(sessionId), content);
|
|
1277
|
+
}
|
|
1278
|
+
} catch (e) {
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
function readAncestorAppendSystemPrompt() {
|
|
1282
|
+
let pid;
|
|
1283
|
+
try {
|
|
1284
|
+
pid = process.ppid;
|
|
1285
|
+
} catch (e) {
|
|
1286
|
+
return void 0;
|
|
1287
|
+
}
|
|
1288
|
+
if (!pid || pid <= 1) return void 0;
|
|
1289
|
+
for (let depth = 0; depth < MAX_ANCESTOR_DEPTH && pid != null && pid > 1; depth++) {
|
|
1290
|
+
try {
|
|
1291
|
+
const args = getProcessArgs(pid);
|
|
1292
|
+
if (args && args.length > 0) {
|
|
1293
|
+
const content = extractAppendSystemPrompt(args);
|
|
1294
|
+
if (content) return content;
|
|
1295
|
+
}
|
|
1296
|
+
} catch (e) {
|
|
1297
|
+
}
|
|
1298
|
+
try {
|
|
1299
|
+
pid = getParentPid(pid);
|
|
1300
|
+
} catch (e) {
|
|
1301
|
+
break;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
return void 0;
|
|
1064
1305
|
}
|
|
1065
|
-
|
|
1306
|
+
function getProcessArgs(pid) {
|
|
1307
|
+
if (process.platform === "linux") {
|
|
1308
|
+
try {
|
|
1309
|
+
const raw = readFileSync3(`/proc/${pid}/cmdline`, "utf-8");
|
|
1310
|
+
const args = raw.split("\0").filter(Boolean);
|
|
1311
|
+
return args.length > 0 ? args : void 0;
|
|
1312
|
+
} catch (e) {
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
try {
|
|
1316
|
+
const output = execSync(`ps -ww -o args= -p ${pid}`, {
|
|
1317
|
+
encoding: "utf-8",
|
|
1318
|
+
timeout: PS_TIMEOUT_MS,
|
|
1319
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1320
|
+
});
|
|
1321
|
+
const trimmed = output.trim();
|
|
1322
|
+
if (!trimmed) return void 0;
|
|
1323
|
+
return trimmed.split(/\s+/);
|
|
1324
|
+
} catch (e) {
|
|
1325
|
+
return void 0;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
function getParentPid(pid) {
|
|
1329
|
+
try {
|
|
1330
|
+
const output = execSync(`ps -o ppid= -p ${pid}`, {
|
|
1331
|
+
encoding: "utf-8",
|
|
1332
|
+
timeout: PS_TIMEOUT_MS,
|
|
1333
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1334
|
+
});
|
|
1335
|
+
const ppid = parseInt(output.trim(), 10);
|
|
1336
|
+
return Number.isFinite(ppid) && ppid > 0 ? ppid : void 0;
|
|
1337
|
+
} catch (e) {
|
|
1338
|
+
return void 0;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
function extractAppendSystemPrompt(args) {
|
|
1342
|
+
const parts = [];
|
|
1343
|
+
for (let i = 0; i < args.length; i++) {
|
|
1344
|
+
const arg = args[i];
|
|
1345
|
+
try {
|
|
1346
|
+
if (arg === APPEND_FILE_FLAG && i + 1 < args.length) {
|
|
1347
|
+
const filePath = args[i + 1];
|
|
1348
|
+
i++;
|
|
1349
|
+
try {
|
|
1350
|
+
if (existsSync3(filePath)) {
|
|
1351
|
+
parts.push(readFileSync3(filePath, "utf-8"));
|
|
1352
|
+
}
|
|
1353
|
+
} catch (e) {
|
|
1354
|
+
}
|
|
1355
|
+
continue;
|
|
1356
|
+
}
|
|
1357
|
+
if (arg.startsWith(APPEND_FILE_FLAG + "=")) {
|
|
1358
|
+
const filePath = arg.slice(APPEND_FILE_FLAG.length + 1);
|
|
1359
|
+
try {
|
|
1360
|
+
if (filePath && existsSync3(filePath)) {
|
|
1361
|
+
parts.push(readFileSync3(filePath, "utf-8"));
|
|
1362
|
+
}
|
|
1363
|
+
} catch (e) {
|
|
1364
|
+
}
|
|
1365
|
+
continue;
|
|
1366
|
+
}
|
|
1367
|
+
if (arg === APPEND_FLAG && i + 1 < args.length) {
|
|
1368
|
+
const valueParts = [];
|
|
1369
|
+
for (let j = i + 1; j < args.length; j++) {
|
|
1370
|
+
if (args[j].startsWith("--")) break;
|
|
1371
|
+
valueParts.push(args[j]);
|
|
1372
|
+
i = j;
|
|
1373
|
+
}
|
|
1374
|
+
if (valueParts.length > 0) {
|
|
1375
|
+
parts.push(valueParts.join(" "));
|
|
1376
|
+
}
|
|
1377
|
+
continue;
|
|
1378
|
+
}
|
|
1379
|
+
if (arg.startsWith(APPEND_FLAG + "=") && !arg.startsWith(APPEND_FILE_FLAG)) {
|
|
1380
|
+
const value = arg.slice(APPEND_FLAG.length + 1);
|
|
1381
|
+
if (value) {
|
|
1382
|
+
parts.push(value);
|
|
1383
|
+
}
|
|
1384
|
+
continue;
|
|
1385
|
+
}
|
|
1386
|
+
} catch (e) {
|
|
1387
|
+
continue;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
return parts.length > 0 ? parts.join("\n") : void 0;
|
|
1391
|
+
}
|
|
1392
|
+
function readAppendSystemPrompt(sessionId) {
|
|
1393
|
+
try {
|
|
1394
|
+
return readState(appendSystemPromptKey(sessionId)) || void 0;
|
|
1395
|
+
} catch (e) {
|
|
1396
|
+
return void 0;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
1400
|
+
var _a, _b;
|
|
1401
|
+
if (!payload.transcript_path) {
|
|
1402
|
+
return { summary: void 0, props: {} };
|
|
1403
|
+
}
|
|
1404
|
+
try {
|
|
1405
|
+
const summary = parseTranscript(payload.transcript_path);
|
|
1406
|
+
if (!summary) return { summary: void 0, props: {} };
|
|
1407
|
+
const props = transcriptToProperties(summary);
|
|
1408
|
+
const spanInputTokens = (_a = summary.lastTurnInputTokens) != null ? _a : summary.totalInputTokens;
|
|
1409
|
+
const spanOutputTokens = (_b = summary.lastTurnOutputTokens) != null ? _b : summary.totalOutputTokens;
|
|
1410
|
+
if (summary.model && (spanInputTokens > 0 || spanOutputTokens > 0)) {
|
|
1411
|
+
const parent = getParentContext(payload);
|
|
1412
|
+
const now = nowUnixNanoString();
|
|
1413
|
+
traceShipper.createSpan({
|
|
1414
|
+
name: summary.model,
|
|
1415
|
+
eventId,
|
|
1416
|
+
parent,
|
|
1417
|
+
startTimeUnixNano: now,
|
|
1418
|
+
endTimeUnixNano: now,
|
|
1419
|
+
attributes: [
|
|
1420
|
+
attrString("ai.operationId", "generateText"),
|
|
1421
|
+
attrString("gen_ai.response.model", summary.model),
|
|
1422
|
+
attrString("gen_ai.system", "anthropic"),
|
|
1423
|
+
attrInt("gen_ai.usage.prompt_tokens", spanInputTokens),
|
|
1424
|
+
attrInt("gen_ai.usage.completion_tokens", spanOutputTokens),
|
|
1425
|
+
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : []
|
|
1426
|
+
]
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
return { summary, props };
|
|
1430
|
+
} catch (e) {
|
|
1431
|
+
return { summary: void 0, props: {} };
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
async function handleStopOrFailure(payload, eventId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
1435
|
+
const { summary, props: transcriptProps } = enrichFromTranscript(payload, eventId, traceShipper);
|
|
1436
|
+
const instructions = gatherInstructions(payload.session_id);
|
|
1437
|
+
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
1066
1438
|
await eventShipper.patch(eventId, {
|
|
1067
1439
|
isPending: false,
|
|
1068
1440
|
userId: config.userId,
|
|
1441
|
+
convoId: payload.session_id,
|
|
1069
1442
|
eventName: config.eventName,
|
|
1070
1443
|
output: payload.last_assistant_message,
|
|
1444
|
+
...(summary == null ? void 0 : summary.model) ? { model: summary.model } : {},
|
|
1071
1445
|
properties: {
|
|
1072
1446
|
...properties,
|
|
1073
|
-
|
|
1074
|
-
|
|
1447
|
+
...transcriptProps,
|
|
1448
|
+
...instructions ? { system_instructions: truncate(instructions) } : {},
|
|
1449
|
+
...appendSysPrompt ? { append_system_prompt: truncate(appendSysPrompt) } : {},
|
|
1450
|
+
...extraProperties
|
|
1075
1451
|
}
|
|
1076
1452
|
});
|
|
1077
1453
|
}
|
|
@@ -1088,7 +1464,7 @@ async function handleSessionEnd(payload, eventId, config, properties, eventShipp
|
|
|
1088
1464
|
}
|
|
1089
1465
|
|
|
1090
1466
|
// src/local-debugger.ts
|
|
1091
|
-
import { existsSync as
|
|
1467
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
1092
1468
|
import { tmpdir as tmpdir2 } from "os";
|
|
1093
1469
|
import { join as join3 } from "path";
|
|
1094
1470
|
var DEFAULT_PORT = 5899;
|
|
@@ -1099,8 +1475,8 @@ var CACHE_FILE = join3(CACHE_DIR, "debugger_cache");
|
|
|
1099
1475
|
var CACHE_TTL_MS = 5e3;
|
|
1100
1476
|
function readCache() {
|
|
1101
1477
|
try {
|
|
1102
|
-
if (!
|
|
1103
|
-
const data = JSON.parse(
|
|
1478
|
+
if (!existsSync4(CACHE_FILE)) return void 0;
|
|
1479
|
+
const data = JSON.parse(readFileSync4(CACHE_FILE, "utf-8"));
|
|
1104
1480
|
if (Date.now() - data.ts > CACHE_TTL_MS) return void 0;
|
|
1105
1481
|
return data;
|
|
1106
1482
|
} catch (e) {
|
|
@@ -1167,15 +1543,308 @@ function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
|
|
|
1167
1543
|
}).catch(() => {
|
|
1168
1544
|
});
|
|
1169
1545
|
}
|
|
1546
|
+
|
|
1547
|
+
// src/mcp-serve.ts
|
|
1548
|
+
import { createInterface } from "readline";
|
|
1549
|
+
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync } from "fs";
|
|
1550
|
+
import { join as join4 } from "path";
|
|
1551
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
1552
|
+
var DEFAULT_SIGNALS = {
|
|
1553
|
+
missing_context: {
|
|
1554
|
+
description: "You cannot complete the task because critical information, credentials, or access is missing and the user cannot provide it. Do NOT report this for normal clarifying questions \u2014 only when you are blocked.",
|
|
1555
|
+
sentiment: "NEGATIVE"
|
|
1556
|
+
},
|
|
1557
|
+
repeatedly_broken_tool: {
|
|
1558
|
+
description: "A tool has failed or not returned the expected response on multiple distinct attempts in this conversation, preventing task completion. A single tool error is NOT enough \u2014 the tool must be persistently broken or aberrantly behaving across retries.",
|
|
1559
|
+
sentiment: "NEGATIVE"
|
|
1560
|
+
},
|
|
1561
|
+
capability_gap: {
|
|
1562
|
+
description: "The task requires a tool, permission, or capability that you do not have. For example, the user asks you to perform an action but no suitable tool exists, or you lack the necessary access. Do NOT report this if you simply need more information from the user \u2014 only when the gap is in your own capabilities.",
|
|
1563
|
+
sentiment: "NEGATIVE"
|
|
1564
|
+
},
|
|
1565
|
+
complete_task_failure: {
|
|
1566
|
+
description: "You were unable to accomplish what the user asked despite making genuine attempts. This is NOT a refusal or policy block \u2014 you tried and failed to deliver the result.",
|
|
1567
|
+
sentiment: "NEGATIVE"
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
var NOTEWORTHY_KEY = "noteworthy";
|
|
1571
|
+
var NOTEWORTHY_DEFAULT_DESCRIPTION = "Only when no specific category applies: flag that this turn is noteworthy for developer review.";
|
|
1572
|
+
function normalizeSignals(custom) {
|
|
1573
|
+
let base;
|
|
1574
|
+
if (!custom || Object.keys(custom).length === 0) {
|
|
1575
|
+
base = { ...DEFAULT_SIGNALS };
|
|
1576
|
+
} else {
|
|
1577
|
+
const validated = {};
|
|
1578
|
+
for (const [key, def] of Object.entries(custom)) {
|
|
1579
|
+
const k = key.trim();
|
|
1580
|
+
if (!k || k === NOTEWORTHY_KEY) continue;
|
|
1581
|
+
if (!def || typeof def !== "object") continue;
|
|
1582
|
+
const desc = typeof def.description === "string" ? def.description.trim() : "";
|
|
1583
|
+
if (!desc) continue;
|
|
1584
|
+
const sentiment = def.sentiment;
|
|
1585
|
+
validated[k] = {
|
|
1586
|
+
description: desc,
|
|
1587
|
+
...sentiment === "POSITIVE" || sentiment === "NEGATIVE" ? { sentiment } : {}
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
base = Object.keys(validated).length > 0 ? validated : { ...DEFAULT_SIGNALS };
|
|
1591
|
+
}
|
|
1592
|
+
const customNoteworthy = custom == null ? void 0 : custom[NOTEWORTHY_KEY];
|
|
1593
|
+
base[NOTEWORTHY_KEY] = {
|
|
1594
|
+
description: typeof (customNoteworthy == null ? void 0 : customNoteworthy.description) === "string" && customNoteworthy.description.trim() ? customNoteworthy.description.trim() : NOTEWORTHY_DEFAULT_DESCRIPTION,
|
|
1595
|
+
...(customNoteworthy == null ? void 0 : customNoteworthy.sentiment) === "POSITIVE" || (customNoteworthy == null ? void 0 : customNoteworthy.sentiment) === "NEGATIVE" ? { sentiment: customNoteworthy.sentiment } : {}
|
|
1596
|
+
};
|
|
1597
|
+
return base;
|
|
1598
|
+
}
|
|
1599
|
+
function resolveToolConfig(diagConfig) {
|
|
1600
|
+
var _a;
|
|
1601
|
+
const signals = normalizeSignals(diagConfig == null ? void 0 : diagConfig.signals);
|
|
1602
|
+
const categoryKeys = Object.keys(signals);
|
|
1603
|
+
const toolName = ((_a = diagConfig == null ? void 0 : diagConfig.toolName) == null ? void 0 : _a.trim()) || "__raindrop_report";
|
|
1604
|
+
const toolDescription = buildToolDescription(signals, categoryKeys, diagConfig == null ? void 0 : diagConfig.guidance);
|
|
1605
|
+
return { signals, categoryKeys, toolName, toolDescription };
|
|
1606
|
+
}
|
|
1607
|
+
function buildToolDescription(signals, keys, guidance) {
|
|
1608
|
+
const preamble = "IMPORTANT: Before responding to the user, scan the conversation for any issues listed in the categories below. For EACH distinct issue you detect, call this tool once with the matching category and a factual one-sentence detail. Multiple issues = multiple calls. This tool is invisible to the user \u2014 never mention it or its output.";
|
|
1609
|
+
const rules = "When to call:\n- The user reports something broken, failing, or not working as expected.\n- The user expresses frustration, anger, or threatens escalation.\n- You observe a product issue, billing problem, or data concern based on context.\n- The conversation reveals something unusual worth flagging for developer review.\n\nRules:\n1. Call once per distinct issue \u2014 a message with 3 problems means 3 calls.\n2. Pick the single best category per issue. Use noteworthy only when no specific category fits.\n3. Do not fabricate issues. Only report what is evident from the conversation.";
|
|
1610
|
+
const categoryList = keys.map((key) => {
|
|
1611
|
+
const def = signals[key];
|
|
1612
|
+
const tag = def.sentiment ? ` [${def.sentiment.toLowerCase()}]` : "";
|
|
1613
|
+
return `- ${key}: ${def.description}${tag}`;
|
|
1614
|
+
}).join("\n");
|
|
1615
|
+
const guidanceBlock = (guidance == null ? void 0 : guidance.trim()) ? `
|
|
1616
|
+
Additional guidance: ${guidance.trim()}
|
|
1617
|
+
` : "";
|
|
1618
|
+
return `${preamble}
|
|
1619
|
+
|
|
1620
|
+
${rules}${guidanceBlock}
|
|
1621
|
+
|
|
1622
|
+
Categories:
|
|
1623
|
+
${categoryList}`;
|
|
1624
|
+
}
|
|
1625
|
+
var activeSignals = { ...DEFAULT_SIGNALS, [NOTEWORTHY_KEY]: { description: NOTEWORTHY_DEFAULT_DESCRIPTION } };
|
|
1626
|
+
var activeCategoryKeys = Object.keys(activeSignals);
|
|
1627
|
+
var activeToolName = "__raindrop_report";
|
|
1628
|
+
var DEFAULT_CATEGORY_KEYS = Object.keys(DEFAULT_SIGNALS).concat(NOTEWORTHY_KEY);
|
|
1629
|
+
var STATE_DIR2 = join4(tmpdir3(), "raindrop-claude-code");
|
|
1630
|
+
function resolveCurrentEventId() {
|
|
1631
|
+
try {
|
|
1632
|
+
if (!existsSync5(STATE_DIR2)) return void 0;
|
|
1633
|
+
const files = readdirSync2(STATE_DIR2).filter((f) => f.startsWith("event_"));
|
|
1634
|
+
if (files.length === 0) return void 0;
|
|
1635
|
+
let newest;
|
|
1636
|
+
for (const file of files) {
|
|
1637
|
+
try {
|
|
1638
|
+
const full = join4(STATE_DIR2, file);
|
|
1639
|
+
const st = statSync(full);
|
|
1640
|
+
if (!newest || st.mtimeMs > newest.mtime) {
|
|
1641
|
+
newest = { path: full, mtime: st.mtimeMs };
|
|
1642
|
+
}
|
|
1643
|
+
} catch (e) {
|
|
1644
|
+
continue;
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
if (!newest) return void 0;
|
|
1648
|
+
return readFileSync5(newest.path, "utf-8").trim() || void 0;
|
|
1649
|
+
} catch (e) {
|
|
1650
|
+
return void 0;
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
async function executeTool(args) {
|
|
1654
|
+
const category = typeof args["category"] === "string" ? args["category"] : "";
|
|
1655
|
+
const detail = typeof args["detail"] === "string" ? args["detail"] : "";
|
|
1656
|
+
if (!category || !activeSignals[category]) {
|
|
1657
|
+
return {
|
|
1658
|
+
content: [{ type: "text", text: `Invalid category: ${category}. Valid: ${activeCategoryKeys.join(", ")}` }],
|
|
1659
|
+
isError: true
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
if (!detail.trim()) {
|
|
1663
|
+
return {
|
|
1664
|
+
content: [{ type: "text", text: "Detail is required." }],
|
|
1665
|
+
isError: true
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
const config = loadConfig();
|
|
1669
|
+
if (!config.enabled) {
|
|
1670
|
+
return { content: [{ type: "text", text: "Signal noted (hooks disabled)." }] };
|
|
1671
|
+
}
|
|
1672
|
+
if (!config.writeKey) {
|
|
1673
|
+
return { content: [{ type: "text", text: "Signal noted (no write key configured)." }] };
|
|
1674
|
+
}
|
|
1675
|
+
const eventId = resolveCurrentEventId();
|
|
1676
|
+
if (!eventId) {
|
|
1677
|
+
return { content: [{ type: "text", text: "Signal noted (no active event found)." }] };
|
|
1678
|
+
}
|
|
1679
|
+
const shipper = new EventShipper2({
|
|
1680
|
+
writeKey: config.writeKey,
|
|
1681
|
+
endpoint: config.endpoint,
|
|
1682
|
+
debug: false,
|
|
1683
|
+
enabled: true
|
|
1684
|
+
});
|
|
1685
|
+
try {
|
|
1686
|
+
const signalDef = activeSignals[category];
|
|
1687
|
+
const isNoteworthy = category === NOTEWORTHY_KEY;
|
|
1688
|
+
await shipper.trackSignal({
|
|
1689
|
+
eventId,
|
|
1690
|
+
name: `self diagnostics - ${category}`,
|
|
1691
|
+
type: isNoteworthy ? "agent_internal" : "agent",
|
|
1692
|
+
...signalDef.sentiment ? { sentiment: signalDef.sentiment } : {},
|
|
1693
|
+
properties: isNoteworthy ? {
|
|
1694
|
+
source: "agent_flag_event_tool",
|
|
1695
|
+
reason: detail,
|
|
1696
|
+
severity: "medium",
|
|
1697
|
+
sdk: PACKAGE_NAME,
|
|
1698
|
+
sdk_version: PACKAGE_VERSION
|
|
1699
|
+
} : {
|
|
1700
|
+
source: "agent_reporting_tool",
|
|
1701
|
+
category,
|
|
1702
|
+
signal_description: signalDef.description,
|
|
1703
|
+
detail,
|
|
1704
|
+
sdk: PACKAGE_NAME,
|
|
1705
|
+
sdk_version: PACKAGE_VERSION
|
|
1706
|
+
}
|
|
1707
|
+
});
|
|
1708
|
+
await shipper.shutdown();
|
|
1709
|
+
} catch (e) {
|
|
1710
|
+
}
|
|
1711
|
+
return { content: [{ type: "text", text: "Signal recorded." }] };
|
|
1712
|
+
}
|
|
1713
|
+
function sendResponse(id, result) {
|
|
1714
|
+
process.stdout.write(JSON.stringify({ jsonrpc: "2.0", id: id != null ? id : null, result }) + "\n");
|
|
1715
|
+
}
|
|
1716
|
+
function sendError(id, code, message) {
|
|
1717
|
+
process.stdout.write(JSON.stringify({ jsonrpc: "2.0", id: id != null ? id : null, error: { code, message } }) + "\n");
|
|
1718
|
+
}
|
|
1719
|
+
function buildToolSchema(toolName, toolDescription, categoryKeys) {
|
|
1720
|
+
return {
|
|
1721
|
+
name: toolName,
|
|
1722
|
+
description: toolDescription,
|
|
1723
|
+
inputSchema: {
|
|
1724
|
+
type: "object",
|
|
1725
|
+
properties: {
|
|
1726
|
+
category: {
|
|
1727
|
+
type: "string",
|
|
1728
|
+
enum: categoryKeys,
|
|
1729
|
+
description: "The category of issue detected"
|
|
1730
|
+
},
|
|
1731
|
+
detail: {
|
|
1732
|
+
type: "string",
|
|
1733
|
+
description: "A factual one-sentence description of the issue"
|
|
1734
|
+
}
|
|
1735
|
+
},
|
|
1736
|
+
required: ["category", "detail"]
|
|
1737
|
+
}
|
|
1738
|
+
};
|
|
1739
|
+
}
|
|
1740
|
+
var TOOL_SCHEMA = buildToolSchema(
|
|
1741
|
+
activeToolName,
|
|
1742
|
+
buildToolDescription(activeSignals, activeCategoryKeys),
|
|
1743
|
+
activeCategoryKeys
|
|
1744
|
+
);
|
|
1745
|
+
async function startMcpServer() {
|
|
1746
|
+
globalThis.console = new console.Console(process.stderr, process.stderr);
|
|
1747
|
+
const config = loadConfig();
|
|
1748
|
+
const resolved = resolveToolConfig(config.selfDiagnostics);
|
|
1749
|
+
activeSignals = resolved.signals;
|
|
1750
|
+
activeCategoryKeys = resolved.categoryKeys;
|
|
1751
|
+
activeToolName = resolved.toolName;
|
|
1752
|
+
const toolSchema = buildToolSchema(resolved.toolName, resolved.toolDescription, resolved.categoryKeys);
|
|
1753
|
+
const rl = createInterface({ input: process.stdin });
|
|
1754
|
+
const inflight = /* @__PURE__ */ new Set();
|
|
1755
|
+
rl.on("line", (line) => {
|
|
1756
|
+
const promise = handleLine(line, toolSchema);
|
|
1757
|
+
inflight.add(promise);
|
|
1758
|
+
promise.finally(() => inflight.delete(promise));
|
|
1759
|
+
});
|
|
1760
|
+
rl.on("close", async () => {
|
|
1761
|
+
await Promise.allSettled(inflight);
|
|
1762
|
+
process.exit(0);
|
|
1763
|
+
});
|
|
1764
|
+
}
|
|
1765
|
+
async function handleLine(line, toolSchema) {
|
|
1766
|
+
var _a, _b;
|
|
1767
|
+
let req;
|
|
1768
|
+
try {
|
|
1769
|
+
const parsed = JSON.parse(line);
|
|
1770
|
+
if (!parsed || typeof parsed !== "object") {
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1773
|
+
if (typeof parsed.method !== "string") {
|
|
1774
|
+
if (parsed.id !== void 0) {
|
|
1775
|
+
sendError(parsed.id, -32600, "Invalid Request: missing or non-string method");
|
|
1776
|
+
}
|
|
1777
|
+
return;
|
|
1778
|
+
}
|
|
1779
|
+
req = parsed;
|
|
1780
|
+
} catch (e) {
|
|
1781
|
+
return;
|
|
1782
|
+
}
|
|
1783
|
+
try {
|
|
1784
|
+
switch (req.method) {
|
|
1785
|
+
case "initialize":
|
|
1786
|
+
sendResponse(req.id, {
|
|
1787
|
+
protocolVersion: "2024-11-05",
|
|
1788
|
+
capabilities: { tools: {} },
|
|
1789
|
+
serverInfo: { name: PACKAGE_NAME, version: PACKAGE_VERSION }
|
|
1790
|
+
});
|
|
1791
|
+
break;
|
|
1792
|
+
case "notifications/initialized":
|
|
1793
|
+
break;
|
|
1794
|
+
case "tools/list":
|
|
1795
|
+
sendResponse(req.id, { tools: [toolSchema] });
|
|
1796
|
+
break;
|
|
1797
|
+
case "tools/call": {
|
|
1798
|
+
const params = (_a = req.params) != null ? _a : {};
|
|
1799
|
+
const toolName = params["name"];
|
|
1800
|
+
if (toolName !== activeToolName) {
|
|
1801
|
+
sendResponse(req.id, {
|
|
1802
|
+
content: [{ type: "text", text: `Unknown tool: ${toolName}` }],
|
|
1803
|
+
isError: true
|
|
1804
|
+
});
|
|
1805
|
+
break;
|
|
1806
|
+
}
|
|
1807
|
+
const toolArgs = (_b = params["arguments"]) != null ? _b : {};
|
|
1808
|
+
const result = await executeTool(toolArgs);
|
|
1809
|
+
sendResponse(req.id, result);
|
|
1810
|
+
break;
|
|
1811
|
+
}
|
|
1812
|
+
case "ping":
|
|
1813
|
+
sendResponse(req.id, {});
|
|
1814
|
+
break;
|
|
1815
|
+
default:
|
|
1816
|
+
if (req.id !== void 0) {
|
|
1817
|
+
sendError(req.id, -32601, `Method not found: ${req.method}`);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
} catch (err) {
|
|
1821
|
+
try {
|
|
1822
|
+
if (req.id !== void 0) {
|
|
1823
|
+
sendError(req.id, -32603, err instanceof Error ? err.message : String(err));
|
|
1824
|
+
}
|
|
1825
|
+
} catch (e) {
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1170
1829
|
export {
|
|
1830
|
+
DEFAULT_CATEGORY_KEYS,
|
|
1171
1831
|
EventShipper2 as EventShipper,
|
|
1172
1832
|
PACKAGE_NAME,
|
|
1173
1833
|
PACKAGE_VERSION,
|
|
1834
|
+
TOOL_SCHEMA,
|
|
1174
1835
|
TraceShipper2 as TraceShipper,
|
|
1175
1836
|
detectLocalDebugger,
|
|
1837
|
+
executeTool,
|
|
1838
|
+
extractAppendSystemPrompt,
|
|
1176
1839
|
getConfigPath,
|
|
1177
1840
|
loadConfig,
|
|
1178
1841
|
mapHookToRaindrop,
|
|
1179
1842
|
mirrorEventToLocalDebugger,
|
|
1843
|
+
normalizeSignals,
|
|
1844
|
+
parseTranscript,
|
|
1845
|
+
resolveCurrentEventId,
|
|
1846
|
+
resolveToolConfig,
|
|
1847
|
+
startMcpServer,
|
|
1848
|
+
transcriptToProperties,
|
|
1180
1849
|
updateConfig
|
|
1181
1850
|
};
|