code-puppy 0.0.200__tar.gz → 0.0.202__tar.gz

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.
Files changed (130) hide show
  1. {code_puppy-0.0.200 → code_puppy-0.0.202}/PKG-INFO +1 -1
  2. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_manager.py +4 -2
  3. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/attachments.py +2 -14
  4. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/session_storage.py +74 -35
  5. {code_puppy-0.0.200 → code_puppy-0.0.202}/pyproject.toml +1 -1
  6. {code_puppy-0.0.200 → code_puppy-0.0.202}/.gitignore +0 -0
  7. {code_puppy-0.0.200 → code_puppy-0.0.202}/LICENSE +0 -0
  8. {code_puppy-0.0.200 → code_puppy-0.0.202}/README.md +0 -0
  9. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/__init__.py +0 -0
  10. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/__main__.py +0 -0
  11. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/__init__.py +0 -0
  12. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_c_reviewer.py +0 -0
  13. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_code_puppy.py +0 -0
  14. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_code_reviewer.py +0 -0
  15. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_cpp_reviewer.py +0 -0
  16. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_creator_agent.py +0 -0
  17. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_golang_reviewer.py +0 -0
  18. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_javascript_reviewer.py +0 -0
  19. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_python_reviewer.py +0 -0
  20. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_qa_expert.py +0 -0
  21. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_qa_kitten.py +0 -0
  22. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_security_auditor.py +0 -0
  23. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/agent_typescript_reviewer.py +0 -0
  24. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/base_agent.py +0 -0
  25. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/agents/json_agent.py +0 -0
  26. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/callbacks.py +0 -0
  27. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/__init__.py +0 -0
  28. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/command_handler.py +0 -0
  29. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/file_path_completion.py +0 -0
  30. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/load_context_completion.py +0 -0
  31. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/__init__.py +0 -0
  32. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/add_command.py +0 -0
  33. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/base.py +0 -0
  34. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/handler.py +0 -0
  35. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/help_command.py +0 -0
  36. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/install_command.py +0 -0
  37. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/list_command.py +0 -0
  38. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/logs_command.py +0 -0
  39. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/remove_command.py +0 -0
  40. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/restart_command.py +0 -0
  41. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/search_command.py +0 -0
  42. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/start_all_command.py +0 -0
  43. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/start_command.py +0 -0
  44. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/status_command.py +0 -0
  45. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
  46. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/stop_command.py +0 -0
  47. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/test_command.py +0 -0
  48. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/utils.py +0 -0
  49. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
  50. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/model_picker_completion.py +0 -0
  51. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/motd.py +0 -0
  52. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  53. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/command_line/utils.py +0 -0
  54. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/config.py +0 -0
  55. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/http_utils.py +0 -0
  56. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/main.py +0 -0
  57. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/__init__.py +0 -0
  58. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/async_lifecycle.py +0 -0
  59. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/blocking_startup.py +0 -0
  60. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/captured_stdio_server.py +0 -0
  61. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/circuit_breaker.py +0 -0
  62. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/config_wizard.py +0 -0
  63. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/dashboard.py +0 -0
  64. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/error_isolation.py +0 -0
  65. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/examples/retry_example.py +0 -0
  66. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/health_monitor.py +0 -0
  67. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/managed_server.py +0 -0
  68. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/manager.py +0 -0
  69. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/registry.py +0 -0
  70. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/retry_manager.py +0 -0
  71. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/server_registry_catalog.py +0 -0
  72. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/status_tracker.py +0 -0
  73. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/mcp_/system_tools.py +0 -0
  74. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/messaging/__init__.py +0 -0
  75. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/messaging/message_queue.py +0 -0
  76. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/messaging/queue_console.py +0 -0
  77. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/messaging/renderers.py +0 -0
  78. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/messaging/spinner/__init__.py +0 -0
  79. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/messaging/spinner/console_spinner.py +0 -0
  80. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/messaging/spinner/spinner_base.py +0 -0
  81. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/messaging/spinner/textual_spinner.py +0 -0
  82. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/model_factory.py +0 -0
  83. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/models.json +0 -0
  84. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/plugins/__init__.py +0 -0
  85. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
  86. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/reopenable_async_client.py +0 -0
  87. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/round_robin_model.py +0 -0
  88. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/status_display.py +0 -0
  89. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/summarization_agent.py +0 -0
  90. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/__init__.py +0 -0
  91. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/agent_tools.py +0 -0
  92. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/__init__.py +0 -0
  93. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/browser_control.py +0 -0
  94. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/browser_interactions.py +0 -0
  95. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/browser_locators.py +0 -0
  96. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/browser_navigation.py +0 -0
  97. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/browser_screenshot.py +0 -0
  98. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/browser_scripts.py +0 -0
  99. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/browser_workflows.py +0 -0
  100. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/camoufox_manager.py +0 -0
  101. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/browser/vqa_agent.py +0 -0
  102. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/command_runner.py +0 -0
  103. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/common.py +0 -0
  104. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/file_modifications.py +0 -0
  105. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/file_operations.py +0 -0
  106. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tools/tools_content.py +0 -0
  107. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/__init__.py +0 -0
  108. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/app.py +0 -0
  109. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/__init__.py +0 -0
  110. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/chat_view.py +0 -0
  111. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/command_history_modal.py +0 -0
  112. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/copy_button.py +0 -0
  113. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/custom_widgets.py +0 -0
  114. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/human_input_modal.py +0 -0
  115. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/input_area.py +0 -0
  116. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/sidebar.py +0 -0
  117. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/components/status_bar.py +0 -0
  118. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/messages.py +0 -0
  119. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/models/__init__.py +0 -0
  120. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/models/chat_message.py +0 -0
  121. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/models/command_history.py +0 -0
  122. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/models/enums.py +0 -0
  123. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/screens/__init__.py +0 -0
  124. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/screens/autosave_picker.py +0 -0
  125. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/screens/help.py +0 -0
  126. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/screens/mcp_install_wizard.py +0 -0
  127. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/screens/settings.py +0 -0
  128. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui/screens/tools.py +0 -0
  129. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/tui_state.py +0 -0
  130. {code_puppy-0.0.200 → code_puppy-0.0.202}/code_puppy/version_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.200
3
+ Version: 0.0.202
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
@@ -252,7 +252,8 @@ def set_current_agent(agent_name: str) -> bool:
252
252
  global _CURRENT_AGENT
253
253
  curr_agent = get_current_agent()
254
254
  if curr_agent is not None:
255
- _AGENT_HISTORIES[curr_agent.name] = curr_agent.get_message_history()
255
+ # Store a shallow copy so future mutations don't affect saved history
256
+ _AGENT_HISTORIES[curr_agent.name] = list(curr_agent.get_message_history())
256
257
  # Generate a message group ID for agent switching
257
258
  message_group_id = str(uuid.uuid4())
258
259
  _discover_agents(message_group_id=message_group_id)
@@ -269,7 +270,8 @@ def set_current_agent(agent_name: str) -> bool:
269
270
  _SESSION_AGENTS_CACHE[session_id] = agent_name
270
271
  _save_session_data(_SESSION_AGENTS_CACHE)
271
272
  if agent_obj.name in _AGENT_HISTORIES:
272
- agent_obj.set_message_history(_AGENT_HISTORIES[agent_obj.name])
273
+ # Restore a copy to avoid sharing the same list instance
274
+ agent_obj.set_message_history(list(_AGENT_HISTORIES[agent_obj.name]))
273
275
  on_agent_reload(agent_obj.id, agent_name)
274
276
  return True
275
277
 
@@ -151,20 +151,8 @@ def _is_supported_extension(path: Path) -> bool:
151
151
 
152
152
 
153
153
  def _parse_link(token: str) -> PromptLinkAttachment | None:
154
- if "://" not in token:
155
- return None
156
- scheme = token.split(":", 1)[0].lower()
157
- if scheme not in SUPPORTED_INLINE_SCHEMES:
158
- return None
159
- if token.lower().endswith(".pdf"):
160
- return PromptLinkAttachment(
161
- placeholder=token,
162
- url_part=DocumentUrl(url=token),
163
- )
164
- return PromptLinkAttachment(
165
- placeholder=token,
166
- url_part=ImageUrl(url=token),
167
- )
154
+ """URL parsing disabled: no URLs are treated as attachments."""
155
+ return None
168
156
 
169
157
 
170
158
  @dataclass
@@ -177,48 +177,87 @@ async def restore_autosave_interactively(base_dir: Path) -> None:
177
177
  return datetime.min
178
178
 
179
179
  entries.sort(key=sort_key, reverse=True)
180
- top_entries = entries[:5]
181
-
182
- emit_system_message("[bold magenta]Autosave Sessions Available:[/bold magenta]")
183
- for index, (name, timestamp, message_count) in enumerate(top_entries, start=1):
184
- timestamp_display = timestamp or "unknown time"
185
- message_display = (
186
- f"{message_count} messages" if message_count is not None else "unknown size"
187
- )
188
- emit_system_message(
189
- f" [{index}] {name} ({message_display}, saved at {timestamp_display})"
190
- )
191
-
192
- if len(entries) > len(top_entries):
193
- emit_system_message(
194
- f" [dim]...and {len(entries) - len(top_entries)} more autosaves[/dim]"
195
- )
196
180
 
197
- try:
198
- selection = await get_input_with_combined_completion(
199
- FormattedText([("class:prompt", "Load autosave (number, name, or Enter to skip): ")])
200
- )
201
- except (KeyboardInterrupt, EOFError):
202
- emit_warning("Autosave selection cancelled")
203
- return
204
-
205
- selection = selection.strip()
206
- if not selection:
207
- return
181
+ PAGE_SIZE = 5
182
+ total = len(entries)
183
+ page = 0
184
+
185
+ def render_page() -> None:
186
+ start = page * PAGE_SIZE
187
+ end = min(start + PAGE_SIZE, total)
188
+ page_entries = entries[start:end]
189
+ emit_system_message("[bold magenta]Autosave Sessions Available:[/bold magenta]")
190
+ for idx, (name, timestamp, message_count) in enumerate(page_entries, start=1):
191
+ timestamp_display = timestamp or "unknown time"
192
+ message_display = (
193
+ f"{message_count} messages" if message_count is not None else "unknown size"
194
+ )
195
+ emit_system_message(
196
+ f" [{idx}] {name} ({message_display}, saved at {timestamp_display})"
197
+ )
198
+ # If there are more pages, offer next-page; show 'Return to first page' on last page
199
+ if total > PAGE_SIZE:
200
+ page_count = (total + PAGE_SIZE - 1) // PAGE_SIZE
201
+ is_last_page = (page + 1) >= page_count
202
+ remaining = total - (page * PAGE_SIZE + len(page_entries))
203
+ summary = f" and {remaining} more" if (remaining > 0 and not is_last_page) else ""
204
+ label = "Return to first page" if is_last_page else f"Next page{summary}"
205
+ emit_system_message(f" [6] {label}")
206
+ emit_system_message(" [Enter] Skip loading autosave")
207
+
208
+ chosen_name: str | None = None
209
+
210
+ while True:
211
+ render_page()
212
+ try:
213
+ selection = await get_input_with_combined_completion(
214
+ FormattedText(
215
+ [
216
+ (
217
+ "class:prompt",
218
+ "Pick 1-5 to load, 6 for next, or name/Enter: ",
219
+ )
220
+ ]
221
+ )
222
+ )
223
+ except (KeyboardInterrupt, EOFError):
224
+ emit_warning("Autosave selection cancelled")
225
+ return
226
+
227
+ selection = (selection or "").strip()
228
+ if not selection:
229
+ return
230
+
231
+ # Numeric choice: 1-5 select within current page; 6 advances page
232
+ if selection.isdigit():
233
+ num = int(selection)
234
+ if num == 6 and total > PAGE_SIZE:
235
+ page = (page + 1) % ((total + PAGE_SIZE - 1) // PAGE_SIZE)
236
+ # loop and re-render next page
237
+ continue
238
+ if 1 <= num <= 5:
239
+ start = page * PAGE_SIZE
240
+ idx = start + (num - 1)
241
+ if 0 <= idx < total:
242
+ chosen_name = entries[idx][0]
243
+ break
244
+ else:
245
+ emit_warning("Invalid selection for this page")
246
+ continue
247
+ emit_warning("Invalid selection; choose 1-5 or 6 for next")
248
+ continue
208
249
 
209
- chosen_name = None
210
- if selection.isdigit():
211
- idx = int(selection) - 1
212
- if 0 <= idx < len(top_entries):
213
- chosen_name = top_entries[idx][0]
214
- else:
215
- for name, _, _ in entries:
250
+ # Allow direct typing by exact session name
251
+ for name, _ts, _mc in entries:
216
252
  if name == selection:
217
253
  chosen_name = name
218
254
  break
255
+ if chosen_name:
256
+ break
257
+ emit_warning("No autosave loaded (invalid selection)")
258
+ # keep looping and allow another try
219
259
 
220
260
  if not chosen_name:
221
- emit_warning("No autosave loaded (invalid selection)")
222
261
  return
223
262
 
224
263
  try:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-puppy"
7
- version = "0.0.200"
7
+ version = "0.0.202"
8
8
  description = "Code generation agent"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
File without changes
File without changes
File without changes