@@ -29,68 +29,54 @@ def main():
2929 uvx ccnotify install --force # Force complete reinstallation
3030 uvx ccnotify install --config-only # Only update configuration
3131 uvx ccnotify install --quiet # Minimal output mode
32- """
32+ """ ,
3333 )
34-
34+
3535 # Simplified argument structure
3636 parser .add_argument (
37- "command" ,
38- nargs = '?' ,
37+ "command" ,
38+ nargs = "?" ,
3939 default = "install" ,
4040 choices = ["install" ],
41- help = "Command to execute (default: install)"
42- )
43-
44- parser .add_argument (
45- "--force" ,
46- action = "store_true" ,
47- help = "Force complete reinstallation"
48- )
49-
50- parser .add_argument (
51- "--config-only" ,
52- action = "store_true" ,
53- help = "Only update configuration, skip script updates"
41+ help = "Command to execute (default: install)" ,
5442 )
55-
56- parser .add_argument (
57- "--quiet" ,
58- action = "store_true" ,
59- help = "Minimal output mode"
60- )
61-
43+
44+ parser .add_argument ("--force" , action = "store_true" , help = "Force complete reinstallation" )
45+
6246 parser .add_argument (
63- "--logging" ,
64- action = "store_true" ,
65- help = "Enable logging to file (off by default)"
47+ "--config-only" , action = "store_true" , help = "Only update configuration, skip script updates"
6648 )
67-
49+
50+ parser .add_argument ("--quiet" , action = "store_true" , help = "Minimal output mode" )
51+
6852 parser .add_argument (
69- "--version" ,
70- action = "version" ,
71- version = f"CCNotify { get_package_version ()} "
53+ "--logging" , action = "store_true" , help = "Enable logging to file (off by default)"
7254 )
73-
55+
56+ parser .add_argument ("--version" , action = "version" , version = f"CCNotify { get_package_version ()} " )
57+
7458 args = parser .parse_args ()
75-
59+
7660 # Always execute install command with intelligent detection
7761 success = execute_install_command (args .force , args .config_only , args .quiet , args .logging )
78-
62+
7963 if not success :
8064 sys .exit (1 )
8165
8266
83- def execute_install_command (force : bool = False , config_only : bool = False , quiet : bool = False , logging : bool = False ) -> bool :
67+ def execute_install_command (
68+ force : bool = False , config_only : bool = False , quiet : bool = False , logging : bool = False
69+ ) -> bool :
8470 """Execute the intelligent install command with detection logic."""
8571 # Validate parameters
8672 if not isinstance (logging , bool ):
8773 raise TypeError ("logging parameter must be a boolean" )
88-
74+
8975 try :
9076 # Detect existing installation
9177 detector = InstallationDetector ()
9278 status = detector .check_existing_installation ()
93-
79+
9480 if status .exists and not force :
9581 # Existing installation - run update flow
9682 update_flow = UpdateFlow ()
@@ -99,7 +85,7 @@ def execute_install_command(force: bool = False, config_only: bool = False, quie
9985 # No installation or force requested - run first-time flow
10086 first_time_flow = FirstTimeFlow ()
10187 return first_time_flow .run (force = force , quiet = quiet , logging = logging )
102-
88+
10389 except KeyboardInterrupt :
10490 if not quiet :
10591 display_error_message ("Installation cancelled by user" )
@@ -116,17 +102,19 @@ def get_notify_template() -> str:
116102 from .notify import main as notify_main
117103 from .version import get_package_version
118104 import inspect
119-
105+
120106 # Get the complete notify.py file content
121107 from pathlib import Path
108+
122109 notify_file = Path (__file__ ).parent / "notify.py"
123-
110+
124111 if notify_file .exists ():
125112 content = notify_file .read_text ()
126113 # Embed version in the generated script
127114 from .version import embed_version_in_script
115+
128116 return embed_version_in_script (content , get_package_version ())
129-
117+
130118 # Fallback minimal template
131119 version = get_package_version ()
132120 return f'''#!/usr/bin/env python3
@@ -188,60 +176,57 @@ def update_claude_settings(script_path: str, logging: bool = False) -> bool:
188176 import json
189177 import shutil
190178 from pathlib import Path
191-
179+
192180 claude_dir = Path .home () / ".claude"
193181 settings_file = claude_dir / "settings.json"
194-
182+
195183 try :
196184 if settings_file .exists ():
197185 # Create backup first
198- backup_file = settings_file .with_suffix (' .json.ccnotify.bak' )
186+ backup_file = settings_file .with_suffix (" .json.ccnotify.bak" )
199187 shutil .copy2 (settings_file , backup_file )
200-
201- with open (settings_file , 'r' ) as f :
188+
189+ with open (settings_file , "r" ) as f :
202190 settings = json .load (f )
203191 else :
204192 settings = {}
205-
193+
206194 # Add our hook configuration
207195 if "hooks" not in settings :
208196 settings ["hooks" ] = {}
209-
197+
210198 # Configure ccnotify hook for relevant events
211199 # Add --logging flag to command if logging is enabled
212200 command = f"uv run { script_path } "
213201 if logging :
214202 command += " --logging"
215-
216- hook_config = {
217- "type" : "command" ,
218- "command" : command
219- }
220-
203+
204+ hook_config = {"type" : "command" , "command" : command }
205+
221206 events_to_hook = ["PreToolUse" , "PostToolUse" , "Stop" , "SubagentStop" , "Notification" ]
222207 hooks_added = False
223-
208+
224209 for event in events_to_hook :
225210 if event not in settings ["hooks" ]:
226211 settings ["hooks" ][event ] = []
227-
212+
228213 # Check if our hook is already configured and update if needed
229214 # Hook structure: {"matcher": ".*", "hooks": [{"type": "command", "command": "..."}]}
230215 hook_updated = False
231216 hook_exists = False
232-
217+
233218 for i , entry in enumerate (settings ["hooks" ][event ]):
234219 if not isinstance (entry , dict ):
235220 continue
236-
221+
237222 hooks_list = entry .get ("hooks" , [])
238223 if not isinstance (hooks_list , list ):
239224 continue
240-
225+
241226 for j , hook in enumerate (hooks_list ):
242227 if not isinstance (hook , dict ):
243228 continue
244-
229+
245230 existing_command = hook .get ("command" , "" )
246231 # Check if this is our ccnotify hook
247232 if "ccnotify.py" in existing_command or str (script_path ) in existing_command :
@@ -254,33 +239,33 @@ def update_claude_settings(script_path: str, logging: bool = False) -> bool:
254239 hooks_added = True
255240 except (KeyError , IndexError ) as e :
256241 # Log error but continue processing
257- print (f"Warning: Could not update hook for { event } : { e } " , file = sys .stderr )
242+ print (
243+ f"Warning: Could not update hook for { event } : { e } " ,
244+ file = sys .stderr ,
245+ )
258246 break
259-
247+
260248 if hook_exists :
261249 break
262-
250+
263251 if not hook_exists :
264- settings ["hooks" ][event ].append ({
265- "matcher" : ".*" ,
266- "hooks" : [hook_config ]
267- })
252+ settings ["hooks" ][event ].append ({"matcher" : ".*" , "hooks" : [hook_config ]})
268253 hooks_added = True
269-
254+
270255 # Enable hooks if not already enabled
271256 if not settings .get ("hooksEnabled" , False ):
272257 settings ["hooksEnabled" ] = True
273258 hooks_added = True
274-
259+
275260 if hooks_added :
276- with open (settings_file , 'w' ) as f :
261+ with open (settings_file , "w" ) as f :
277262 json .dump (settings , f , indent = 2 )
278-
263+
279264 return True
280-
265+
281266 except Exception :
282267 return False
283268
284269
285270if __name__ == "__main__" :
286- main ()
271+ main ()
0 commit comments