@raindrop-ai/claude-code 0.0.8 → 0.0.10
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/.claude-plugin/plugin.json +14 -0
- package/.mcp.json +9 -0
- package/dist/cli.js +91 -15
- package/dist/index.cjs +24 -15
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +24 -15
- package/hooks/hooks.json +147 -0
- package/package.json +5 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "raindrop",
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"description": "Observability for Claude Code \u2014 automatic session, tool call, and prompt tracing",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Raindrop AI",
|
|
7
|
+
"email": "support@raindrop.ai"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://docs.raindrop.ai/sdk/claude-code",
|
|
10
|
+
"repository": "https://github.com/raindrop-ai/claude-code-plugin",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"hooks": "./hooks/hooks.json",
|
|
13
|
+
"mcpServers": "./.mcp.json"
|
|
14
|
+
}
|
package/.mcp.json
ADDED
package/dist/cli.js
CHANGED
|
@@ -654,7 +654,7 @@ globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
|
654
654
|
|
|
655
655
|
// src/package-info.ts
|
|
656
656
|
var PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
657
|
-
var PACKAGE_VERSION = "0.0.
|
|
657
|
+
var PACKAGE_VERSION = "0.0.10";
|
|
658
658
|
|
|
659
659
|
// src/shipper.ts
|
|
660
660
|
var EventShipper2 = class extends EventShipper {
|
|
@@ -1010,12 +1010,13 @@ function readTimestamp(key) {
|
|
|
1010
1010
|
return Number.isFinite(ts) ? ts : void 0;
|
|
1011
1011
|
}
|
|
1012
1012
|
async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
1013
|
-
var _a;
|
|
1014
|
-
const convoId = payload.session_id;
|
|
1013
|
+
var _a, _b;
|
|
1014
|
+
const convoId = (_a = config.convoId) != null ? _a : payload.session_id;
|
|
1015
1015
|
const baseProperties = {
|
|
1016
1016
|
...config.customProperties,
|
|
1017
1017
|
cwd: payload.cwd,
|
|
1018
1018
|
permission_mode: payload.permission_mode,
|
|
1019
|
+
claude_code_session_id: payload.session_id,
|
|
1019
1020
|
plugin_version: PACKAGE_VERSION,
|
|
1020
1021
|
sdk: PACKAGE_NAME,
|
|
1021
1022
|
sdk_version: PACKAGE_VERSION,
|
|
@@ -1024,7 +1025,7 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1024
1025
|
};
|
|
1025
1026
|
switch (payload.hook_event_name) {
|
|
1026
1027
|
case "SessionStart":
|
|
1027
|
-
writeState(`model_${payload.session_id}`, (
|
|
1028
|
+
writeState(`model_${payload.session_id}`, (_b = payload.model) != null ? _b : "");
|
|
1028
1029
|
tryCaptureAppendSystemPrompt(payload.session_id);
|
|
1029
1030
|
break;
|
|
1030
1031
|
case "UserPromptSubmit":
|
|
@@ -1040,10 +1041,10 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1040
1041
|
handlePostToolUseFailure(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
1041
1042
|
break;
|
|
1042
1043
|
case "Stop":
|
|
1043
|
-
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper);
|
|
1044
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper, traceShipper);
|
|
1044
1045
|
break;
|
|
1045
1046
|
case "StopFailure":
|
|
1046
|
-
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper, {
|
|
1047
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper, traceShipper, {
|
|
1047
1048
|
error: payload.error,
|
|
1048
1049
|
error_details: payload.error_details
|
|
1049
1050
|
});
|
|
@@ -1061,10 +1062,10 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1061
1062
|
handleInstructionsLoaded(payload);
|
|
1062
1063
|
break;
|
|
1063
1064
|
case "PostCompact":
|
|
1064
|
-
await handlePostCompact(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper);
|
|
1065
|
+
await handlePostCompact(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper);
|
|
1065
1066
|
break;
|
|
1066
1067
|
case "SessionEnd":
|
|
1067
|
-
await handleSessionEnd(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper);
|
|
1068
|
+
await handleSessionEnd(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper);
|
|
1068
1069
|
deleteState(turnEventKey(payload.session_id));
|
|
1069
1070
|
deleteState(rootSpanKey(payload.session_id));
|
|
1070
1071
|
deleteState(`model_${payload.session_id}`);
|
|
@@ -1214,11 +1215,11 @@ function handlePermissionDenied(payload, eventId, traceShipper) {
|
|
|
1214
1215
|
}
|
|
1215
1216
|
});
|
|
1216
1217
|
}
|
|
1217
|
-
async function handlePostCompact(payload, eventId, config, properties, eventShipper) {
|
|
1218
|
+
async function handlePostCompact(payload, eventId, convoId, config, properties, eventShipper) {
|
|
1218
1219
|
await eventShipper.patch(eventId, {
|
|
1219
1220
|
isPending: true,
|
|
1220
1221
|
userId: config.userId,
|
|
1221
|
-
convoId
|
|
1222
|
+
convoId,
|
|
1222
1223
|
eventName: config.eventName,
|
|
1223
1224
|
properties: {
|
|
1224
1225
|
...properties,
|
|
@@ -1508,7 +1509,7 @@ function buildStopOutput(summary, lastAssistantMessage) {
|
|
|
1508
1509
|
}
|
|
1509
1510
|
return finalMessage;
|
|
1510
1511
|
}
|
|
1511
|
-
async function handleStopOrFailure(payload, eventId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
1512
|
+
async function handleStopOrFailure(payload, eventId, convoId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
1512
1513
|
const { summary, props: transcriptProps } = enrichFromTranscript(payload, eventId, traceShipper);
|
|
1513
1514
|
const instructions = gatherInstructions(payload.session_id);
|
|
1514
1515
|
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
@@ -1516,7 +1517,7 @@ async function handleStopOrFailure(payload, eventId, config, properties, eventSh
|
|
|
1516
1517
|
await eventShipper.patch(eventId, {
|
|
1517
1518
|
isPending: false,
|
|
1518
1519
|
userId: config.userId,
|
|
1519
|
-
convoId
|
|
1520
|
+
convoId,
|
|
1520
1521
|
eventName: config.eventName,
|
|
1521
1522
|
output,
|
|
1522
1523
|
...(summary == null ? void 0 : summary.model) ? { model: summary.model } : {},
|
|
@@ -1529,10 +1530,11 @@ async function handleStopOrFailure(payload, eventId, config, properties, eventSh
|
|
|
1529
1530
|
}
|
|
1530
1531
|
});
|
|
1531
1532
|
}
|
|
1532
|
-
async function handleSessionEnd(payload, eventId, config, properties, eventShipper) {
|
|
1533
|
+
async function handleSessionEnd(payload, eventId, convoId, config, properties, eventShipper) {
|
|
1533
1534
|
await eventShipper.patch(eventId, {
|
|
1534
1535
|
isPending: false,
|
|
1535
1536
|
userId: config.userId,
|
|
1537
|
+
convoId,
|
|
1536
1538
|
eventName: config.eventName,
|
|
1537
1539
|
properties: {
|
|
1538
1540
|
...properties,
|
|
@@ -1588,8 +1590,15 @@ function loadConfig() {
|
|
|
1588
1590
|
writeKey: (_c = (_b = process.env["RAINDROP_WRITE_KEY"]) != null ? _b : file.write_key) != null ? _c : "",
|
|
1589
1591
|
endpoint: (_e = (_d = process.env["RAINDROP_API_URL"]) != null ? _d : file.api_url) != null ? _e : "https://api.raindrop.ai/v1",
|
|
1590
1592
|
userId: (_g = (_f = process.env["RAINDROP_USER_ID"]) != null ? _f : file.user_id) != null ? _g : systemUser,
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
+
convoId: ((_h = process.env["RAINDROP_CONVO_ID"]) == null ? void 0 : _h.trim()) || void 0,
|
|
1594
|
+
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_i = file.debug) != null ? _i : false,
|
|
1595
|
+
enabled: (() => {
|
|
1596
|
+
var _a2;
|
|
1597
|
+
const env = process.env["RAINDROP_ENABLED"];
|
|
1598
|
+
if (!env) return (_a2 = file.enabled) != null ? _a2 : true;
|
|
1599
|
+
const lower = env.toLowerCase();
|
|
1600
|
+
return lower !== "false" && env !== "0";
|
|
1601
|
+
})(),
|
|
1593
1602
|
eventName: (_k = (_j = process.env["RAINDROP_EVENT_NAME"]) != null ? _j : file.event_name) != null ? _k : "claude_code_session",
|
|
1594
1603
|
customProperties,
|
|
1595
1604
|
selfDiagnostics
|
|
@@ -1763,6 +1772,7 @@ async function handleHook() {
|
|
|
1763
1772
|
}
|
|
1764
1773
|
const mapperConfig = {
|
|
1765
1774
|
userId: config.userId,
|
|
1775
|
+
convoId: config.convoId,
|
|
1766
1776
|
debug: config.debug,
|
|
1767
1777
|
eventName: config.eventName,
|
|
1768
1778
|
customProperties: config.customProperties
|
|
@@ -2043,6 +2053,62 @@ async function runSetup(args2) {
|
|
|
2043
2053
|
`);
|
|
2044
2054
|
}
|
|
2045
2055
|
}
|
|
2056
|
+
function runUninstall(scope = "user") {
|
|
2057
|
+
const settingsPath = getClaudeSettingsPath(scope, process.cwd());
|
|
2058
|
+
const scopeLabel = scope === "project" ? "project" : "global";
|
|
2059
|
+
if (!existsSync6(settingsPath)) {
|
|
2060
|
+
console.log(`
|
|
2061
|
+
No settings file found at ${settingsPath}. Nothing to uninstall.
|
|
2062
|
+
`);
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
let settings;
|
|
2066
|
+
try {
|
|
2067
|
+
settings = JSON.parse(readFileSync6(settingsPath, "utf-8"));
|
|
2068
|
+
} catch (e) {
|
|
2069
|
+
console.error(` Could not parse ${settingsPath}`);
|
|
2070
|
+
process.exit(1);
|
|
2071
|
+
}
|
|
2072
|
+
const hooks = settings["hooks"];
|
|
2073
|
+
let removedHooks = 0;
|
|
2074
|
+
if (hooks) {
|
|
2075
|
+
for (const event of Object.keys(hooks)) {
|
|
2076
|
+
const groups = hooks[event];
|
|
2077
|
+
if (!Array.isArray(groups)) continue;
|
|
2078
|
+
const original = groups.length;
|
|
2079
|
+
hooks[event] = groups.filter((group) => {
|
|
2080
|
+
var _a;
|
|
2081
|
+
const hookList = (_a = group.hooks) != null ? _a : [];
|
|
2082
|
+
return !hookList.some(
|
|
2083
|
+
(h) => typeof h["command"] === "string" && h["command"].includes("raindrop-claude-code")
|
|
2084
|
+
);
|
|
2085
|
+
});
|
|
2086
|
+
removedHooks += original - hooks[event].length;
|
|
2087
|
+
if (hooks[event].length === 0) {
|
|
2088
|
+
delete hooks[event];
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
if (Object.keys(hooks).length === 0) {
|
|
2092
|
+
delete settings["hooks"];
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
2096
|
+
let mcpRemoved = false;
|
|
2097
|
+
try {
|
|
2098
|
+
execSync2(`claude mcp remove raindrop-diagnostics --scope ${scope}`, { stdio: "ignore" });
|
|
2099
|
+
mcpRemoved = true;
|
|
2100
|
+
} catch (e) {
|
|
2101
|
+
}
|
|
2102
|
+
console.log(`
|
|
2103
|
+
Raindrop uninstalled (${scopeLabel}):`);
|
|
2104
|
+
console.log(` - ${removedHooks} hook entries removed from ${settingsPath}`);
|
|
2105
|
+
if (mcpRemoved) {
|
|
2106
|
+
console.log(` - raindrop-diagnostics MCP server deregistered`);
|
|
2107
|
+
}
|
|
2108
|
+
console.log(`
|
|
2109
|
+
To reinstall, run: raindrop-claude-code setup
|
|
2110
|
+
`);
|
|
2111
|
+
}
|
|
2046
2112
|
var DEBUG_LOG_PATH = "/tmp/raindrop-hooks.log";
|
|
2047
2113
|
var DEBUG_PREFIX = "RAINDROP_DEBUG=true ";
|
|
2048
2114
|
var TEE_SUFFIX = ` 2>&1 | tee -a ${DEBUG_LOG_PATH} || true`;
|
|
@@ -2448,6 +2514,11 @@ async function main() {
|
|
|
2448
2514
|
console.log(" Raindrop hooks disabled.");
|
|
2449
2515
|
break;
|
|
2450
2516
|
}
|
|
2517
|
+
case "uninstall": {
|
|
2518
|
+
const uninstallScope = parseFlag("scope") === "project" ? "project" : "user";
|
|
2519
|
+
runUninstall(uninstallScope);
|
|
2520
|
+
break;
|
|
2521
|
+
}
|
|
2451
2522
|
case "debug-on": {
|
|
2452
2523
|
const debugScope = parseFlag("scope") === "project" ? "project" : "user";
|
|
2453
2524
|
toggleDebug(true, debugScope);
|
|
@@ -2484,6 +2555,8 @@ async function main() {
|
|
|
2484
2555
|
hook Handle a Claude Code hook event (reads JSON from stdin)
|
|
2485
2556
|
mcp-serve Start the self-diagnostics MCP server (stdio)
|
|
2486
2557
|
status Check local debugger connectivity
|
|
2558
|
+
uninstall Remove all Raindrop hooks from settings.json
|
|
2559
|
+
--scope=SCOPE "user" (default) or "project"
|
|
2487
2560
|
enable Enable Raindrop hooks
|
|
2488
2561
|
disable Disable Raindrop hooks
|
|
2489
2562
|
debug-on Enable debug logging to /tmp/raindrop-hooks.log
|
|
@@ -2494,11 +2567,14 @@ async function main() {
|
|
|
2494
2567
|
Environment:
|
|
2495
2568
|
RAINDROP_WRITE_KEY API write key (alternative to --write-key or config file)
|
|
2496
2569
|
RAINDROP_USER_ID User ID override
|
|
2570
|
+
RAINDROP_CONVO_ID Conversation/thread ID override
|
|
2497
2571
|
RAINDROP_EVENT_NAME Custom event name (default: "claude_code_session")
|
|
2498
2572
|
RAINDROP_PROPERTIES JSON object merged into every event's properties
|
|
2573
|
+
RAINDROP_ENABLED Set to "false" to disable all telemetry
|
|
2499
2574
|
RAINDROP_API_URL Custom API endpoint
|
|
2500
2575
|
RAINDROP_LOCAL_DEBUGGER Local debugger URL (auto-detected if running on :5899)
|
|
2501
2576
|
RAINDROP_DEBUG Set to "true" for verbose logging
|
|
2577
|
+
RAINDROP_SELF_DIAGNOSTICS JSON object to customize self-diagnostics signal categories
|
|
2502
2578
|
`);
|
|
2503
2579
|
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
2504
2580
|
process.exit(0);
|
package/dist/index.cjs
CHANGED
|
@@ -690,7 +690,7 @@ globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = import_async_hooks.AsyncLocalStorage;
|
|
|
690
690
|
|
|
691
691
|
// src/package-info.ts
|
|
692
692
|
var PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
693
|
-
var PACKAGE_VERSION = "0.0.
|
|
693
|
+
var PACKAGE_VERSION = "0.0.10";
|
|
694
694
|
|
|
695
695
|
// src/shipper.ts
|
|
696
696
|
var EventShipper2 = class extends EventShipper {
|
|
@@ -774,8 +774,15 @@ function loadConfig() {
|
|
|
774
774
|
writeKey: (_c = (_b = process.env["RAINDROP_WRITE_KEY"]) != null ? _b : file.write_key) != null ? _c : "",
|
|
775
775
|
endpoint: (_e = (_d = process.env["RAINDROP_API_URL"]) != null ? _d : file.api_url) != null ? _e : "https://api.raindrop.ai/v1",
|
|
776
776
|
userId: (_g = (_f = process.env["RAINDROP_USER_ID"]) != null ? _f : file.user_id) != null ? _g : systemUser,
|
|
777
|
-
|
|
778
|
-
|
|
777
|
+
convoId: ((_h = process.env["RAINDROP_CONVO_ID"]) == null ? void 0 : _h.trim()) || void 0,
|
|
778
|
+
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_i = file.debug) != null ? _i : false,
|
|
779
|
+
enabled: (() => {
|
|
780
|
+
var _a2;
|
|
781
|
+
const env = process.env["RAINDROP_ENABLED"];
|
|
782
|
+
if (!env) return (_a2 = file.enabled) != null ? _a2 : true;
|
|
783
|
+
const lower = env.toLowerCase();
|
|
784
|
+
return lower !== "false" && env !== "0";
|
|
785
|
+
})(),
|
|
779
786
|
eventName: (_k = (_j = process.env["RAINDROP_EVENT_NAME"]) != null ? _j : file.event_name) != null ? _k : "claude_code_session",
|
|
780
787
|
customProperties,
|
|
781
788
|
selfDiagnostics
|
|
@@ -1123,12 +1130,13 @@ function readTimestamp(key) {
|
|
|
1123
1130
|
return Number.isFinite(ts) ? ts : void 0;
|
|
1124
1131
|
}
|
|
1125
1132
|
async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
1126
|
-
var _a;
|
|
1127
|
-
const convoId = payload.session_id;
|
|
1133
|
+
var _a, _b;
|
|
1134
|
+
const convoId = (_a = config.convoId) != null ? _a : payload.session_id;
|
|
1128
1135
|
const baseProperties = {
|
|
1129
1136
|
...config.customProperties,
|
|
1130
1137
|
cwd: payload.cwd,
|
|
1131
1138
|
permission_mode: payload.permission_mode,
|
|
1139
|
+
claude_code_session_id: payload.session_id,
|
|
1132
1140
|
plugin_version: PACKAGE_VERSION,
|
|
1133
1141
|
sdk: PACKAGE_NAME,
|
|
1134
1142
|
sdk_version: PACKAGE_VERSION,
|
|
@@ -1137,7 +1145,7 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1137
1145
|
};
|
|
1138
1146
|
switch (payload.hook_event_name) {
|
|
1139
1147
|
case "SessionStart":
|
|
1140
|
-
writeState(`model_${payload.session_id}`, (
|
|
1148
|
+
writeState(`model_${payload.session_id}`, (_b = payload.model) != null ? _b : "");
|
|
1141
1149
|
tryCaptureAppendSystemPrompt(payload.session_id);
|
|
1142
1150
|
break;
|
|
1143
1151
|
case "UserPromptSubmit":
|
|
@@ -1153,10 +1161,10 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1153
1161
|
handlePostToolUseFailure(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
1154
1162
|
break;
|
|
1155
1163
|
case "Stop":
|
|
1156
|
-
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper);
|
|
1164
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper, traceShipper);
|
|
1157
1165
|
break;
|
|
1158
1166
|
case "StopFailure":
|
|
1159
|
-
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper, {
|
|
1167
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper, traceShipper, {
|
|
1160
1168
|
error: payload.error,
|
|
1161
1169
|
error_details: payload.error_details
|
|
1162
1170
|
});
|
|
@@ -1174,10 +1182,10 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1174
1182
|
handleInstructionsLoaded(payload);
|
|
1175
1183
|
break;
|
|
1176
1184
|
case "PostCompact":
|
|
1177
|
-
await handlePostCompact(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper);
|
|
1185
|
+
await handlePostCompact(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper);
|
|
1178
1186
|
break;
|
|
1179
1187
|
case "SessionEnd":
|
|
1180
|
-
await handleSessionEnd(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper);
|
|
1188
|
+
await handleSessionEnd(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper);
|
|
1181
1189
|
deleteState(turnEventKey(payload.session_id));
|
|
1182
1190
|
deleteState(rootSpanKey(payload.session_id));
|
|
1183
1191
|
deleteState(`model_${payload.session_id}`);
|
|
@@ -1327,11 +1335,11 @@ function handlePermissionDenied(payload, eventId, traceShipper) {
|
|
|
1327
1335
|
}
|
|
1328
1336
|
});
|
|
1329
1337
|
}
|
|
1330
|
-
async function handlePostCompact(payload, eventId, config, properties, eventShipper) {
|
|
1338
|
+
async function handlePostCompact(payload, eventId, convoId, config, properties, eventShipper) {
|
|
1331
1339
|
await eventShipper.patch(eventId, {
|
|
1332
1340
|
isPending: true,
|
|
1333
1341
|
userId: config.userId,
|
|
1334
|
-
convoId
|
|
1342
|
+
convoId,
|
|
1335
1343
|
eventName: config.eventName,
|
|
1336
1344
|
properties: {
|
|
1337
1345
|
...properties,
|
|
@@ -1621,7 +1629,7 @@ function buildStopOutput(summary, lastAssistantMessage) {
|
|
|
1621
1629
|
}
|
|
1622
1630
|
return finalMessage;
|
|
1623
1631
|
}
|
|
1624
|
-
async function handleStopOrFailure(payload, eventId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
1632
|
+
async function handleStopOrFailure(payload, eventId, convoId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
1625
1633
|
const { summary, props: transcriptProps } = enrichFromTranscript(payload, eventId, traceShipper);
|
|
1626
1634
|
const instructions = gatherInstructions(payload.session_id);
|
|
1627
1635
|
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
@@ -1629,7 +1637,7 @@ async function handleStopOrFailure(payload, eventId, config, properties, eventSh
|
|
|
1629
1637
|
await eventShipper.patch(eventId, {
|
|
1630
1638
|
isPending: false,
|
|
1631
1639
|
userId: config.userId,
|
|
1632
|
-
convoId
|
|
1640
|
+
convoId,
|
|
1633
1641
|
eventName: config.eventName,
|
|
1634
1642
|
output,
|
|
1635
1643
|
...(summary == null ? void 0 : summary.model) ? { model: summary.model } : {},
|
|
@@ -1642,10 +1650,11 @@ async function handleStopOrFailure(payload, eventId, config, properties, eventSh
|
|
|
1642
1650
|
}
|
|
1643
1651
|
});
|
|
1644
1652
|
}
|
|
1645
|
-
async function handleSessionEnd(payload, eventId, config, properties, eventShipper) {
|
|
1653
|
+
async function handleSessionEnd(payload, eventId, convoId, config, properties, eventShipper) {
|
|
1646
1654
|
await eventShipper.patch(eventId, {
|
|
1647
1655
|
isPending: false,
|
|
1648
1656
|
userId: config.userId,
|
|
1657
|
+
convoId,
|
|
1649
1658
|
eventName: config.eventName,
|
|
1650
1659
|
properties: {
|
|
1651
1660
|
...properties,
|
package/dist/index.d.cts
CHANGED
|
@@ -244,6 +244,7 @@ interface RaindropConfig {
|
|
|
244
244
|
writeKey: string;
|
|
245
245
|
endpoint: string;
|
|
246
246
|
userId: string;
|
|
247
|
+
convoId?: string;
|
|
247
248
|
debug: boolean;
|
|
248
249
|
enabled: boolean;
|
|
249
250
|
eventName: string;
|
|
@@ -292,6 +293,7 @@ interface HookPayload {
|
|
|
292
293
|
}
|
|
293
294
|
interface MapperConfig {
|
|
294
295
|
userId: string;
|
|
296
|
+
convoId?: string;
|
|
295
297
|
debug: boolean;
|
|
296
298
|
eventName: string;
|
|
297
299
|
customProperties: Record<string, unknown>;
|
|
@@ -308,7 +310,7 @@ declare function mapHookToRaindrop(payload: HookPayload, config: MapperConfig, e
|
|
|
308
310
|
declare function extractAppendSystemPrompt(args: string[]): string | undefined;
|
|
309
311
|
|
|
310
312
|
declare const PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
311
|
-
declare const PACKAGE_VERSION = "0.0.
|
|
313
|
+
declare const PACKAGE_VERSION = "0.0.10";
|
|
312
314
|
|
|
313
315
|
/** A tool call extracted from an assistant message content block. */
|
|
314
316
|
interface LLMToolCall {
|
package/dist/index.d.ts
CHANGED
|
@@ -244,6 +244,7 @@ interface RaindropConfig {
|
|
|
244
244
|
writeKey: string;
|
|
245
245
|
endpoint: string;
|
|
246
246
|
userId: string;
|
|
247
|
+
convoId?: string;
|
|
247
248
|
debug: boolean;
|
|
248
249
|
enabled: boolean;
|
|
249
250
|
eventName: string;
|
|
@@ -292,6 +293,7 @@ interface HookPayload {
|
|
|
292
293
|
}
|
|
293
294
|
interface MapperConfig {
|
|
294
295
|
userId: string;
|
|
296
|
+
convoId?: string;
|
|
295
297
|
debug: boolean;
|
|
296
298
|
eventName: string;
|
|
297
299
|
customProperties: Record<string, unknown>;
|
|
@@ -308,7 +310,7 @@ declare function mapHookToRaindrop(payload: HookPayload, config: MapperConfig, e
|
|
|
308
310
|
declare function extractAppendSystemPrompt(args: string[]): string | undefined;
|
|
309
311
|
|
|
310
312
|
declare const PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
311
|
-
declare const PACKAGE_VERSION = "0.0.
|
|
313
|
+
declare const PACKAGE_VERSION = "0.0.10";
|
|
312
314
|
|
|
313
315
|
/** A tool call extracted from an assistant message content block. */
|
|
314
316
|
interface LLMToolCall {
|
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.10";
|
|
649
649
|
|
|
650
650
|
// src/shipper.ts
|
|
651
651
|
var EventShipper2 = class extends EventShipper {
|
|
@@ -729,8 +729,15 @@ function loadConfig() {
|
|
|
729
729
|
writeKey: (_c = (_b = process.env["RAINDROP_WRITE_KEY"]) != null ? _b : file.write_key) != null ? _c : "",
|
|
730
730
|
endpoint: (_e = (_d = process.env["RAINDROP_API_URL"]) != null ? _d : file.api_url) != null ? _e : "https://api.raindrop.ai/v1",
|
|
731
731
|
userId: (_g = (_f = process.env["RAINDROP_USER_ID"]) != null ? _f : file.user_id) != null ? _g : systemUser,
|
|
732
|
-
|
|
733
|
-
|
|
732
|
+
convoId: ((_h = process.env["RAINDROP_CONVO_ID"]) == null ? void 0 : _h.trim()) || void 0,
|
|
733
|
+
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_i = file.debug) != null ? _i : false,
|
|
734
|
+
enabled: (() => {
|
|
735
|
+
var _a2;
|
|
736
|
+
const env = process.env["RAINDROP_ENABLED"];
|
|
737
|
+
if (!env) return (_a2 = file.enabled) != null ? _a2 : true;
|
|
738
|
+
const lower = env.toLowerCase();
|
|
739
|
+
return lower !== "false" && env !== "0";
|
|
740
|
+
})(),
|
|
734
741
|
eventName: (_k = (_j = process.env["RAINDROP_EVENT_NAME"]) != null ? _j : file.event_name) != null ? _k : "claude_code_session",
|
|
735
742
|
customProperties,
|
|
736
743
|
selfDiagnostics
|
|
@@ -1078,12 +1085,13 @@ function readTimestamp(key) {
|
|
|
1078
1085
|
return Number.isFinite(ts) ? ts : void 0;
|
|
1079
1086
|
}
|
|
1080
1087
|
async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
1081
|
-
var _a;
|
|
1082
|
-
const convoId = payload.session_id;
|
|
1088
|
+
var _a, _b;
|
|
1089
|
+
const convoId = (_a = config.convoId) != null ? _a : payload.session_id;
|
|
1083
1090
|
const baseProperties = {
|
|
1084
1091
|
...config.customProperties,
|
|
1085
1092
|
cwd: payload.cwd,
|
|
1086
1093
|
permission_mode: payload.permission_mode,
|
|
1094
|
+
claude_code_session_id: payload.session_id,
|
|
1087
1095
|
plugin_version: PACKAGE_VERSION,
|
|
1088
1096
|
sdk: PACKAGE_NAME,
|
|
1089
1097
|
sdk_version: PACKAGE_VERSION,
|
|
@@ -1092,7 +1100,7 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1092
1100
|
};
|
|
1093
1101
|
switch (payload.hook_event_name) {
|
|
1094
1102
|
case "SessionStart":
|
|
1095
|
-
writeState(`model_${payload.session_id}`, (
|
|
1103
|
+
writeState(`model_${payload.session_id}`, (_b = payload.model) != null ? _b : "");
|
|
1096
1104
|
tryCaptureAppendSystemPrompt(payload.session_id);
|
|
1097
1105
|
break;
|
|
1098
1106
|
case "UserPromptSubmit":
|
|
@@ -1108,10 +1116,10 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1108
1116
|
handlePostToolUseFailure(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
1109
1117
|
break;
|
|
1110
1118
|
case "Stop":
|
|
1111
|
-
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper);
|
|
1119
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper, traceShipper);
|
|
1112
1120
|
break;
|
|
1113
1121
|
case "StopFailure":
|
|
1114
|
-
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper, {
|
|
1122
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper, traceShipper, {
|
|
1115
1123
|
error: payload.error,
|
|
1116
1124
|
error_details: payload.error_details
|
|
1117
1125
|
});
|
|
@@ -1129,10 +1137,10 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
1129
1137
|
handleInstructionsLoaded(payload);
|
|
1130
1138
|
break;
|
|
1131
1139
|
case "PostCompact":
|
|
1132
|
-
await handlePostCompact(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper);
|
|
1140
|
+
await handlePostCompact(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper);
|
|
1133
1141
|
break;
|
|
1134
1142
|
case "SessionEnd":
|
|
1135
|
-
await handleSessionEnd(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper);
|
|
1143
|
+
await handleSessionEnd(payload, getCurrentEventId(payload.session_id), convoId, config, baseProperties, eventShipper);
|
|
1136
1144
|
deleteState(turnEventKey(payload.session_id));
|
|
1137
1145
|
deleteState(rootSpanKey(payload.session_id));
|
|
1138
1146
|
deleteState(`model_${payload.session_id}`);
|
|
@@ -1282,11 +1290,11 @@ function handlePermissionDenied(payload, eventId, traceShipper) {
|
|
|
1282
1290
|
}
|
|
1283
1291
|
});
|
|
1284
1292
|
}
|
|
1285
|
-
async function handlePostCompact(payload, eventId, config, properties, eventShipper) {
|
|
1293
|
+
async function handlePostCompact(payload, eventId, convoId, config, properties, eventShipper) {
|
|
1286
1294
|
await eventShipper.patch(eventId, {
|
|
1287
1295
|
isPending: true,
|
|
1288
1296
|
userId: config.userId,
|
|
1289
|
-
convoId
|
|
1297
|
+
convoId,
|
|
1290
1298
|
eventName: config.eventName,
|
|
1291
1299
|
properties: {
|
|
1292
1300
|
...properties,
|
|
@@ -1576,7 +1584,7 @@ function buildStopOutput(summary, lastAssistantMessage) {
|
|
|
1576
1584
|
}
|
|
1577
1585
|
return finalMessage;
|
|
1578
1586
|
}
|
|
1579
|
-
async function handleStopOrFailure(payload, eventId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
1587
|
+
async function handleStopOrFailure(payload, eventId, convoId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
1580
1588
|
const { summary, props: transcriptProps } = enrichFromTranscript(payload, eventId, traceShipper);
|
|
1581
1589
|
const instructions = gatherInstructions(payload.session_id);
|
|
1582
1590
|
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
@@ -1584,7 +1592,7 @@ async function handleStopOrFailure(payload, eventId, config, properties, eventSh
|
|
|
1584
1592
|
await eventShipper.patch(eventId, {
|
|
1585
1593
|
isPending: false,
|
|
1586
1594
|
userId: config.userId,
|
|
1587
|
-
convoId
|
|
1595
|
+
convoId,
|
|
1588
1596
|
eventName: config.eventName,
|
|
1589
1597
|
output,
|
|
1590
1598
|
...(summary == null ? void 0 : summary.model) ? { model: summary.model } : {},
|
|
@@ -1597,10 +1605,11 @@ async function handleStopOrFailure(payload, eventId, config, properties, eventSh
|
|
|
1597
1605
|
}
|
|
1598
1606
|
});
|
|
1599
1607
|
}
|
|
1600
|
-
async function handleSessionEnd(payload, eventId, config, properties, eventShipper) {
|
|
1608
|
+
async function handleSessionEnd(payload, eventId, convoId, config, properties, eventShipper) {
|
|
1601
1609
|
await eventShipper.patch(eventId, {
|
|
1602
1610
|
isPending: false,
|
|
1603
1611
|
userId: config.userId,
|
|
1612
|
+
convoId,
|
|
1604
1613
|
eventName: config.eventName,
|
|
1605
1614
|
properties: {
|
|
1606
1615
|
...properties,
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
9
|
+
"timeout": 10
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"UserPromptSubmit": [
|
|
15
|
+
{
|
|
16
|
+
"hooks": [
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
20
|
+
"timeout": 10
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"PreToolUse": [
|
|
26
|
+
{
|
|
27
|
+
"hooks": [
|
|
28
|
+
{
|
|
29
|
+
"type": "command",
|
|
30
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
31
|
+
"timeout": 10
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"PostToolUse": [
|
|
37
|
+
{
|
|
38
|
+
"hooks": [
|
|
39
|
+
{
|
|
40
|
+
"type": "command",
|
|
41
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
42
|
+
"timeout": 10
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
"PostToolUseFailure": [
|
|
48
|
+
{
|
|
49
|
+
"hooks": [
|
|
50
|
+
{
|
|
51
|
+
"type": "command",
|
|
52
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
53
|
+
"timeout": 10
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"SubagentStart": [
|
|
59
|
+
{
|
|
60
|
+
"hooks": [
|
|
61
|
+
{
|
|
62
|
+
"type": "command",
|
|
63
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
64
|
+
"timeout": 10
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"SubagentStop": [
|
|
70
|
+
{
|
|
71
|
+
"hooks": [
|
|
72
|
+
{
|
|
73
|
+
"type": "command",
|
|
74
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
75
|
+
"timeout": 10
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"Stop": [
|
|
81
|
+
{
|
|
82
|
+
"hooks": [
|
|
83
|
+
{
|
|
84
|
+
"type": "command",
|
|
85
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
86
|
+
"timeout": 10
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
"StopFailure": [
|
|
92
|
+
{
|
|
93
|
+
"hooks": [
|
|
94
|
+
{
|
|
95
|
+
"type": "command",
|
|
96
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
97
|
+
"timeout": 10
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
"SessionEnd": [
|
|
103
|
+
{
|
|
104
|
+
"hooks": [
|
|
105
|
+
{
|
|
106
|
+
"type": "command",
|
|
107
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
108
|
+
"timeout": 10
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"PostCompact": [
|
|
114
|
+
{
|
|
115
|
+
"hooks": [
|
|
116
|
+
{
|
|
117
|
+
"type": "command",
|
|
118
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
119
|
+
"timeout": 10
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
"InstructionsLoaded": [
|
|
125
|
+
{
|
|
126
|
+
"hooks": [
|
|
127
|
+
{
|
|
128
|
+
"type": "command",
|
|
129
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
130
|
+
"timeout": 10
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
"PermissionDenied": [
|
|
136
|
+
{
|
|
137
|
+
"hooks": [
|
|
138
|
+
{
|
|
139
|
+
"type": "command",
|
|
140
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/node_modules/.bin/raindrop-claude-code\" hook",
|
|
141
|
+
"timeout": 10
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raindrop-ai/claude-code",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -25,7 +25,10 @@
|
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"files": [
|
|
27
27
|
"dist/**",
|
|
28
|
-
"README.md"
|
|
28
|
+
"README.md",
|
|
29
|
+
".claude-plugin/**",
|
|
30
|
+
"hooks/**",
|
|
31
|
+
".mcp.json"
|
|
29
32
|
],
|
|
30
33
|
"keywords": [
|
|
31
34
|
"raindrop",
|