@@ -40,10 +40,10 @@ for (const envPath of envPaths) {
4040}
4141
4242const CONFIG_PATH = path . join ( os . homedir ( ) , '.stackmemory' , 'sms-notify.json' ) ;
43- const PENDING_PATH = path . join (
43+ const DEBUG_LOG = path . join (
4444 os . homedir ( ) ,
4545 '.stackmemory' ,
46- 'sms-pending-prompts.json '
46+ 'claude-session-debug.log '
4747) ;
4848
4949function loadConfig ( ) {
@@ -52,25 +52,44 @@ function loadConfig() {
5252 return JSON . parse ( fs . readFileSync ( CONFIG_PATH , 'utf8' ) ) ;
5353 }
5454 } catch { }
55- return { enabled : false } ;
55+ return { enabled : false , pendingPrompts : [ ] } ;
5656}
5757
58- function savePendingPrompt ( prompt ) {
58+ function saveConfig ( config ) {
5959 try {
6060 const dir = path . join ( os . homedir ( ) , '.stackmemory' ) ;
6161 if ( ! fs . existsSync ( dir ) ) {
6262 fs . mkdirSync ( dir , { recursive : true } ) ;
6363 }
64- let pending = { prompts : [ ] } ;
65- if ( fs . existsSync ( PENDING_PATH ) ) {
66- pending = JSON . parse ( fs . readFileSync ( PENDING_PATH , 'utf8' ) ) ;
64+ fs . writeFileSync ( CONFIG_PATH , JSON . stringify ( config , null , 2 ) ) ;
65+ } catch ( err ) {
66+ console . error ( '[notify-hook] Failed to save config:' , err . message ) ;
67+ }
68+ }
69+
70+ function logDebug ( event , data ) {
71+ try {
72+ const entry = `[${ new Date ( ) . toISOString ( ) } ] ${ event } : ${ typeof data === 'string' ? data : JSON . stringify ( data ) } \n` ;
73+ fs . appendFileSync ( DEBUG_LOG , entry ) ;
74+ } catch { }
75+ }
76+
77+ function savePendingPrompt ( prompt ) {
78+ try {
79+ const config = loadConfig ( ) ;
80+ if ( ! config . pendingPrompts ) {
81+ config . pendingPrompts = [ ] ;
6782 }
68- pending . prompts . push ( prompt ) ;
83+ config . pendingPrompts . push ( prompt ) ;
6984 // Keep only last 10 prompts
70- if ( pending . prompts . length > 10 ) {
71- pending . prompts = pending . prompts . slice ( - 10 ) ;
85+ if ( config . pendingPrompts . length > 10 ) {
86+ config . pendingPrompts = config . pendingPrompts . slice ( - 10 ) ;
7287 }
73- fs . writeFileSync ( PENDING_PATH , JSON . stringify ( pending , null , 2 ) ) ;
88+ saveConfig ( config ) ;
89+ logDebug ( 'PENDING_PROMPT' , {
90+ id : prompt . id ,
91+ options : prompt . options . length ,
92+ } ) ;
7493 } catch ( err ) {
7594 console . error ( '[notify-hook] Failed to save pending prompt:' , err . message ) ;
7695 }
@@ -85,40 +104,46 @@ function shouldNotify(toolName, toolInput, output) {
85104 const questions = toolInput ?. questions || [ ] ;
86105 if ( questions . length === 0 ) return null ;
87106
88- // Format questions for WhatsApp
89- const formattedQuestions = questions . map ( ( q , qIdx ) => {
90- let text = q . question ;
91- if ( q . options && q . options . length > 0 ) {
92- text += '\n' ;
93- q . options . forEach ( ( opt , i ) => {
94- text += `${ i + 1 } . ${ opt . label } ` ;
95- if ( opt . description ) {
96- text += ` - ${ opt . description } ` ;
97- }
98- text += '\n' ;
99- } ) ;
100- text += `${ q . options . length + 1 } . Other (type your answer)` ;
101- }
102- return { index : qIdx , text, options : q . options , header : q . header } ;
103- } ) ;
104-
105- // Store pending prompt for response matching
107+ // Take first question (most common case)
108+ const q = questions [ 0 ] ;
106109 const promptId = Math . random ( ) . toString ( 36 ) . substring ( 2 , 10 ) ;
110+
111+ // Build message text
112+ let messageText = q . question ;
113+ const options = [ ] ;
114+
115+ if ( q . options && q . options . length > 0 ) {
116+ messageText += '\n' ;
117+ q . options . forEach ( ( opt , i ) => {
118+ const key = String ( i + 1 ) ;
119+ messageText += `${ key } . ${ opt . label } ` ;
120+ if ( opt . description ) {
121+ messageText += ` - ${ opt . description } ` ;
122+ }
123+ messageText += '\n' ;
124+ options . push ( { key, label : opt . label } ) ;
125+ } ) ;
126+ // Add "Other" option
127+ const otherKey = String ( q . options . length + 1 ) ;
128+ messageText += `${ otherKey } . Other (type your answer)` ;
129+ options . push ( { key : otherKey , label : 'Other' } ) ;
130+ }
131+
132+ // Store pending prompt in format webhook expects
107133 const pendingPrompt = {
108134 id : promptId ,
109135 timestamp : new Date ( ) . toISOString ( ) ,
110- questions : formattedQuestions ,
111- expiresAt : new Date ( Date . now ( ) + 10 * 60 * 1000 ) . toISOString ( ) , // 10 min
136+ message : q . question ,
137+ options : options ,
138+ type : options . length > 0 ? 'options' : 'freeform' ,
139+ expiresAt : new Date ( Date . now ( ) + 60 * 60 * 1000 ) . toISOString ( ) , // 1 hour
112140 } ;
113141 savePendingPrompt ( pendingPrompt ) ;
114142
115- // Build message
116- const message = formattedQuestions . map ( ( q ) => q . text ) . join ( '\n\n' ) ;
117-
118143 return {
119144 type : 'custom' ,
120145 title : 'Claude needs your input' ,
121- message : message ,
146+ message : messageText ,
122147 promptId : promptId ,
123148 isQuestion : true ,
124149 } ;
@@ -282,8 +307,14 @@ function sendNotification(notification) {
282307 console . error (
283308 `[notify-hook] Sent via ${ numbers . channel } : ${ notification . title } `
284309 ) ;
310+ logDebug ( 'MESSAGE_SENT' , {
311+ channel : numbers . channel ,
312+ title : notification . title ,
313+ promptId : notification . promptId ,
314+ } ) ;
285315 } else {
286316 console . error ( `[notify-hook] Failed (${ res . statusCode } ): ${ body } ` ) ;
317+ logDebug ( 'MESSAGE_FAILED' , { status : res . statusCode , error : body } ) ;
287318 }
288319 } ) ;
289320 } ) ;
@@ -305,6 +336,8 @@ process.stdin.on('end', () => {
305336 const hookData = JSON . parse ( input ) ;
306337 const { tool_name, tool_input, tool_output } = hookData ;
307338
339+ logDebug ( 'PostToolUse' , { tool : tool_name , session : hookData . session_id } ) ;
340+
308341 const notification = shouldNotify ( tool_name , tool_input , tool_output ) ;
309342
310343 if ( notification ) {
@@ -314,6 +347,7 @@ process.stdin.on('end', () => {
314347 // Always allow (post-tool hooks don't block)
315348 console . log ( JSON . stringify ( { status : 'ok' } ) ) ;
316349 } catch ( err ) {
350+ logDebug ( 'ERROR' , err . message ) ;
317351 console . error ( '[notify-hook] Error:' , err . message ) ;
318352 console . log ( JSON . stringify ( { status : 'ok' } ) ) ;
319353 }
0 commit comments