gemcode 0.4.28__tar.gz → 0.4.29__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 (210) hide show
  1. {gemcode-0.4.28/src/gemcode.egg-info → gemcode-0.4.29}/PKG-INFO +1 -1
  2. {gemcode-0.4.28 → gemcode-0.4.29}/pyproject.toml +1 -1
  3. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/preview_api.py +65 -14
  4. {gemcode-0.4.28 → gemcode-0.4.29/src/gemcode.egg-info}/PKG-INFO +1 -1
  5. {gemcode-0.4.28 → gemcode-0.4.29}/LICENSE +0 -0
  6. {gemcode-0.4.28 → gemcode-0.4.29}/MANIFEST.in +0 -0
  7. {gemcode-0.4.28 → gemcode-0.4.29}/README.md +0 -0
  8. {gemcode-0.4.28 → gemcode-0.4.29}/setup.cfg +0 -0
  9. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/__init__.py +0 -0
  10. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/__main__.py +0 -0
  11. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/a2a_bridge.py +0 -0
  12. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/agent.py +0 -0
  13. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/agent_habits.py +0 -0
  14. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/agent_intelligence.py +0 -0
  15. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/agent_mesh.py +0 -0
  16. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/agent_triggers.py +0 -0
  17. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/audit.py +0 -0
  18. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/autocompact.py +0 -0
  19. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/automations.py +0 -0
  20. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/autotune.py +0 -0
  21. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/callbacks.py +0 -0
  22. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/capability_routing.py +0 -0
  23. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/checkpoints.py +0 -0
  24. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/cli.py +0 -0
  25. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/codebase_awareness.py +0 -0
  26. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/compaction.py +0 -0
  27. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/computer_use/__init__.py +0 -0
  28. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/computer_use/browser_computer.py +0 -0
  29. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/config.py +0 -0
  30. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/context_budget.py +0 -0
  31. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/context_warning.py +0 -0
  32. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/credentials.py +0 -0
  33. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/curated_memory.py +0 -0
  34. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/delegation_learning.py +0 -0
  35. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/dynamic_policy.py +0 -0
  36. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/evals/harness.py +0 -0
  37. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/event_bus.py +0 -0
  38. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/fleet_reports.py +0 -0
  39. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/habit_chains.py +0 -0
  40. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/habit_runs.py +0 -0
  41. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/hitl_session.py +0 -0
  42. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/hooks.py +0 -0
  43. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/ide_protocol.py +0 -0
  44. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/ide_stdio.py +0 -0
  45. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/intent_classifier.py +0 -0
  46. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/interactions.py +0 -0
  47. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/invoke.py +0 -0
  48. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/kaira_client.py +0 -0
  49. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/kaira_daemon.py +0 -0
  50. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/kaira_ipc.py +0 -0
  51. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/kaira_job_store.py +0 -0
  52. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/learning.py +0 -0
  53. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/limits.py +0 -0
  54. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/live_audio_engine.py +0 -0
  55. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/logging_config.py +0 -0
  56. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/mcp_loader.py +0 -0
  57. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/memory/__init__.py +0 -0
  58. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/memory/embedding_memory_service.py +0 -0
  59. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/memory/file_memory_service.py +0 -0
  60. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/modality_tools.py +0 -0
  61. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/model_errors.py +0 -0
  62. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/model_routing.py +0 -0
  63. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/multimodal_input.py +0 -0
  64. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/openapi_loader.py +0 -0
  65. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/org.py +0 -0
  66. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/output_styles.py +0 -0
  67. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/paths.py +0 -0
  68. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/permissions.py +0 -0
  69. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/plugins/__init__.py +0 -0
  70. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  71. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  72. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/policy_profile.py +0 -0
  73. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/pricing.py +0 -0
  74. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/prompt_suggestions.py +0 -0
  75. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/query/__init__.py +0 -0
  76. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/query/config.py +0 -0
  77. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/query/deps.py +0 -0
  78. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/query/engine.py +0 -0
  79. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/query/stop_hooks.py +0 -0
  80. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/query/token_budget.py +0 -0
  81. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/query/transitions.py +0 -0
  82. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/query_sanitizer.py +0 -0
  83. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/refine.py +0 -0
  84. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/repl_commands.py +0 -0
  85. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/repl_slash.py +0 -0
  86. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/review_agent.py +0 -0
  87. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/rules.py +0 -0
  88. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/self_healing.py +0 -0
  89. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/session_runtime.py +0 -0
  90. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/session_store.py +0 -0
  91. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/session_summariser.py +0 -0
  92. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/skills.py +0 -0
  93. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/slash_commands.py +0 -0
  94. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/thinking.py +0 -0
  95. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tool_prompt_manifest.py +0 -0
  96. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tool_registry.py +0 -0
  97. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tool_result_store.py +0 -0
  98. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tool_synthesis.py +0 -0
  99. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/__init__.py +0 -0
  100. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/automations_tools.py +0 -0
  101. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/bash.py +0 -0
  102. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/browser.py +0 -0
  103. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/compress_memory.py +0 -0
  104. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/curated_memory.py +0 -0
  105. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/edit.py +0 -0
  106. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/filesystem.py +0 -0
  107. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/notebook.py +0 -0
  108. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/notes.py +0 -0
  109. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/org_tools.py +0 -0
  110. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/repo_map.py +0 -0
  111. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/search.py +0 -0
  112. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/shell.py +0 -0
  113. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/shell_gate.py +0 -0
  114. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/skills.py +0 -0
  115. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/subtask.py +0 -0
  116. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/tasks.py +0 -0
  117. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/think.py +0 -0
  118. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/todo.py +0 -0
  119. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/user_choice.py +0 -0
  120. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/veomem_tools.py +0 -0
  121. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/web.py +0 -0
  122. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools/web_search.py +0 -0
  123. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tools_inspector.py +0 -0
  124. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/trust.py +0 -0
  125. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tui/input_handler.py +0 -0
  126. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tui/scrollback.py +0 -0
  127. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tui/spinner.py +0 -0
  128. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tui/welcome_banner.py +0 -0
  129. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/tui/welcome_rich.py +0 -0
  130. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/veomem_bridge.py +0 -0
  131. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/version.py +0 -0
  132. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/vertex.py +0 -0
  133. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/wal.py +0 -0
  134. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/__init__.py +0 -0
  135. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/chat_skills.py +0 -0
  136. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/customize_api.py +0 -0
  137. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/files_api.py +0 -0
  138. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/fleet_api.py +0 -0
  139. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/hitl_bridge.py +0 -0
  140. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/project_root.py +0 -0
  141. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/runtime_api.py +0 -0
  142. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/serve_bind.py +0 -0
  143. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/serve_state.py +0 -0
  144. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/server.py +0 -0
  145. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/sessions_api.py +0 -0
  146. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/sse_adapter.py +0 -0
  147. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/terminal_api.py +0 -0
  148. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/terminal_repl.py +0 -0
  149. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/ui_chat_store.py +0 -0
  150. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/web_config_api.py +0 -0
  151. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/web_sse_compat.py +0 -0
  152. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/web/workspace_panel_api.py +0 -0
  153. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode/workspace_hints.py +0 -0
  154. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode.egg-info/SOURCES.txt +0 -0
  155. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode.egg-info/dependency_links.txt +0 -0
  156. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode.egg-info/entry_points.txt +0 -0
  157. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode.egg-info/requires.txt +0 -0
  158. {gemcode-0.4.28 → gemcode-0.4.29}/src/gemcode.egg-info/top_level.txt +0 -0
  159. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_add_dir.py +0 -0
  160. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_agent_habits.py +0 -0
  161. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_agent_instruction.py +0 -0
  162. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_agent_mesh.py +0 -0
  163. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_autocompact.py +0 -0
  164. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_automations.py +0 -0
  165. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_capability_routing.py +0 -0
  166. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_checkpoint_diff_command.py +0 -0
  167. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_cli_init.py +0 -0
  168. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_compress_memory_tool.py +0 -0
  169. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_computer_use_permissions.py +0 -0
  170. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_context_budget.py +0 -0
  171. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_context_warning.py +0 -0
  172. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_credentials.py +0 -0
  173. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_eval_harness_layout.py +0 -0
  174. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_event_bus.py +0 -0
  175. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_files_api.py +0 -0
  176. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_fleet_reports.py +0 -0
  177. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_habit_chains.py +0 -0
  178. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_habit_runs.py +0 -0
  179. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_hitl_bridge_cross_process.py +0 -0
  180. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_hosted_tenant.py +0 -0
  181. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_ide_stdio_attachments.py +0 -0
  182. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_interactive_permission_ask.py +0 -0
  183. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_kaira_ipc_paths.py +0 -0
  184. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_kaira_scheduler.py +0 -0
  185. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_modality_tools.py +0 -0
  186. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_model_error_retry.py +0 -0
  187. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_model_errors.py +0 -0
  188. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_model_routing.py +0 -0
  189. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_multimodal_input.py +0 -0
  190. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_output_styles_and_rules.py +0 -0
  191. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_paths.py +0 -0
  192. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_permissions.py +0 -0
  193. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_preview_proxy.py +0 -0
  194. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_prompt_suggestions.py +0 -0
  195. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_repl_commands.py +0 -0
  196. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_repl_slash.py +0 -0
  197. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_session_runtime_cache.py +0 -0
  198. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_skills.py +0 -0
  199. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_slash_commands.py +0 -0
  200. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_slash_completion_registry.py +0 -0
  201. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_sse_confirmation_batch.py +0 -0
  202. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_thinking_config.py +0 -0
  203. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_token_budget.py +0 -0
  204. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_tool_context_circulation.py +0 -0
  205. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_tools.py +0 -0
  206. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_tools_inspector.py +0 -0
  207. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_web_permissions_hitl.py +0 -0
  208. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_web_server.py +0 -0
  209. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_web_sse_adapter.py +0 -0
  210. {gemcode-0.4.28 → gemcode-0.4.29}/tests/test_workspace_hints.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.4.28
3
+ Version: 0.4.29
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gemcode"
7
- version = "0.4.28"
7
+ version = "0.4.29"
8
8
  description = "Local-first coding agent on Google Gemini + ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -157,14 +157,30 @@ def _cleanup_managed_servers() -> None:
157
157
  atexit.register(_cleanup_managed_servers)
158
158
 
159
159
 
160
+ def _http_responds(port: int, request_path: str = "/", *, timeout: float = 1.0) -> bool:
161
+ try:
162
+ conn = HTTPConnection("127.0.0.1", port, timeout=timeout)
163
+ conn.request(
164
+ "GET",
165
+ request_path or "/",
166
+ headers={"User-Agent": "GemCode-Web-Preview/1.0", "Accept": "*/*"},
167
+ )
168
+ resp = conn.getresponse()
169
+ resp.read()
170
+ conn.close()
171
+ return True
172
+ except OSError:
173
+ return False
174
+
175
+
160
176
  def ensure_workspace_static_server(port: int, root: Path) -> tuple[bool, str | None]:
161
177
  """
162
- Ensure something accepts TCP on ``127.0.0.1:port``.
178
+ Ensure something accepts HTTP on ``127.0.0.1:port``.
163
179
 
164
180
  If the port is free and eligible, start ``python -m http.server`` in ``root``.
165
181
  Returns (ok, note).
166
182
  """
167
- if _port_open("127.0.0.1", port, timeout=0.35):
183
+ if _http_responds(port):
168
184
  return True, None
169
185
  if port not in STATIC_AUTOSTART_PORTS:
170
186
  return False, (
@@ -176,16 +192,16 @@ def ensure_workspace_static_server(port: int, root: Path) -> tuple[bool, str | N
176
192
  return False, f"Workspace root is not a directory: {root}"
177
193
 
178
194
  with _server_lock:
179
- if _port_open("127.0.0.1", port, timeout=0.35):
195
+ if _http_responds(port):
180
196
  return True, None
181
197
  existing = _managed_servers.get(port)
182
198
  if existing is not None and existing.poll() is None:
183
- for _ in range(25):
184
- if _port_open("127.0.0.1", port, timeout=0.2):
199
+ for _ in range(40):
200
+ if _http_responds(port):
185
201
  return True, "managed"
186
202
  if existing.poll() is not None:
187
203
  break
188
- time.sleep(0.08)
204
+ time.sleep(0.1)
189
205
  try:
190
206
  proc = subprocess.Popen(
191
207
  [
@@ -204,13 +220,13 @@ def ensure_workspace_static_server(port: int, root: Path) -> tuple[bool, str | N
204
220
  except OSError as exc:
205
221
  return False, f"Could not start static preview server: {exc}"
206
222
  _managed_servers[port] = proc
207
- for _ in range(30):
208
- if _port_open("127.0.0.1", port, timeout=0.2):
223
+ for _ in range(50):
224
+ if _http_responds(port):
209
225
  return True, "started"
210
226
  if proc.poll() is not None:
211
227
  _managed_servers.pop(port, None)
212
228
  return False, "Static preview server exited immediately (port may be busy)."
213
- time.sleep(0.08)
229
+ time.sleep(0.1)
214
230
  return False, "Timed out waiting for static preview server."
215
231
 
216
232
 
@@ -299,13 +315,29 @@ def handle_preview_proxy(
299
315
  if root is not None:
300
316
  ok, note = ensure_workspace_static_server(port, root)
301
317
  if ok:
302
- try:
303
- time.sleep(0.05)
304
- status, body, ctype, headers_list = _fetch()
305
- except OSError as second_exc:
318
+ status = 0
319
+ body = b""
320
+ ctype = ""
321
+ headers_list = []
322
+ last_err: OSError | None = None
323
+ # Retry briefly — TCP can accept before http.server is ready to route paths.
324
+ for attempt in range(12):
325
+ try:
326
+ time.sleep(0.08 if attempt else 0.05)
327
+ status, body, ctype, headers_list = _fetch()
328
+ if status != 404:
329
+ break
330
+ # 404 right after start: file may not be visible yet; retry a few times.
331
+ if attempt < 8:
332
+ continue
333
+ break
334
+ except OSError as second_exc:
335
+ last_err = second_exc
336
+ continue
337
+ if last_err is not None and status == 0:
306
338
  msg = (
307
339
  f'{{"error":"Preview upstream unreachable after starting static server: '
308
- f'{type(second_exc).__name__}: {second_exc}"}}'
340
+ f'{type(last_err).__name__}: {last_err}"}}'
309
341
  )
310
342
  return 502, msg.encode(), {"Content-Type": "application/json; charset=utf-8"}
311
343
  else:
@@ -315,6 +347,25 @@ def handle_preview_proxy(
315
347
  else:
316
348
  msg = f'{{"error":"Preview upstream unreachable: {type(first_exc).__name__}: {first_exc}"}}'
317
349
  return 502, msg.encode(), {"Content-Type": "application/json; charset=utf-8"}
350
+ else:
351
+ # Live server returned 404 — retry once after a short wait (startup race).
352
+ if status == 404 and root is not None:
353
+ for _ in range(6):
354
+ time.sleep(0.12)
355
+ try:
356
+ status, body, ctype, headers_list = _fetch()
357
+ if status != 404:
358
+ break
359
+ except OSError:
360
+ ok, _ = ensure_workspace_static_server(port, root)
361
+ if not ok:
362
+ break
363
+ try:
364
+ status, body, ctype, headers_list = _fetch()
365
+ except OSError:
366
+ break
367
+ if status != 404:
368
+ break
318
369
 
319
370
  headers: dict[str, str] = {}
320
371
  for key, value in headers_list:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.4.28
3
+ Version: 0.4.29
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes