yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
2d775b54d
master
1#!/usr/bin/env python3 2 3import argparse 4import json 5import os 6import sys 7 8 9def parse_transcript_for_todos (transcript_path ): 10"""Parse transcript to find the last TodoWrite and check if all todos are completed.""" 11if not os .path .exists (transcript_path ): 12return True # If no transcript, assume OK to proceed 13 14try : 15last_todo_write = None 16 17# Read .jsonl file and find the last TodoWrite 18with open (transcript_path ,"r" )as f : 19for line in f : 20line = line .strip () 21if line : 22try : 23entry = json .loads (line ) 24# Check if this is an assistant message with TodoWrite tool use 25if ( 26entry .get ("type" )== "assistant" 27and "message" in entry 28and "content" in entry ["message" ] 29 ): 30content = entry ["message" ]["content" ] 31if isinstance (content ,list ): 32for item in content : 33if ( 34isinstance (item ,dict ) 35and item .get ("type" )== "tool_use" 36and item .get ("name" )== "TodoWrite" 37and "input" in item 38and "todos" in item ["input" ] 39 ): 40last_todo_write = item ["input" ]["todos" ] 41except json .JSONDecodeError : 42continue # Skip invalid lines 43 44# If no TodoWrite found, assume OK to proceed 45if not last_todo_write : 46return True 47 48# Check if all todos are completed 49incomplete_todos = [] 50for todo in last_todo_write : 51if todo .get ("status" )!= "completed" : 52incomplete_todos .append (todo ) 53 54return len (incomplete_todos )== 0 ,incomplete_todos 55 56except Exception : 57# If any error occurs during parsing, assume OK to proceed 58return True 59 60 61def main (): 62try : 63# Parse command line arguments 64parser = argparse .ArgumentParser () 65parser .add_argument ( 66"--validate" , 67action = "store_true" , 68help = "Validate that all todos are completed before allowing stop" , 69 ) 70args = parser .parse_args () 71 72# Read JSON input from stdin 73input_data = json .load (sys .stdin ) 74 75# Extract required fields 76session_id = input_data .get ("session_id" ,"" ) 77stop_hook_active = input_data .get ("stop_hook_active" ,False ) 78 79# Handle --validate switch 80if args .validate and "transcript_path" in input_data : 81transcript_path = input_data ["transcript_path" ] 82validation_result = parse_transcript_for_todos (transcript_path ) 83 84# Check if validation returned a tuple (incomplete todos found) 85if isinstance (validation_result ,tuple ): 86all_complete ,incomplete_todos = validation_result 87if not all_complete : 88# Create a detailed message about incomplete todos 89incomplete_items = [] 90for todo in incomplete_todos : 91status = todo .get ("status" ,"unknown" ) 92content = todo .get ("content" ,"unknown task" ) 93incomplete_items .append (f"- { content } ( { status } )" ) 94 95incomplete_list = "\n" .join (incomplete_items ) 96reason = f"Tasks are not yet complete. Please finish the following todos:\n { incomplete_list } \n\nUse TodoWrite to mark tasks as completed when finished." 97 98# Return JSON decision to block stopping 99output = {"decision" :"block" ,"reason" :reason } 100json .dumps (output )) 101sys .exit (0 ) 102elif not validation_result : 103# Single boolean returned as False 104reason = "Tasks are not yet complete. Please finish all todos before stopping. Use TodoWrite to mark tasks as completed when finished." 105output = {"decision" :"block" ,"reason" :reason } 106json .dumps (output )) 107sys .exit (0 ) 108 109sys .exit (0 ) 110 111except json .JSONDecodeError : 112# Handle JSON decode errors gracefully 113sys .exit (0 ) 114except Exception : 115# Handle any other errors gracefully 116sys .exit (0 ) 117 118 119if __name__ == "__main__" : 120main ()