11#!/usr/bin/env node
22
3- import { readFileSync } from "node:fs" ;
3+ import { readFileSync , appendFileSync } from "node:fs" ;
44import { resolve } from "node:path" ;
5+ import { tmpdir } from "node:os" ;
56import { isTelemetryEnabled , trackEvents } from "./telemetry.mjs" ;
67
8+ const DEBUG = [ "debug" , "trace" ] . includes ( process . env . VERCEL_PLUGIN_LOG_LEVEL || "" )
9+ || process . env . VERCEL_PLUGIN_DEBUG === "1"
10+ || process . env . VERCEL_PLUGIN_HOOK_DEBUG === "1" ;
11+
12+ const DBG_FILE = resolve ( tmpdir ( ) , "vercel-plugin-telemetry-debug.log" ) ;
13+
14+ function dbg ( event : string , data : Record < string , unknown > ) : void {
15+ if ( ! DEBUG ) return ;
16+ const line = JSON . stringify ( { ts : new Date ( ) . toISOString ( ) , hook : "posttooluse-telemetry" , event, ...data } ) + "\n" ;
17+ process . stderr . write ( line ) ;
18+ try { appendFileSync ( DBG_FILE , line ) ; } catch { }
19+ }
20+
721function parseStdin ( ) : Record < string , unknown > | null {
822 try {
923 const raw = readFileSync ( 0 , "utf-8" ) . trim ( ) ;
@@ -15,22 +29,38 @@ function parseStdin(): Record<string, unknown> | null {
1529}
1630
1731async function main(): Promise< void > {
32+ // Always log — unconditional, so we can verify the hook runs at all
33+ try { appendFileSync ( DBG_FILE , JSON . stringify ( { ts : new Date ( ) . toISOString ( ) , event : "hook-entered" , telemetryEnabled : isTelemetryEnabled ( ) , debugEnabled : DEBUG , env_TELEMETRY : process . env . VERCEL_PLUGIN_TELEMETRY || "(unset)" } ) + "\n" ) ; } catch { }
34+
35+ dbg("start", { telemetryEnabled : isTelemetryEnabled ( ) , env_TELEMETRY : process . env . VERCEL_PLUGIN_TELEMETRY || "(unset)" } );
36+
1837 if (!isTelemetryEnabled()) {
38+ dbg ( "bail" , { reason : "telemetry_disabled" } ) ;
1939 process . stdout . write ( "{}" ) ;
2040 process . exit ( 0 ) ;
2141 }
2242
2343 const input = parseStdin();
2444 if (!input) {
45+ dbg ( "bail" , { reason : "stdin_empty_or_invalid" } ) ;
2546 process . stdout . write ( "{}" ) ;
2647 process . exit ( 0 ) ;
2748 }
2849
2950 const toolName = (input.tool_name as string) || "";
3051 const toolInput = (input.tool_input as Record< string , unknown > ) || { } ;
31- const sessionId = ( input . session_id as string ) || "" ;
52+ const sessionId = (input.session_id as string) || (input.conversation_id as string) || "";
53+
54+ dbg("parsed", {
55+ toolName ,
56+ hasSessionId : ! ! ( input . session_id ) ,
57+ hasConversationId : ! ! ( input . conversation_id ) ,
58+ resolvedSessionId : sessionId . slice ( 0 , 20 ) ,
59+ inputKeys : Object . keys ( input ) ,
60+ } );
3261
3362 if (!sessionId) {
63+ dbg ( "bail" , { reason : "no_session_id" } ) ;
3464 process . stdout . write ( "{}" ) ;
3565 process . exit ( 0 ) ;
3666 }
@@ -64,8 +94,13 @@ async function main(): Promise<void> {
6494 ) ;
6595 }
6696
97+ dbg("entries", { count : entries . length , keys : entries . map ( e => e . key ) } );
98+
6799 if (entries.length > 0 ) {
68100 await trackEvents ( sessionId , entries ) ;
101+ dbg ( "sent" , { count : entries . length , sessionId : sessionId . slice ( 0 , 20 ) } ) ;
102+ } else {
103+ dbg ( "skip" , { reason : "no_entries" , toolName } ) ;
69104 }
70105
71106 process.stdout.write("{ } ");
0 commit comments