@raindrop-ai/claude-code 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/cli.js +433 -46
- package/dist/index.cjs +423 -33
- package/dist/index.d.cts +60 -2
- package/dist/index.d.ts +60 -2
- package/dist/index.js +415 -28
- 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.5";
|
|
649
649
|
|
|
650
650
|
// src/shipper.ts
|
|
651
651
|
var EventShipper2 = class extends EventShipper {
|
|
@@ -688,7 +688,7 @@ import { homedir, userInfo } from "os";
|
|
|
688
688
|
import { dirname, join } from "path";
|
|
689
689
|
var CONFIG_PATH = join(homedir(), ".config", "raindrop", "config.json");
|
|
690
690
|
function loadConfig() {
|
|
691
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
691
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
692
692
|
let file = {};
|
|
693
693
|
try {
|
|
694
694
|
if (existsSync(CONFIG_PATH)) {
|
|
@@ -703,12 +703,25 @@ function loadConfig() {
|
|
|
703
703
|
return "unknown";
|
|
704
704
|
}
|
|
705
705
|
})();
|
|
706
|
+
let customProperties = (_a = file.custom_properties) != null ? _a : {};
|
|
707
|
+
const envProps = process.env["RAINDROP_PROPERTIES"];
|
|
708
|
+
if (envProps) {
|
|
709
|
+
try {
|
|
710
|
+
const parsed = JSON.parse(envProps);
|
|
711
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
712
|
+
customProperties = { ...customProperties, ...parsed };
|
|
713
|
+
}
|
|
714
|
+
} catch (e) {
|
|
715
|
+
}
|
|
716
|
+
}
|
|
706
717
|
return {
|
|
707
|
-
writeKey: (
|
|
708
|
-
endpoint: (
|
|
709
|
-
userId: (
|
|
710
|
-
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (
|
|
711
|
-
enabled: (
|
|
718
|
+
writeKey: (_c = (_b = process.env["RAINDROP_WRITE_KEY"]) != null ? _b : file.write_key) != null ? _c : "",
|
|
719
|
+
endpoint: (_e = (_d = process.env["RAINDROP_API_URL"]) != null ? _d : file.api_url) != null ? _e : "https://api.raindrop.ai/v1",
|
|
720
|
+
userId: (_g = (_f = process.env["RAINDROP_USER_ID"]) != null ? _f : file.user_id) != null ? _g : systemUser,
|
|
721
|
+
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_h = file.debug) != null ? _h : false,
|
|
722
|
+
enabled: (_i = file.enabled) != null ? _i : true,
|
|
723
|
+
eventName: (_k = (_j = process.env["RAINDROP_EVENT_NAME"]) != null ? _j : file.event_name) != null ? _k : "claude_code_session",
|
|
724
|
+
customProperties
|
|
712
725
|
};
|
|
713
726
|
}
|
|
714
727
|
function getConfigPath() {
|
|
@@ -728,10 +741,145 @@ function updateConfig(patch) {
|
|
|
728
741
|
}
|
|
729
742
|
|
|
730
743
|
// src/event-mapper.ts
|
|
731
|
-
import { existsSync as
|
|
744
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
745
|
+
import { execSync } from "child_process";
|
|
732
746
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
733
747
|
import { tmpdir } from "os";
|
|
734
748
|
import { join as join2 } from "path";
|
|
749
|
+
|
|
750
|
+
// src/transcript.ts
|
|
751
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
752
|
+
function parseTranscript(transcriptPath) {
|
|
753
|
+
var _a, _b, _c, _d, _e;
|
|
754
|
+
try {
|
|
755
|
+
if (!existsSync2(transcriptPath)) return void 0;
|
|
756
|
+
const content = readFileSync2(transcriptPath, "utf-8");
|
|
757
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
758
|
+
const summary = {
|
|
759
|
+
totalInputTokens: 0,
|
|
760
|
+
totalOutputTokens: 0,
|
|
761
|
+
totalCacheReadTokens: 0,
|
|
762
|
+
totalCacheCreationTokens: 0,
|
|
763
|
+
turnCount: 0,
|
|
764
|
+
toolsUsed: [],
|
|
765
|
+
hasThinking: false
|
|
766
|
+
};
|
|
767
|
+
const toolNames = /* @__PURE__ */ new Set();
|
|
768
|
+
let lastUsage;
|
|
769
|
+
for (const line of lines) {
|
|
770
|
+
let entry;
|
|
771
|
+
try {
|
|
772
|
+
entry = JSON.parse(line);
|
|
773
|
+
} catch (e) {
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
if (entry.type === "system" && entry.subtype === "turn_duration") {
|
|
777
|
+
const durationMs = entry["durationMs"];
|
|
778
|
+
if (typeof durationMs === "number") {
|
|
779
|
+
summary.totalDurationMs = ((_a = summary.totalDurationMs) != null ? _a : 0) + durationMs;
|
|
780
|
+
}
|
|
781
|
+
const version = entry["version"];
|
|
782
|
+
if (typeof version === "string") {
|
|
783
|
+
summary.codeVersion = version;
|
|
784
|
+
}
|
|
785
|
+
const branch = entry["gitBranch"];
|
|
786
|
+
if (typeof branch === "string") {
|
|
787
|
+
summary.gitBranch = branch;
|
|
788
|
+
}
|
|
789
|
+
continue;
|
|
790
|
+
}
|
|
791
|
+
if (entry.type !== "assistant") continue;
|
|
792
|
+
const msg = entry.message;
|
|
793
|
+
if (!msg) continue;
|
|
794
|
+
summary.turnCount++;
|
|
795
|
+
if (msg.model) {
|
|
796
|
+
summary.model = msg.model;
|
|
797
|
+
}
|
|
798
|
+
if (msg.stop_reason) {
|
|
799
|
+
summary.stopReason = msg.stop_reason;
|
|
800
|
+
}
|
|
801
|
+
const entryVersion = entry["version"];
|
|
802
|
+
if (typeof entryVersion === "string") {
|
|
803
|
+
summary.codeVersion = entryVersion;
|
|
804
|
+
}
|
|
805
|
+
const entryBranch = entry["gitBranch"];
|
|
806
|
+
if (typeof entryBranch === "string") {
|
|
807
|
+
summary.gitBranch = entryBranch;
|
|
808
|
+
}
|
|
809
|
+
if (msg.usage) {
|
|
810
|
+
const u = msg.usage;
|
|
811
|
+
summary.totalInputTokens += (_b = u.input_tokens) != null ? _b : 0;
|
|
812
|
+
summary.totalOutputTokens += (_c = u.output_tokens) != null ? _c : 0;
|
|
813
|
+
summary.totalCacheReadTokens += (_d = u.cache_read_input_tokens) != null ? _d : 0;
|
|
814
|
+
summary.totalCacheCreationTokens += (_e = u.cache_creation_input_tokens) != null ? _e : 0;
|
|
815
|
+
if (u.service_tier) {
|
|
816
|
+
summary.serviceTier = u.service_tier;
|
|
817
|
+
}
|
|
818
|
+
lastUsage = u;
|
|
819
|
+
}
|
|
820
|
+
if (Array.isArray(msg.content)) {
|
|
821
|
+
for (const block of msg.content) {
|
|
822
|
+
if (block.type === "tool_use" && block.name) {
|
|
823
|
+
toolNames.add(block.name);
|
|
824
|
+
}
|
|
825
|
+
if (block.type === "thinking") {
|
|
826
|
+
summary.hasThinking = true;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
if (lastUsage) {
|
|
832
|
+
summary.lastTurnInputTokens = lastUsage.input_tokens;
|
|
833
|
+
summary.lastTurnOutputTokens = lastUsage.output_tokens;
|
|
834
|
+
summary.lastTurnCacheReadTokens = lastUsage.cache_read_input_tokens;
|
|
835
|
+
}
|
|
836
|
+
summary.toolsUsed = [...toolNames].sort();
|
|
837
|
+
return summary;
|
|
838
|
+
} catch (e) {
|
|
839
|
+
return void 0;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
function transcriptToProperties(summary) {
|
|
843
|
+
var _a, _b;
|
|
844
|
+
const props = {};
|
|
845
|
+
props["ai.usage.prompt_tokens"] = (_a = summary.lastTurnInputTokens) != null ? _a : summary.totalInputTokens;
|
|
846
|
+
props["ai.usage.completion_tokens"] = (_b = summary.lastTurnOutputTokens) != null ? _b : summary.totalOutputTokens;
|
|
847
|
+
if (summary.lastTurnCacheReadTokens !== void 0) {
|
|
848
|
+
props["ai.usage.cache_read_tokens"] = summary.lastTurnCacheReadTokens;
|
|
849
|
+
}
|
|
850
|
+
props["ai.usage.session_total.prompt_tokens"] = summary.totalInputTokens;
|
|
851
|
+
props["ai.usage.session_total.completion_tokens"] = summary.totalOutputTokens;
|
|
852
|
+
props["ai.usage.session_total.cache_read_tokens"] = summary.totalCacheReadTokens;
|
|
853
|
+
props["ai.usage.session_total.cache_creation_tokens"] = summary.totalCacheCreationTokens;
|
|
854
|
+
if (summary.model) {
|
|
855
|
+
props["ai.model"] = summary.model;
|
|
856
|
+
}
|
|
857
|
+
if (summary.serviceTier) {
|
|
858
|
+
props["ai.service_tier"] = summary.serviceTier;
|
|
859
|
+
}
|
|
860
|
+
if (summary.stopReason) {
|
|
861
|
+
props["ai.stop_reason"] = summary.stopReason;
|
|
862
|
+
}
|
|
863
|
+
if (summary.toolsUsed.length > 0) {
|
|
864
|
+
props["ai.tools_used"] = summary.toolsUsed.join(", ");
|
|
865
|
+
}
|
|
866
|
+
props["ai.turn_count"] = summary.turnCount;
|
|
867
|
+
if (summary.totalDurationMs !== void 0) {
|
|
868
|
+
props["ai.duration_ms"] = summary.totalDurationMs;
|
|
869
|
+
}
|
|
870
|
+
if (summary.codeVersion) {
|
|
871
|
+
props["claude_code.version"] = summary.codeVersion;
|
|
872
|
+
}
|
|
873
|
+
if (summary.gitBranch) {
|
|
874
|
+
props["git.branch"] = summary.gitBranch;
|
|
875
|
+
}
|
|
876
|
+
if (summary.hasThinking) {
|
|
877
|
+
props["ai.has_thinking"] = true;
|
|
878
|
+
}
|
|
879
|
+
return props;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
// src/event-mapper.ts
|
|
735
883
|
var MAX_ATTR_LENGTH = 32768;
|
|
736
884
|
function truncate(value) {
|
|
737
885
|
if (value === void 0) return void 0;
|
|
@@ -775,8 +923,8 @@ function writeState(key, value) {
|
|
|
775
923
|
function readState(key) {
|
|
776
924
|
try {
|
|
777
925
|
const filePath = statePath(key);
|
|
778
|
-
if (!
|
|
779
|
-
return
|
|
926
|
+
if (!existsSync3(filePath)) return void 0;
|
|
927
|
+
return readFileSync3(filePath, "utf-8");
|
|
780
928
|
} catch (e) {
|
|
781
929
|
return void 0;
|
|
782
930
|
}
|
|
@@ -837,15 +985,19 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
837
985
|
var _a;
|
|
838
986
|
const convoId = payload.session_id;
|
|
839
987
|
const baseProperties = {
|
|
988
|
+
...config.customProperties,
|
|
840
989
|
cwd: payload.cwd,
|
|
841
990
|
permission_mode: payload.permission_mode,
|
|
842
991
|
plugin_version: PACKAGE_VERSION,
|
|
992
|
+
sdk: PACKAGE_NAME,
|
|
993
|
+
sdk_version: PACKAGE_VERSION,
|
|
843
994
|
...payload.agent_id ? { agent_id: payload.agent_id } : {},
|
|
844
995
|
...payload.agent_type ? { agent_type: payload.agent_type } : {}
|
|
845
996
|
};
|
|
846
997
|
switch (payload.hook_event_name) {
|
|
847
998
|
case "SessionStart":
|
|
848
999
|
writeState(`model_${payload.session_id}`, (_a = payload.model) != null ? _a : "");
|
|
1000
|
+
tryCaptureAppendSystemPrompt(payload.session_id);
|
|
849
1001
|
break;
|
|
850
1002
|
case "UserPromptSubmit":
|
|
851
1003
|
await handleUserPromptSubmit(payload, convoId, config, baseProperties, eventShipper, traceShipper);
|
|
@@ -860,10 +1012,13 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
860
1012
|
handlePostToolUseFailure(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
861
1013
|
break;
|
|
862
1014
|
case "Stop":
|
|
863
|
-
await
|
|
1015
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper);
|
|
864
1016
|
break;
|
|
865
1017
|
case "StopFailure":
|
|
866
|
-
await
|
|
1018
|
+
await handleStopOrFailure(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper, traceShipper, {
|
|
1019
|
+
error: payload.error,
|
|
1020
|
+
error_details: payload.error_details
|
|
1021
|
+
});
|
|
867
1022
|
break;
|
|
868
1023
|
case "SubagentStart":
|
|
869
1024
|
handleSubagentStart(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
@@ -874,6 +1029,9 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
874
1029
|
case "PermissionDenied":
|
|
875
1030
|
handlePermissionDenied(payload, getCurrentEventId(payload.session_id), traceShipper);
|
|
876
1031
|
break;
|
|
1032
|
+
case "InstructionsLoaded":
|
|
1033
|
+
handleInstructionsLoaded(payload);
|
|
1034
|
+
break;
|
|
877
1035
|
case "PostCompact":
|
|
878
1036
|
await handlePostCompact(payload, getCurrentEventId(payload.session_id), config, baseProperties, eventShipper);
|
|
879
1037
|
break;
|
|
@@ -882,6 +1040,8 @@ async function mapHookToRaindrop(payload, config, eventShipper, traceShipper) {
|
|
|
882
1040
|
deleteState(turnEventKey(payload.session_id));
|
|
883
1041
|
deleteState(rootSpanKey(payload.session_id));
|
|
884
1042
|
deleteState(`model_${payload.session_id}`);
|
|
1043
|
+
deleteState(appendSystemPromptKey(payload.session_id));
|
|
1044
|
+
cleanupInstructions(payload.session_id);
|
|
885
1045
|
break;
|
|
886
1046
|
default:
|
|
887
1047
|
if (config.debug) {
|
|
@@ -911,7 +1071,7 @@ async function handleUserPromptSubmit(payload, convoId, config, properties, even
|
|
|
911
1071
|
isPending: true,
|
|
912
1072
|
userId: config.userId,
|
|
913
1073
|
convoId,
|
|
914
|
-
eventName:
|
|
1074
|
+
eventName: config.eventName,
|
|
915
1075
|
input: payload.prompt,
|
|
916
1076
|
model,
|
|
917
1077
|
properties
|
|
@@ -1031,7 +1191,7 @@ async function handlePostCompact(payload, eventId, config, properties, eventShip
|
|
|
1031
1191
|
isPending: true,
|
|
1032
1192
|
userId: config.userId,
|
|
1033
1193
|
convoId: payload.session_id,
|
|
1034
|
-
eventName:
|
|
1194
|
+
eventName: config.eventName,
|
|
1035
1195
|
properties: {
|
|
1036
1196
|
...properties,
|
|
1037
1197
|
compaction_trigger: payload.trigger,
|
|
@@ -1039,27 +1199,251 @@ async function handlePostCompact(payload, eventId, config, properties, eventShip
|
|
|
1039
1199
|
}
|
|
1040
1200
|
});
|
|
1041
1201
|
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1202
|
+
function handleInstructionsLoaded(payload) {
|
|
1203
|
+
var _a;
|
|
1204
|
+
if (!payload.file_path || !payload.session_id) return;
|
|
1205
|
+
try {
|
|
1206
|
+
if (existsSync3(payload.file_path)) {
|
|
1207
|
+
const content = readFileSync3(payload.file_path, "utf-8");
|
|
1208
|
+
const MAX_INSTRUCTIONS_LENGTH = 8192;
|
|
1209
|
+
const truncated = content.length > MAX_INSTRUCTIONS_LENGTH ? content.slice(0, MAX_INSTRUCTIONS_LENGTH) + "\n...[truncated]" : content;
|
|
1210
|
+
const fileKey = safeKey(payload.file_path);
|
|
1211
|
+
const header = `# ${(_a = payload.memory_type) != null ? _a : "instructions"}: ${payload.file_path}
|
|
1212
|
+
`;
|
|
1213
|
+
writeState(
|
|
1214
|
+
`instr_${payload.session_id}_${fileKey}`,
|
|
1215
|
+
header + truncated
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
} catch (e) {
|
|
1219
|
+
}
|
|
1048
1220
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1221
|
+
function gatherInstructions(sessionId) {
|
|
1222
|
+
try {
|
|
1223
|
+
if (!existsSync3(STATE_DIR)) return void 0;
|
|
1224
|
+
const prefix = safeKey(`instr_${sessionId}_`);
|
|
1225
|
+
const files = readdirSync(STATE_DIR).filter((f) => f.startsWith(prefix));
|
|
1226
|
+
if (files.length === 0) return void 0;
|
|
1227
|
+
const parts = [];
|
|
1228
|
+
for (const file of files.sort()) {
|
|
1229
|
+
try {
|
|
1230
|
+
parts.push(readFileSync3(join2(STATE_DIR, file), "utf-8"));
|
|
1231
|
+
} catch (e) {
|
|
1232
|
+
continue;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
return parts.length > 0 ? parts.join("\n\n---\n\n") : void 0;
|
|
1236
|
+
} catch (e) {
|
|
1237
|
+
return void 0;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
function cleanupInstructions(sessionId) {
|
|
1241
|
+
try {
|
|
1242
|
+
if (!existsSync3(STATE_DIR)) return;
|
|
1243
|
+
const prefix = safeKey(`instr_${sessionId}_`);
|
|
1244
|
+
for (const file of readdirSync(STATE_DIR).filter((f) => f.startsWith(prefix))) {
|
|
1245
|
+
try {
|
|
1246
|
+
unlinkSync(join2(STATE_DIR, file));
|
|
1247
|
+
} catch (e) {
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
} catch (e) {
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
var APPEND_FLAG = "--append-system-prompt";
|
|
1254
|
+
var APPEND_FILE_FLAG = "--append-system-prompt-file";
|
|
1255
|
+
var MAX_ANCESTOR_DEPTH = 15;
|
|
1256
|
+
var PS_TIMEOUT_MS = 3e3;
|
|
1257
|
+
function appendSystemPromptKey(sessionId) {
|
|
1258
|
+
return `append_sysprompt_${sessionId}`;
|
|
1259
|
+
}
|
|
1260
|
+
function tryCaptureAppendSystemPrompt(sessionId) {
|
|
1261
|
+
try {
|
|
1262
|
+
const content = readAncestorAppendSystemPrompt();
|
|
1263
|
+
if (content) {
|
|
1264
|
+
writeState(appendSystemPromptKey(sessionId), content);
|
|
1265
|
+
}
|
|
1266
|
+
} catch (e) {
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
function readAncestorAppendSystemPrompt() {
|
|
1270
|
+
let pid;
|
|
1271
|
+
try {
|
|
1272
|
+
pid = process.ppid;
|
|
1273
|
+
} catch (e) {
|
|
1274
|
+
return void 0;
|
|
1275
|
+
}
|
|
1276
|
+
if (!pid || pid <= 1) return void 0;
|
|
1277
|
+
for (let depth = 0; depth < MAX_ANCESTOR_DEPTH && pid != null && pid > 1; depth++) {
|
|
1278
|
+
try {
|
|
1279
|
+
const args = getProcessArgs(pid);
|
|
1280
|
+
if (args && args.length > 0) {
|
|
1281
|
+
const content = extractAppendSystemPrompt(args);
|
|
1282
|
+
if (content) return content;
|
|
1283
|
+
}
|
|
1284
|
+
} catch (e) {
|
|
1285
|
+
}
|
|
1286
|
+
try {
|
|
1287
|
+
pid = getParentPid(pid);
|
|
1288
|
+
} catch (e) {
|
|
1289
|
+
break;
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
return void 0;
|
|
1293
|
+
}
|
|
1294
|
+
function getProcessArgs(pid) {
|
|
1295
|
+
if (process.platform === "linux") {
|
|
1296
|
+
try {
|
|
1297
|
+
const raw = readFileSync3(`/proc/${pid}/cmdline`, "utf-8");
|
|
1298
|
+
const args = raw.split("\0").filter(Boolean);
|
|
1299
|
+
return args.length > 0 ? args : void 0;
|
|
1300
|
+
} catch (e) {
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
try {
|
|
1304
|
+
const output = execSync(`ps -ww -o args= -p ${pid}`, {
|
|
1305
|
+
encoding: "utf-8",
|
|
1306
|
+
timeout: PS_TIMEOUT_MS,
|
|
1307
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1308
|
+
});
|
|
1309
|
+
const trimmed = output.trim();
|
|
1310
|
+
if (!trimmed) return void 0;
|
|
1311
|
+
return trimmed.split(/\s+/);
|
|
1312
|
+
} catch (e) {
|
|
1313
|
+
return void 0;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
function getParentPid(pid) {
|
|
1317
|
+
try {
|
|
1318
|
+
const output = execSync(`ps -o ppid= -p ${pid}`, {
|
|
1319
|
+
encoding: "utf-8",
|
|
1320
|
+
timeout: PS_TIMEOUT_MS,
|
|
1321
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1322
|
+
});
|
|
1323
|
+
const ppid = parseInt(output.trim(), 10);
|
|
1324
|
+
return Number.isFinite(ppid) && ppid > 0 ? ppid : void 0;
|
|
1325
|
+
} catch (e) {
|
|
1326
|
+
return void 0;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
function extractAppendSystemPrompt(args) {
|
|
1330
|
+
const parts = [];
|
|
1331
|
+
for (let i = 0; i < args.length; i++) {
|
|
1332
|
+
const arg = args[i];
|
|
1333
|
+
try {
|
|
1334
|
+
if (arg === APPEND_FILE_FLAG && i + 1 < args.length) {
|
|
1335
|
+
const filePath = args[i + 1];
|
|
1336
|
+
i++;
|
|
1337
|
+
try {
|
|
1338
|
+
if (existsSync3(filePath)) {
|
|
1339
|
+
parts.push(readFileSync3(filePath, "utf-8"));
|
|
1340
|
+
}
|
|
1341
|
+
} catch (e) {
|
|
1342
|
+
}
|
|
1343
|
+
continue;
|
|
1344
|
+
}
|
|
1345
|
+
if (arg.startsWith(APPEND_FILE_FLAG + "=")) {
|
|
1346
|
+
const filePath = arg.slice(APPEND_FILE_FLAG.length + 1);
|
|
1347
|
+
try {
|
|
1348
|
+
if (filePath && existsSync3(filePath)) {
|
|
1349
|
+
parts.push(readFileSync3(filePath, "utf-8"));
|
|
1350
|
+
}
|
|
1351
|
+
} catch (e) {
|
|
1352
|
+
}
|
|
1353
|
+
continue;
|
|
1354
|
+
}
|
|
1355
|
+
if (arg === APPEND_FLAG && i + 1 < args.length) {
|
|
1356
|
+
const valueParts = [];
|
|
1357
|
+
for (let j = i + 1; j < args.length; j++) {
|
|
1358
|
+
if (args[j].startsWith("--")) break;
|
|
1359
|
+
valueParts.push(args[j]);
|
|
1360
|
+
i = j;
|
|
1361
|
+
}
|
|
1362
|
+
if (valueParts.length > 0) {
|
|
1363
|
+
parts.push(valueParts.join(" "));
|
|
1364
|
+
}
|
|
1365
|
+
continue;
|
|
1366
|
+
}
|
|
1367
|
+
if (arg.startsWith(APPEND_FLAG + "=") && !arg.startsWith(APPEND_FILE_FLAG)) {
|
|
1368
|
+
const value = arg.slice(APPEND_FLAG.length + 1);
|
|
1369
|
+
if (value) {
|
|
1370
|
+
parts.push(value);
|
|
1371
|
+
}
|
|
1372
|
+
continue;
|
|
1373
|
+
}
|
|
1374
|
+
} catch (e) {
|
|
1375
|
+
continue;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
return parts.length > 0 ? parts.join("\n") : void 0;
|
|
1379
|
+
}
|
|
1380
|
+
function readAppendSystemPrompt(sessionId) {
|
|
1381
|
+
try {
|
|
1382
|
+
return readState(appendSystemPromptKey(sessionId)) || void 0;
|
|
1383
|
+
} catch (e) {
|
|
1384
|
+
return void 0;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
1388
|
+
var _a, _b;
|
|
1389
|
+
if (!payload.transcript_path) {
|
|
1390
|
+
return { summary: void 0, props: {} };
|
|
1391
|
+
}
|
|
1392
|
+
try {
|
|
1393
|
+
const summary = parseTranscript(payload.transcript_path);
|
|
1394
|
+
if (!summary) return { summary: void 0, props: {} };
|
|
1395
|
+
const props = transcriptToProperties(summary);
|
|
1396
|
+
const spanInputTokens = (_a = summary.lastTurnInputTokens) != null ? _a : summary.totalInputTokens;
|
|
1397
|
+
const spanOutputTokens = (_b = summary.lastTurnOutputTokens) != null ? _b : summary.totalOutputTokens;
|
|
1398
|
+
if (summary.model && (spanInputTokens > 0 || spanOutputTokens > 0)) {
|
|
1399
|
+
const parent = getParentContext(payload);
|
|
1400
|
+
const now = nowUnixNanoString();
|
|
1401
|
+
traceShipper.createSpan({
|
|
1402
|
+
name: summary.model,
|
|
1403
|
+
eventId,
|
|
1404
|
+
parent,
|
|
1405
|
+
startTimeUnixNano: now,
|
|
1406
|
+
endTimeUnixNano: now,
|
|
1407
|
+
attributes: [
|
|
1408
|
+
attrString("ai.operationId", "generateText"),
|
|
1409
|
+
attrString("gen_ai.response.model", summary.model),
|
|
1410
|
+
attrString("gen_ai.system", "anthropic"),
|
|
1411
|
+
attrInt("gen_ai.usage.prompt_tokens", spanInputTokens),
|
|
1412
|
+
attrInt("gen_ai.usage.completion_tokens", spanOutputTokens),
|
|
1413
|
+
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : []
|
|
1414
|
+
]
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
return { summary, props };
|
|
1418
|
+
} catch (e) {
|
|
1419
|
+
return { summary: void 0, props: {} };
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
async function handleStopOrFailure(payload, eventId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
1423
|
+
const { summary, props: transcriptProps } = enrichFromTranscript(payload, eventId, traceShipper);
|
|
1424
|
+
const instructions = gatherInstructions(payload.session_id);
|
|
1425
|
+
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
1426
|
+
await eventShipper.patch(eventId, {
|
|
1427
|
+
isPending: false,
|
|
1051
1428
|
userId: config.userId,
|
|
1429
|
+
convoId: payload.session_id,
|
|
1430
|
+
eventName: config.eventName,
|
|
1052
1431
|
output: payload.last_assistant_message,
|
|
1432
|
+
...(summary == null ? void 0 : summary.model) ? { model: summary.model } : {},
|
|
1053
1433
|
properties: {
|
|
1054
1434
|
...properties,
|
|
1055
|
-
|
|
1056
|
-
|
|
1435
|
+
...transcriptProps,
|
|
1436
|
+
...instructions ? { system_instructions: truncate(instructions) } : {},
|
|
1437
|
+
...appendSysPrompt ? { append_system_prompt: truncate(appendSysPrompt) } : {},
|
|
1438
|
+
...extraProperties
|
|
1057
1439
|
}
|
|
1058
1440
|
});
|
|
1059
1441
|
}
|
|
1060
1442
|
async function handleSessionEnd(payload, eventId, config, properties, eventShipper) {
|
|
1061
|
-
await eventShipper.
|
|
1443
|
+
await eventShipper.patch(eventId, {
|
|
1444
|
+
isPending: false,
|
|
1062
1445
|
userId: config.userId,
|
|
1446
|
+
eventName: config.eventName,
|
|
1063
1447
|
properties: {
|
|
1064
1448
|
...properties,
|
|
1065
1449
|
session_end_reason: payload.reason
|
|
@@ -1068,7 +1452,7 @@ async function handleSessionEnd(payload, eventId, config, properties, eventShipp
|
|
|
1068
1452
|
}
|
|
1069
1453
|
|
|
1070
1454
|
// src/local-debugger.ts
|
|
1071
|
-
import { existsSync as
|
|
1455
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
1072
1456
|
import { tmpdir as tmpdir2 } from "os";
|
|
1073
1457
|
import { join as join3 } from "path";
|
|
1074
1458
|
var DEFAULT_PORT = 5899;
|
|
@@ -1079,8 +1463,8 @@ var CACHE_FILE = join3(CACHE_DIR, "debugger_cache");
|
|
|
1079
1463
|
var CACHE_TTL_MS = 5e3;
|
|
1080
1464
|
function readCache() {
|
|
1081
1465
|
try {
|
|
1082
|
-
if (!
|
|
1083
|
-
const data = JSON.parse(
|
|
1466
|
+
if (!existsSync4(CACHE_FILE)) return void 0;
|
|
1467
|
+
const data = JSON.parse(readFileSync4(CACHE_FILE, "utf-8"));
|
|
1084
1468
|
if (Date.now() - data.ts > CACHE_TTL_MS) return void 0;
|
|
1085
1469
|
return data;
|
|
1086
1470
|
} catch (e) {
|
|
@@ -1153,9 +1537,12 @@ export {
|
|
|
1153
1537
|
PACKAGE_VERSION,
|
|
1154
1538
|
TraceShipper2 as TraceShipper,
|
|
1155
1539
|
detectLocalDebugger,
|
|
1540
|
+
extractAppendSystemPrompt,
|
|
1156
1541
|
getConfigPath,
|
|
1157
1542
|
loadConfig,
|
|
1158
1543
|
mapHookToRaindrop,
|
|
1159
1544
|
mirrorEventToLocalDebugger,
|
|
1545
|
+
parseTranscript,
|
|
1546
|
+
transcriptToProperties,
|
|
1160
1547
|
updateConfig
|
|
1161
1548
|
};
|
package/package.json
CHANGED