@claudecam/hook 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/handlers/compact.d.ts +3 -0
  2. package/dist/handlers/compact.d.ts.map +1 -0
  3. package/dist/handlers/compact.js +28 -0
  4. package/dist/handlers/compact.js.map +1 -0
  5. package/dist/handlers/notification.d.ts +2 -0
  6. package/dist/handlers/notification.d.ts.map +1 -0
  7. package/dist/handlers/notification.js +20 -0
  8. package/dist/handlers/notification.js.map +1 -0
  9. package/dist/handlers/post-tool-use-failure.d.ts +2 -0
  10. package/dist/handlers/post-tool-use-failure.d.ts.map +1 -0
  11. package/dist/handlers/post-tool-use-failure.js +62 -0
  12. package/dist/handlers/post-tool-use-failure.js.map +1 -0
  13. package/dist/handlers/post-tool-use.d.ts +2 -0
  14. package/dist/handlers/post-tool-use.d.ts.map +1 -0
  15. package/dist/handlers/post-tool-use.js +57 -0
  16. package/dist/handlers/post-tool-use.js.map +1 -0
  17. package/dist/handlers/pre-tool-use.d.ts +2 -0
  18. package/dist/handlers/pre-tool-use.d.ts.map +1 -0
  19. package/dist/handlers/pre-tool-use.js +36 -0
  20. package/dist/handlers/pre-tool-use.js.map +1 -0
  21. package/dist/handlers/session-end.d.ts +2 -0
  22. package/dist/handlers/session-end.d.ts.map +1 -0
  23. package/dist/handlers/session-end.js +15 -0
  24. package/dist/handlers/session-end.js.map +1 -0
  25. package/dist/handlers/session-start.d.ts +2 -0
  26. package/dist/handlers/session-start.d.ts.map +1 -0
  27. package/dist/handlers/session-start.js +17 -0
  28. package/dist/handlers/session-start.js.map +1 -0
  29. package/dist/handlers/stop.d.ts +2 -0
  30. package/dist/handlers/stop.d.ts.map +1 -0
  31. package/dist/handlers/stop.js +17 -0
  32. package/dist/handlers/stop.js.map +1 -0
  33. package/dist/handlers/subagent-start.d.ts +2 -0
  34. package/dist/handlers/subagent-start.d.ts.map +1 -0
  35. package/dist/handlers/subagent-start.js +18 -0
  36. package/dist/handlers/subagent-start.js.map +1 -0
  37. package/dist/handlers/subagent-stop.d.ts +2 -0
  38. package/dist/handlers/subagent-stop.d.ts.map +1 -0
  39. package/dist/handlers/subagent-stop.js +16 -0
  40. package/dist/handlers/subagent-stop.js.map +1 -0
  41. package/dist/handlers/user-prompt-submit.d.ts +2 -0
  42. package/dist/handlers/user-prompt-submit.d.ts.map +1 -0
  43. package/dist/handlers/user-prompt-submit.js +19 -0
  44. package/dist/handlers/user-prompt-submit.js.map +1 -0
  45. package/dist/index.d.ts +17 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +89 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/transport.d.ts +15 -0
  50. package/dist/transport.d.ts.map +1 -0
  51. package/dist/transport.js +187 -0
  52. package/dist/transport.js.map +1 -0
  53. package/package.json +52 -0
@@ -0,0 +1,3 @@
1
+ export declare function handlePreCompact(stdinData: Record<string, unknown>): void;
2
+ export declare function handlePostCompact(stdinData: Record<string, unknown>): void;
3
+ //# sourceMappingURL=compact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact.d.ts","sourceRoot":"","sources":["../../src/handlers/compact.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAazE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAa1E"}
@@ -0,0 +1,28 @@
1
+ import { sendEvent } from "../transport.js";
2
+ export function handlePreCompact(stdinData) {
3
+ const sessionId = stdinData["session_id"] ?? "";
4
+ const trigger = stdinData["trigger"] ?? "unknown";
5
+ sendEvent({
6
+ hook: "PreCompact",
7
+ timestamp: new Date().toISOString(),
8
+ session_id: sessionId,
9
+ agent_id: sessionId || "main",
10
+ data: {
11
+ trigger,
12
+ },
13
+ });
14
+ }
15
+ export function handlePostCompact(stdinData) {
16
+ const sessionId = stdinData["session_id"] ?? "";
17
+ sendEvent({
18
+ hook: "PostCompact",
19
+ timestamp: new Date().toISOString(),
20
+ session_id: sessionId,
21
+ agent_id: sessionId || "main",
22
+ data: {
23
+ // PostCompact data from Claude Code stdin - extract what's available
24
+ summary: stdinData["summary"] ?? null,
25
+ },
26
+ });
27
+ }
28
+ //# sourceMappingURL=compact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact.js","sourceRoot":"","sources":["../../src/handlers/compact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,gBAAgB,CAAC,SAAkC;IACjE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAC5D,MAAM,OAAO,GAAI,SAAS,CAAC,SAAS,CAAY,IAAI,SAAS,CAAC;IAE9D,SAAS,CAAC;QACR,IAAI,EAAE,YAAY;QAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,OAAO;SACR;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,SAAkC;IAClE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAE5D,SAAS,CAAC;QACR,IAAI,EAAE,aAAa;QACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,qEAAqE;YACrE,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,IAAI,IAAI;SACtC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handleNotification(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=notification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../src/handlers/notification.ts"],"names":[],"mappings":"AAGA,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAmB3E"}
@@ -0,0 +1,20 @@
1
+ import { MAX_OUTPUT_LENGTH } from "@claudecam/shared";
2
+ import { sendEvent } from "../transport.js";
3
+ export function handleNotification(stdinData) {
4
+ const sessionId = stdinData["session_id"] ?? "";
5
+ const rawMessage = stdinData["message"] ?? "";
6
+ const message = rawMessage.length > MAX_OUTPUT_LENGTH
7
+ ? rawMessage.slice(0, MAX_OUTPUT_LENGTH)
8
+ : rawMessage;
9
+ sendEvent({
10
+ hook: "Notification",
11
+ timestamp: new Date().toISOString(),
12
+ session_id: sessionId,
13
+ agent_id: sessionId || "main",
14
+ data: {
15
+ message,
16
+ level: "info",
17
+ },
18
+ });
19
+ }
20
+ //# sourceMappingURL=notification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification.js","sourceRoot":"","sources":["../../src/handlers/notification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,kBAAkB,CAAC,SAAkC;IACnE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAC5D,MAAM,UAAU,GAAI,SAAS,CAAC,SAAS,CAAY,IAAI,EAAE,CAAC;IAE1D,MAAM,OAAO,GACX,UAAU,CAAC,MAAM,GAAG,iBAAiB;QACnC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC;QACxC,CAAC,CAAC,UAAU,CAAC;IAEjB,SAAS,CAAC;QACR,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,OAAO;YACP,KAAK,EAAE,MAAM;SACd;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handlePostToolUseFailure(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=post-tool-use-failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-tool-use-failure.d.ts","sourceRoot":"","sources":["../../src/handlers/post-tool-use-failure.ts"],"names":[],"mappings":"AAGA,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,IAAI,CA+DN"}
@@ -0,0 +1,62 @@
1
+ import { MAX_INPUT_LENGTH, MAX_OUTPUT_LENGTH } from "@claudecam/shared";
2
+ import { sendEvent } from "../transport.js";
3
+ export function handlePostToolUseFailure(stdinData) {
4
+ const toolName = stdinData["tool_name"] ?? "unknown";
5
+ const sessionId = stdinData["session_id"] ?? "";
6
+ // Extract tool_input
7
+ const toolInput = stdinData["tool_input"];
8
+ let inputStr;
9
+ if (toolInput) {
10
+ const raw = JSON.stringify(toolInput);
11
+ inputStr =
12
+ raw.length > MAX_INPUT_LENGTH ? raw.slice(0, MAX_INPUT_LENGTH) : raw;
13
+ }
14
+ // Extract file_path from tool_input
15
+ let filePath;
16
+ if (toolInput) {
17
+ if (typeof toolInput["file_path"] === "string") {
18
+ filePath = toolInput["file_path"];
19
+ }
20
+ else if (typeof toolInput["path"] === "string") {
21
+ filePath = toolInput["path"];
22
+ }
23
+ }
24
+ // Extract error message - could come from various fields
25
+ let error;
26
+ const errorSources = [
27
+ stdinData["error"],
28
+ stdinData["error_message"],
29
+ stdinData["tool_response"],
30
+ ];
31
+ for (const src of errorSources) {
32
+ if (typeof src === "string") {
33
+ error =
34
+ src.length > MAX_OUTPUT_LENGTH ? src.slice(0, MAX_OUTPUT_LENGTH) : src;
35
+ break;
36
+ }
37
+ if (typeof src === "object" && src !== null) {
38
+ const obj = src;
39
+ const msg = obj["error"] ?? obj["error_message"] ?? obj["message"];
40
+ if (typeof msg === "string") {
41
+ error =
42
+ msg.length > MAX_OUTPUT_LENGTH
43
+ ? msg.slice(0, MAX_OUTPUT_LENGTH)
44
+ : msg;
45
+ break;
46
+ }
47
+ }
48
+ }
49
+ sendEvent({
50
+ hook: "PostToolUseFailure",
51
+ timestamp: new Date().toISOString(),
52
+ session_id: sessionId,
53
+ agent_id: sessionId || "main",
54
+ data: {
55
+ tool_name: toolName,
56
+ tool_input: inputStr,
57
+ file_path: filePath,
58
+ error: error ?? "Unknown tool failure",
59
+ },
60
+ });
61
+ }
62
+ //# sourceMappingURL=post-tool-use-failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-tool-use-failure.js","sourceRoot":"","sources":["../../src/handlers/post-tool-use-failure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,wBAAwB,CACtC,SAAkC;IAElC,MAAM,QAAQ,GAAI,SAAS,CAAC,WAAW,CAAY,IAAI,SAAS,CAAC;IACjE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAE5D,qBAAqB;IACrB,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAE3B,CAAC;IACd,IAAI,QAA4B,CAAC;IACjC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACtC,QAAQ;YACN,GAAG,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACzE,CAAC;IAED,oCAAoC;IACpC,IAAI,QAA4B,CAAC;IACjC,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,OAAO,SAAS,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC/C,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjD,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,IAAI,KAAyB,CAAC;IAC9B,MAAM,YAAY,GAAG;QACnB,SAAS,CAAC,OAAO,CAAC;QAClB,SAAS,CAAC,eAAe,CAAC;QAC1B,SAAS,CAAC,eAAe,CAAC;KAC3B,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,KAAK;gBACH,GAAG,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACzE,MAAM;QACR,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,GAAG,GAAG,GAA8B,CAAC;YAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;YACnE,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC5B,KAAK;oBACH,GAAG,CAAC,MAAM,GAAG,iBAAiB;wBAC5B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC;wBACjC,CAAC,CAAC,GAAG,CAAC;gBACV,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,SAAS,CAAC;QACR,IAAI,EAAE,oBAAoB;QAC1B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,QAAQ;YACnB,KAAK,EAAE,KAAK,IAAI,sBAAsB;SACvC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handlePostToolUse(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=post-tool-use.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-tool-use.d.ts","sourceRoot":"","sources":["../../src/handlers/post-tool-use.ts"],"names":[],"mappings":"AAGA,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA6D1E"}
@@ -0,0 +1,57 @@
1
+ import { MAX_INPUT_LENGTH, MAX_OUTPUT_LENGTH } from "@claudecam/shared";
2
+ import { sendEvent } from "../transport.js";
3
+ export function handlePostToolUse(stdinData) {
4
+ const toolName = stdinData["tool_name"] ?? "unknown";
5
+ const sessionId = stdinData["session_id"] ?? "";
6
+ // tool_input comes as an object from Claude Code stdin
7
+ const toolInput = stdinData["tool_input"];
8
+ let inputStr;
9
+ if (toolInput) {
10
+ const raw = JSON.stringify(toolInput);
11
+ inputStr =
12
+ raw.length > MAX_INPUT_LENGTH ? raw.slice(0, MAX_INPUT_LENGTH) : raw;
13
+ }
14
+ // tool_response comes as an object from Claude Code stdin
15
+ const toolResponse = stdinData["tool_response"];
16
+ let outputStr;
17
+ if (toolResponse) {
18
+ const raw = JSON.stringify(toolResponse);
19
+ outputStr =
20
+ raw.length > MAX_OUTPUT_LENGTH ? raw.slice(0, MAX_OUTPUT_LENGTH) : raw;
21
+ }
22
+ // Extract file_path from tool_input
23
+ let filePath;
24
+ if (toolInput) {
25
+ if (typeof toolInput["file_path"] === "string") {
26
+ filePath = toolInput["file_path"];
27
+ }
28
+ else if (typeof toolInput["path"] === "string") {
29
+ filePath = toolInput["path"];
30
+ }
31
+ }
32
+ // Check for error in tool_response
33
+ let error;
34
+ if (toolResponse) {
35
+ const errMsg = toolResponse["error"] ?? toolResponse["error_message"];
36
+ if (typeof errMsg === "string") {
37
+ error =
38
+ errMsg.length > MAX_OUTPUT_LENGTH
39
+ ? errMsg.slice(0, MAX_OUTPUT_LENGTH)
40
+ : errMsg;
41
+ }
42
+ }
43
+ sendEvent({
44
+ hook: "PostToolUse",
45
+ timestamp: new Date().toISOString(),
46
+ session_id: sessionId,
47
+ agent_id: sessionId || "main",
48
+ data: {
49
+ tool_name: toolName,
50
+ tool_input: inputStr,
51
+ tool_output: outputStr,
52
+ file_path: filePath,
53
+ error,
54
+ },
55
+ });
56
+ }
57
+ //# sourceMappingURL=post-tool-use.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-tool-use.js","sourceRoot":"","sources":["../../src/handlers/post-tool-use.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,iBAAiB,CAAC,SAAkC;IAClE,MAAM,QAAQ,GAAI,SAAS,CAAC,WAAW,CAAY,IAAI,SAAS,CAAC;IACjE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAE5D,uDAAuD;IACvD,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAE3B,CAAC;IACd,IAAI,QAA4B,CAAC;IACjC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACtC,QAAQ;YACN,GAAG,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACzE,CAAC;IAED,0DAA0D;IAC1D,MAAM,YAAY,GAAG,SAAS,CAAC,eAAe,CAEjC,CAAC;IACd,IAAI,SAA6B,CAAC;IAClC,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACzC,SAAS;YACP,GAAG,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3E,CAAC;IAED,oCAAoC;IACpC,IAAI,QAA4B,CAAC;IACjC,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,OAAO,SAAS,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC/C,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjD,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,IAAI,KAAyB,CAAC;IAC9B,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,eAAe,CAAC,CAAC;QACtE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,KAAK;gBACH,MAAM,CAAC,MAAM,GAAG,iBAAiB;oBAC/B,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC;oBACpC,CAAC,CAAC,MAAM,CAAC;QACf,CAAC;IACH,CAAC;IAED,SAAS,CAAC;QACR,IAAI,EAAE,aAAa;QACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,QAAQ;YACpB,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,QAAQ;YACnB,KAAK;SACN;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handlePreToolUse(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=pre-tool-use.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-tool-use.d.ts","sourceRoot":"","sources":["../../src/handlers/pre-tool-use.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAoCzE"}
@@ -0,0 +1,36 @@
1
+ import { MAX_INPUT_LENGTH } from "@claudecam/shared";
2
+ import { sendEvent } from "../transport.js";
3
+ export function handlePreToolUse(stdinData) {
4
+ const toolName = stdinData["tool_name"] ?? "unknown";
5
+ const sessionId = stdinData["session_id"] ?? "";
6
+ // tool_input comes as an object from Claude Code stdin
7
+ const toolInput = stdinData["tool_input"];
8
+ let inputStr;
9
+ if (toolInput) {
10
+ const raw = JSON.stringify(toolInput);
11
+ inputStr =
12
+ raw.length > MAX_INPUT_LENGTH ? raw.slice(0, MAX_INPUT_LENGTH) : raw;
13
+ }
14
+ // Extract file_path from tool_input
15
+ let filePath;
16
+ if (toolInput) {
17
+ if (typeof toolInput["file_path"] === "string") {
18
+ filePath = toolInput["file_path"];
19
+ }
20
+ else if (typeof toolInput["path"] === "string") {
21
+ filePath = toolInput["path"];
22
+ }
23
+ }
24
+ sendEvent({
25
+ hook: "PreToolUse",
26
+ timestamp: new Date().toISOString(),
27
+ session_id: sessionId,
28
+ agent_id: sessionId || "main",
29
+ data: {
30
+ tool_name: toolName,
31
+ tool_input: inputStr,
32
+ file_path: filePath,
33
+ },
34
+ });
35
+ }
36
+ //# sourceMappingURL=pre-tool-use.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-tool-use.js","sourceRoot":"","sources":["../../src/handlers/pre-tool-use.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,gBAAgB,CAAC,SAAkC;IACjE,MAAM,QAAQ,GAAI,SAAS,CAAC,WAAW,CAAY,IAAI,SAAS,CAAC;IACjE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAE5D,uDAAuD;IACvD,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAE3B,CAAC;IACd,IAAI,QAA4B,CAAC;IACjC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACtC,QAAQ;YACN,GAAG,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACzE,CAAC;IAED,oCAAoC;IACpC,IAAI,QAA4B,CAAC;IACjC,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,OAAO,SAAS,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC/C,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjD,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,SAAS,CAAC;QACR,IAAI,EAAE,YAAY;QAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,QAAQ;SACpB;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handleSessionEnd(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=session-end.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-end.d.ts","sourceRoot":"","sources":["../../src/handlers/session-end.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAazE"}
@@ -0,0 +1,15 @@
1
+ import { sendEvent } from "../transport.js";
2
+ export function handleSessionEnd(stdinData) {
3
+ const sessionId = stdinData["session_id"] ?? "";
4
+ const workingDirectory = stdinData["cwd"] || process.cwd();
5
+ sendEvent({
6
+ hook: "SessionEnd",
7
+ timestamp: new Date().toISOString(),
8
+ session_id: sessionId,
9
+ agent_id: sessionId || "main",
10
+ data: {
11
+ working_directory: workingDirectory,
12
+ },
13
+ });
14
+ }
15
+ //# sourceMappingURL=session-end.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-end.js","sourceRoot":"","sources":["../../src/handlers/session-end.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,gBAAgB,CAAC,SAAkC;IACjE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAC5D,MAAM,gBAAgB,GAAI,SAAS,CAAC,KAAK,CAAY,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEvE,SAAS,CAAC;QACR,IAAI,EAAE,YAAY;QAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,iBAAiB,EAAE,gBAAgB;SACpC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handleSessionStart(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=session-start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/handlers/session-start.ts"],"names":[],"mappings":"AAEA,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAe3E"}
@@ -0,0 +1,17 @@
1
+ import { sendEvent } from "../transport.js";
2
+ export function handleSessionStart(stdinData) {
3
+ const sessionId = stdinData["session_id"] ?? "";
4
+ const workingDirectory = stdinData["cwd"] || process.cwd();
5
+ const model = stdinData["model"] ?? "";
6
+ sendEvent({
7
+ hook: "SessionStart",
8
+ timestamp: new Date().toISOString(),
9
+ session_id: sessionId,
10
+ agent_id: sessionId || "main",
11
+ data: {
12
+ working_directory: workingDirectory,
13
+ model,
14
+ },
15
+ });
16
+ }
17
+ //# sourceMappingURL=session-start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../src/handlers/session-start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,kBAAkB,CAAC,SAAkC;IACnE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAC5D,MAAM,gBAAgB,GAAI,SAAS,CAAC,KAAK,CAAY,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACvE,MAAM,KAAK,GAAI,SAAS,CAAC,OAAO,CAAY,IAAI,EAAE,CAAC;IAEnD,SAAS,CAAC;QACR,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,iBAAiB,EAAE,gBAAgB;YACnC,KAAK;SACN;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handleStop(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/handlers/stop.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAenE"}
@@ -0,0 +1,17 @@
1
+ import { sendEvent } from "../transport.js";
2
+ export function handleStop(stdinData) {
3
+ const sessionId = stdinData["session_id"] ?? "";
4
+ const stopHookActive = stdinData["stop_hook_active"];
5
+ sendEvent({
6
+ hook: "Stop",
7
+ timestamp: new Date().toISOString(),
8
+ session_id: sessionId,
9
+ agent_id: sessionId || "main",
10
+ data: {
11
+ reason: stopHookActive ? "stop_hook" : "natural",
12
+ stop_type: "natural",
13
+ stop_hook_active: stopHookActive,
14
+ },
15
+ });
16
+ }
17
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/handlers/stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,UAAU,CAAC,SAAkC;IAC3D,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAC5D,MAAM,cAAc,GAAG,SAAS,CAAC,kBAAkB,CAAwB,CAAC;IAE5E,SAAS,CAAC;QACR,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;YAChD,SAAS,EAAE,SAAS;YACpB,gBAAgB,EAAE,cAAc;SACjC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handleSubagentStart(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=subagent-start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-start.d.ts","sourceRoot":"","sources":["../../src/handlers/subagent-start.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAgB5E"}
@@ -0,0 +1,18 @@
1
+ import { sendEvent } from "../transport.js";
2
+ export function handleSubagentStart(stdinData) {
3
+ const sessionId = stdinData["session_id"] ?? "";
4
+ const agentId = (stdinData["agent_id"] ?? sessionId) || "unknown";
5
+ const agentType = stdinData["agent_type"] ?? "general-purpose";
6
+ const workingDirectory = stdinData["cwd"] || process.cwd();
7
+ sendEvent({
8
+ hook: "SubagentStart",
9
+ timestamp: new Date().toISOString(),
10
+ session_id: sessionId,
11
+ agent_id: agentId,
12
+ data: {
13
+ agent_type: agentType,
14
+ working_directory: workingDirectory,
15
+ },
16
+ });
17
+ }
18
+ //# sourceMappingURL=subagent-start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-start.js","sourceRoot":"","sources":["../../src/handlers/subagent-start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,mBAAmB,CAAC,SAAkC;IACpE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAC5D,MAAM,OAAO,GAAG,CAAE,SAAS,CAAC,UAAU,CAAY,IAAI,SAAS,CAAC,IAAI,SAAS,CAAC;IAC9E,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,iBAAiB,CAAC;IAC3E,MAAM,gBAAgB,GAAI,SAAS,CAAC,KAAK,CAAY,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAEvE,SAAS,CAAC;QACR,IAAI,EAAE,eAAe;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE;YACJ,UAAU,EAAE,SAAS;YACrB,iBAAiB,EAAE,gBAAgB;SACpC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handleSubagentStop(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=subagent-stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-stop.d.ts","sourceRoot":"","sources":["../../src/handlers/subagent-stop.ts"],"names":[],"mappings":"AAEA,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAc3E"}
@@ -0,0 +1,16 @@
1
+ import { sendEvent } from "../transport.js";
2
+ export function handleSubagentStop(stdinData) {
3
+ const sessionId = stdinData["session_id"] ?? "";
4
+ const stopHookActive = stdinData["stop_hook_active"];
5
+ sendEvent({
6
+ hook: "SubagentStop",
7
+ timestamp: new Date().toISOString(),
8
+ session_id: sessionId,
9
+ agent_id: sessionId || "main",
10
+ data: {
11
+ reason: stopHookActive ? "stop_hook" : "shutdown_approved",
12
+ stop_hook_active: stopHookActive,
13
+ },
14
+ });
15
+ }
16
+ //# sourceMappingURL=subagent-stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subagent-stop.js","sourceRoot":"","sources":["../../src/handlers/subagent-stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,kBAAkB,CAAC,SAAkC;IACnE,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAC5D,MAAM,cAAc,GAAG,SAAS,CAAC,kBAAkB,CAAwB,CAAC;IAE5E,SAAS,CAAC;QACR,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB;YAC1D,gBAAgB,EAAE,cAAc;SACjC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function handleUserPromptSubmit(stdinData: Record<string, unknown>): void;
2
+ //# sourceMappingURL=user-prompt-submit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-prompt-submit.d.ts","sourceRoot":"","sources":["../../src/handlers/user-prompt-submit.ts"],"names":[],"mappings":"AAGA,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,IAAI,CAkBN"}
@@ -0,0 +1,19 @@
1
+ import { MAX_INPUT_LENGTH } from "@claudecam/shared";
2
+ import { sendEvent } from "../transport.js";
3
+ export function handleUserPromptSubmit(stdinData) {
4
+ const sessionId = stdinData["session_id"] ?? "";
5
+ const rawPrompt = stdinData["prompt"] ?? "";
6
+ const prompt = rawPrompt.length > MAX_INPUT_LENGTH
7
+ ? rawPrompt.slice(0, MAX_INPUT_LENGTH)
8
+ : rawPrompt;
9
+ sendEvent({
10
+ hook: "UserPromptSubmit",
11
+ timestamp: new Date().toISOString(),
12
+ session_id: sessionId,
13
+ agent_id: sessionId || "main",
14
+ data: {
15
+ prompt,
16
+ },
17
+ });
18
+ }
19
+ //# sourceMappingURL=user-prompt-submit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-prompt-submit.js","sourceRoot":"","sources":["../../src/handlers/user-prompt-submit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,sBAAsB,CACpC,SAAkC;IAElC,MAAM,SAAS,GAAI,SAAS,CAAC,YAAY,CAAY,IAAI,EAAE,CAAC;IAC5D,MAAM,SAAS,GAAI,SAAS,CAAC,QAAQ,CAAY,IAAI,EAAE,CAAC;IAExD,MAAM,MAAM,GACV,SAAS,CAAC,MAAM,GAAG,gBAAgB;QACjC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC;QACtC,CAAC,CAAC,SAAS,CAAC;IAEhB,SAAS,CAAC;QACR,IAAI,EAAE,kBAAkB;QACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,SAAS,IAAI,MAAM;QAC7B,IAAI,EAAE;YACJ,MAAM;SACP;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CAM Hook - Ultra-light binary called by Claude Code hooks.
4
+ *
5
+ * Claude Code passes hook data via STDIN as JSON:
6
+ * {
7
+ * "session_id": "abc123",
8
+ * "hook_event_name": "PostToolUse",
9
+ * "tool_name": "Edit",
10
+ * "tool_input": { "file_path": "/src/index.ts" },
11
+ * "tool_response": { ... }
12
+ * }
13
+ *
14
+ * We read stdin, parse JSON, and route to the appropriate handler.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;GAaG"}
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CAM Hook - Ultra-light binary called by Claude Code hooks.
4
+ *
5
+ * Claude Code passes hook data via STDIN as JSON:
6
+ * {
7
+ * "session_id": "abc123",
8
+ * "hook_event_name": "PostToolUse",
9
+ * "tool_name": "Edit",
10
+ * "tool_input": { "file_path": "/src/index.ts" },
11
+ * "tool_response": { ... }
12
+ * }
13
+ *
14
+ * We read stdin, parse JSON, and route to the appropriate handler.
15
+ */
16
+ import { handlePreToolUse } from "./handlers/pre-tool-use.js";
17
+ import { handlePostToolUse } from "./handlers/post-tool-use.js";
18
+ import { handlePostToolUseFailure } from "./handlers/post-tool-use-failure.js";
19
+ import { handleNotification } from "./handlers/notification.js";
20
+ import { handleStop } from "./handlers/stop.js";
21
+ import { handleSubagentStop } from "./handlers/subagent-stop.js";
22
+ import { handleSubagentStart } from "./handlers/subagent-start.js";
23
+ import { handlePreCompact, handlePostCompact } from "./handlers/compact.js";
24
+ import { handleSessionStart } from "./handlers/session-start.js";
25
+ import { handleSessionEnd } from "./handlers/session-end.js";
26
+ import { handleUserPromptSubmit } from "./handlers/user-prompt-submit.js";
27
+ const command = process.argv[2];
28
+ // Read all stdin, parse as JSON, then route to handler
29
+ const chunks = [];
30
+ process.stdin.on("data", (chunk) => chunks.push(chunk));
31
+ process.stdin.on("end", () => {
32
+ let stdinData = {};
33
+ try {
34
+ const raw = Buffer.concat(chunks).toString("utf8").trim();
35
+ if (raw) {
36
+ stdinData = JSON.parse(raw);
37
+ }
38
+ }
39
+ catch {
40
+ // Failed to parse stdin - continue with empty data
41
+ }
42
+ switch (command) {
43
+ case "pre-tool-use":
44
+ handlePreToolUse(stdinData);
45
+ break;
46
+ case "post-tool-use":
47
+ handlePostToolUse(stdinData);
48
+ break;
49
+ case "post-tool-use-failure":
50
+ handlePostToolUseFailure(stdinData);
51
+ break;
52
+ case "notification":
53
+ handleNotification(stdinData);
54
+ break;
55
+ case "stop":
56
+ handleStop(stdinData);
57
+ break;
58
+ case "subagent-stop":
59
+ handleSubagentStop(stdinData);
60
+ break;
61
+ case "subagent-start":
62
+ handleSubagentStart(stdinData);
63
+ break;
64
+ case "pre-compact":
65
+ handlePreCompact(stdinData);
66
+ break;
67
+ case "post-compact":
68
+ handlePostCompact(stdinData);
69
+ break;
70
+ case "session-start":
71
+ handleSessionStart(stdinData);
72
+ break;
73
+ case "session-end":
74
+ handleSessionEnd(stdinData);
75
+ break;
76
+ case "user-prompt-submit":
77
+ handleUserPromptSubmit(stdinData);
78
+ break;
79
+ default:
80
+ // Unknown command - fail silently, exit 0
81
+ break;
82
+ }
83
+ });
84
+ // If stdin closes immediately (no data), handle it
85
+ process.stdin.on("error", () => { });
86
+ // Timeout: if stdin doesn't close in 5s, exit gracefully.
87
+ // Increased from 3s to 5s to allow transport retries with fallback hosts.
88
+ setTimeout(() => process.exit(0), 5000);
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Sends an event payload to the CAM server via HTTP POST.
3
+ *
4
+ * Resilience strategy:
5
+ * 1. Try the primary host (resolved via WSL detection or env var)
6
+ * 2. On failure, try fallback hosts (localhost, 127.0.0.1) with exponential backoff
7
+ * 3. Max 3 attempts total across all hosts
8
+ * 4. Each attempt has a 2s timeout
9
+ * 5. Debug logging available via CAM_DEBUG=1
10
+ *
11
+ * Always fire-and-forget: never blocks the calling code.
12
+ * Fails silently if the server is not running.
13
+ */
14
+ export declare function sendEvent(payload: Record<string, unknown>): void;
15
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAqKA;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAiChE"}
@@ -0,0 +1,187 @@
1
+ import { request } from "node:http";
2
+ import { readFileSync } from "node:fs";
3
+ import { execSync } from "node:child_process";
4
+ import { DEFAULT_SERVER_PORT, DEFAULT_HOST } from "@claudecam/shared";
5
+ /**
6
+ * Debug logging via CAM_DEBUG=1 environment variable.
7
+ * Outputs to stderr so it never interferes with hook stdout (used by Claude Code).
8
+ */
9
+ const DEBUG = process.env["CAM_DEBUG"] === "1";
10
+ /** Timeout per individual HTTP request (ms). */
11
+ const REQUEST_TIMEOUT_MS = 2000;
12
+ /** Maximum number of send attempts across all fallback hosts. */
13
+ const MAX_ATTEMPTS = 3;
14
+ /** Base delay for exponential backoff between attempts (ms). */
15
+ const BASE_BACKOFF_MS = 100;
16
+ function debugLog(msg) {
17
+ if (DEBUG) {
18
+ process.stderr.write(`[cam-hook] ${msg}\n`);
19
+ }
20
+ }
21
+ /**
22
+ * Resolve the server host for hook connections.
23
+ * Priority:
24
+ * 1. CAM_SERVER_HOST env var (explicit override)
25
+ * 2. Auto-detect WSL → use Windows host IP (default gateway)
26
+ * 3. DEFAULT_HOST ('localhost')
27
+ */
28
+ let resolvedHost;
29
+ function getServerHost() {
30
+ if (resolvedHost)
31
+ return resolvedHost;
32
+ // 1. Explicit env var override
33
+ const envHost = process.env["CAM_SERVER_HOST"];
34
+ if (envHost) {
35
+ resolvedHost = envHost;
36
+ debugLog(`Host from CAM_SERVER_HOST: ${resolvedHost}`);
37
+ return resolvedHost;
38
+ }
39
+ // 2. Auto-detect WSL and resolve Windows host IP
40
+ try {
41
+ const procVersion = readFileSync("/proc/version", "utf8");
42
+ if (procVersion.toLowerCase().includes("microsoft")) {
43
+ debugLog("WSL detected, resolving Windows host IP...");
44
+ // Running inside WSL2 - resolve Windows host IP via default gateway
45
+ // (nameserver in /etc/resolv.conf may point to Docker DNS, not Windows)
46
+ try {
47
+ const route = execSync("ip route show default 2>/dev/null", {
48
+ encoding: "utf8",
49
+ timeout: 2000,
50
+ });
51
+ const gwMatch = route.match(/via\s+(\d+\.\d+\.\d+\.\d+)/);
52
+ if (gwMatch) {
53
+ resolvedHost = gwMatch[1];
54
+ debugLog(`Resolved via default gateway: ${resolvedHost}`);
55
+ return resolvedHost;
56
+ }
57
+ }
58
+ catch {
59
+ debugLog("ip route failed, trying resolv.conf...");
60
+ }
61
+ try {
62
+ const resolv = readFileSync("/etc/resolv.conf", "utf8");
63
+ const match = resolv.match(/nameserver\s+(\d+\.\d+\.\d+\.\d+)/);
64
+ if (match) {
65
+ resolvedHost = match[1];
66
+ debugLog(`Resolved via nameserver: ${resolvedHost}`);
67
+ return resolvedHost;
68
+ }
69
+ }
70
+ catch {
71
+ debugLog("resolv.conf read failed");
72
+ }
73
+ }
74
+ }
75
+ catch {
76
+ // Not WSL or can't read files - fall through
77
+ }
78
+ // 3. Default
79
+ resolvedHost = DEFAULT_HOST;
80
+ debugLog(`Using default host: ${resolvedHost}`);
81
+ return resolvedHost;
82
+ }
83
+ /**
84
+ * Build an ordered list of hosts to try.
85
+ * Primary host first, then fallbacks (localhost, 127.0.0.1).
86
+ * Deduplicates entries so we never retry the same host.
87
+ */
88
+ function getFallbackHosts() {
89
+ const primary = getServerHost();
90
+ const candidates = [primary, "localhost", "127.0.0.1"];
91
+ const seen = new Set();
92
+ const hosts = [];
93
+ for (const host of candidates) {
94
+ if (!seen.has(host)) {
95
+ seen.add(host);
96
+ hosts.push(host);
97
+ }
98
+ }
99
+ return hosts;
100
+ }
101
+ /**
102
+ * Attempt a single HTTP POST to the given host.
103
+ * Resolves to `true` on success (2xx/3xx/4xx), `false` on connection error or timeout.
104
+ * 4xx is considered "delivered" (server received it but rejected the payload).
105
+ * 5xx triggers a retry on the next host.
106
+ */
107
+ function doPost(hostname, body) {
108
+ return new Promise((resolve) => {
109
+ const req = request({
110
+ hostname,
111
+ port: DEFAULT_SERVER_PORT,
112
+ path: "/api/events",
113
+ method: "POST",
114
+ headers: {
115
+ "Content-Type": "application/json",
116
+ "Content-Length": Buffer.byteLength(body),
117
+ },
118
+ timeout: REQUEST_TIMEOUT_MS,
119
+ }, (res) => {
120
+ // Drain response to free socket
121
+ res.resume();
122
+ const code = res.statusCode ?? 0;
123
+ const ok = code >= 200 && code < 500;
124
+ if (!ok) {
125
+ debugLog(`Server responded with HTTP ${code} on ${hostname}`);
126
+ }
127
+ resolve(ok);
128
+ });
129
+ req.on("error", (err) => {
130
+ debugLog(`Connection error on ${hostname}: ${err.code ?? err.message}`);
131
+ resolve(false);
132
+ });
133
+ req.on("timeout", () => {
134
+ debugLog(`Request timeout on ${hostname} (${REQUEST_TIMEOUT_MS}ms)`);
135
+ req.destroy();
136
+ resolve(false);
137
+ });
138
+ req.write(body);
139
+ req.end();
140
+ });
141
+ }
142
+ /**
143
+ * Wait for a given number of milliseconds.
144
+ */
145
+ function delay(ms) {
146
+ return new Promise((resolve) => setTimeout(resolve, ms));
147
+ }
148
+ /**
149
+ * Sends an event payload to the CAM server via HTTP POST.
150
+ *
151
+ * Resilience strategy:
152
+ * 1. Try the primary host (resolved via WSL detection or env var)
153
+ * 2. On failure, try fallback hosts (localhost, 127.0.0.1) with exponential backoff
154
+ * 3. Max 3 attempts total across all hosts
155
+ * 4. Each attempt has a 2s timeout
156
+ * 5. Debug logging available via CAM_DEBUG=1
157
+ *
158
+ * Always fire-and-forget: never blocks the calling code.
159
+ * Fails silently if the server is not running.
160
+ */
161
+ export function sendEvent(payload) {
162
+ const body = JSON.stringify(payload);
163
+ const hosts = getFallbackHosts();
164
+ // Fire-and-forget async retry cascade
165
+ void (async () => {
166
+ let attempt = 0;
167
+ for (const hostname of hosts) {
168
+ if (attempt >= MAX_ATTEMPTS)
169
+ break;
170
+ // Exponential backoff between retries (skip delay on first attempt)
171
+ if (attempt > 0) {
172
+ const backoffMs = BASE_BACKOFF_MS * Math.pow(2, attempt - 1);
173
+ debugLog(`Backoff ${backoffMs}ms before attempt ${attempt + 1}`);
174
+ await delay(backoffMs);
175
+ }
176
+ debugLog(`POST to ${hostname}:${DEFAULT_SERVER_PORT} (attempt ${attempt + 1}/${MAX_ATTEMPTS})`);
177
+ const success = await doPost(hostname, body);
178
+ if (success) {
179
+ debugLog(`Event delivered via ${hostname}`);
180
+ return;
181
+ }
182
+ attempt++;
183
+ }
184
+ debugLog("All attempts exhausted, event dropped");
185
+ })();
186
+ }
187
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@claudecam/hook",
3
+ "version": "0.1.0",
4
+ "description": "Ultra-lightweight CLI binary for Claude Code hooks",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "cam-hook": "./dist/index.js"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/index.js",
15
+ "types": "./dist/index.d.ts"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "dependencies": {
22
+ "@claudecam/shared": "0.1.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^22.0.0",
26
+ "typescript": "^5.7.0"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/pedropauloai/claude-agent-monitor.git",
31
+ "directory": "packages/hook"
32
+ },
33
+ "homepage": "https://github.com/pedropauloai/claude-agent-monitor",
34
+ "bugs": "https://github.com/pedropauloai/claude-agent-monitor/issues",
35
+ "keywords": [
36
+ "claude",
37
+ "agent",
38
+ "monitor",
39
+ "observability",
40
+ "claude-code"
41
+ ],
42
+ "author": "CAM Contributors",
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "scripts": {
47
+ "build": "tsc",
48
+ "dev": "tsc --watch",
49
+ "typecheck": "tsc --noEmit",
50
+ "clean": "rm -rf dist"
51
+ }
52
+ }