code-puppy 0.0.336__py3-none-any.whl → 0.0.341__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.
@@ -21,6 +21,8 @@ from .config import (
21
21
  get_token_storage_path,
22
22
  )
23
23
 
24
+ TOKEN_REFRESH_BUFFER_SECONDS = 60
25
+
24
26
  logger = logging.getLogger(__name__)
25
27
 
26
28
 
@@ -132,6 +134,124 @@ def load_stored_tokens() -> Optional[Dict[str, Any]]:
132
134
  return None
133
135
 
134
136
 
137
+ def _calculate_expires_at(expires_in: Optional[float]) -> Optional[float]:
138
+ if expires_in is None:
139
+ return None
140
+ try:
141
+ return time.time() + float(expires_in)
142
+ except (TypeError, ValueError):
143
+ return None
144
+
145
+
146
+ def is_token_expired(tokens: Dict[str, Any]) -> bool:
147
+ expires_at = tokens.get("expires_at")
148
+ if expires_at is None:
149
+ return False
150
+ try:
151
+ expires_at_value = float(expires_at)
152
+ except (TypeError, ValueError):
153
+ return False
154
+ return time.time() >= expires_at_value - TOKEN_REFRESH_BUFFER_SECONDS
155
+
156
+
157
+ def update_claude_code_model_tokens(access_token: str) -> bool:
158
+ try:
159
+ claude_models = load_claude_models()
160
+ if not claude_models:
161
+ return False
162
+
163
+ updated = False
164
+ for config in claude_models.values():
165
+ if config.get("oauth_source") != "claude-code-plugin":
166
+ continue
167
+ custom_endpoint = config.get("custom_endpoint")
168
+ if not isinstance(custom_endpoint, dict):
169
+ continue
170
+ custom_endpoint["api_key"] = access_token
171
+ updated = True
172
+
173
+ if updated:
174
+ return save_claude_models(claude_models)
175
+ except Exception as exc: # pragma: no cover - defensive logging
176
+ logger.error("Failed to update Claude model tokens: %s", exc)
177
+ return False
178
+
179
+
180
+ def refresh_access_token(force: bool = False) -> Optional[str]:
181
+ tokens = load_stored_tokens()
182
+ if not tokens:
183
+ return None
184
+
185
+ if not force and not is_token_expired(tokens):
186
+ return tokens.get("access_token")
187
+
188
+ refresh_token = tokens.get("refresh_token")
189
+ if not refresh_token:
190
+ logger.debug("No refresh_token available")
191
+ return None
192
+
193
+ payload = {
194
+ "grant_type": "refresh_token",
195
+ "client_id": CLAUDE_CODE_OAUTH_CONFIG["client_id"],
196
+ "refresh_token": refresh_token,
197
+ }
198
+
199
+ headers = {
200
+ "Content-Type": "application/json",
201
+ "Accept": "application/json",
202
+ "anthropic-beta": "oauth-2025-04-20",
203
+ }
204
+
205
+ try:
206
+ response = requests.post(
207
+ CLAUDE_CODE_OAUTH_CONFIG["token_url"],
208
+ json=payload,
209
+ headers=headers,
210
+ timeout=30,
211
+ )
212
+ if response.status_code == 200:
213
+ new_tokens = response.json()
214
+ tokens["access_token"] = new_tokens.get("access_token")
215
+ tokens["refresh_token"] = new_tokens.get("refresh_token", refresh_token)
216
+ if "expires_in" in new_tokens:
217
+ tokens["expires_in"] = new_tokens["expires_in"]
218
+ tokens["expires_at"] = _calculate_expires_at(
219
+ new_tokens.get("expires_in")
220
+ )
221
+ if save_tokens(tokens):
222
+ update_claude_code_model_tokens(tokens["access_token"])
223
+ return tokens["access_token"]
224
+ else:
225
+ logger.error(
226
+ "Token refresh failed: %s - %s", response.status_code, response.text
227
+ )
228
+ except Exception as exc: # pragma: no cover - defensive logging
229
+ logger.error("Token refresh error: %s", exc)
230
+ return None
231
+
232
+
233
+ def get_valid_access_token() -> Optional[str]:
234
+ tokens = load_stored_tokens()
235
+ if not tokens:
236
+ logger.debug("No stored Claude Code OAuth tokens found")
237
+ return None
238
+
239
+ access_token = tokens.get("access_token")
240
+ if not access_token:
241
+ logger.debug("No access_token in stored tokens")
242
+ return None
243
+
244
+ if is_token_expired(tokens):
245
+ logger.info("Claude Code OAuth token expired, attempting refresh")
246
+ refreshed = refresh_access_token()
247
+ if refreshed:
248
+ return refreshed
249
+ logger.warning("Claude Code token refresh failed")
250
+ return None
251
+
252
+ return access_token
253
+
254
+
135
255
  def save_tokens(tokens: Dict[str, Any]) -> bool:
136
256
  try:
137
257
  token_path = get_token_storage_path()
@@ -243,7 +363,11 @@ def exchange_code_for_tokens(
243
363
  logger.info("Token exchange response: %s", response.status_code)
244
364
  logger.debug("Response body: %s", response.text)
245
365
  if response.status_code == 200:
246
- return response.json()
366
+ token_data = response.json()
367
+ token_data["expires_at"] = _calculate_expires_at(
368
+ token_data.get("expires_in")
369
+ )
370
+ return token_data
247
371
  logger.error(
248
372
  "Token exchange failed: %s - %s",
249
373
  response.status_code,
@@ -341,12 +465,7 @@ def add_models_to_extra_config(models: List[str]) -> bool:
341
465
  # Start fresh - overwrite the file on every auth instead of loading existing
342
466
  claude_models = {}
343
467
  added = 0
344
- tokens = load_stored_tokens()
345
-
346
- # Handle case where tokens are None or empty
347
- access_token = ""
348
- if tokens and "access_token" in tokens:
349
- access_token = tokens["access_token"]
468
+ access_token = get_valid_access_token() or ""
350
469
 
351
470
  for model_name in filtered_models:
352
471
  prefixed = f"{CLAUDE_CODE_OAUTH_CONFIG['prefix']}{model_name}"
@@ -3,10 +3,14 @@
3
3
  Handles Windows console mode resets and Unix terminal sanity restoration.
4
4
  """
5
5
 
6
+ import os
6
7
  import platform
7
8
  import subprocess
8
9
  import sys
9
- from typing import Callable, Optional
10
+ from typing import TYPE_CHECKING, Callable, Optional
11
+
12
+ if TYPE_CHECKING:
13
+ from rich.console import Console
10
14
 
11
15
  # Store the original console ctrl handler so we can restore it if needed
12
16
  _original_ctrl_handler: Optional[Callable] = None
@@ -289,3 +293,126 @@ def ensure_ctrl_c_disabled() -> bool:
289
293
 
290
294
  except Exception:
291
295
  return False
296
+
297
+
298
+ def detect_truecolor_support() -> bool:
299
+ """Detect if the terminal supports truecolor (24-bit color).
300
+
301
+ Checks multiple indicators:
302
+ 1. COLORTERM environment variable (most reliable)
303
+ 2. TERM environment variable patterns
304
+ 3. Rich's Console color_system detection as fallback
305
+
306
+ Returns:
307
+ True if truecolor is supported, False otherwise.
308
+ """
309
+ # Check COLORTERM - this is the most reliable indicator
310
+ colorterm = os.environ.get("COLORTERM", "").lower()
311
+ if colorterm in ("truecolor", "24bit"):
312
+ return True
313
+
314
+ # Check TERM for known truecolor-capable terminals
315
+ term = os.environ.get("TERM", "").lower()
316
+ truecolor_terms = (
317
+ "xterm-direct",
318
+ "xterm-truecolor",
319
+ "iterm2",
320
+ "vte-256color", # Many modern terminals set this
321
+ )
322
+ if any(t in term for t in truecolor_terms):
323
+ return True
324
+
325
+ # Some terminals like iTerm2, Kitty, Alacritty set specific env vars
326
+ if os.environ.get("ITERM_SESSION_ID"):
327
+ return True
328
+ if os.environ.get("KITTY_WINDOW_ID"):
329
+ return True
330
+ if os.environ.get("ALACRITTY_SOCKET"):
331
+ return True
332
+ if os.environ.get("WT_SESSION"): # Windows Terminal
333
+ return True
334
+
335
+ # Use Rich's detection as a fallback
336
+ try:
337
+ from rich.console import Console
338
+
339
+ console = Console(force_terminal=True)
340
+ color_system = console.color_system
341
+ return color_system == "truecolor"
342
+ except Exception:
343
+ pass
344
+
345
+ return False
346
+
347
+
348
+ def print_truecolor_warning(console: Optional["Console"] = None) -> None:
349
+ """Print a big fat red warning if truecolor is not supported.
350
+
351
+ Args:
352
+ console: Optional Rich Console instance. If None, creates a new one.
353
+ """
354
+ if detect_truecolor_support():
355
+ return # All good, no warning needed
356
+
357
+ if console is None:
358
+ try:
359
+ from rich.console import Console
360
+
361
+ console = Console()
362
+ except ImportError:
363
+ # Rich not available, fall back to plain print
364
+ print("\n" + "=" * 70)
365
+ print("⚠️ WARNING: TERMINAL DOES NOT SUPPORT TRUECOLOR (24-BIT COLOR)")
366
+ print("=" * 70)
367
+ print("Code Puppy looks best with truecolor support.")
368
+ print("Consider using a modern terminal like:")
369
+ print(" • iTerm2 (macOS)")
370
+ print(" • Windows Terminal (Windows)")
371
+ print(" • Kitty, Alacritty, or any modern terminal emulator")
372
+ print("")
373
+ print("You can also try setting: export COLORTERM=truecolor")
374
+ print("")
375
+ print("Note: The built-in macOS Terminal.app does not support truecolor")
376
+ print("(Sequoia and earlier). You'll need a different terminal app.")
377
+ print("=" * 70 + "\n")
378
+ return
379
+
380
+ # Get detected color system for diagnostic info
381
+ color_system = console.color_system or "unknown"
382
+
383
+ # Build the warning box
384
+ warning_lines = [
385
+ "",
386
+ "[bold bright_red on red]" + "━" * 72 + "[/]",
387
+ "[bold bright_red on red]┃[/][bold bright_white on red]"
388
+ + " " * 70
389
+ + "[/][bold bright_red on red]┃[/]",
390
+ "[bold bright_red on red]┃[/][bold bright_white on red] ⚠️ WARNING: TERMINAL DOES NOT SUPPORT TRUECOLOR (24-BIT COLOR) ⚠️ [/][bold bright_red on red]┃[/]",
391
+ "[bold bright_red on red]┃[/][bold bright_white on red]"
392
+ + " " * 70
393
+ + "[/][bold bright_red on red]┃[/]",
394
+ "[bold bright_red on red]" + "━" * 72 + "[/]",
395
+ "",
396
+ f"[yellow]Detected color system:[/] [bold]{color_system}[/]",
397
+ "",
398
+ "[bold white]Code Puppy uses rich colors and will look degraded without truecolor.[/]",
399
+ "",
400
+ "[cyan]Consider using a modern terminal emulator:[/]",
401
+ " [green]•[/] [bold]iTerm2[/] (macOS) - https://iterm2.com",
402
+ " [green]•[/] [bold]Windows Terminal[/] (Windows) - Built into Windows 11",
403
+ " [green]•[/] [bold]Kitty[/] - https://sw.kovidgoyal.net/kitty",
404
+ " [green]•[/] [bold]Alacritty[/] - https://alacritty.org",
405
+ " [green]•[/] [bold]Warp[/] (macOS) - https://warp.dev",
406
+ "",
407
+ "[cyan]Or try setting the COLORTERM environment variable:[/]",
408
+ " [dim]export COLORTERM=truecolor[/]",
409
+ "",
410
+ "[dim italic]Note: The built-in macOS Terminal.app does not support truecolor (Sequoia and earlier).[/]",
411
+ "[dim italic]Setting COLORTERM=truecolor won't help - you'll need a different terminal app.[/]",
412
+ "",
413
+ "[bold bright_red]" + "─" * 72 + "[/]",
414
+ "",
415
+ ]
416
+
417
+ for line in warning_lines:
418
+ console.print(line)
@@ -880,6 +880,7 @@ async def run_shell_command(
880
880
  command=command,
881
881
  cwd=cwd,
882
882
  timeout=0, # No timeout for background processes
883
+ background=True,
883
884
  )
884
885
  )
885
886
 
@@ -727,15 +727,9 @@ def _format_diff_with_syntax_highlighting(
727
727
  result.append("\n")
728
728
  continue
729
729
 
730
- # Handle diff headers specially
731
- if line.startswith("---"):
732
- result.append(line, style="yellow")
733
- elif line.startswith("+++"):
734
- result.append(line, style="yellow")
735
- elif line.startswith("@@"):
736
- result.append(line, style="cyan")
737
- elif line.startswith(("diff ", "index ")):
738
- result.append(line, style="dim")
730
+ # Skip diff headers - they're redundant noise since we show the filename in the banner
731
+ if line.startswith(("---", "+++", "@@", "diff ", "index ")):
732
+ continue
739
733
  else:
740
734
  # Determine line type and extract code content
741
735
  if line.startswith("-"):
@@ -55,9 +55,9 @@
55
55
  "supported_settings": ["reasoning_effort", "verbosity"],
56
56
  "supports_xhigh_reasoning": true
57
57
  },
58
- "Cerebras-GLM-4.6": {
58
+ "Cerebras-GLM-4.7": {
59
59
  "type": "cerebras",
60
- "name": "zai-glm-4.6",
60
+ "name": "zai-glm-4.7",
61
61
  "custom_endpoint": {
62
62
  "url": "https://api.cerebras.ai/v1",
63
63
  "api_key": "$CEREBRAS_API_KEY"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.336
3
+ Version: 0.0.341
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
@@ -22,6 +22,7 @@ Requires-Dist: httpx[http2]>=0.24.1
22
22
  Requires-Dist: json-repair>=0.46.2
23
23
  Requires-Dist: logfire>=0.7.1
24
24
  Requires-Dist: openai>=1.99.1
25
+ Requires-Dist: pillow>=10.0.0
25
26
  Requires-Dist: playwright>=1.40.0
26
27
  Requires-Dist: prompt-toolkit>=3.0.52
27
28
  Requires-Dist: pydantic-ai==1.25.0
@@ -34,6 +35,7 @@ Requires-Dist: rich>=13.4.2
34
35
  Requires-Dist: ripgrep==14.1.0
35
36
  Requires-Dist: ruff>=0.11.11
36
37
  Requires-Dist: tenacity>=8.2.0
38
+ Requires-Dist: termflow-md>=0.1.6
37
39
  Requires-Dist: uvicorn>=0.30.0
38
40
  Description-Content-Type: text/markdown
39
41
 
@@ -106,12 +108,7 @@ uvx code-puppy -i
106
108
  # Install UV if you don't have it
107
109
  curl -LsSf https://astral.sh/uv/install.sh | sh
108
110
 
109
- # Set UV to always use managed Python (one-time setup)
110
- echo 'export UV_MANAGED_PYTHON=1' >> ~/.zshrc # or ~/.bashrc
111
- source ~/.zshrc # or ~/.bashrc
112
-
113
- # Install and run code-puppy
114
- uvx code-puppy -i
111
+ uvx code-puppy
115
112
  ```
116
113
 
117
114
  #### Windows
@@ -122,73 +119,15 @@ On Windows, we recommend installing code-puppy as a global tool for the best exp
122
119
  # Install UV if you don't have it (run in PowerShell as Admin)
123
120
  powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
124
121
 
125
- # Install code-puppy as a global tool
126
- uv tool install code-puppy
127
-
128
- # Run code-puppy
129
- code-puppy -i
130
- ```
131
-
132
- **Why `uv tool install` on Windows?** Running with `uvx` creates an extra process layer that can interfere with keyboard signal handling (Ctrl+C, Ctrl+X). Installing as a tool runs code-puppy directly for reliable cancellation.
133
-
134
- #### Upgrading
135
-
136
- ```bash
137
- # Upgrade code-puppy to the latest version
138
- uv tool upgrade code-puppy
139
-
140
- # Or upgrade all installed tools
141
- uv tool upgrade --all
142
- ```
143
-
144
- UV will automatically download the latest compatible Python version (3.11+) if your system doesn't have one.
145
-
146
- ### pip (Alternative)
147
-
148
- ```bash
149
- pip install code-puppy
122
+ uvx code-puppy
150
123
  ```
151
124
 
152
- *Note: pip installation requires your system Python to be 3.11 or newer.*
153
-
154
- ### Permanent Python Management
155
-
156
- To make UV always use managed Python versions (recommended):
157
-
158
- ```bash
159
- # Set environment variable permanently
160
- echo 'export UV_MANAGED_PYTHON=1' >> ~/.zshrc # or ~/.bashrc
161
- source ~/.zshrc # or ~/.bashrc
162
-
163
- # Now all UV commands will prefer managed Python installations
164
- uvx code-puppy # No need for --managed-python flag anymore
165
- ```
125
+ ## Changelog (By Kittylog!)
166
126
 
167
- ### Verifying Python Version
168
-
169
- ```bash
170
- # Check which Python UV will use
171
- uv python find
172
-
173
- # Or check the current project's Python
174
- uv run python --version
175
- ```
127
+ [📋 View the full changelog on Kittylog](https://kittylog.app/c/mpfaffenberger/code_puppy)
176
128
 
177
129
  ## Usage
178
130
 
179
- ### Custom Commands
180
- Create markdown files in `.claude/commands/`, `.github/prompts/`, or `.agents/commands/` to define custom slash commands. The filename becomes the command name and the content runs as a prompt.
181
-
182
- ```bash
183
- # Create a custom command
184
- echo "# Code Review
185
-
186
- Please review this code for security issues." > .claude/commands/review.md
187
-
188
- # Use it in Code Puppy
189
- /review with focus on authentication
190
- ```
191
-
192
131
  ### Adding Models from models.dev 🆕
193
132
 
194
133
  While there are several models configured right out of the box from providers like Synthetic, Cerebras, OpenAI, Google, and Anthropic, Code Puppy integrates with [models.dev](https://models.dev) to let you browse and add models from **65+ providers** with a single command:
@@ -256,6 +195,18 @@ The following environment variables control DBOS behavior:
256
195
  - `DBOS_SYSTEM_DATABASE_URL`: Database URL used by DBOS. Can point to a local SQLite file or a Postgres instance. Example: `postgresql://postgres:dbos@localhost:5432/postgres`. Default: `dbos_store.sqlite` file in the config directory.
257
196
  - `DBOS_APP_VERSION`: If set, Code Puppy uses it as the [DBOS application version](https://docs.dbos.dev/architecture#application-and-workflow-versions) and automatically tries to recover pending workflows for this version. Default: Code Puppy version + Unix timestamp in millisecond (disable automatic recovery).
258
197
 
198
+ ### Custom Commands
199
+ Create markdown files in `.claude/commands/`, `.github/prompts/`, or `.agents/commands/` to define custom slash commands. The filename becomes the command name and the content runs as a prompt.
200
+
201
+ ```bash
202
+ # Create a custom command
203
+ echo "# Code Review
204
+
205
+ Please review this code for security issues." > .claude/commands/review.md
206
+
207
+ # Use it in Code Puppy
208
+ /review with focus on authentication
209
+ ```
259
210
 
260
211
  ## Requirements
261
212
 
@@ -275,9 +226,6 @@ For examples and more information about agent rules, visit [https://agent.md](ht
275
226
 
276
227
  Use the `/mcp` command to manage MCP (list, start, stop, status, etc.)
277
228
 
278
- Watch this video for examples! https://www.youtube.com/watch?v=1t1zEetOqlo
279
-
280
-
281
229
  ## Round Robin Model Distribution
282
230
 
283
231
  Code Puppy supports **Round Robin model distribution** to help you overcome rate limits and distribute load across multiple AI models. This feature automatically cycles through configured models with each request, maximizing your API usage while staying within rate limits.
@@ -2,17 +2,17 @@ code_puppy/__init__.py,sha256=xMPewo9RNHb3yfFNIk5WCbv2cvSPtJOCgK2-GqLbNnU,373
2
2
  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
- code_puppy/claude_cache_client.py,sha256=hZr_YtXZSQvBoJFtRbbecKucYqJgoMopqUmm0IxFYGY,6071
6
- code_puppy/cli_runner.py,sha256=4iosJ_zXv9WcG4764yFW-VOLjE3B7Og9yclp6Q4kaSQ,33875
5
+ code_puppy/claude_cache_client.py,sha256=MLIRSJP428r9IK_aV6XyCXrCfQnNti32U60psPymLM4,14860
6
+ code_puppy/cli_runner.py,sha256=BQu5Sa9y_ueqtgvbmuhWS-Tmd1FAjMbhTrtjFKbVZjM,34919
7
7
  code_puppy/config.py,sha256=RlnrLkyFXm7h2Htf8rQA7vqoAyzLPMrESle417uLmFw,52373
8
8
  code_puppy/error_logging.py,sha256=a80OILCUtJhexI6a9GM-r5LqIdjvSRzggfgPp2jv1X0,3297
9
9
  code_puppy/gemini_code_assist.py,sha256=KGS7sO5OLc83nDF3xxS-QiU6vxW9vcm6hmzilu79Ef8,13867
10
- code_puppy/http_utils.py,sha256=BV_bf0i5iPh7HC7T1vlsbz3hvlVwdIzwpS2pfBBKPRo,11823
10
+ code_puppy/http_utils.py,sha256=H3N5Qz2B1CcsGUYOycGWAqoNMr2P1NCVluKX3aRwRqI,10358
11
11
  code_puppy/keymap.py,sha256=IvMkTlB_bIqOWpbTpmftkdyjhtD5todXuEIw1zCZ4u0,3584
12
12
  code_puppy/main.py,sha256=82r3vZy_XcyEsenLn82BnUusaoyL3Bpm_Th_jKgqecE,273
13
- code_puppy/model_factory.py,sha256=Djhp_ukLTMNi8UdZsodhIU6D2X4DmJXnjZy_bzfce3k,37517
13
+ code_puppy/model_factory.py,sha256=BSGHZlwtF7jkYz2qFG9oJglG-NnfmbsQXbx4I6stXW0,38313
14
14
  code_puppy/model_utils.py,sha256=NU8W8NW5F7QS_PXHaLeh55Air1koUV7IVYFP7Rz3XpY,3615
15
- code_puppy/models.json,sha256=IPABdOrDw2OZJxa0XGBWSWmBRerV6_pIEmKVLRtUbAk,3105
15
+ code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
16
16
  code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
17
17
  code_puppy/models_dev_parser.py,sha256=8ndmWrsSyKbXXpRZPXc0w6TfWMuCcgaHiMifmlaBaPc,20611
18
18
  code_puppy/pydantic_patches.py,sha256=YecAEeCOjSIwIBu2O5vEw72atMSL37cXGrbEuukI07o,4582
@@ -21,7 +21,7 @@ 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=CxcNLfPwTDblI0AEtEwhfZ4DTfqqwHjM_A10QslaMBk,8220
24
+ code_puppy/terminal_utils.py,sha256=TaS19x7EZqudlBUAQwLMzBMNxBHBNInvQQREXqRGtkM,12984
25
25
  code_puppy/uvx_detection.py,sha256=tP9X9Nvzow--KIqtqjgrHQkSxMJ3EevfoaeoB9VLY2o,7224
26
26
  code_puppy/version_checker.py,sha256=aq2Mwxl1CR9sEFBgrPt3OQOowLOBUp9VaQYWJhuUv8Q,1780
27
27
  code_puppy/agents/__init__.py,sha256=PtPB7Z5MSwmUKipgt_qxvIuGggcuVaYwNbnp1UP4tPc,518
@@ -40,18 +40,19 @@ code_puppy/agents/agent_qa_expert.py,sha256=5Ikb4U3SZQknUEfwlHZiyZXKqnffnOTQagr_
40
40
  code_puppy/agents/agent_qa_kitten.py,sha256=5PeFFSwCFlTUvP6h5bGntx0xv5NmRwBiw0HnMqY8nLI,9107
41
41
  code_puppy/agents/agent_security_auditor.py,sha256=SpiYNA0XAsIwBj7S2_EQPRslRUmF_-b89pIJyW7DYtY,12022
42
42
  code_puppy/agents/agent_typescript_reviewer.py,sha256=vsnpp98xg6cIoFAEJrRTUM_i4wLEWGm5nJxs6fhHobM,10275
43
- code_puppy/agents/base_agent.py,sha256=r_znuUZJMv97Lh8zeSdS_KJzVGe7X3rAgBk3NZpIO7I,82855
43
+ code_puppy/agents/base_agent.py,sha256=QnPmROIw-rs5wopcVTZdBZusP0mGRC6EFZ7y_V00rMI,84825
44
44
  code_puppy/agents/json_agent.py,sha256=lhopDJDoiSGHvD8A6t50hi9ZBoNRKgUywfxd0Po_Dzc,4886
45
45
  code_puppy/agents/prompt_reviewer.py,sha256=JJrJ0m5q0Puxl8vFsyhAbY9ftU9n6c6UxEVdNct1E-Q,5558
46
46
  code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
47
47
  code_puppy/command_line/add_model_menu.py,sha256=caXxSQc6dgx0qQ68RRFrDTsiH-wZjl4nUv2r0javhaM,43262
48
48
  code_puppy/command_line/attachments.py,sha256=4Q5I2Es4j0ltnz5wjw2z0QXMsiMJvEfWRkPf_lJeITM,13093
49
- code_puppy/command_line/autosave_menu.py,sha256=vW-2UqX8qT2Rb07ZSbsCG1MMwCPIH4MQ4YM9PEkcPyo,20105
49
+ code_puppy/command_line/autosave_menu.py,sha256=de7nOmFmEH6x5T7C95U8N8xgxxeF-l5lgaJzGJsF3ZY,19824
50
+ code_puppy/command_line/clipboard.py,sha256=oe9bfAX5RnT81FiYrDmhvHaePS1tAT-NFG1fSXubSD4,16869
50
51
  code_puppy/command_line/colors_menu.py,sha256=LoFVfJ-Mo-Eq9hnb2Rj5mn7oBCnadAGr-8NNHsHlu18,17273
51
52
  code_puppy/command_line/command_handler.py,sha256=CY9F27eovZJK_kpU1YmbroYLWGTCuouCOQ-TXfDp-nw,10916
52
53
  code_puppy/command_line/command_registry.py,sha256=qFySsw1g8dol3kgi0p6cXrIDlP11_OhOoaQ5nAadWXg,4416
53
54
  code_puppy/command_line/config_commands.py,sha256=qS9Cm758DPz2QGvHLhAV4Tp_Xfgo3PyoCoLDusbnmCw,25742
54
- code_puppy/command_line/core_commands.py,sha256=MhnyqcTIMheT8W1cqmfZTGLWo8iGM-fAAo8E3dNORro,26468
55
+ code_puppy/command_line/core_commands.py,sha256=ujAPD4yDbXwYGJJfR2u4ei24eBV-Ps_-BVBjFMEoJy0,27668
55
56
  code_puppy/command_line/diff_menu.py,sha256=_Gr9SP9fbItk-08dya9WTAR53s_PlyAvEnbt-8VWKPk,24141
56
57
  code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
57
58
  code_puppy/command_line/load_context_completion.py,sha256=a3JvLDeLLSYxVgTjAdqWzS4spjv6ccCrK2LKZgVJ1IM,2202
@@ -62,7 +63,7 @@ code_puppy/command_line/motd.py,sha256=XuIk3UTLawwVFM-NfoaJGU5F2hPLASTFXq84UdDMT
62
63
  code_puppy/command_line/onboarding_slides.py,sha256=tHob7rB_n32dfjtPH-RSG0WLMjDHhlmNxfsF7WCgcVc,7191
63
64
  code_puppy/command_line/onboarding_wizard.py,sha256=U5lV_1P3IwDYZUHar0zKgdp121zzkvOwwORvdCZwFcw,10241
64
65
  code_puppy/command_line/pin_command_completion.py,sha256=juSvdqRpk7AdfkPy1DJx5NzfEUU5KYGlChvP0hisM18,11667
65
- code_puppy/command_line/prompt_toolkit_completion.py,sha256=x4Of32g8oH9ckhx-P6BigV7HUUhhjL8xkvK03uq9HRw,27308
66
+ code_puppy/command_line/prompt_toolkit_completion.py,sha256=U6rRMU3gNqTf3vz3K5V5PZ1xjE8I2ldoEk2FiT8kHJg,32535
66
67
  code_puppy/command_line/session_commands.py,sha256=Jh8GGfhlfBAEVfucKLbcZjNaXYd0twImiOwq2ZnGdQQ,9902
67
68
  code_puppy/command_line/utils.py,sha256=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
68
69
  code_puppy/command_line/mcp/__init__.py,sha256=0-OQuwjq_pLiTVJ1_NrirVwdRerghyKs_MTZkwPC7YY,315
@@ -98,7 +99,7 @@ code_puppy/mcp_/config_wizard.py,sha256=JNNpgnSD6PFSyS3pTdEdD164oXd2VKp4VHLSz3To
98
99
  code_puppy/mcp_/dashboard.py,sha256=VtaFxLtPnbM_HL2TXRDAg6IqcM-EcFkoghGgkfhMrKI,9417
99
100
  code_puppy/mcp_/error_isolation.py,sha256=mpPBiH17zTXPsOEAn9WmkbwQwnt4gmgiaWv87JBJbUo,12426
100
101
  code_puppy/mcp_/health_monitor.py,sha256=n5R6EeYOYbUucUFe74qGWCU3g6Mep5UEQbLF0wbT0dU,19688
101
- code_puppy/mcp_/managed_server.py,sha256=KmrFQAQBS-XHuvkuWUltFJk2jiR0pt55gdQlI0gA2QE,14304
102
+ code_puppy/mcp_/managed_server.py,sha256=APqFKjHtsG8iM4so1dYxvKnb0BTmppHnaY8UJ5DBE9g,14075
102
103
  code_puppy/mcp_/manager.py,sha256=pJ4cALicTxfwG2JIjJraLLf0Mzes-cEVAKIcUwfOoKA,29172
103
104
  code_puppy/mcp_/mcp_logs.py,sha256=o4pSHwELWIjEjqhfaMMEGrBvb159-VIgUp21E707BPo,6264
104
105
  code_puppy/mcp_/registry.py,sha256=U_t12WQ-En-KGyZoiTYdqlhp9NkDTWafu8g5InvF2NM,15774
@@ -112,10 +113,10 @@ code_puppy/messaging/bus.py,sha256=TbdltJ0D5tqnaE4irq1fcXllDYm-mQ_SiX1IFm-S4sw,2
112
113
  code_puppy/messaging/commands.py,sha256=77CtKVNaF5KS3Xyzd0ccDAisZWQxL3weVEt3J-SfYxo,5464
113
114
  code_puppy/messaging/markdown_patches.py,sha256=dMIJozzJChuHa8QNMSEz_kC-dyt7kZiDLZ7rjthbcmg,1626
114
115
  code_puppy/messaging/message_queue.py,sha256=e-viZxacBoNSxRJnCJ4hU4vzsSI3oX_rN58RwhJKFfU,11825
115
- code_puppy/messaging/messages.py,sha256=vNenUTgeZLk2clH4-BLcj44vpzDMmAsOrbwn_msaCVw,16351
116
+ code_puppy/messaging/messages.py,sha256=F7RwMHeQrIk-8kuSSBU76wBq1NGuLb2H5cJrSMTC3XM,16464
116
117
  code_puppy/messaging/queue_console.py,sha256=T0U_V1tdN6hd9DLokp-HCk0mhu8Ivpfajha368CBZrU,9983
117
118
  code_puppy/messaging/renderers.py,sha256=GHVtMnxE1pJ-yrcRjacY81JcjlHRz3UVHzp-ohN-CGE,12058
118
- code_puppy/messaging/rich_renderer.py,sha256=YMj5bdZSjufzFL6kNUuNhsoI_NfXUfvWBQ1FDWPw2Ho,37480
119
+ code_puppy/messaging/rich_renderer.py,sha256=FiT1e5S8nNQte0E6CMFQ3KyTixadkgKSjp1hcZXtyOE,37892
119
120
  code_puppy/messaging/spinner/__init__.py,sha256=KpK5tJqq9YnN3wklqvdH0BQmuwYnT83Mp4tPfQa9RqI,1664
120
121
  code_puppy/messaging/spinner/console_spinner.py,sha256=YIReuWPD01YPy58FqWdMDWj2QhauTUxKo675Ub4-eDA,8451
121
122
  code_puppy/messaging/spinner/spinner_base.py,sha256=JiQDAhCfwrWUFunb8Xcj1caEl34JJY7Bcio7mDeckSc,2694
@@ -123,7 +124,7 @@ code_puppy/plugins/__init__.py,sha256=gWgrXWoFpl-3Mxz2DAvxKW6SkCWrOnw-hKsY9O7nHc
123
124
  code_puppy/plugins/oauth_puppy_html.py,sha256=Wpa-V_NlRiBAvo_OXHuR7wvOH_jSt8L9HSFGiab6xI0,13058
124
125
  code_puppy/plugins/antigravity_oauth/__init__.py,sha256=1miHihSqRNXO20Vh_Gn9M3Aa2szh0gtdSCaKKj9nq0Q,362
125
126
  code_puppy/plugins/antigravity_oauth/accounts.py,sha256=GQit2-K24bsopmTZyscFUq3M0cAEO5WutHWnipVdgz8,14304
126
- code_puppy/plugins/antigravity_oauth/antigravity_model.py,sha256=FgZtXHsyTIX0wcJB7ivcdFd5DpRLqDFO_idcvMuDKtc,25336
127
+ code_puppy/plugins/antigravity_oauth/antigravity_model.py,sha256=g0_nXnMg288CvBE48CFgZ-iAqlYbtbi1dcB4Up6cYYc,26115
127
128
  code_puppy/plugins/antigravity_oauth/config.py,sha256=BoQgqf5I2XoHWnBBo9vhCIc_XwPj9Mbp0Z95ygWwt78,1362
128
129
  code_puppy/plugins/antigravity_oauth/constants.py,sha256=qsrA10JJvzNuY0OobvvwCQcoGpILBninllcUUMKkUrQ,4644
129
130
  code_puppy/plugins/antigravity_oauth/oauth.py,sha256=ZHXJtZP63l6brOpX1WdLfuUClIleA79-4y36YUJc6Wo,15137
@@ -145,7 +146,7 @@ code_puppy/plugins/claude_code_oauth/__init__.py,sha256=mCcOU-wM7LNCDjr-w-WLPzom
145
146
  code_puppy/plugins/claude_code_oauth/config.py,sha256=DjGySCkvjSGZds6DYErLMAi3TItt8iSLGvyJN98nSEM,2013
146
147
  code_puppy/plugins/claude_code_oauth/register_callbacks.py,sha256=g8sl-i7jIOF6OFALeaLqTF3mS4tD8GR_FCzvPjVw2js,10165
147
148
  code_puppy/plugins/claude_code_oauth/test_plugin.py,sha256=yQy4EeZl4bjrcog1d8BjknoDTRK75mRXXvkSQJYSSEM,9286
148
- code_puppy/plugins/claude_code_oauth/utils.py,sha256=wDaOU21zB3y6PWkuMXwE4mFjQuffyDae-vXysPTS-w8,13438
149
+ code_puppy/plugins/claude_code_oauth/utils.py,sha256=TVgz5aFd2GFPHSiG9NnOYiw-y6KRkWwt_SZxmMpwMIY,17243
149
150
  code_puppy/plugins/customizable_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
150
151
  code_puppy/plugins/customizable_commands/register_callbacks.py,sha256=zVMfIzr--hVn0IOXxIicbmgj2s-HZUgtrOc0NCDOnDw,5183
151
152
  code_puppy/plugins/example_custom_command/README.md,sha256=5c5Zkm7CW6BDSfe3WoLU7GW6t5mjjYAbu9-_pu-b3p4,8244
@@ -159,8 +160,8 @@ code_puppy/plugins/shell_safety/register_callbacks.py,sha256=W3v664RR48Fdbbbltf_
159
160
  code_puppy/prompts/codex_system_prompt.md,sha256=hEFTCziroLqZmqNle5kG34A8kvTteOWezCiVrAEKhE0,24400
160
161
  code_puppy/tools/__init__.py,sha256=BVTZ85jLHgDANwOnUSOz3UDlp8VQDq4DoGF23BRlyWw,6032
161
162
  code_puppy/tools/agent_tools.py,sha256=snBI6FlFtR03CbYKXwu53R48c_fRSuDIwcNdVUruLcA,21020
162
- code_puppy/tools/command_runner.py,sha256=4RlgPWWE2Mk35t69QJWR4Md4etMGLR2rFSZAKrNohU4,44917
163
- code_puppy/tools/common.py,sha256=IboS6sbwN4a3FzHdfsZJtEFiyDUCszevI6LpH14ydEk,40561
163
+ code_puppy/tools/command_runner.py,sha256=3qXVnVTaBPia6y2D29As47_TRKgpyCj82yMFK-8UUYc,44954
164
+ code_puppy/tools/common.py,sha256=IYf-KOcP5eN2MwTlpULSXNATn7GzloAKl7_M1Uyfe4Y,40360
164
165
  code_puppy/tools/file_modifications.py,sha256=vz9n7R0AGDSdLUArZr_55yJLkyI30M8zreAppxIx02M,29380
165
166
  code_puppy/tools/file_operations.py,sha256=CqhpuBnOFOcQCIYXOujskxq2VMLWYJhibYrH0YcPSfA,35692
166
167
  code_puppy/tools/tools_content.py,sha256=bsBqW-ppd1XNAS_g50B3UHDQBWEALC1UneH6-afz1zo,2365
@@ -174,10 +175,10 @@ code_puppy/tools/browser/browser_scripts.py,sha256=sNb8eLEyzhasy5hV4B9OjM8yIVMLV
174
175
  code_puppy/tools/browser/browser_workflows.py,sha256=nitW42vCf0ieTX1gLabozTugNQ8phtoFzZbiAhw1V90,6491
175
176
  code_puppy/tools/browser/camoufox_manager.py,sha256=RZjGOEftE5sI_tsercUyXFSZI2wpStXf-q0PdYh2G3I,8680
176
177
  code_puppy/tools/browser/vqa_agent.py,sha256=DBn9HKloILqJSTSdNZzH_PYWT0B2h9VwmY6akFQI_uU,2913
177
- code_puppy-0.0.336.data/data/code_puppy/models.json,sha256=IPABdOrDw2OZJxa0XGBWSWmBRerV6_pIEmKVLRtUbAk,3105
178
- code_puppy-0.0.336.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
179
- code_puppy-0.0.336.dist-info/METADATA,sha256=K0YyE2O8F9-nMuMdbs2rAovJHJmtQox98_r4beIjGPA,28854
180
- code_puppy-0.0.336.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
181
- code_puppy-0.0.336.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
182
- code_puppy-0.0.336.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
183
- code_puppy-0.0.336.dist-info/RECORD,,
178
+ code_puppy-0.0.341.data/data/code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
179
+ code_puppy-0.0.341.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
180
+ code_puppy-0.0.341.dist-info/METADATA,sha256=TyW2aMaB5pukc2EP2CV8fjW-qotBUDUms_CeaiUbKv4,27550
181
+ code_puppy-0.0.341.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
182
+ code_puppy-0.0.341.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
183
+ code_puppy-0.0.341.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
184
+ code_puppy-0.0.341.dist-info/RECORD,,