code-puppy 0.0.337__py3-none-any.whl → 0.0.339__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.
@@ -388,6 +388,20 @@ class ModelFactory:
388
388
  return AnthropicModel(model_name=model_config["name"], provider=provider)
389
389
  elif model_type == "claude_code":
390
390
  url, headers, verify, api_key = get_custom_config(model_config)
391
+ if model_config.get("oauth_source") == "claude-code-plugin":
392
+ try:
393
+ from code_puppy.plugins.claude_code_oauth.utils import (
394
+ get_valid_access_token,
395
+ )
396
+
397
+ refreshed_token = get_valid_access_token()
398
+ if refreshed_token:
399
+ api_key = refreshed_token
400
+ custom_endpoint = model_config.get("custom_endpoint")
401
+ if isinstance(custom_endpoint, dict):
402
+ custom_endpoint["api_key"] = refreshed_token
403
+ except ImportError:
404
+ pass
391
405
  if not api_key:
392
406
  emit_warning(
393
407
  f"API key is not set for Claude Code endpoint; skipping model '{model_config.get('name')}'."
@@ -663,6 +677,8 @@ class ModelFactory:
663
677
  f"API key is not set for Cerebras endpoint; skipping model '{model_config.get('name')}'."
664
678
  )
665
679
  return None
680
+ # Add Cerebras 3rd party integration header
681
+ headers["X-Cerebras-3rd-Party-Integration"] = "code-puppy"
666
682
  client = create_async_client(headers=headers, verify=verify)
667
683
  provider_args = dict(
668
684
  api_key=api_key,
code_puppy/models.json CHANGED
@@ -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"
@@ -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)
@@ -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.337
3
+ Version: 0.0.339
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=QaucFONE0InS1GANCZwMFx-7sEptbZfjVzb_CgjvuUo,7949
6
+ code_puppy/cli_runner.py,sha256=qxhxK3-33b60J85urcCdvruKwftg_sdzreR88cWRW8I,34703
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
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=FsjSw4i4YYVi9iyxviy6Y0aRGsm9ALvkOLbAfjcGAmc,83923
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
49
  code_puppy/command_line/autosave_menu.py,sha256=vW-2UqX8qT2Rb07ZSbsCG1MMwCPIH4MQ4YM9PEkcPyo,20105
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=pyawy4qWGIkEMZVWDRYy_noFTD25k6vR3Z2fSH12jVU,32009
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
@@ -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
@@ -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.337.data/data/code_puppy/models.json,sha256=IPABdOrDw2OZJxa0XGBWSWmBRerV6_pIEmKVLRtUbAk,3105
178
- code_puppy-0.0.337.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
179
- code_puppy-0.0.337.dist-info/METADATA,sha256=F1DCPuk3QS0E2t1o_HRId-DiNTtOs29kcmSueGwHUHk,28854
180
- code_puppy-0.0.337.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
181
- code_puppy-0.0.337.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
182
- code_puppy-0.0.337.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
183
- code_puppy-0.0.337.dist-info/RECORD,,
178
+ code_puppy-0.0.339.data/data/code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
179
+ code_puppy-0.0.339.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
180
+ code_puppy-0.0.339.dist-info/METADATA,sha256=YaFaqaIzzRRCZmmfCrNsf9Z-k92mgvBKc22jEKm_F8U,27550
181
+ code_puppy-0.0.339.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
182
+ code_puppy-0.0.339.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
183
+ code_puppy-0.0.339.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
184
+ code_puppy-0.0.339.dist-info/RECORD,,