code-puppy 0.0.332__py3-none-any.whl → 0.0.334__py3-none-any.whl

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.
@@ -44,70 +44,9 @@ def _truncate_line(line: str) -> str:
44
44
  if sys.platform.startswith("win"):
45
45
  import msvcrt
46
46
 
47
- # Load kernel32 for PeekNamedPipe and SetConsoleCtrlHandler
47
+ # Load kernel32 for PeekNamedPipe
48
48
  _kernel32 = ctypes.windll.kernel32
49
49
 
50
- # SetConsoleCtrlHandler types for Ctrl+C handling on Windows
51
- # This is more reliable than signal.SIGINT when running under uvx
52
- _CTRL_C_EVENT = 0
53
- _CTRL_BREAK_EVENT = 1
54
- _HANDLER_ROUTINE = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_ulong)
55
-
56
- # Track registered handlers to prevent garbage collection
57
- _registered_console_handlers: list = []
58
-
59
- def _add_windows_ctrl_handler(callback: Callable[[], None]) -> Optional[Callable]:
60
- """Register a Windows console control handler for Ctrl+C/Ctrl+Break.
61
-
62
- Args:
63
- callback: Function to call when Ctrl+C or Ctrl+Break is pressed.
64
- Should take no arguments.
65
-
66
- Returns:
67
- The wrapped handler function (needed for removal), or None if failed.
68
- """
69
-
70
- def handler(ctrl_type: int) -> int:
71
- if ctrl_type in (_CTRL_C_EVENT, _CTRL_BREAK_EVENT):
72
- try:
73
- callback()
74
- except Exception:
75
- pass
76
- return 1 # TRUE = we handled it, don't pass to next handler
77
- return 0 # FALSE = let next handler deal with it
78
-
79
- # Wrap in WINFUNCTYPE to make it callable from C
80
- wrapped = _HANDLER_ROUTINE(handler)
81
- # Keep reference to prevent GC
82
- _registered_console_handlers.append(wrapped)
83
-
84
- try:
85
- if _kernel32.SetConsoleCtrlHandler(wrapped, True):
86
- return wrapped
87
- except Exception:
88
- pass
89
- return None
90
-
91
- def _remove_windows_ctrl_handler(handler: Callable) -> bool:
92
- """Remove a previously registered Windows console control handler.
93
-
94
- Args:
95
- handler: The handler returned by _add_windows_ctrl_handler.
96
-
97
- Returns:
98
- True if successfully removed, False otherwise.
99
- """
100
- if handler is None:
101
- return False
102
- try:
103
- result = _kernel32.SetConsoleCtrlHandler(handler, False)
104
- # Clean up our reference
105
- if handler in _registered_console_handlers:
106
- _registered_console_handlers.remove(handler)
107
- return bool(result)
108
- except Exception:
109
- return False
110
-
111
50
  def _win32_pipe_has_data(pipe) -> bool:
112
51
  """Check if a Windows pipe has data available without blocking.
113
52
 
@@ -148,15 +87,8 @@ if sys.platform.startswith("win"):
148
87
  except (ValueError, OSError, ctypes.ArgumentError):
149
88
  # Handle closed, invalid, or other errors
150
89
  return False
151
-
152
90
  else:
153
- # Non-Windows: provide no-op stubs
154
- def _add_windows_ctrl_handler(callback: Callable[[], None]) -> Optional[Callable]:
155
- return None
156
-
157
- def _remove_windows_ctrl_handler(handler: Callable) -> bool:
158
- return False
159
-
91
+ # POSIX stub - not used, but keeps the code clean
160
92
  def _win32_pipe_has_data(pipe) -> bool:
161
93
  return False
162
94
 
@@ -174,7 +106,6 @@ _USER_KILLED_PROCESSES = set()
174
106
  _SHELL_CTRL_X_STOP_EVENT: Optional[threading.Event] = None
175
107
  _SHELL_CTRL_X_THREAD: Optional[threading.Thread] = None
176
108
  _ORIGINAL_SIGINT_HANDLER = None
177
- _WINDOWS_CTRL_HANDLER = None # For SetConsoleCtrlHandler on Windows
178
109
 
179
110
  # Stop event to signal reader threads to terminate
180
111
  _READER_STOP_EVENT: Optional[threading.Event] = None
@@ -504,10 +435,8 @@ def _shell_command_keyboard_context():
504
435
  1. Disables the agent's Ctrl-C handler (so it doesn't cancel the agent)
505
436
  2. Enables a Ctrl-X listener to kill the running shell process
506
437
  3. Restores the original Ctrl-C handler when done
507
- 4. On Windows, uses SetConsoleCtrlHandler for reliable Ctrl+C with uvx
508
438
  """
509
439
  global _SHELL_CTRL_X_STOP_EVENT, _SHELL_CTRL_X_THREAD, _ORIGINAL_SIGINT_HANDLER
510
- global _WINDOWS_CTRL_HANDLER
511
440
 
512
441
  # Handler for Ctrl-X: kill all running shell processes
513
442
  def handle_ctrl_x_press() -> None:
@@ -515,15 +444,11 @@ def _shell_command_keyboard_context():
515
444
  kill_all_running_shell_processes()
516
445
 
517
446
  # Handler for Ctrl-C during shell execution: just kill the shell process, don't cancel agent
518
- def shell_ctrl_c_callback():
447
+ def shell_sigint_handler(_sig, _frame):
519
448
  """During shell execution, Ctrl-C kills the shell but doesn't cancel the agent."""
520
449
  emit_warning("\n🛑 Ctrl-C detected! Interrupting shell command...")
521
450
  kill_all_running_shell_processes()
522
451
 
523
- def shell_sigint_handler(_sig, _frame):
524
- """Signal handler wrapper for SIGINT."""
525
- shell_ctrl_c_callback()
526
-
527
452
  # Set up Ctrl-X listener
528
453
  _SHELL_CTRL_X_STOP_EVENT = threading.Event()
529
454
  _SHELL_CTRL_X_THREAD = _spawn_ctrl_x_key_listener(
@@ -531,12 +456,7 @@ def _shell_command_keyboard_context():
531
456
  handle_ctrl_x_press,
532
457
  )
533
458
 
534
- # On Windows, use SetConsoleCtrlHandler for reliable Ctrl+C handling
535
- # This works even when running under uvx where SIGINT doesn't propagate properly
536
- if sys.platform.startswith("win"):
537
- _WINDOWS_CTRL_HANDLER = _add_windows_ctrl_handler(shell_ctrl_c_callback)
538
-
539
- # Also set SIGINT handler (works on POSIX, may work on some Windows setups)
459
+ # Replace SIGINT handler temporarily
540
460
  try:
541
461
  _ORIGINAL_SIGINT_HANDLER = signal.signal(signal.SIGINT, shell_sigint_handler)
542
462
  except (ValueError, OSError):
@@ -556,10 +476,6 @@ def _shell_command_keyboard_context():
556
476
  except Exception:
557
477
  pass
558
478
 
559
- # Remove Windows console handler
560
- if _WINDOWS_CTRL_HANDLER is not None:
561
- _remove_windows_ctrl_handler(_WINDOWS_CTRL_HANDLER)
562
-
563
479
  # Restore original SIGINT handler
564
480
  if _ORIGINAL_SIGINT_HANDLER is not None:
565
481
  try:
@@ -571,7 +487,6 @@ def _shell_command_keyboard_context():
571
487
  _SHELL_CTRL_X_STOP_EVENT = None
572
488
  _SHELL_CTRL_X_THREAD = None
573
489
  _ORIGINAL_SIGINT_HANDLER = None
574
- _WINDOWS_CTRL_HANDLER = None
575
490
 
576
491
 
577
492
  def run_shell_command_streaming(
@@ -0,0 +1,242 @@
1
+ """Detect if code-puppy was launched via uvx on Windows.
2
+
3
+ This module provides utilities to detect the launch method of code-puppy,
4
+ specifically to handle signal differences when running via uvx on Windows.
5
+
6
+ On Windows, when launched via `uvx code-puppy`, Ctrl+C (SIGINT) gets captured
7
+ by uvx's process handling before reaching our Python process. To work around
8
+ this, we detect the uvx launch scenario and switch to Ctrl+K for cancellation.
9
+
10
+ Note: This issue is specific to uvx.exe, NOT uv.exe. Running via `uv run`
11
+ handles SIGINT correctly on Windows.
12
+
13
+ On non-Windows platforms, this is not an issue - Ctrl+C works fine with uvx.
14
+ """
15
+
16
+ import os
17
+ import platform
18
+ import sys
19
+ from functools import lru_cache
20
+ from typing import Optional
21
+
22
+ # Cache the detection result - it won't change during runtime
23
+ _uvx_detection_cache: Optional[bool] = None
24
+
25
+
26
+ def _get_parent_process_name_psutil(pid: int) -> Optional[str]:
27
+ """Get parent process name using psutil (if available).
28
+
29
+ Args:
30
+ pid: Process ID to get parent name for
31
+
32
+ Returns:
33
+ Parent process name (lowercase) or None if not found
34
+ """
35
+ try:
36
+ import psutil
37
+
38
+ proc = psutil.Process(pid)
39
+ parent = proc.parent()
40
+ if parent:
41
+ return parent.name().lower()
42
+ except Exception:
43
+ pass
44
+ return None
45
+
46
+
47
+ def _get_parent_process_chain_psutil() -> list[str]:
48
+ """Get the entire parent process chain using psutil.
49
+
50
+ Returns:
51
+ List of process names from current process up to init/System
52
+ """
53
+ chain = []
54
+ try:
55
+ import psutil
56
+
57
+ proc = psutil.Process(os.getpid())
58
+ while proc:
59
+ chain.append(proc.name().lower())
60
+ parent = proc.parent()
61
+ if parent is None or parent.pid in (0, proc.pid):
62
+ break
63
+ proc = parent
64
+ except Exception:
65
+ pass
66
+ return chain
67
+
68
+
69
+ def _get_parent_process_chain_windows_ctypes() -> list[str]:
70
+ """Get parent process chain on Windows using ctypes (no external deps).
71
+
72
+ This is a fallback when psutil is not available.
73
+
74
+ Returns:
75
+ List of process names from current process up to System
76
+ """
77
+ if platform.system() != "Windows":
78
+ return []
79
+
80
+ chain = []
81
+ try:
82
+ import ctypes
83
+ from ctypes import wintypes
84
+
85
+ # Windows API constants
86
+ TH32CS_SNAPPROCESS = 0x00000002
87
+ INVALID_HANDLE_VALUE = -1
88
+
89
+ class PROCESSENTRY32(ctypes.Structure):
90
+ _fields_ = [
91
+ ("dwSize", wintypes.DWORD),
92
+ ("cntUsage", wintypes.DWORD),
93
+ ("th32ProcessID", wintypes.DWORD),
94
+ ("th32DefaultHeapID", ctypes.POINTER(wintypes.ULONG)),
95
+ ("th32ModuleID", wintypes.DWORD),
96
+ ("cntThreads", wintypes.DWORD),
97
+ ("th32ParentProcessID", wintypes.DWORD),
98
+ ("pcPriClassBase", wintypes.LONG),
99
+ ("dwFlags", wintypes.DWORD),
100
+ ("szExeFile", ctypes.c_char * 260),
101
+ ]
102
+
103
+ kernel32 = ctypes.windll.kernel32
104
+
105
+ # Take a snapshot of all processes
106
+ snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
107
+ if snapshot == INVALID_HANDLE_VALUE:
108
+ return chain
109
+
110
+ try:
111
+ # Build a map of PID -> (parent_pid, exe_name)
112
+ process_map: dict[int, tuple[int, str]] = {}
113
+ pe = PROCESSENTRY32()
114
+ pe.dwSize = ctypes.sizeof(PROCESSENTRY32)
115
+
116
+ if kernel32.Process32First(snapshot, ctypes.byref(pe)):
117
+ while True:
118
+ pid = pe.th32ProcessID
119
+ parent_pid = pe.th32ParentProcessID
120
+ exe_name = pe.szExeFile.decode("utf-8", errors="ignore").lower()
121
+ process_map[pid] = (parent_pid, exe_name)
122
+
123
+ if not kernel32.Process32Next(snapshot, ctypes.byref(pe)):
124
+ break
125
+
126
+ # Traverse from current PID up the parent chain
127
+ current_pid = os.getpid()
128
+ visited = set() # Prevent infinite loops
129
+
130
+ while current_pid in process_map and current_pid not in visited:
131
+ visited.add(current_pid)
132
+ parent_pid, exe_name = process_map[current_pid]
133
+ chain.append(exe_name)
134
+
135
+ if parent_pid == 0 or parent_pid == current_pid:
136
+ break
137
+ current_pid = parent_pid
138
+
139
+ finally:
140
+ kernel32.CloseHandle(snapshot)
141
+
142
+ except Exception:
143
+ pass
144
+
145
+ return chain
146
+
147
+
148
+ def _get_parent_process_chain() -> list[str]:
149
+ """Get the parent process chain using best available method.
150
+
151
+ Returns:
152
+ List of process names from current process up to init/System
153
+ """
154
+ # Try psutil first (more reliable, cross-platform)
155
+ try:
156
+ import psutil # noqa: F401
157
+
158
+ return _get_parent_process_chain_psutil()
159
+ except ImportError:
160
+ pass
161
+
162
+ # Fall back to ctypes on Windows
163
+ if platform.system() == "Windows":
164
+ return _get_parent_process_chain_windows_ctypes()
165
+
166
+ return []
167
+
168
+
169
+ def _is_uvx_in_chain(chain: list[str]) -> bool:
170
+ """Check if uvx is in the process chain.
171
+
172
+ Note: We only check for uvx.exe, NOT uv.exe. The uv.exe binary
173
+ (used by `uv run`) handles SIGINT correctly on Windows, but
174
+ uvx.exe captures it before it reaches Python.
175
+
176
+ Args:
177
+ chain: List of process names (lowercase)
178
+
179
+ Returns:
180
+ True if uvx.exe is found in the chain
181
+ """
182
+ # Only uvx.exe has the SIGINT issue, not uv.exe
183
+ uvx_names = {"uvx.exe", "uvx"}
184
+ return any(name in uvx_names for name in chain)
185
+
186
+
187
+ @lru_cache(maxsize=1)
188
+ def is_launched_via_uvx() -> bool:
189
+ """Detect if code-puppy was launched via uvx.
190
+
191
+ Traverses the parent process chain to find uvx.exe or uv.exe.
192
+ Result is cached for the lifetime of the process.
193
+
194
+ Returns:
195
+ True if launched via uvx, False otherwise
196
+ """
197
+ chain = _get_parent_process_chain()
198
+ return _is_uvx_in_chain(chain)
199
+
200
+
201
+ def is_windows() -> bool:
202
+ """Check if we're running on Windows.
203
+
204
+ Returns:
205
+ True if running on Windows, False otherwise
206
+ """
207
+ return platform.system() == "Windows"
208
+
209
+
210
+ def should_use_alternate_cancel_key() -> bool:
211
+ """Determine if we should use an alternate cancel key (Ctrl+K) instead of Ctrl+C.
212
+
213
+ This returns True when:
214
+ - Running on Windows AND
215
+ - Launched via uvx
216
+
217
+ In this scenario, Ctrl+C is captured by uvx before reaching Python,
218
+ so we need to use a different key (Ctrl+K) for agent cancellation.
219
+
220
+ Returns:
221
+ True if alternate cancel key should be used, False otherwise
222
+ """
223
+ return is_windows() and is_launched_via_uvx()
224
+
225
+
226
+ def get_uvx_detection_info() -> dict:
227
+ """Get diagnostic information about uvx detection.
228
+
229
+ Useful for debugging and testing.
230
+
231
+ Returns:
232
+ Dictionary with detection details
233
+ """
234
+ chain = _get_parent_process_chain()
235
+ return {
236
+ "is_windows": is_windows(),
237
+ "is_launched_via_uvx": is_launched_via_uvx(),
238
+ "should_use_alternate_cancel_key": should_use_alternate_cancel_key(),
239
+ "parent_process_chain": chain,
240
+ "current_pid": os.getpid(),
241
+ "python_executable": sys.executable,
242
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.332
3
+ Version: 0.0.334
4
4
  Summary: Code generation agent
5
5
  Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
6
6
  Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
@@ -3,12 +3,12 @@ code_puppy/__main__.py,sha256=pDVssJOWP8A83iFkxMLY9YteHYat0EyWDQqMkKHpWp4,203
3
3
  code_puppy/callbacks.py,sha256=hqTV--dNxG5vwWWm3MrEjmb8MZuHFFdmHePl23NXPHk,8621
4
4
  code_puppy/chatgpt_codex_client.py,sha256=Om0ANB_kpHubhCwNzF9ENf8RvKBqs0IYzBLl_SNw0Vk,9833
5
5
  code_puppy/claude_cache_client.py,sha256=hZr_YtXZSQvBoJFtRbbecKucYqJgoMopqUmm0IxFYGY,6071
6
- code_puppy/cli_runner.py,sha256=M3UlDgH4h8IPCfxwadElztGKhaNe47FNZJtxtcoVbBg,29875
7
- code_puppy/config.py,sha256=qqeJrQP7gqADqeYqVzfksP7NYGROLrBQCuYic5PuQfY,52295
6
+ code_puppy/cli_runner.py,sha256=_nbaVSsX5FfXEf0jSiVQ7cPUZ96JUFYV71bD668YfR4,32216
7
+ code_puppy/config.py,sha256=25HJ6ppNIPUWg5uHMIBrF2wY-lyqqaDVSpBfghFik3g,52297
8
8
  code_puppy/error_logging.py,sha256=a80OILCUtJhexI6a9GM-r5LqIdjvSRzggfgPp2jv1X0,3297
9
9
  code_puppy/gemini_code_assist.py,sha256=KGS7sO5OLc83nDF3xxS-QiU6vxW9vcm6hmzilu79Ef8,13867
10
10
  code_puppy/http_utils.py,sha256=w5mWYIGIWJZJvgvMahXs9BmdidoJvGn4CASDRY88a8o,13414
11
- code_puppy/keymap.py,sha256=Uzvq7HB-6inTjKox-90JWzuijztRdWqhJpfTDZVy5no,3235
11
+ code_puppy/keymap.py,sha256=IvMkTlB_bIqOWpbTpmftkdyjhtD5todXuEIw1zCZ4u0,3584
12
12
  code_puppy/main.py,sha256=82r3vZy_XcyEsenLn82BnUusaoyL3Bpm_Th_jKgqecE,273
13
13
  code_puppy/model_factory.py,sha256=H_a5nX462Q-dhX3g3ZY7dmBCIAUOd1aOSZa4HMxF1o4,34191
14
14
  code_puppy/model_utils.py,sha256=NU8W8NW5F7QS_PXHaLeh55Air1koUV7IVYFP7Rz3XpY,3615
@@ -21,7 +21,8 @@ code_puppy/round_robin_model.py,sha256=kSawwPUiPgg0yg8r4AAVgvjzsWkptxpSORd75-HP7
21
21
  code_puppy/session_storage.py,sha256=T4hOsAl9z0yz2JZCptjJBOnN8fCmkLZx5eLy1hTdv6Q,9631
22
22
  code_puppy/status_display.py,sha256=qHzIQGAPEa2_-4gQSg7_rE1ihOosBq8WO73MWFNmmlo,8938
23
23
  code_puppy/summarization_agent.py,sha256=6Pu_Wp_rF-HAhoX9u2uXTabRVkOZUYwRoMP1lzNS4ew,4485
24
- code_puppy/terminal_utils.py,sha256=P6ProVD_3nHW0zHNRIMWTcg8HvBk9e0ir5bhUgJpT5k,3921
24
+ code_puppy/terminal_utils.py,sha256=CxcNLfPwTDblI0AEtEwhfZ4DTfqqwHjM_A10QslaMBk,8220
25
+ code_puppy/uvx_detection.py,sha256=tP9X9Nvzow--KIqtqjgrHQkSxMJ3EevfoaeoB9VLY2o,7224
25
26
  code_puppy/version_checker.py,sha256=aq2Mwxl1CR9sEFBgrPt3OQOowLOBUp9VaQYWJhuUv8Q,1780
26
27
  code_puppy/agents/__init__.py,sha256=PtPB7Z5MSwmUKipgt_qxvIuGggcuVaYwNbnp1UP4tPc,518
27
28
  code_puppy/agents/agent_c_reviewer.py,sha256=1kO_89hcrhlS4sJ6elDLSEx-h43jAaWGgvIL0SZUuKo,8214
@@ -39,7 +40,7 @@ code_puppy/agents/agent_qa_expert.py,sha256=5Ikb4U3SZQknUEfwlHZiyZXKqnffnOTQagr_
39
40
  code_puppy/agents/agent_qa_kitten.py,sha256=5PeFFSwCFlTUvP6h5bGntx0xv5NmRwBiw0HnMqY8nLI,9107
40
41
  code_puppy/agents/agent_security_auditor.py,sha256=SpiYNA0XAsIwBj7S2_EQPRslRUmF_-b89pIJyW7DYtY,12022
41
42
  code_puppy/agents/agent_typescript_reviewer.py,sha256=vsnpp98xg6cIoFAEJrRTUM_i4wLEWGm5nJxs6fhHobM,10275
42
- code_puppy/agents/base_agent.py,sha256=32nNAGnBMUXLrI-5qTGpEWNEGW_gIN1ELQP1eH_lBCo,84509
43
+ code_puppy/agents/base_agent.py,sha256=r_znuUZJMv97Lh8zeSdS_KJzVGe7X3rAgBk3NZpIO7I,82855
43
44
  code_puppy/agents/json_agent.py,sha256=lhopDJDoiSGHvD8A6t50hi9ZBoNRKgUywfxd0Po_Dzc,4886
44
45
  code_puppy/agents/prompt_reviewer.py,sha256=JJrJ0m5q0Puxl8vFsyhAbY9ftU9n6c6UxEVdNct1E-Q,5558
45
46
  code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
@@ -49,8 +50,8 @@ code_puppy/command_line/autosave_menu.py,sha256=7w2SXfEfR-SGFZcHxM-QZfT0p42KxJjX
49
50
  code_puppy/command_line/colors_menu.py,sha256=F_OYuApwXWGP2w9o0CMEbIHtqwdKUh5eDhi7qtDP9h0,17144
50
51
  code_puppy/command_line/command_handler.py,sha256=CY9F27eovZJK_kpU1YmbroYLWGTCuouCOQ-TXfDp-nw,10916
51
52
  code_puppy/command_line/command_registry.py,sha256=qFySsw1g8dol3kgi0p6cXrIDlP11_OhOoaQ5nAadWXg,4416
52
- code_puppy/command_line/config_commands.py,sha256=5RG8oBaG52vBbZ2Nd5BnHszh_uwPit23AYmEckJRyTc,25764
53
- code_puppy/command_line/core_commands.py,sha256=qxIZ5tCAPkNDfDYjcG86h0tsi7RUQ4ueQ5C2BZ2H214,24809
53
+ code_puppy/command_line/config_commands.py,sha256=qS9Cm758DPz2QGvHLhAV4Tp_Xfgo3PyoCoLDusbnmCw,25742
54
+ code_puppy/command_line/core_commands.py,sha256=MhnyqcTIMheT8W1cqmfZTGLWo8iGM-fAAo8E3dNORro,26468
54
55
  code_puppy/command_line/diff_menu.py,sha256=6qolM8ECpXTAo2q0Yvqw8Oohsj3MLPxQI8PJvYuKGS4,24014
55
56
  code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
56
57
  code_puppy/command_line/load_context_completion.py,sha256=a3JvLDeLLSYxVgTjAdqWzS4spjv6ccCrK2LKZgVJ1IM,2202
@@ -58,6 +59,8 @@ code_puppy/command_line/mcp_completion.py,sha256=eKzW2O7gun7HoHekOW0XVXhNS5J2xCt
58
59
  code_puppy/command_line/model_picker_completion.py,sha256=nDnlf0qFCG2zAm_mWW2eMYwVC7eROVQrFe92hZqOKa8,6810
59
60
  code_puppy/command_line/model_settings_menu.py,sha256=O5nPp_OyShFcXzpSmsCeYsnnVNrSwcTBFY9bzcayvj0,32263
60
61
  code_puppy/command_line/motd.py,sha256=OoNxwewsckexSgJ5H5y40IawP-TzqlqY-rqFUdRbIhs,2186
62
+ code_puppy/command_line/onboarding_slides.py,sha256=EdssKWx_hT3mneeMEL4QXTLiUxdm-ZXfb6QJOSFtBbE,17066
63
+ code_puppy/command_line/onboarding_wizard.py,sha256=hoMvSb3zvHGSScaCqPMaXSjSAvfX_OMUz7Hu68wP2qE,13134
61
64
  code_puppy/command_line/pin_command_completion.py,sha256=juSvdqRpk7AdfkPy1DJx5NzfEUU5KYGlChvP0hisM18,11667
62
65
  code_puppy/command_line/prompt_toolkit_completion.py,sha256=x4Of32g8oH9ckhx-P6BigV7HUUhhjL8xkvK03uq9HRw,27308
63
66
  code_puppy/command_line/session_commands.py,sha256=Jh8GGfhlfBAEVfucKLbcZjNaXYd0twImiOwq2ZnGdQQ,9902
@@ -121,14 +124,14 @@ code_puppy/plugins/oauth_puppy_html.py,sha256=Wpa-V_NlRiBAvo_OXHuR7wvOH_jSt8L9HS
121
124
  code_puppy/plugins/chatgpt_oauth/__init__.py,sha256=Kjc6Hsz1sWvMD2OdAlWZvJRiKJSj4fx22boa-aVFKjA,189
122
125
  code_puppy/plugins/chatgpt_oauth/config.py,sha256=H_wAH9Duyn8WH2Kq8oe72uda-_4qu1uXLPun_SDdtsk,2023
123
126
  code_puppy/plugins/chatgpt_oauth/oauth_flow.py,sha256=i-CP2gpzEBT3ogUt-oTMexiP2on41N6PbRGIy2lZF30,11028
124
- code_puppy/plugins/chatgpt_oauth/register_callbacks.py,sha256=-JB1isODQ7v2Kn2alnSIg3mPjqnC-wTfsMO_G12V7iU,2872
127
+ code_puppy/plugins/chatgpt_oauth/register_callbacks.py,sha256=oPfAOdh5hp3Jg3tK5ylk1sy0ydxBebK9a9w1EL1dw9I,2965
125
128
  code_puppy/plugins/chatgpt_oauth/test_plugin.py,sha256=oHX7Eb_Hb4rgRpOWdhtFp8Jj6_FDuvXQITRPiNy4tRo,9622
126
129
  code_puppy/plugins/chatgpt_oauth/utils.py,sha256=fzpsCQOv0kqPWmG5vNEV_GLSUrMQh8cF7tdIjSOt1Dc,16504
127
130
  code_puppy/plugins/claude_code_oauth/README.md,sha256=76nHhMlhk61DZa5g0Q2fc0AtpplLmpbwuWFZt7PHH5g,5458
128
131
  code_puppy/plugins/claude_code_oauth/SETUP.md,sha256=lnGzofPLogBy3oPPFLv5_cZ7vjg_GYrIyYnF-EoTJKg,3278
129
132
  code_puppy/plugins/claude_code_oauth/__init__.py,sha256=mCcOU-wM7LNCDjr-w-WLPzom8nTF1UNt4nqxGE6Rt0k,187
130
133
  code_puppy/plugins/claude_code_oauth/config.py,sha256=DjGySCkvjSGZds6DYErLMAi3TItt8iSLGvyJN98nSEM,2013
131
- code_puppy/plugins/claude_code_oauth/register_callbacks.py,sha256=0NeX1hhkYIlVfPmjZ1xmcf1yueDAJh_FMUmvJlxSO-E,10057
134
+ code_puppy/plugins/claude_code_oauth/register_callbacks.py,sha256=g8sl-i7jIOF6OFALeaLqTF3mS4tD8GR_FCzvPjVw2js,10165
132
135
  code_puppy/plugins/claude_code_oauth/test_plugin.py,sha256=yQy4EeZl4bjrcog1d8BjknoDTRK75mRXXvkSQJYSSEM,9286
133
136
  code_puppy/plugins/claude_code_oauth/utils.py,sha256=wDaOU21zB3y6PWkuMXwE4mFjQuffyDae-vXysPTS-w8,13438
134
137
  code_puppy/plugins/customizable_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -144,7 +147,7 @@ code_puppy/plugins/shell_safety/register_callbacks.py,sha256=W3v664RR48Fdbbbltf_
144
147
  code_puppy/prompts/codex_system_prompt.md,sha256=hEFTCziroLqZmqNle5kG34A8kvTteOWezCiVrAEKhE0,24400
145
148
  code_puppy/tools/__init__.py,sha256=BVTZ85jLHgDANwOnUSOz3UDlp8VQDq4DoGF23BRlyWw,6032
146
149
  code_puppy/tools/agent_tools.py,sha256=snBI6FlFtR03CbYKXwu53R48c_fRSuDIwcNdVUruLcA,21020
147
- code_puppy/tools/command_runner.py,sha256=miofNbQ0B62B_iaBpa4ZiifaUk-kgGWWGHWOW-CRzaA,47524
150
+ code_puppy/tools/command_runner.py,sha256=WLesijwbXEsnyuIJvWZHbVVyoUAPQcTWJbz31pXPSi0,44325
148
151
  code_puppy/tools/common.py,sha256=IboS6sbwN4a3FzHdfsZJtEFiyDUCszevI6LpH14ydEk,40561
149
152
  code_puppy/tools/file_modifications.py,sha256=vz9n7R0AGDSdLUArZr_55yJLkyI30M8zreAppxIx02M,29380
150
153
  code_puppy/tools/file_operations.py,sha256=CqhpuBnOFOcQCIYXOujskxq2VMLWYJhibYrH0YcPSfA,35692
@@ -159,10 +162,10 @@ code_puppy/tools/browser/browser_scripts.py,sha256=sNb8eLEyzhasy5hV4B9OjM8yIVMLV
159
162
  code_puppy/tools/browser/browser_workflows.py,sha256=nitW42vCf0ieTX1gLabozTugNQ8phtoFzZbiAhw1V90,6491
160
163
  code_puppy/tools/browser/camoufox_manager.py,sha256=RZjGOEftE5sI_tsercUyXFSZI2wpStXf-q0PdYh2G3I,8680
161
164
  code_puppy/tools/browser/vqa_agent.py,sha256=DBn9HKloILqJSTSdNZzH_PYWT0B2h9VwmY6akFQI_uU,2913
162
- code_puppy-0.0.332.data/data/code_puppy/models.json,sha256=IPABdOrDw2OZJxa0XGBWSWmBRerV6_pIEmKVLRtUbAk,3105
163
- code_puppy-0.0.332.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
164
- code_puppy-0.0.332.dist-info/METADATA,sha256=_5P2HAkEUyhzQqQu0AxUJpB8Nn9-8tD4KtbB3m2Ei_4,28854
165
- code_puppy-0.0.332.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
166
- code_puppy-0.0.332.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
167
- code_puppy-0.0.332.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
168
- code_puppy-0.0.332.dist-info/RECORD,,
165
+ code_puppy-0.0.334.data/data/code_puppy/models.json,sha256=IPABdOrDw2OZJxa0XGBWSWmBRerV6_pIEmKVLRtUbAk,3105
166
+ code_puppy-0.0.334.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
167
+ code_puppy-0.0.334.dist-info/METADATA,sha256=DhyliNW_DINXn1BNLHXz80YoI7JrvOltgzhFP4LA77I,28854
168
+ code_puppy-0.0.334.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
169
+ code_puppy-0.0.334.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
170
+ code_puppy-0.0.334.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
171
+ code_puppy-0.0.334.dist-info/RECORD,,