gdmcode 0.1.5__tar.gz → 0.1.6__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 (267) hide show
  1. {gdmcode-0.1.5 → gdmcode-0.1.6}/PKG-INFO +1 -1
  2. gdmcode-0.1.6/gdmcode/__init__.py +1 -0
  3. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/cli.py +81 -3
  4. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/integrations/mcp_server.py +1 -1
  5. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/models/definitions.py +2 -3
  6. {gdmcode-0.1.5 → gdmcode-0.1.6}/pyproject.toml +1 -1
  7. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_cli_smoke.py +20 -1
  8. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_health.py +9 -0
  9. gdmcode-0.1.5/gdmcode/__init__.py +0 -1
  10. {gdmcode-0.1.5 → gdmcode-0.1.6}/.gitignore +0 -0
  11. {gdmcode-0.1.5 → gdmcode-0.1.6}/CONTRIBUTING.md +0 -0
  12. {gdmcode-0.1.5 → gdmcode-0.1.6}/README.md +0 -0
  13. {gdmcode-0.1.5 → gdmcode-0.1.6}/config.toml +0 -0
  14. {gdmcode-0.1.5 → gdmcode-0.1.6}/docs/agentic-runtime-audit.md +0 -0
  15. {gdmcode-0.1.5 → gdmcode-0.1.6}/docs/architecture.md +0 -0
  16. {gdmcode-0.1.5 → gdmcode-0.1.6}/docs/cli-reference.md +0 -0
  17. {gdmcode-0.1.5 → gdmcode-0.1.6}/docs/configuration.md +0 -0
  18. {gdmcode-0.1.5 → gdmcode-0.1.6}/docs/deployment.md +0 -0
  19. {gdmcode-0.1.5 → gdmcode-0.1.6}/docs/plugin-guide.md +0 -0
  20. {gdmcode-0.1.5 → gdmcode-0.1.6}/docs/quick-start.md +0 -0
  21. {gdmcode-0.1.5 → gdmcode-0.1.6}/docs/security-hardening.md +0 -0
  22. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/_internal/__init__.py +0 -0
  23. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/_internal/constants.py +0 -0
  24. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/_internal/domain_skills.py +0 -0
  25. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/__init__.py +0 -0
  26. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/commit_classifier.py +0 -0
  27. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/context_budget.py +0 -0
  28. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/daemon.py +0 -0
  29. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/dag_validator.py +0 -0
  30. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/debug_loop.py +0 -0
  31. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/impact_analyzer.py +0 -0
  32. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/impact_graph.py +0 -0
  33. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/loop.py +0 -0
  34. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/orchestrator.py +0 -0
  35. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/regression_guard.py +0 -0
  36. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/review_gate.py +0 -0
  37. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/risk_scorer.py +0 -0
  38. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/self_healing.py +0 -0
  39. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/smart_test_selector.py +0 -0
  40. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/system_prompt.py +0 -0
  41. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/task_tracker.py +0 -0
  42. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/test_validator.py +0 -0
  43. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/tool_orchestrator.py +0 -0
  44. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/transcript.py +0 -0
  45. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/verification_loop.py +0 -0
  46. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/work_director.py +0 -0
  47. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/agent/worktree_manager.py +0 -0
  48. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/artifacts/__init__.py +0 -0
  49. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/artifacts/artifact_store.py +0 -0
  50. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/artifacts/verification_graph.py +0 -0
  51. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/auth.py +0 -0
  52. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/commands.py +0 -0
  53. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/config.py +0 -0
  54. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/cost_tracker.py +0 -0
  55. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/db/__init__.py +0 -0
  56. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/db/migrations.py +0 -0
  57. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/enterprise/__init__.py +0 -0
  58. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/enterprise/audit_log.py +0 -0
  59. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/enterprise/identity.py +0 -0
  60. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/enterprise/rbac.py +0 -0
  61. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/enterprise/team_config.py +0 -0
  62. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/enterprise/usage_analytics.py +0 -0
  63. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/exceptions.py +0 -0
  64. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/git_workflow.py +0 -0
  65. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/integrations/__init__.py +0 -0
  66. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/integrations/github_actions.py +0 -0
  67. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/integrations/sentry_integration.py +0 -0
  68. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/integrations/sentry_server.py +0 -0
  69. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/integrations/webhook_security.py +0 -0
  70. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/main.py +0 -0
  71. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/__init__.py +0 -0
  72. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/code_index.py +0 -0
  73. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/compressor.py +0 -0
  74. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/context_memory.py +0 -0
  75. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/continuous_memory.py +0 -0
  76. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/conventions.py +0 -0
  77. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/db.py +0 -0
  78. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/document_index.py +0 -0
  79. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/file_cache.py +0 -0
  80. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/project_scanner.py +0 -0
  81. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/memory/session_store.py +0 -0
  82. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/models/__init__.py +0 -0
  83. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/models/client.py +0 -0
  84. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/models/router.py +0 -0
  85. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/models/schemas.py +0 -0
  86. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/permissions.py +0 -0
  87. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/__init__.py +0 -0
  88. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/command_filter.py +0 -0
  89. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/models.py +0 -0
  90. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/permission_handler.py +0 -0
  91. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/phone_ui.py +0 -0
  92. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/protocol.py +0 -0
  93. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/qr.py +0 -0
  94. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/server.py +0 -0
  95. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/token_manager.py +0 -0
  96. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/remote/tunnel.py +0 -0
  97. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/repl.py +0 -0
  98. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/runtime/__init__.py +0 -0
  99. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/runtime/branch_farm.py +0 -0
  100. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/runtime/replay.py +0 -0
  101. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/sandbox/__init__.py +0 -0
  102. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/sandbox/hermetic.py +0 -0
  103. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/sandbox/policy.py +0 -0
  104. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/sdk/__init__.py +0 -0
  105. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/sdk/plugin_base.py +0 -0
  106. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/sdk/plugin_host.py +0 -0
  107. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/sdk/plugin_loader.py +0 -0
  108. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/security.py +0 -0
  109. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/server/__init__.py +0 -0
  110. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/server/bridge.py +0 -0
  111. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/server/bridge_cli.py +0 -0
  112. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/server/bridge_client.py +0 -0
  113. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/server/protocol_version.py +0 -0
  114. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/session/__init__.py +0 -0
  115. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/session/event_fanout.py +0 -0
  116. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/session/input_broker.py +0 -0
  117. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/session/permission_bridge.py +0 -0
  118. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/__init__.py +0 -0
  119. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/_atomic.py +0 -0
  120. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/agent_tools.py +0 -0
  121. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/ask_user_tool.py +0 -0
  122. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/bash_tool.py +0 -0
  123. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/browser_tool.py +0 -0
  124. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/browser_tools.py +0 -0
  125. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/dep_tools.py +0 -0
  126. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/document_reader.py +0 -0
  127. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/document_tool.py +0 -0
  128. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/document_writer.py +0 -0
  129. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/impact_tools.py +0 -0
  130. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/playwright_tool.py +0 -0
  131. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/quality_tools.py +0 -0
  132. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/read_tools.py +0 -0
  133. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/result_cache.py +0 -0
  134. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/search_tools.py +0 -0
  135. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/shell_tools.py +0 -0
  136. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/tools/write_tools.py +0 -0
  137. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/voice/__init__.py +0 -0
  138. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/voice/audio_capture.py +0 -0
  139. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/voice/audio_playback.py +0 -0
  140. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/voice/errors.py +0 -0
  141. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/voice/models.py +0 -0
  142. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/voice/providers.py +0 -0
  143. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/voice/vad.py +0 -0
  144. {gdmcode-0.1.5 → gdmcode-0.1.6}/gdmcode/voice/voice_loop.py +0 -0
  145. {gdmcode-0.1.5 → gdmcode-0.1.6}/proxy/Dockerfile +0 -0
  146. {gdmcode-0.1.5 → gdmcode-0.1.6}/proxy/main.py +0 -0
  147. {gdmcode-0.1.5 → gdmcode-0.1.6}/proxy/requirements.txt +0 -0
  148. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/__init__.py +0 -0
  149. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/remote/__init__.py +0 -0
  150. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/remote/test_remote_server.py +0 -0
  151. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_agent_loop.py +0 -0
  152. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_agent_tools.py +0 -0
  153. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_api_fallback.py +0 -0
  154. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_artifact_store.py +0 -0
  155. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_audit_log.py +0 -0
  156. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_auth.py +0 -0
  157. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_auto_quality.py +0 -0
  158. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_autonomy_levels.py +0 -0
  159. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_bash_tool.py +0 -0
  160. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_batch_api.py +0 -0
  161. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_branch_farm.py +0 -0
  162. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_bridge.py +0 -0
  163. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_bridge_smoke.py +0 -0
  164. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_browser_tool_smoke.py +0 -0
  165. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_browser_tools.py +0 -0
  166. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_btw_queue.py +0 -0
  167. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_budget_tracker.py +0 -0
  168. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_chrome_extension.py +0 -0
  169. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_ci_runner.py +0 -0
  170. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_code_index.py +0 -0
  171. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_commands.py +0 -0
  172. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_compression.py +0 -0
  173. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_confidence.py +0 -0
  174. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_config.py +0 -0
  175. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_continuous_memory.py +0 -0
  176. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_convention_drift.py +0 -0
  177. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_cost_tracker.py +0 -0
  178. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_daemon.py +0 -0
  179. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_daemon_stability.py +0 -0
  180. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_daemon_watchdog.py +0 -0
  181. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_db.py +0 -0
  182. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_debate.py +0 -0
  183. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_debug_loop.py +0 -0
  184. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_debug_loop_smoke.py +0 -0
  185. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_dep_tools.py +0 -0
  186. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_doctor.py +0 -0
  187. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_document_index.py +0 -0
  188. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_document_reader.py +0 -0
  189. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_document_tool.py +0 -0
  190. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_document_writer.py +0 -0
  191. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_domain_skills.py +0 -0
  192. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_eval_harness.py +0 -0
  193. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_event_log.py +0 -0
  194. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_failure_taxonomy.py +0 -0
  195. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_file_tools.py +0 -0
  196. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_git_workflow.py +0 -0
  197. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_github_actions.py +0 -0
  198. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_hermetic_sandbox.py +0 -0
  199. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_identity_rbac.py +0 -0
  200. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_impact_analysis.py +0 -0
  201. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_impact_analyzer.py +0 -0
  202. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_impact_graph.py +0 -0
  203. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_impact_tools.py +0 -0
  204. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_injection_gate.py +0 -0
  205. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_leaderboard.py +0 -0
  206. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_local_models.py +0 -0
  207. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_loop.py +0 -0
  208. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_loop_p3.py +0 -0
  209. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_mcp_server.py +0 -0
  210. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_memory.py +0 -0
  211. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_migrations.py +0 -0
  212. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_mock_provider.py +0 -0
  213. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_model_config.py +0 -0
  214. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_orchestrator.py +0 -0
  215. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_package.py +0 -0
  216. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_permissions.py +0 -0
  217. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_phase2_modules.py +0 -0
  218. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_phone_ui.py +0 -0
  219. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_playwright_tool.py +0 -0
  220. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_plugin_sdk.py +0 -0
  221. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_protocol_version.py +0 -0
  222. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_provenance.py +0 -0
  223. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_proxy_server.py +0 -0
  224. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_quality_integration.py +0 -0
  225. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_reasoning_toggle.py +0 -0
  226. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_redaction.py +0 -0
  227. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_regression_collector.py +0 -0
  228. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_regression_guard_integration.py +0 -0
  229. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_regression_runner.py +0 -0
  230. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_repl_smoke.py +0 -0
  231. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_replay.py +0 -0
  232. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_resilience.py +0 -0
  233. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_result_cache.py +0 -0
  234. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_review_gate_expanded.py +0 -0
  235. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_risk_scorer.py +0 -0
  236. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_rollback.py +0 -0
  237. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_router.py +0 -0
  238. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_router_compressor_conventions.py +0 -0
  239. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_router_escalation.py +0 -0
  240. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_sandbox.py +0 -0
  241. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_scoring.py +0 -0
  242. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_search_tools.py +0 -0
  243. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_self_healing.py +0 -0
  244. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_semantic_edit.py +0 -0
  245. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_sentry_integration.py +0 -0
  246. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_session_checkpoint.py +0 -0
  247. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_session_controller.py +0 -0
  248. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_session_restore.py +0 -0
  249. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_signal_handling.py +0 -0
  250. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_swebench_adapter.py +0 -0
  251. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_swebench_runner.py +0 -0
  252. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_system_prompt.py +0 -0
  253. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_team_config.py +0 -0
  254. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_tool_cache.py +0 -0
  255. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_tool_orchestrator.py +0 -0
  256. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_tool_timeout.py +0 -0
  257. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_tools_registry.py +0 -0
  258. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_tunnel_qr.py +0 -0
  259. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_usage_analytics.py +0 -0
  260. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_verification_graph.py +0 -0
  261. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_verification_loop.py +0 -0
  262. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_voice_loop.py +0 -0
  263. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_voice_providers.py +0 -0
  264. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_whole_codebase.py +0 -0
  265. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/test_work_director.py +0 -0
  266. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/voice/__init__.py +0 -0
  267. {gdmcode-0.1.5 → gdmcode-0.1.6}/tests/voice/test_audio_foundation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gdmcode
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: gdm: AI coding agent for professional developers
5
5
  Project-URL: Homepage, https://github.com/guidegdm/gdmcode
6
6
  Project-URL: Repository, https://github.com/guidegdm/gdmcode
@@ -0,0 +1 @@
1
+ __version__ = "0.1.6"
@@ -348,6 +348,34 @@ def cmd_health(
348
348
  except Exception as exc: # noqa: BLE001
349
349
  return CheckResult(f"api ({cfg.provider})", "fail", detail=str(exc)[:60])
350
350
 
351
+ def _check_completion() -> CheckResult:
352
+ t0 = time.monotonic()
353
+ try:
354
+ from gdmcode.models.client import GdmClient
355
+
356
+ model_def = get_model(ModelTier.CODER, cfg.provider)
357
+ proxy_active = bool(
358
+ getattr(cfg, "proxy_enabled", False)
359
+ and getattr(cfg, "proxy_url", "")
360
+ and getattr(cfg, "proxy_token", "")
361
+ )
362
+ client = (
363
+ GdmClient.for_proxy(getattr(cfg, "proxy_url"), getattr(cfg, "proxy_token"))
364
+ if proxy_active
365
+ else GdmClient(cfg)
366
+ )
367
+ text = client.complete_text(
368
+ "Reply with exactly: OK",
369
+ model=model_def.id,
370
+ max_tokens=8,
371
+ system="You are a health check. Reply only with OK.",
372
+ )
373
+ status = "ok" if text.strip() else "fail"
374
+ detail = f"{model_def.id}: {text.strip()[:30] or 'empty response'}"
375
+ return CheckResult("llm completion", status, latency_ms=int((time.monotonic() - t0) * 1000), detail=detail, priority="P0")
376
+ except Exception as exc: # noqa: BLE001
377
+ return CheckResult("llm completion", "fail", latency_ms=int((time.monotonic() - t0) * 1000), detail=str(exc)[:120], priority="P0")
378
+
351
379
  def _check_tools() -> CheckResult:
352
380
  t0 = time.monotonic()
353
381
  try:
@@ -401,10 +429,11 @@ def cmd_health(
401
429
  return results
402
430
 
403
431
  # Run scalar checks in parallel; sysdeps is fast so fine in its own slot
404
- with ThreadPoolExecutor(max_workers=6) as executor:
432
+ with ThreadPoolExecutor(max_workers=7) as executor:
405
433
  f_db = executor.submit(_check_db)
406
434
  f_daemon = executor.submit(_check_daemon)
407
435
  f_api = executor.submit(_check_api)
436
+ f_completion = executor.submit(_check_completion)
408
437
  f_tools = executor.submit(_check_tools)
409
438
  f_budget = executor.submit(_check_budget)
410
439
  f_sys = executor.submit(_check_sysdeps)
@@ -413,6 +442,7 @@ def cmd_health(
413
442
  f_db.result(),
414
443
  f_daemon.result(),
415
444
  f_api.result(),
445
+ f_completion.result(),
416
446
  f_tools.result(),
417
447
  f_budget.result(),
418
448
  *f_sys.result(),
@@ -1201,13 +1231,17 @@ def _run_one_shot(cfg: object, prompt: str, *, yes: bool, model_override: str |
1201
1231
  """
1202
1232
  from rich.status import Status
1203
1233
  from gdmcode.agent.loop import EventType
1204
- from gdmcode.repl import _format_llm_error
1234
+ from gdmcode.repl import _format_llm_error, _is_connection_probe
1205
1235
 
1206
1236
  if not _has_model_connection(cfg):
1207
1237
  console.print("[red]No model connection configured.[/red]")
1208
1238
  console.print("Run [bold]gdm login grok[/bold], [bold]gdm login gemini[/bold], or start [bold]gdm[/bold] and use [bold]/proxy token[/bold] then [bold]/proxy on[/bold].")
1209
1239
  raise typer.Exit(1)
1210
1240
 
1241
+ if _is_connection_probe(prompt):
1242
+ _run_connection_probe_once(cfg, prompt, model_override=model_override)
1243
+ return
1244
+
1211
1245
  try:
1212
1246
  loop, cost_tracker, _db = _setup_agent(cfg, yes=yes, model_override=model_override)
1213
1247
  except Exception as exc: # noqa: BLE001
@@ -1271,7 +1305,12 @@ def _run_one_shot(cfg: object, prompt: str, *, yes: bool, model_override: str |
1271
1305
  console.print(event.content)
1272
1306
  elif event.type == EventType.ERROR:
1273
1307
  status.stop()
1274
- console.print(_format_llm_error(event.content))
1308
+ content = str(event.content or "")
1309
+ if content.lower().startswith("max turns"):
1310
+ console.print(f"[yellow]Agent stopped before completion:[/yellow] {content}")
1311
+ console.print("[dim]Increase --max-turns or simplify the prompt.[/dim]")
1312
+ else:
1313
+ console.print(_format_llm_error(event.content))
1275
1314
  had_error = True
1276
1315
  elif event.type == EventType.TOOL_CALL:
1277
1316
  status.stop()
@@ -1301,6 +1340,45 @@ def _run_one_shot(cfg: object, prompt: str, *, yes: bool, model_override: str |
1301
1340
  raise typer.Exit(1)
1302
1341
 
1303
1342
 
1343
+ def _run_connection_probe_once(cfg: object, prompt: str, *, model_override: str | None) -> None:
1344
+ """Run a one-shot no-tools LLM connection probe."""
1345
+ from rich.status import Status
1346
+ from gdmcode.models.client import GdmClient
1347
+ from gdmcode.models.definitions import ModelTier, get_model
1348
+ from gdmcode.repl import _format_llm_error
1349
+
1350
+ status = Status("[cyan]Checking LLM connection...[/cyan]", console=console, spinner="dots")
1351
+ status.start()
1352
+ try:
1353
+ tier = model_override or ModelTier.CODER
1354
+ model_def = get_model(tier, cfg.provider) # type: ignore[union-attr]
1355
+ proxy_active = bool(
1356
+ getattr(cfg, "proxy_enabled", False)
1357
+ and getattr(cfg, "proxy_url", "")
1358
+ and getattr(cfg, "proxy_token", "")
1359
+ )
1360
+ client = (
1361
+ GdmClient.for_proxy(getattr(cfg, "proxy_url"), getattr(cfg, "proxy_token"))
1362
+ if proxy_active
1363
+ else GdmClient(cfg) # type: ignore[arg-type]
1364
+ )
1365
+ response = client.complete_text(
1366
+ prompt,
1367
+ model=model_def.id,
1368
+ max_tokens=80,
1369
+ system=(
1370
+ "You are gdm code's CLI connection check. Reply in one short, friendly "
1371
+ "sentence. Confirm the LLM is connected. Do not inspect files or call tools."
1372
+ ),
1373
+ ).strip()
1374
+ status.stop()
1375
+ console.print(response or "[green]LLM connected.[/green]")
1376
+ except Exception as exc: # noqa: BLE001
1377
+ status.stop()
1378
+ console.print(_format_llm_error(exc))
1379
+ raise typer.Exit(1) from exc
1380
+
1381
+
1304
1382
  # ---------------------------------------------------------------------------
1305
1383
  # Helpers
1306
1384
  # ---------------------------------------------------------------------------
@@ -51,7 +51,7 @@ _INTERNAL_ERROR = -32603
51
51
  class MCPServer:
52
52
  """Minimal MCP server with stdio transport."""
53
53
 
54
- def __init__(self, name: str = "gdmcode", version: str = "0.1.5") -> None:
54
+ def __init__(self, name: str = "gdmcode", version: str = "0.1.6") -> None:
55
55
  self._name = name
56
56
  self._version = version
57
57
  self._tools: dict[str, MCPTool] = {}
@@ -201,14 +201,14 @@ GEMINI_SCOUT = ModelDef(
201
201
  )
202
202
 
203
203
  GEMINI_CODER = ModelDef(
204
- id="gemini-2.5-flash-8b",
204
+ id="gemini-2.5-flash",
205
205
  tier=ModelTier.CODER,
206
206
  provider=Provider.GEMINI,
207
207
  input_per_m=0.075,
208
208
  output_per_m=0.30,
209
209
  cached_per_m=0.0,
210
210
  context_window=1_000_000,
211
- notes="Ultra-cheap bulk: file indexing, convention extraction, boilerplate edits.",
211
+ notes="Cheap bulk: file indexing, convention extraction, boilerplate edits.",
212
212
  )
213
213
 
214
214
  GEMINI_THINKER = ModelDef(
@@ -456,4 +456,3 @@ def get_capability(tier: str, provider: str, capability: str) -> bool:
456
456
  return bool(getattr(m, capability, False))
457
457
  except KeyError:
458
458
  return False
459
-
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "gdmcode"
7
- version = "0.1.5"
7
+ version = "0.1.6"
8
8
  description = "gdm: AI coding agent for professional developers"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -89,8 +89,27 @@ class TestCliSmoke:
89
89
 
90
90
  response = SimpleNamespace(status_code=200)
91
91
  with patch("gdmcode.cli.httpx.get", return_value=response):
92
- result = runner.invoke(app, ["health"])
92
+ with patch("gdmcode.models.client.GdmClient.complete_text", return_value="OK"):
93
+ result = runner.invoke(app, ["health"])
93
94
 
94
95
  assert "tools" in result.output
95
96
  assert "registered" in result.output
96
97
  assert "probe ok" in result.output
98
+ assert "llm completion" in result.output
99
+
100
+ def test_one_shot_greeting_uses_connection_probe(self, tmp_path, monkeypatch) -> None:
101
+ import gdmcode.cli as cli
102
+
103
+ cfg = SimpleNamespace(provider="gemini", api_key="key", project_root=tmp_path)
104
+ monkeypatch.setattr(cli, "load_config", lambda require_credentials=False: cfg)
105
+ monkeypatch.setattr(cli, "_print_header", lambda _cfg: None)
106
+ monkeypatch.setattr(cli, "_has_model_connection", lambda _cfg: True)
107
+ probe = MagicMock()
108
+ monkeypatch.setattr(cli, "_run_connection_probe_once", probe)
109
+
110
+ result = runner.invoke(app, ["code", "--prompt", "hey"])
111
+
112
+ assert result.exit_code == 0
113
+ probe.assert_called_once()
114
+ assert probe.call_args.args[1] == "hey"
115
+ assert probe.call_args.kwargs == {"model_override": None}
@@ -22,6 +22,9 @@ def _make_cfg(**kwargs):
22
22
  cfg.provider = kwargs.get("provider", "grok")
23
23
  cfg.api_key = kwargs.get("api_key", "sk-test")
24
24
  cfg.project_root = Path("/tmp/gdm-test")
25
+ cfg.proxy_enabled = kwargs.get("proxy_enabled", False)
26
+ cfg.proxy_url = kwargs.get("proxy_url", "")
27
+ cfg.proxy_token = kwargs.get("proxy_token", None)
25
28
  return cfg
26
29
 
27
30
 
@@ -63,6 +66,7 @@ def _run_health(
63
66
  daemon = _make_daemon(running=daemon_running)
64
67
  mock_registry = MagicMock()
65
68
  mock_registry.all_tools.return_value = [MagicMock()] * tools_count
69
+ mock_registry.call.return_value = MagicMock(ok=True, output="ok", error=None)
66
70
 
67
71
  mock_response = MagicMock()
68
72
  mock_response.status_code = api_status
@@ -75,6 +79,7 @@ def _run_health(
75
79
  patch("gdmcode.cli.shutil.which", side_effect=lambda cmd: which_map.get(cmd)),
76
80
  patch("gdmcode.cli.httpx.get",
77
81
  side_effect=api_exc if api_exc else lambda *a, **kw: mock_response),
82
+ patch("gdmcode.models.client.GdmClient.complete_text", return_value="OK"),
78
83
  ):
79
84
  runner = CliRunner()
80
85
  result = runner.invoke(app, ["health", *args])
@@ -138,6 +143,7 @@ def test_api_probe_sends_auth_header():
138
143
  daemon = _make_daemon()
139
144
  mock_registry = MagicMock()
140
145
  mock_registry.all_tools.return_value = [MagicMock()]
146
+ mock_registry.call.return_value = MagicMock(ok=True, output="ok", error=None)
141
147
 
142
148
  with (
143
149
  patch("gdmcode.cli.load_config", return_value=cfg),
@@ -146,6 +152,7 @@ def test_api_probe_sends_auth_header():
146
152
  patch("gdmcode.cli.REGISTRY", mock_registry),
147
153
  patch("gdmcode.cli.shutil.which", return_value="/usr/bin/git"),
148
154
  patch("gdmcode.cli.httpx.get", side_effect=fake_get),
155
+ patch("gdmcode.models.client.GdmClient.complete_text", return_value="OK"),
149
156
  ):
150
157
  runner = CliRunner()
151
158
  runner.invoke(app, ["health"])
@@ -280,6 +287,7 @@ def test_parallel_execution_completes():
280
287
  daemon = _make_daemon()
281
288
  mock_registry = MagicMock()
282
289
  mock_registry.all_tools.return_value = [MagicMock()]
290
+ mock_registry.call.return_value = MagicMock(ok=True, output="ok", error=None)
283
291
 
284
292
  def slow_api(*a, **kw):
285
293
  import time as _t
@@ -295,6 +303,7 @@ def test_parallel_execution_completes():
295
303
  patch("gdmcode.cli.REGISTRY", mock_registry),
296
304
  patch("gdmcode.cli.shutil.which", return_value="/bin/git"),
297
305
  patch("gdmcode.cli.httpx.get", side_effect=slow_api),
306
+ patch("gdmcode.models.client.GdmClient.complete_text", return_value="OK"),
298
307
  ):
299
308
  runner = CliRunner()
300
309
  t0 = time.monotonic()
@@ -1 +0,0 @@
1
- __version__ = "0.1.5"
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
File without changes
File without changes
File without changes
File without changes
File without changes