devops-bot-sdk 1.6.34__tar.gz → 1.6.38__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 (196) hide show
  1. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/PKG-INFO +1 -1
  2. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/devops_bot_sdk.egg-info/PKG-INFO +1 -1
  3. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/devops_bot_sdk.egg-info/SOURCES.txt +10 -2
  4. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/devops_bot_sdk.egg-info/entry_points.txt +1 -0
  5. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/pyproject.toml +1 -0
  6. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/__init__.py +2 -2
  7. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/cli.py +36 -1
  8. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/client.py +104 -35
  9. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/config.py +9 -1
  10. devops_bot_sdk-1.6.38/sdk/firewall.py +472 -0
  11. devops_bot_sdk-1.6.38/sdk/github_fetch.py +198 -0
  12. devops_bot_sdk-1.6.38/sdk/github_ingest.py +618 -0
  13. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/intake.py +126 -1
  14. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/run_auto.py +17 -24
  15. devops_bot_sdk-1.6.38/sdk/swagger.py +356 -0
  16. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/api.py +0 -27
  17. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/ip_allowlist.py +43 -16
  18. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/models.py +0 -13
  19. devops_bot_sdk-1.6.38/sdk/ui/server.py +309 -0
  20. devops_bot_sdk-1.6.38/sdk/ui/swagger.py +167 -0
  21. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/updater.py +42 -0
  22. devops_bot_sdk-1.6.38/sdk/vps_health.py +264 -0
  23. devops_bot_sdk-1.6.38/tests/test_firewall_open_on_update.py +213 -0
  24. devops_bot_sdk-1.6.38/tests/test_github_fetch.py +216 -0
  25. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_github_ingest.py +105 -4
  26. devops_bot_sdk-1.6.38/tests/test_intake_job_outcome.py +180 -0
  27. devops_bot_sdk-1.6.38/tests/test_swagger_command.py +260 -0
  28. devops_bot_sdk-1.6.38/tests/test_ui_gate.py +351 -0
  29. devops_bot_sdk-1.6.38/tests/test_ui_lifespan.py +89 -0
  30. devops_bot_sdk-1.6.34/sdk/github_ingest.py +0 -161
  31. devops_bot_sdk-1.6.34/sdk/ui/server.py +0 -189
  32. devops_bot_sdk-1.6.34/sdk/ui/static/login.html +0 -111
  33. devops_bot_sdk-1.6.34/sdk/vps_health.py +0 -111
  34. devops_bot_sdk-1.6.34/tests/test_otp_login.py +0 -178
  35. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/README.md +0 -0
  36. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/devops_bot_sdk.egg-info/dependency_links.txt +0 -0
  37. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/devops_bot_sdk.egg-info/requires.txt +0 -0
  38. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/devops_bot_sdk.egg-info/top_level.txt +0 -0
  39. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agentd.py +0 -0
  40. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/__init__.py +0 -0
  41. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/activity.py +0 -0
  42. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/builder.py +0 -0
  43. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/chat.py +0 -0
  44. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/connectors.py +0 -0
  45. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/engines/__init__.py +0 -0
  46. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/engines/claude_code.py +0 -0
  47. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/engines/http.py +0 -0
  48. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/engines/mcp.py +0 -0
  49. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/engines/n8n.py +0 -0
  50. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/engines/shell.py +0 -0
  51. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/integrations.py +0 -0
  52. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/inventory.py +0 -0
  53. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/library/__init__.py +0 -0
  54. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/manifest.py +0 -0
  55. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/prompt_studio.py +0 -0
  56. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/prompt_template.py +0 -0
  57. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/prompt_vars.py +0 -0
  58. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/run_log.py +0 -0
  59. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/schedules.py +0 -0
  60. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/secrets.py +0 -0
  61. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/ticket_run.py +0 -0
  62. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/usage.py +0 -0
  63. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/agents/varstore.py +0 -0
  64. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/browser_profile.py +0 -0
  65. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/collectors/__init__.py +0 -0
  66. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/collectors/files.py +0 -0
  67. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/collectors/process.py +0 -0
  68. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/collectors/screenshot.py +0 -0
  69. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/crucial.py +0 -0
  70. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/departments.py +0 -0
  71. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/design_verify/__init__.py +0 -0
  72. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/design_verify/assets.py +0 -0
  73. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/design_verify/bootstrap.py +0 -0
  74. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/design_verify/browser.py +0 -0
  75. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/design_verify/compare.py +0 -0
  76. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/design_verify/loop.py +0 -0
  77. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/estimator.py +0 -0
  78. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/exceptions.py +0 -0
  79. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/formats.py +0 -0
  80. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/git_ops.py +0 -0
  81. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/graph_recon.py +0 -0
  82. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/graphify.py +0 -0
  83. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/hooks/__init__.py +0 -0
  84. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/hooks/crucial_guard.py +0 -0
  85. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ipc/__init__.py +0 -0
  86. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ipc/electron_bridge.py +0 -0
  87. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ipc/handlers.py +0 -0
  88. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/journal.py +0 -0
  89. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/local_exec.py +0 -0
  90. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/models/__init__.py +0 -0
  91. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/models/envelope.py +0 -0
  92. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/models/requests.py +0 -0
  93. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/models/responses.py +0 -0
  94. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/models/snapshots.py +0 -0
  95. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/phase_timer.py +0 -0
  96. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/plan_run.py +0 -0
  97. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/platform_compat.py +0 -0
  98. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/prd_progress.py +0 -0
  99. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/proof_readers.py +0 -0
  100. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/providers.py +0 -0
  101. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/py.typed +0 -0
  102. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/resume.py +0 -0
  103. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/router.py +0 -0
  104. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/scheduler.py +0 -0
  105. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/self_report.py +0 -0
  106. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/self_report_local.py +0 -0
  107. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/sse.py +0 -0
  108. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/task_file.py +0 -0
  109. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/task_types.py +0 -0
  110. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/test.py +0 -0
  111. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/test_pipeline.py +0 -0
  112. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ticket_fields.py +0 -0
  113. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/tiers/__init__.py +0 -0
  114. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/tiers/mini_agent.py +0 -0
  115. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/__init__.py +0 -0
  116. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/dashboard.py +0 -0
  117. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/health.py +0 -0
  118. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/jobs.py +0 -0
  119. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/runner.py +0 -0
  120. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/security.py +0 -0
  121. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/service.py +0 -0
  122. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/session.py +0 -0
  123. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/setup_manager.py +0 -0
  124. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/agents.html +0 -0
  125. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/app.js +0 -0
  126. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/chat.html +0 -0
  127. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/custom-agents.html +0 -0
  128. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/default-agents.html +0 -0
  129. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/index.html +0 -0
  130. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/report.html +0 -0
  131. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/runs.html +0 -0
  132. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/schedules.html +0 -0
  133. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/setup.html +0 -0
  134. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/styles.css +0 -0
  135. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/ui/static/tickets.html +0 -0
  136. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/url_access.py +0 -0
  137. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/sdk/write_hook.py +0 -0
  138. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/setup.cfg +0 -0
  139. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_activity.py +0 -0
  140. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_activity_tracking.py +0 -0
  141. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_chat_features.py +0 -0
  142. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_listing.py +0 -0
  143. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_prompt_async.py +0 -0
  144. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_prompt_models.py +0 -0
  145. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_run_ticket.py +0 -0
  146. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_schedules.py +0 -0
  147. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agent_workspace_settings.py +0 -0
  148. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_agents_connectors_builder.py +0 -0
  149. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_allowed_tools_config.py +0 -0
  150. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_auto_agent_dispatch.py +0 -0
  151. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_browser_profile.py +0 -0
  152. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_cheap_tier.py +0 -0
  153. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_client_jira_projects.py +0 -0
  154. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_config_token_diagnostics.py +0 -0
  155. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_configure_token_owner.py +0 -0
  156. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_console_encoding.py +0 -0
  157. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_departments.py +0 -0
  158. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_epic_decompose_run.py +0 -0
  159. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_epic_inherited_agent_id.py +0 -0
  160. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_epic_session_isolation.py +0 -0
  161. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_estimator.py +0 -0
  162. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_formats.py +0 -0
  163. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_git_action.py +0 -0
  164. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_graph_recon.py +0 -0
  165. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_graphify_build.py +0 -0
  166. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_graphify_hook_install.py +0 -0
  167. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_health.py +0 -0
  168. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_intake_plan_review.py +0 -0
  169. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_journal.py +0 -0
  170. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_local_exec_provider.py +0 -0
  171. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_phase_timer.py +0 -0
  172. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_plan_new_command.py +0 -0
  173. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_plan_run_activity.py +0 -0
  174. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_prd_artifact.py +0 -0
  175. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_proof_readers.py +0 -0
  176. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_providers.py +0 -0
  177. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_recon_session_isolation.py +0 -0
  178. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_resume.py +0 -0
  179. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_router.py +0 -0
  180. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_run_auto_agent_only.py +0 -0
  181. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_run_outputs.py +0 -0
  182. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_schedule_api.py +0 -0
  183. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_scheduler.py +0 -0
  184. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_self_report.py +0 -0
  185. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_service_token_warning.py +0 -0
  186. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_task_file_and_plan_run.py +0 -0
  187. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_task_file_format_doc.py +0 -0
  188. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_ticket_fields.py +0 -0
  189. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_ticket_run_resolve_by_id.py +0 -0
  190. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_ticket_speed_fixes.py +0 -0
  191. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_tier_flag_parity.py +0 -0
  192. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_update_timer.py +0 -0
  193. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_updater_extras.py +0 -0
  194. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_url_access.py +0 -0
  195. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_vps_health.py +0 -0
  196. {devops_bot_sdk-1.6.34 → devops_bot_sdk-1.6.38}/tests/test_write_hook.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devops-bot-sdk
3
- Version: 1.6.34
3
+ Version: 1.6.38
4
4
  Summary: DevOps Bot Desktop SDK — thin client for the AgentOS Electron desktop app
5
5
  Author: noumanaziz2128
6
6
  License-Expression: LicenseRef-Proprietary
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devops-bot-sdk
3
- Version: 1.6.34
3
+ Version: 1.6.38
4
4
  Summary: DevOps Bot Desktop SDK — thin client for the AgentOS Electron desktop app
5
5
  Author: noumanaziz2128
6
6
  License-Expression: LicenseRef-Proprietary
@@ -16,8 +16,10 @@ sdk/crucial.py
16
16
  sdk/departments.py
17
17
  sdk/estimator.py
18
18
  sdk/exceptions.py
19
+ sdk/firewall.py
19
20
  sdk/formats.py
20
21
  sdk/git_ops.py
22
+ sdk/github_fetch.py
21
23
  sdk/github_ingest.py
22
24
  sdk/graph_recon.py
23
25
  sdk/graphify.py
@@ -38,6 +40,7 @@ sdk/scheduler.py
38
40
  sdk/self_report.py
39
41
  sdk/self_report_local.py
40
42
  sdk/sse.py
43
+ sdk/swagger.py
41
44
  sdk/task_file.py
42
45
  sdk/task_types.py
43
46
  sdk/test.py
@@ -106,13 +109,13 @@ sdk/ui/server.py
106
109
  sdk/ui/service.py
107
110
  sdk/ui/session.py
108
111
  sdk/ui/setup_manager.py
112
+ sdk/ui/swagger.py
109
113
  sdk/ui/static/agents.html
110
114
  sdk/ui/static/app.js
111
115
  sdk/ui/static/chat.html
112
116
  sdk/ui/static/custom-agents.html
113
117
  sdk/ui/static/default-agents.html
114
118
  sdk/ui/static/index.html
115
- sdk/ui/static/login.html
116
119
  sdk/ui/static/report.html
117
120
  sdk/ui/static/runs.html
118
121
  sdk/ui/static/schedules.html
@@ -142,17 +145,19 @@ tests/test_epic_decompose_run.py
142
145
  tests/test_epic_inherited_agent_id.py
143
146
  tests/test_epic_session_isolation.py
144
147
  tests/test_estimator.py
148
+ tests/test_firewall_open_on_update.py
145
149
  tests/test_formats.py
146
150
  tests/test_git_action.py
151
+ tests/test_github_fetch.py
147
152
  tests/test_github_ingest.py
148
153
  tests/test_graph_recon.py
149
154
  tests/test_graphify_build.py
150
155
  tests/test_graphify_hook_install.py
151
156
  tests/test_health.py
157
+ tests/test_intake_job_outcome.py
152
158
  tests/test_intake_plan_review.py
153
159
  tests/test_journal.py
154
160
  tests/test_local_exec_provider.py
155
- tests/test_otp_login.py
156
161
  tests/test_phase_timer.py
157
162
  tests/test_plan_new_command.py
158
163
  tests/test_plan_run_activity.py
@@ -168,12 +173,15 @@ tests/test_schedule_api.py
168
173
  tests/test_scheduler.py
169
174
  tests/test_self_report.py
170
175
  tests/test_service_token_warning.py
176
+ tests/test_swagger_command.py
171
177
  tests/test_task_file_and_plan_run.py
172
178
  tests/test_task_file_format_doc.py
173
179
  tests/test_ticket_fields.py
174
180
  tests/test_ticket_run_resolve_by_id.py
175
181
  tests/test_ticket_speed_fixes.py
176
182
  tests/test_tier_flag_parity.py
183
+ tests/test_ui_gate.py
184
+ tests/test_ui_lifespan.py
177
185
  tests/test_update_timer.py
178
186
  tests/test_updater_extras.py
179
187
  tests/test_url_access.py
@@ -2,4 +2,5 @@
2
2
  agentos = sdk.cli:main
3
3
  agentos-agentd = sdk.agentd:main
4
4
  agentos-auto = sdk.run_auto:main
5
+ agentos-swagger = sdk.swagger:main
5
6
  agentos-ui = sdk.ui.server:main
@@ -54,6 +54,7 @@ agentos = "sdk.cli:main" # unified CLI: configure/agent/integ
54
54
  agentos-auto = "sdk.run_auto:main" # run orchestrate-auto LOCALLY (co_ token from config)
55
55
  agentos-agentd = "sdk.agentd:main" # long-running custom-agent daemon
56
56
  agentos-ui = "sdk.ui.server:main" # local web control panel (needs the [ui] extra)
57
+ agentos-swagger = "sdk.swagger:main" # where /docs is + can you reach it (= `agentos swagger`)
57
58
 
58
59
  [project.urls]
59
60
  Homepage = "https://agentos.io"
@@ -1,6 +1,6 @@
1
1
  """AgentOS Desktop SDK — thin HTTPS/SSE client for the Electron app.
2
2
 
3
- Version: 1.6.34
3
+ Version: 1.6.38
4
4
 
5
5
  Public surface:
6
6
  BackendClient.from_config() — create client from ~/.agentos/config.toml
@@ -34,7 +34,7 @@ Rules:
34
34
  - All data egress through submit_webhook only
35
35
  """
36
36
 
37
- __version__ = "1.6.34" # SINGLE SOURCE OF TRUTH — bump on every change; pyproject,
37
+ __version__ = "1.6.38" # SINGLE SOURCE OF TRUTH — bump on every change; pyproject,
38
38
  __author__ = "AgentOS" # sdk.client.SDK_VERSION and the UI server version all read this.
39
39
 
40
40
  from sdk.client import BackendClient
@@ -58,6 +58,30 @@ Command surface:
58
58
  agentos integration rm <name>
59
59
  Remove a registered integration.
60
60
 
61
+ agentos firewall [--apply] [--any] [--revoke IP] [--port N]
62
+ Print the host-firewall rules that open the agentos-ui port to every IP in
63
+ the application allowlist (`sdk.config.get_allowed_ips`), for THIS OS — ufw
64
+ on Linux, `netsh advfirewall` on Windows, a pf note on macOS. Prints by
65
+ default; `--apply` executes them and needs root / Administrator. The host
66
+ firewall is a separate layer the allowlist cannot reach, and the two drifting
67
+ apart is what silently blinded every VPS when the backend's egress IP moved.
68
+ `--any` opens the port to every source instead, leaving
69
+ IPAllowlistMiddleware as the gate — the more robust choice when the
70
+ backend's egress IP can move, since a stale per-IP kernel rule drops the
71
+ SYN before the allowlist is ever consulted. This is what runs
72
+ automatically after a self-update. See sdk.firewall.
73
+
74
+ agentos swagger [--open] [--json [PATH]] [--port N]
75
+ Where the panel's Swagger UI is and whether it can actually be reached:
76
+ the URL derived from the bind address the service was installed with,
77
+ whether a co_ token is configured (masked), how many operations the spec
78
+ has, and a ufw/netsh diff against sdk.config.get_allowed_ips when the HOST
79
+ firewall would drop the port — a layer the SDK's own allowlist cannot see.
80
+ `--open` launches a browser; `--json` writes openapi.json from
81
+ create_app().openapi() with no server running (`--json -` pipes it).
82
+ Also flags routes registered twice, since the second copy is dead code.
83
+ Needs the [ui] extra for the route count and --json. See sdk.swagger.
84
+
61
85
  agentos report submit [--date YYYY-MM-DD] (--text "…" | --file PATH)
62
86
  [--project NAME] [--proof PATH|URL]… [--no-wait]
63
87
  Report work that never reached Jira or GitHub, attach proofs (local
@@ -139,6 +163,14 @@ def main() -> None:
139
163
  _github_command(rest)
140
164
  return
141
165
 
166
+ if noun == "firewall":
167
+ from sdk import firewall
168
+ sys.exit(firewall.cli(rest))
169
+
170
+ if noun == "swagger":
171
+ from sdk import swagger
172
+ sys.exit(swagger.cli(rest))
173
+
142
174
  if noun == "report":
143
175
  _report_command(rest)
144
176
  return
@@ -152,7 +184,7 @@ def main() -> None:
152
184
 
153
185
 
154
186
  def _print_usage() -> None:
155
- print("usage: agentos <configure|chat|agent|integration|default-agents|agentd|github|report|browser> ...")
187
+ print("usage: agentos <configure|chat|agent|integration|default-agents|agentd|github|report|browser|firewall|swagger> ...")
156
188
  print()
157
189
  print(" agentos configure [--rotate]")
158
190
  print(" agentos chat [--product-id ID] [--pv-id ID] [--no-autorun] # requirements → ticket")
@@ -164,6 +196,9 @@ def _print_usage() -> None:
164
196
  print(" agentos github <ingest [--days N]|status> # PR ingestion; --days N backfills N days")
165
197
  print(" agentos report <submit|list|show ID> # report work Jira/GitHub never saw")
166
198
  print(" agentos browser <login URL|status|logout> # sign in once; private links become readable")
199
+ print(" agentos firewall [--apply] [--revoke IP] [--port N] # open the UI port to the allowlisted IPs")
200
+ print(" agentos firewall --any [--apply] # open the UI port to any source (allowlist is the gate)")
201
+ print(" agentos swagger [--open] [--json [PATH]] # where /docs is, and can you reach it")
167
202
 
168
203
 
169
204
  # ── agent ────────────────────────────────────────────────────────────────
@@ -45,6 +45,13 @@ logger = logging.getLogger(__name__)
45
45
  # agents without a lookup on every run.
46
46
  _AGENT_ID_CACHE: dict[str, str] = {}
47
47
 
48
+ # GitHub access token, keyed by the co_ token that fetched it → (token, expires_at
49
+ # monotonic). Keyed per credential so two clients on one box never share a token.
50
+ # Without this the token is re-fetched on EVERY call, which is what
51
+ # tests/test_ticket_speed_fixes.py::TestGithubTokenCache guards against.
52
+ _GITHUB_TOKEN_CACHE: dict[str, tuple[str, float]] = {}
53
+ _GITHUB_TOKEN_TTL_S = float(os.getenv("AGENTOS_GITHUB_TOKEN_TTL_S", "") or 1800.0)
54
+
48
55
  # GitHub access token, keyed by the co_ token that fetched it → (token, expires_at
49
56
  # monotonic). Keyed per credential so two clients on one box never share a token.
50
57
  _GITHUB_TOKEN_CACHE: dict[str, tuple[str, float]] = {}
@@ -952,51 +959,113 @@ class BackendClient:
952
959
  co_ token. Best-effort: returns None on any failure so a run without a
953
960
  connected GitHub account still proceeds (clone/PR steps just won't auth).
954
961
  """
962
+ import time as _time
963
+
964
+ now = _time.monotonic()
965
+ cached = _GITHUB_TOKEN_CACHE.get(self._token)
966
+ if cached and now < cached[1]:
967
+ return cached[0]
955
968
  record = await self.github_token_record()
956
- return (record or {}).get("accessToken") or None
969
+ token = (record or {}).get("accessToken") or None
970
+ if token:
971
+ _GITHUB_TOKEN_CACHE[self._token] = (token, now + _GITHUB_TOKEN_TTL_S)
972
+ return token
957
973
 
958
- async def ingest_github_prs(self, since: str | None = None) -> dict:
974
+ async def ingest_github_prs(self, since: str | None = None) -> dict | None:
959
975
  """POST {AI}/api/v1/github/prs — trigger this user's daily PR ingestion.
960
976
 
961
- The backend resolves the caller's GitHub link server-side from the co_
962
- token in ``Authorization`` (see ``docs/GITHUB_SCHEDULING_SDK_MIGRATION.md``);
963
- ``githubUsername``/``githubAccessToken`` below are placeholders kept only
964
- for backends that predate that resolution and are otherwise ignored.
965
- ``since`` (ISO-8601 date) scopes the fetch — omit for "today".
966
-
967
- Returns the backend's ``{status, job_id, status_url, ...}`` envelope.
968
- Raises BackendUnreachable / HTTP errors — the github_ingest cron catches
969
- and logs these itself rather than treating them as success.
977
+ The daily trigger. The work runs on the AI backend (LLM summarise, the
978
+ downstream daily-summary forward, the Qdrant upsert); the SDK only decides
979
+ WHEN, because only this machine knows its own catch-up watermark.
980
+
981
+ The backend resolves the caller's GitHub link server-side from the co_ token
982
+ in ``Authorization`` and OVERWRITES whatever the body sends
983
+ (``docs/GITHUB_SCHEDULING_SDK_MIGRATION.md`` §7/§9 — that endpoint used to
984
+ take a GitHub access token in an unauthenticated body). So this deliberately
985
+ sends NO credentials: a client that still supplied them would be shipping a
986
+ secret the server ignores.
987
+
988
+ ``since`` is an ISO date (``YYYY-MM-DD``) → the backend's ``date_from``.
989
+ Omitted means "today", which is what a never-missed run wants; the cron sends
990
+ the watermark instead so a machine that was off does not lose days.
991
+
992
+ Returns the response JSON (``{status, job_id, status_url, ...}``) or **None**
993
+ on any failure — never raises into the cron. WHY it failed lands in
994
+ ``self.last_ingest_error`` (``{status, body, retryable}``), which the
995
+ scheduler needs to tell a busy backend (retry in 30 min) from a rejected
996
+ request (wait for the next slot).
970
997
  """
971
- body = [{
998
+ payload = [{
972
999
  "userId": self._user_id_from_token(),
973
- "githubUsername": "",
974
- "githubAccessToken": "",
975
- "apiTokenHash": self._token,
976
- "date_from": since,
1000
+ "apiTokenHash": self._token, # downstream daily-summary Authorization
977
1001
  }]
978
- async with httpx.AsyncClient(timeout=30.0) as client:
979
- resp = await client.post(
980
- self._url("/api/v1/github/prs"), json=body, headers=self._headers,
981
- )
982
- _check_status(resp.status_code, self._url("/api/v1/github/prs"))
983
- return resp.json()
1002
+ if since:
1003
+ payload[0]["date_from"] = since
1004
+ self.last_ingest_error = {}
1005
+ try:
1006
+ async with httpx.AsyncClient(timeout=60.0) as client:
1007
+ resp = await client.post(
1008
+ self._url("/api/v1/github/prs"), json=payload, headers=self._headers,
1009
+ )
1010
+ if resp.status_code >= 400:
1011
+ body = resp.text[:500]
1012
+ logger.warning("client.ingest_github_prs failed status=%s body=%s",
1013
+ resp.status_code, body[:200])
1014
+ self.last_ingest_error = {
1015
+ "status": resp.status_code,
1016
+ "body": body,
1017
+ "retryable": is_retryable_backend_error(resp.status_code, body),
1018
+ }
1019
+ return None
1020
+ return resp.json()
1021
+ except Exception as exc: # noqa: BLE001 — a cron must not die on a blip
1022
+ logger.warning("client.ingest_github_prs error err=%s", exc)
1023
+ # A transport failure (timeout, reset, DNS blip) is as retryable as an
1024
+ # exhausted pool — the backend may simply be busy.
1025
+ self.last_ingest_error = {"status": 0, "body": str(exc)[:500], "retryable": True}
1026
+ return None
1027
+
1028
+ async def ingest_github_prs_raw(self, prs: list[dict],
1029
+ since: str | None = None) -> dict | None:
1030
+ """POST {AI}/api/v1/github/prs/raw — PRs THIS machine already fetched.
984
1031
 
985
- async def report_vps_health(self, payload: dict) -> dict:
986
- """PATCH {AI}/api/v1/vps/health — heartbeat this machine's resource usage.
1032
+ The counterpart to :meth:`ingest_github_prs`. That one asks the backend to
1033
+ fetch with a GitHub token the platform has to hold; this one sends records
1034
+ `sdk.github_fetch` produced with the developer's own `gh`, so no GitHub
1035
+ credential exists on the platform at all, the request runs under that
1036
+ developer's own rate limit, and their private repos resolve.
987
1037
 
988
- Feeds the backend's ``contabo_allocation`` row (VPS health shown in chat /
989
- activity reports) — a live GET of the same path answers on-demand checks,
990
- this PATCH is what keeps that data from going stale. Raises on failure
991
- (BackendUnreachable / HTTP error); the vps_health cron logs and continues
992
- rather than crashing the loop.
1038
+ Only PR DATA travels. The backend resolves the GitHub username and user id
1039
+ from the ``co_`` token server-side and files the records under those, so this
1040
+ cannot be used to attribute PRs to anyone else.
1041
+
1042
+ Same contract as `ingest_github_prs`: the response JSON on success,
1043
+ **None** on any failure, with the reason in ``self.last_ingest_error``.
993
1044
  """
994
- async with httpx.AsyncClient(timeout=30.0) as client:
995
- resp = await client.request(
996
- "PATCH", self._url("/api/v1/vps/health"), json=payload, headers=self._headers,
997
- )
998
- _check_status(resp.status_code, self._url("/api/v1/vps/health"))
999
- return resp.json()
1045
+ self.last_ingest_error = {}
1046
+ body: dict = {"prs": prs}
1047
+ if since:
1048
+ body["date_from"] = since
1049
+ try:
1050
+ async with httpx.AsyncClient(timeout=120.0) as client:
1051
+ resp = await client.post(
1052
+ self._url("/api/v1/github/prs/raw"), json=body, headers=self._headers,
1053
+ )
1054
+ if resp.status_code >= 400:
1055
+ detail = resp.text[:500]
1056
+ logger.warning("client.ingest_github_prs_raw failed status=%s body=%s",
1057
+ resp.status_code, detail[:200])
1058
+ self.last_ingest_error = {
1059
+ "status": resp.status_code,
1060
+ "body": detail,
1061
+ "retryable": is_retryable_backend_error(resp.status_code, detail),
1062
+ }
1063
+ return None
1064
+ return resp.json()
1065
+ except Exception as exc: # noqa: BLE001 — a cron must not die on a blip
1066
+ logger.warning("client.ingest_github_prs_raw error err=%s", exc)
1067
+ self.last_ingest_error = {"status": 0, "body": str(exc)[:500], "retryable": True}
1068
+ return None
1000
1069
 
1001
1070
  async def move_to_backlog(self, task_id: str) -> bool:
1002
1071
  """PUT {BE}/tasks-ml/{id} status=backlog (best-effort).
@@ -192,7 +192,15 @@ def _dotenv_value(key: str) -> str:
192
192
  # backend can reach EVERY VPS's /api/ui/* out of the box (no per-VPS .env needed);
193
193
  # always allowed, treated as permanent (not removable via the API). Extend/override
194
194
  # with AGENTOS_UI_ALLOWED_IPS in .env or the process env.
195
- _DEFAULT_ALLOWED_IPS: list[str] = ["20.12.201.148"]
195
+ #
196
+ # A LIST, not one value, because the backend's egress address is not stable: when it
197
+ # moved to 20.127.87.169 every VPS silently stopped answering `GET /api/v1/vps/health`
198
+ # (30s hang, then 502 — the SYNs were dropped at the host firewall, observed
199
+ # 2026-09-03). Both addresses stay listed rather than swapping, so a rollback or a
200
+ # blue/green pair does not re-break it. Note the host firewall is a SEPARATE layer this
201
+ # list cannot reach: `sudo ufw allow from <ip> to any port 8765 proto tcp` is still
202
+ # required per VPS. See docs/VPS_HEALTH_AND_GITHUB_INGEST_DIAGNOSIS.md #5.
203
+ _DEFAULT_ALLOWED_IPS: list[str] = ["20.12.201.148", "20.127.87.169"]
196
204
 
197
205
 
198
206
  def _parse_token_list(raw: str) -> list[str]: