devops-bot-sdk 1.7.6__tar.gz → 1.7.8__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 (270) hide show
  1. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/PKG-INFO +1 -1
  2. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/PKG-INFO +1 -1
  3. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/__init__.py +2 -2
  4. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/helpdesk_kb.md +4 -2
  5. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/log_colors.py +47 -6
  6. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/platform_compat.py +5 -4
  7. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/run_auto.py +2 -2
  8. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/app.js +26 -2
  9. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/styles.css +11 -0
  10. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_log_colors_backlog.py +55 -0
  11. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/README.md +0 -0
  12. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/SOURCES.txt +0 -0
  13. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/dependency_links.txt +0 -0
  14. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/entry_points.txt +0 -0
  15. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/requires.txt +0 -0
  16. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/top_level.txt +0 -0
  17. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/pyproject.toml +0 -0
  18. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/__init__.py +0 -0
  19. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/classifier.py +0 -0
  20. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/__init__.py +0 -0
  21. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/common.py +0 -0
  22. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/linux_auditd.py +0 -0
  23. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/macos_eslogger.py +0 -0
  24. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/windows_eventlog.py +0 -0
  25. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/models.py +0 -0
  26. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/os_setup.py +0 -0
  27. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/recorder.py +0 -0
  28. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/redact.py +0 -0
  29. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/settings.py +0 -0
  30. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/shipper.py +0 -0
  31. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/spool.py +0 -0
  32. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agent_sharing.py +0 -0
  33. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agentd.py +0 -0
  34. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/__init__.py +0 -0
  35. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/activity.py +0 -0
  36. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/builder.py +0 -0
  37. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/chat.py +0 -0
  38. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/connectors.py +0 -0
  39. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/__init__.py +0 -0
  40. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/claude_code.py +0 -0
  41. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/http.py +0 -0
  42. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/mcp.py +0 -0
  43. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/n8n.py +0 -0
  44. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/shell.py +0 -0
  45. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/integrations.py +0 -0
  46. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/inventory.py +0 -0
  47. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/library/__init__.py +0 -0
  48. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/manifest.py +0 -0
  49. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/prompt_studio.py +0 -0
  50. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/prompt_template.py +0 -0
  51. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/prompt_vars.py +0 -0
  52. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/run_log.py +0 -0
  53. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/schedules.py +0 -0
  54. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/secrets.py +0 -0
  55. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/ticket_run.py +0 -0
  56. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/usage.py +0 -0
  57. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/varstore.py +0 -0
  58. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/browser_profile.py +0 -0
  59. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/claude_usage.py +0 -0
  60. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/cli.py +0 -0
  61. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/client.py +0 -0
  62. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/collectors/__init__.py +0 -0
  63. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/collectors/files.py +0 -0
  64. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/collectors/process.py +0 -0
  65. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/collectors/screenshot.py +0 -0
  66. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/config.py +0 -0
  67. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/crucial.py +0 -0
  68. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/custom_agents.py +0 -0
  69. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/deferred_tickets.py +0 -0
  70. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/departments.py +0 -0
  71. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/__init__.py +0 -0
  72. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/assets.py +0 -0
  73. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/bootstrap.py +0 -0
  74. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/browser.py +0 -0
  75. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/compare.py +0 -0
  76. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/loop.py +0 -0
  77. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/estimator.py +0 -0
  78. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/exceptions.py +0 -0
  79. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/fallback_handoff.py +0 -0
  80. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/firewall.py +0 -0
  81. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/formats.py +0 -0
  82. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/git_ops.py +0 -0
  83. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/github_fetch.py +0 -0
  84. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/github_ingest.py +0 -0
  85. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/graph_recon.py +0 -0
  86. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/graphify.py +0 -0
  87. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/help_actions.py +0 -0
  88. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/helpdesk.py +0 -0
  89. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/hooks/__init__.py +0 -0
  90. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/hooks/crucial_guard.py +0 -0
  91. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/intake.py +0 -0
  92. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ipc/__init__.py +0 -0
  93. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ipc/electron_bridge.py +0 -0
  94. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ipc/handlers.py +0 -0
  95. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/journal.py +0 -0
  96. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/local_exec.py +0 -0
  97. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/memory_guard.py +0 -0
  98. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/model_policy.py +0 -0
  99. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/__init__.py +0 -0
  100. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/envelope.py +0 -0
  101. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/requests.py +0 -0
  102. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/responses.py +0 -0
  103. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/snapshots.py +0 -0
  104. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/phase_timer.py +0 -0
  105. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/plan_run.py +0 -0
  106. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/prd_progress.py +0 -0
  107. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/proof_readers.py +0 -0
  108. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/providers.py +0 -0
  109. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/py.typed +0 -0
  110. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/resume.py +0 -0
  111. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/router.py +0 -0
  112. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/schedule_tickets.py +0 -0
  113. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/scheduler.py +0 -0
  114. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/self_report.py +0 -0
  115. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/self_report_local.py +0 -0
  116. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/sse.py +0 -0
  117. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/swagger.py +0 -0
  118. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/task_file.py +0 -0
  119. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/task_types.py +0 -0
  120. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/test.py +0 -0
  121. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/test_pipeline.py +0 -0
  122. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ticket_board.py +0 -0
  123. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ticket_fields.py +0 -0
  124. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/tickets.py +0 -0
  125. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/tiers/__init__.py +0 -0
  126. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/tiers/mini_agent.py +0 -0
  127. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/__init__.py +0 -0
  128. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/api.py +0 -0
  129. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/dashboard.py +0 -0
  130. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/health.py +0 -0
  131. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/ip_allowlist.py +0 -0
  132. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/jobs.py +0 -0
  133. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/models.py +0 -0
  134. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/runner.py +0 -0
  135. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/security.py +0 -0
  136. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/server.py +0 -0
  137. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/service.py +0 -0
  138. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/session.py +0 -0
  139. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/setup_manager.py +0 -0
  140. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/agents.html +0 -0
  141. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/chat.html +0 -0
  142. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/custom-agents.html +0 -0
  143. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/default-agents.html +0 -0
  144. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/help.html +0 -0
  145. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/index.html +0 -0
  146. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/report.html +0 -0
  147. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/runs.html +0 -0
  148. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/schedules.html +0 -0
  149. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/setup.html +0 -0
  150. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/tickets.html +0 -0
  151. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/swagger.py +0 -0
  152. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/updater.py +0 -0
  153. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/url_access.py +0 -0
  154. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/vps_health.py +0 -0
  155. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/vps_identity.py +0 -0
  156. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/write_hook.py +0 -0
  157. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/setup.cfg +0 -0
  158. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_claude_runs.py +0 -0
  159. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_collectors.py +0 -0
  160. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_core.py +0 -0
  161. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_live_tracking.py +0 -0
  162. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_macos.py +0 -0
  163. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_os_setup.py +0 -0
  164. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_pipeline.py +0 -0
  165. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_activity.py +0 -0
  166. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_activity_tracking.py +0 -0
  167. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_chat_features.py +0 -0
  168. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_crud_cli.py +0 -0
  169. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_listing.py +0 -0
  170. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_prompt_async.py +0 -0
  171. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_prompt_models.py +0 -0
  172. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_run_ticket.py +0 -0
  173. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_schedules.py +0 -0
  174. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_sharing.py +0 -0
  175. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_workspace_settings.py +0 -0
  176. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agents_connectors_builder.py +0 -0
  177. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_allowed_tools_config.py +0 -0
  178. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_approval_park.py +0 -0
  179. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_auto_agent_dispatch.py +0 -0
  180. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_auto_ticket_queue.py +0 -0
  181. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_browser_profile.py +0 -0
  182. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_cheap_tier.py +0 -0
  183. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_claude_usage_gate.py +0 -0
  184. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_client_jira_projects.py +0 -0
  185. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_config_token_diagnostics.py +0 -0
  186. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_configure_token_owner.py +0 -0
  187. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_console_encoding.py +0 -0
  188. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_crash_recovery.py +0 -0
  189. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_create_safe_retry.py +0 -0
  190. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_deferred_tickets.py +0 -0
  191. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_departments.py +0 -0
  192. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_done_transition.py +0 -0
  193. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_epic_decompose_run.py +0 -0
  194. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_epic_inherited_agent_id.py +0 -0
  195. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_epic_session_isolation.py +0 -0
  196. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_estimator.py +0 -0
  197. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_fallback_cli.py +0 -0
  198. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_fallback_cli_upgrade.py +0 -0
  199. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_firewall_open_on_update.py +0 -0
  200. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_formats.py +0 -0
  201. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_git_action.py +0 -0
  202. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_github_fetch.py +0 -0
  203. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_github_ingest.py +0 -0
  204. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_graph_recon.py +0 -0
  205. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_graphify_build.py +0 -0
  206. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_graphify_hook_install.py +0 -0
  207. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_health.py +0 -0
  208. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_help_actions.py +0 -0
  209. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_help_attachments.py +0 -0
  210. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_help_questions.py +0 -0
  211. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_helpdesk.py +0 -0
  212. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_infographic_data.py +0 -0
  213. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_intake_job_outcome.py +0 -0
  214. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_intake_plan_review.py +0 -0
  215. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_journal.py +0 -0
  216. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_limit_fallback_handoff.py +0 -0
  217. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_local_exec_provider.py +0 -0
  218. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_mcp_route_contract.py +0 -0
  219. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_memory_guard.py +0 -0
  220. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_model_policy.py +0 -0
  221. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_panel_help.py +0 -0
  222. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_panel_ticket_schedules.py +0 -0
  223. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_parallel_tickets.py +0 -0
  224. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_phase_timer.py +0 -0
  225. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_plan_new_command.py +0 -0
  226. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_plan_run_activity.py +0 -0
  227. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_pr_identity.py +0 -0
  228. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_prd_artifact.py +0 -0
  229. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_project_path_resolution.py +0 -0
  230. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_proof_readers.py +0 -0
  231. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_providers.py +0 -0
  232. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_recon_session_isolation.py +0 -0
  233. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_resume.py +0 -0
  234. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_router.py +0 -0
  235. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_run_auto_agent_only.py +0 -0
  236. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_run_outputs.py +0 -0
  237. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_run_verdict_is_honest.py +0 -0
  238. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_schedule_api.py +0 -0
  239. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_schedule_outputs_and_plans.py +0 -0
  240. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_schedule_tickets.py +0 -0
  241. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_scheduler.py +0 -0
  242. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_scheduler_transient_retry.py +0 -0
  243. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_self_report.py +0 -0
  244. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_service_token_warning.py +0 -0
  245. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_stale_panel_restart.py +0 -0
  246. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_swagger_command.py +0 -0
  247. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_task_file_and_plan_run.py +0 -0
  248. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_task_file_format_doc.py +0 -0
  249. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_board.py +0 -0
  250. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_cli.py +0 -0
  251. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_fields.py +0 -0
  252. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_run_resolve_by_id.py +0 -0
  253. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_schedule_and_agent.py +0 -0
  254. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_speed_fixes.py +0 -0
  255. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_tier_flag_parity.py +0 -0
  256. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ui_gate.py +0 -0
  257. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ui_lifespan.py +0 -0
  258. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_update_timer.py +0 -0
  259. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_updater_extras.py +0 -0
  260. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_updater_ignores_cwd.py +0 -0
  261. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_updater_pep668.py +0 -0
  262. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_updater_reports_the_truth.py +0 -0
  263. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_url_access.py +0 -0
  264. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_vps_health.py +0 -0
  265. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_vps_only_reporting.py +0 -0
  266. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_windows_loop_identity.py +0 -0
  267. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_windows_panel_task.py +0 -0
  268. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_windows_stop_and_pidfile.py +0 -0
  269. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_windows_task_paths.py +0 -0
  270. {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/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.7.6
3
+ Version: 1.7.8
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.7.6
3
+ Version: 1.7.8
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
  """AgentOS Desktop SDK — thin HTTPS/SSE client for the Electron app.
2
2
 
3
- Version: 1.7.6
3
+ Version: 1.7.8
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.7.6" # SINGLE SOURCE OF TRUTH — bump on every change; pyproject,
37
+ __version__ = "1.7.8" # 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
@@ -205,8 +205,10 @@ the fix is not in their code, `agentos-auto update` installs the latest.
205
205
  `agentos-auto logs [-f]` and a foreground run colour lines in a terminal
206
206
  (`sdk/log_colors.py`): every status change prints `● KEY → Done` (green) /
207
207
  `→ To Do` (cyan) / `→ In Progress` (yellow) / `→ Backlog` (magenta); failures red,
208
- warnings and parked tickets yellow. The log file stays plain. No colour → the output
209
- isn't a terminal or `NO_COLOR` / `AGENTOS_COLOR=never` is set; `AGENTOS_COLOR=always`
208
+ warnings, parked and partial yellow, `— ok` agent runs green. Same colours in Windows
209
+ PowerShell/cmd (ANSI mode is enabled on the console) and on the panel's Runs live log
210
+ and Schedules run history. The log file stays plain. No colour → the output isn't a
211
+ terminal, an old Windows console refused ANSI mode, or `NO_COLOR` / `AGENTOS_COLOR=never` is set; `AGENTOS_COLOR=always`
210
212
  forces it. `agentos tickets` (= `agentos ticket list`, `sdk/ticket_board.py`) prints
211
213
  the counts per status and the tickets in each; `agentos-auto status` ends with a
212
214
  one-line `board:` count. The control panel shows **Backlog** next to To Do / In Progress / Done: a
@@ -9,8 +9,11 @@ the panel, Help and grep, so colour codes never go into it. Instead
9
9
  ● KEY → In Progress yellow ▶ run headers bold
10
10
  ● KEY → Backlog magenta ticket keys (ABC-123) bold, [timestamps] dim
11
11
 
12
+ ✓ / completed / "— ok" green ↳ transcript pointers, "… idle" dim
13
+
12
14
  Colour is on only for a terminal, and honours ``NO_COLOR`` (any value → off) and
13
- ``AGENTOS_COLOR=always|never``.
15
+ ``AGENTOS_COLOR=always|never``. On Windows (PowerShell, cmd, Windows Terminal) the
16
+ console's ANSI mode is switched on first; a console that refuses gets plain text.
14
17
  """
15
18
  from __future__ import annotations
16
19
 
@@ -31,29 +34,64 @@ _ARROW = re.compile(r"(→\s*)(Done|To Do|In Progress|Backlog|backlog)\b")
31
34
  _MOVED = re.compile(r"\b((?:moved (?:back )?to|returned to|status →)\s+)(Done|To Do|In Progress|Backlog|backlog)\b",
32
35
  re.IGNORECASE)
33
36
  _BAD = re.compile(r"(✗|\bTraceback\b|\berror\b|\bfailed\b|\bnon-compliant\b|\bFAILED\b)", re.IGNORECASE)
34
- _WARN = re.compile(r"(⚠|\bwarning\b|\bparked\b|⏸)", re.IGNORECASE)
35
- _GOOD = re.compile(r"(✓|\bcompleted\b)")
37
+ _WARN = re.compile(r"(⚠|\bwarning\b|\bparked\b|⏸|◐|\bpartial\b)", re.IGNORECASE)
38
+ _GOOD = re.compile(r"(✓|\bcompleted\b|— ok\b)")
39
+ _POINTER = re.compile(r"^(\s*)(↳ \w+:)")
40
+ _IDLE = re.compile(r"^\s*…\s*(?:idle|waiting)\b")
36
41
  _HEADER = re.compile(r"^\s*(?:\[[^\]]*\]\s*)?▶")
37
42
 
38
43
 
44
+ _win_vt: bool | None = None
45
+
46
+
47
+ def _windows_vt() -> bool:
48
+ """Turn on ANSI escape handling for this Windows console (once). conhost —
49
+ what PowerShell and cmd run in — prints raw ``←[32m`` without it."""
50
+ global _win_vt
51
+ if _win_vt is None:
52
+ _win_vt = False
53
+ try:
54
+ import ctypes
55
+ from ctypes import wintypes
56
+ k32 = ctypes.WinDLL("kernel32", use_last_error=True)
57
+ k32.GetStdHandle.restype = wintypes.HANDLE
58
+ ok = False
59
+ for std in (-11, -12): # STD_OUTPUT_HANDLE, STD_ERROR_HANDLE
60
+ h, mode = k32.GetStdHandle(std), wintypes.DWORD()
61
+ if h and k32.GetConsoleMode(h, ctypes.byref(mode)):
62
+ # ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING
63
+ ok = bool(k32.SetConsoleMode(h, mode.value | 0x0001 | 0x0004)) or ok
64
+ _win_vt = ok
65
+ except Exception: # noqa: BLE001
66
+ _win_vt = False
67
+ return _win_vt
68
+
69
+
39
70
  def enabled(stream=None) -> bool:
40
- """Colour this stream? Env first, then whether it is a terminal."""
71
+ """Colour this stream? Env first, then whether it is a terminal (and, on
72
+ Windows, whether its console accepts ANSI colour)."""
41
73
  if os.environ.get("NO_COLOR"):
42
74
  return False
43
75
  pref = (os.environ.get("AGENTOS_COLOR") or "").strip().lower()
44
76
  if pref in ("always", "1", "on", "yes"):
77
+ if sys.platform == "win32":
78
+ _windows_vt()
45
79
  return True
46
80
  if pref in ("never", "0", "off", "no"):
47
81
  return False
48
82
  stream = stream or sys.stdout
49
83
  try:
50
- return bool(stream.isatty())
84
+ tty = bool(stream.isatty())
51
85
  except Exception: # noqa: BLE001
52
86
  return False
87
+ if tty and sys.platform == "win32":
88
+ return _windows_vt()
89
+ return tty
53
90
 
54
91
 
55
92
  def _paint(color: str, text: str) -> str:
56
- return f"{color}{text}{_RESET}"
93
+ # An inner span's reset would end the outer colour too — re-open it after each.
94
+ return f"{color}{text.replace(_RESET, _RESET + color)}{_RESET}"
57
95
 
58
96
 
59
97
  def colorize(line: str) -> str:
@@ -75,6 +113,7 @@ def colorize(line: str) -> str:
75
113
  body = _MOVED.sub(_status, body)
76
114
  body = _KEY.sub(lambda m: _paint(BOLD, m.group(0)), body)
77
115
  body = _STAMP.sub(lambda m: m.group(1) + _paint(DIM, m.group(2)), body)
116
+ body = _POINTER.sub(lambda m: m.group(1) + _paint(DIM, m.group(2)), body)
78
117
 
79
118
  if _HEADER.match(line):
80
119
  body = _paint(BOLD + BLUE, body)
@@ -82,6 +121,8 @@ def colorize(line: str) -> str:
82
121
  body = _paint(YELLOW, body)
83
122
  elif _GOOD.search(line):
84
123
  body = _paint(GREEN, body)
124
+ elif _IDLE.match(line):
125
+ body = _paint(DIM, body)
85
126
  return body + nl
86
127
 
87
128
 
@@ -16,7 +16,7 @@ _ASCII_FALLBACK = str.maketrans({
16
16
  })
17
17
 
18
18
 
19
- def safe_print(message: str = "") -> None:
19
+ def safe_print(message: str = "", **kw) -> None:
20
20
  """``print`` that cannot take a command down on a legacy Windows codepage.
21
21
 
22
22
  :func:`ensure_utf8_stdio` is the real fix and every entry point installs it.
@@ -31,14 +31,15 @@ def safe_print(message: str = "") -> None:
31
31
  ``run_auto._send``, the glyph raises inside the ERROR handler, so the real
32
32
  error is replaced by a UnicodeEncodeError traceback and is never seen at all.
33
33
  """
34
+ # ``end``/``flush``/``file`` pass through to print (run_auto's status lines flush).
34
35
  try:
35
- print(message)
36
+ print(message, **kw)
36
37
  except UnicodeEncodeError:
37
38
  try:
38
- print(message.translate(_ASCII_FALLBACK))
39
+ print(message.translate(_ASCII_FALLBACK), **kw)
39
40
  except UnicodeEncodeError:
40
41
  # A glyph outside the table (engine output echoed into the line).
41
- print(message.encode("ascii", "replace").decode("ascii"))
42
+ print(message.encode("ascii", "replace").decode("ascii"), **kw)
42
43
 
43
44
 
44
45
  def ensure_utf8_stdio() -> None:
@@ -1817,13 +1817,13 @@ def _run_loop(workspace_root: str | None, only_keys: list[str] | None = None,
1817
1817
  + ", ".join(_describe_parked(p) for p in parked)) if parked else ""
1818
1818
  if continuous:
1819
1819
  _idle_s = _idle_refetch_s
1820
- print(f"… idle — watching for new To Do tickets "
1820
+ _print(f"… idle — watching for new To Do tickets "
1821
1821
  f"(re-checking every {int(_idle_s)}s{waiting}; "
1822
1822
  f"`agentos-auto stop` to end)")
1823
1823
  else:
1824
1824
  _idle_s = _PARK_RECHECK_S
1825
1825
  if waiting != last_wait: # say it once per change, not every minute
1826
- print(f"… waiting{waiting} (re-checking every {int(_idle_s)}s; "
1826
+ _print(f"… waiting{waiting} (re-checking every {int(_idle_s)}s; "
1827
1827
  f"`agentos-auto skip KEY` drops one, `agentos-auto stop` ends)")
1828
1828
  last_wait = waiting
1829
1829
  _waited = 0.0
@@ -131,6 +131,30 @@
131
131
  const STATUS_COLOR = { "To Do": "var(--blue)", "In Progress": "var(--amber)", "Done": "var(--green)", "Backlog": "var(--violet)" };
132
132
  function esc(s) { return String(s == null ? "" : s).replace(/[&<>"]/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c])); }
133
133
 
134
+ // One log line as coloured HTML — the panel's twin of sdk/log_colors.colorize:
135
+ // statuses in their own colour, errors red, warnings amber, ▶ headers bold,
136
+ // ticket keys bold, [timestamps] dim. Never changes the text itself.
137
+ const LOG_STATUS = { "done": "lg-done", "to do": "lg-todo", "in progress": "lg-prog", "backlog": "lg-back" };
138
+ function colorLogLine(line) {
139
+ let h = esc(line);
140
+ if (!line.trim()) return h;
141
+ const arrow = /(→\s*)(Done|To Do|In Progress|Backlog|backlog)\b/;
142
+ if (/(✗|\bTraceback\b|\berror\b|\bfailed\b|\bnon-compliant\b)/i.test(line) && !arrow.test(line))
143
+ return `<span class="lg-bad">${h}</span>`;
144
+ const status = (_, pre, word) => `${pre}<b class="${LOG_STATUS[word.toLowerCase()] || ""}">${word}</b>`;
145
+ h = h.replace(/(→\s*)(Done|To Do|In Progress|Backlog|backlog)\b/g, status)
146
+ .replace(/\b((?:moved (?:back )?to|returned to|status →)\s+)(Done|To Do|In Progress|Backlog|backlog)\b/gi, status)
147
+ .replace(/\b[A-Z][A-Z0-9]{1,9}-\d+\b/g, m => `<b>${m}</b>`)
148
+ .replace(/^(\s*(?:•\s*)?)(\[\d{4}-\d{2}-\d{2}[ T][\d:]+Z?\])/, (_, pre, ts) => `${pre}<span class="lg-dim">${ts}</span>`)
149
+ .replace(/(↳ transcript:)/, `<span class="lg-dim">$1</span>`);
150
+ if (/^\s*(?:\[[^\]]*\]\s*)?▶/.test(line)) return `<span class="lg-head">${h}</span>`;
151
+ if (/(⚠|\bwarning\b|\bparked\b|⏸|\bpartial\b)/i.test(line) && !line.includes("→")) return `<span class="lg-warn">${h}</span>`;
152
+ if (/(✓|\bcompleted\b|— ok\b)/.test(line)) return `<span class="lg-good">${h}</span>`;
153
+ if (/^\s*…\s*idle\b/.test(line)) return `<span class="lg-dim">${h}</span>`;
154
+ return h;
155
+ }
156
+ function colorLog(text) { return String(text || "").split("\n").map(colorLogLine).join("\n"); }
157
+
134
158
  // Parse a "KEY=VALUE per line" textarea into an object. Used for ephemeral
135
159
  // run-time secrets (never persisted). Blank lines / lines without "=" ignored.
136
160
  function parseSecrets(id) {
@@ -2386,7 +2410,7 @@
2386
2410
  ev.preventDefault();
2387
2411
  loadHistory(a.getAttribute("data-file"));
2388
2412
  }));
2389
- $("sc-file-body").textContent = d.content || "";
2413
+ $("sc-file-body").innerHTML = colorLog(d.content);
2390
2414
  } catch (e) { toast("Could not load run history", "err"); }
2391
2415
  }
2392
2416
 
@@ -2902,7 +2926,7 @@
2902
2926
  const es = new EventSource("/api/ui/logs/stream?token=" + encodeURIComponent(TOKEN));
2903
2927
  es.onmessage = (ev) => {
2904
2928
  const atBottom = box.scrollHeight - box.scrollTop - box.clientHeight < 40;
2905
- box.textContent += (box.textContent ? "\n" : "") + ev.data;
2929
+ box.insertAdjacentHTML("beforeend", (box.childNodes.length ? "\n" : "") + colorLogLine(ev.data));
2906
2930
  if (atBottom) box.scrollTop = box.scrollHeight;
2907
2931
  };
2908
2932
  es.onerror = () => { es.close(); setTimeout(connectLog, 3000); };
@@ -139,6 +139,17 @@ tr:last-child td { border-bottom: none; }
139
139
  white-space: pre-wrap; word-break: break-word;
140
140
  }
141
141
  .log:empty::before { content: "Waiting for activity…"; color: #64748b; }
142
+ /* Log colours — the panel's twin of sdk/log_colors.py (the .log box is always dark). */
143
+ .log b { color: #f1f5f9; }
144
+ .log .lg-done { color: #4ade80; }
145
+ .log .lg-todo { color: #22d3ee; }
146
+ .log .lg-prog { color: #facc15; }
147
+ .log .lg-back { color: #c084fc; }
148
+ .log .lg-bad { color: #f87171; }
149
+ .log .lg-warn { color: #fbbf24; }
150
+ .log .lg-good { color: #86efac; }
151
+ .log .lg-head { color: #93c5fd; font-weight: 700; }
152
+ .log .lg-dim { color: #64748b; }
142
153
 
143
154
  /* ── Toast ── */
144
155
  #toasts { position: fixed; right: 18px; bottom: 18px; display: flex; flex-direction: column; gap: 10px; z-index: 100; }
@@ -89,3 +89,58 @@ def test_backlog_is_a_dashboard_status_and_queries_lowercase(monkeypatch):
89
89
  assert [t["key"] for t in out["tickets"]] == ["ABC-7"]
90
90
  assert out["tickets"][0]["status"] == "Backlog"
91
91
  assert set(client.asked) == {"backlog"}
92
+
93
+
94
+ def test_the_panel_colours_its_log_views_too():
95
+ """Runs → Live activity log and Schedules → Run history colour lines like the CLI."""
96
+ from pathlib import Path
97
+ static = Path(__file__).resolve().parents[1] / "sdk" / "ui" / "static"
98
+ js, css = (static / "app.js").read_text(), (static / "styles.css").read_text()
99
+ assert "colorLogLine(ev.data)" in js and 'innerHTML = colorLog(d.content)' in js
100
+ for cls in ("lg-done", "lg-todo", "lg-prog", "lg-back", "lg-bad", "lg-warn", "lg-head", "lg-dim"):
101
+ assert f".log .{cls}" in css
102
+
103
+
104
+ def test_agent_run_lines_from_the_log_are_coloured():
105
+ """The lines `agentos-auto logs` shows most: agent runs, pointers, idle, partial."""
106
+ ok = log_colors.colorize(" • [2026-10-27 13:02:08Z] Ran (schedule) agent 'x' — ok (27.9s)")
107
+ assert ok.startswith(log_colors.GREEN) and log_colors.DIM + "[2026-10-27 13:02:08Z]" in ok
108
+ assert log_colors.DIM + "↳ transcript:" in log_colors.colorize(" ↳ transcript: /a/b")
109
+ assert log_colors.colorize("… idle — watching for new To Do tickets").startswith(log_colors.DIM)
110
+ assert log_colors.colorize("◐ partial — 1/12 task(s) carried through").startswith(log_colors.YELLOW)
111
+ for line in (" ↳ transcript: /a/b", "… idle — watching", "◐ partial — 1/12"):
112
+ assert _plain(log_colors.colorize(line)) == line
113
+
114
+
115
+ def test_status_change_line_prints_with_flush(capsys, monkeypatch):
116
+ """Regression: _print(..., flush=True) raised TypeError, so no `● KEY → Done` line ever printed."""
117
+ from sdk import run_auto
118
+ monkeypatch.setenv("AGENTOS_COLOR", "never")
119
+ run_auto._TASK_KEYS["t-1"] = "ABC-1"
120
+ run_auto._print_status_change("t-1", "done")
121
+ assert "● ABC-1 → Done" in capsys.readouterr().out
122
+
123
+
124
+ class _Tty:
125
+ def isatty(self):
126
+ return True
127
+
128
+
129
+ def test_windows_console_gets_ansi_mode_switched_on(monkeypatch):
130
+ monkeypatch.delenv("NO_COLOR", raising=False)
131
+ monkeypatch.delenv("AGENTOS_COLOR", raising=False)
132
+ monkeypatch.setattr(log_colors.sys, "platform", "win32")
133
+ monkeypatch.setattr(log_colors, "_windows_vt", lambda: True)
134
+ assert log_colors.enabled(_Tty())
135
+ monkeypatch.setattr(log_colors, "_windows_vt", lambda: False) # a console that refuses → plain
136
+ assert not log_colors.enabled(_Tty())
137
+
138
+
139
+ def test_windows_vt_never_raises_off_windows(monkeypatch):
140
+ monkeypatch.setattr(log_colors, "_win_vt", None)
141
+ assert log_colors._windows_vt() in (True, False)
142
+
143
+
144
+ def test_a_coloured_line_stays_coloured_after_a_dim_timestamp():
145
+ out = log_colors.colorize(" • [2026-10-27 13:02:08Z] Ran agent 'x' — ok (1s)")
146
+ assert log_colors._RESET + log_colors.GREEN + " Ran agent" in out
File without changes