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.
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/PKG-INFO +1 -1
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/PKG-INFO +1 -1
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/__init__.py +2 -2
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/helpdesk_kb.md +4 -2
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/log_colors.py +47 -6
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/platform_compat.py +5 -4
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/run_auto.py +2 -2
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/app.js +26 -2
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/styles.css +11 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_log_colors_backlog.py +55 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/README.md +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/SOURCES.txt +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/dependency_links.txt +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/entry_points.txt +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/requires.txt +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/devops_bot_sdk.egg-info/top_level.txt +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/pyproject.toml +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/classifier.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/common.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/linux_auditd.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/macos_eslogger.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/collectors/windows_eventlog.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/models.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/os_setup.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/recorder.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/redact.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/settings.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/shipper.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/activity/spool.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agent_sharing.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agentd.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/activity.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/builder.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/chat.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/connectors.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/claude_code.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/http.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/mcp.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/n8n.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/engines/shell.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/integrations.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/inventory.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/library/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/manifest.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/prompt_studio.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/prompt_template.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/prompt_vars.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/run_log.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/schedules.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/secrets.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/ticket_run.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/usage.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/agents/varstore.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/browser_profile.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/claude_usage.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/cli.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/client.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/collectors/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/collectors/files.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/collectors/process.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/collectors/screenshot.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/config.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/crucial.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/custom_agents.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/deferred_tickets.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/departments.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/assets.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/bootstrap.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/browser.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/compare.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/design_verify/loop.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/estimator.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/exceptions.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/fallback_handoff.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/firewall.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/formats.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/git_ops.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/github_fetch.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/github_ingest.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/graph_recon.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/graphify.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/help_actions.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/helpdesk.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/hooks/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/hooks/crucial_guard.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/intake.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ipc/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ipc/electron_bridge.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ipc/handlers.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/journal.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/local_exec.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/memory_guard.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/model_policy.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/envelope.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/requests.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/responses.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/models/snapshots.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/phase_timer.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/plan_run.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/prd_progress.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/proof_readers.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/providers.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/py.typed +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/resume.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/router.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/schedule_tickets.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/scheduler.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/self_report.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/self_report_local.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/sse.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/swagger.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/task_file.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/task_types.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/test.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/test_pipeline.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ticket_board.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ticket_fields.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/tickets.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/tiers/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/tiers/mini_agent.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/__init__.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/api.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/dashboard.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/health.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/ip_allowlist.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/jobs.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/models.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/runner.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/security.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/server.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/service.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/session.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/setup_manager.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/agents.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/chat.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/custom-agents.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/default-agents.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/help.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/index.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/report.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/runs.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/schedules.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/setup.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/static/tickets.html +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/ui/swagger.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/updater.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/url_access.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/vps_health.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/vps_identity.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/sdk/write_hook.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/setup.cfg +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_claude_runs.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_collectors.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_core.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_live_tracking.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_macos.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_os_setup.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_activity_pipeline.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_activity.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_activity_tracking.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_chat_features.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_crud_cli.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_listing.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_prompt_async.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_prompt_models.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_run_ticket.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_schedules.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_sharing.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agent_workspace_settings.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_agents_connectors_builder.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_allowed_tools_config.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_approval_park.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_auto_agent_dispatch.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_auto_ticket_queue.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_browser_profile.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_cheap_tier.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_claude_usage_gate.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_client_jira_projects.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_config_token_diagnostics.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_configure_token_owner.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_console_encoding.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_crash_recovery.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_create_safe_retry.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_deferred_tickets.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_departments.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_done_transition.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_epic_decompose_run.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_epic_inherited_agent_id.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_epic_session_isolation.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_estimator.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_fallback_cli.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_fallback_cli_upgrade.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_firewall_open_on_update.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_formats.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_git_action.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_github_fetch.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_github_ingest.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_graph_recon.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_graphify_build.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_graphify_hook_install.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_health.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_help_actions.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_help_attachments.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_help_questions.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_helpdesk.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_infographic_data.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_intake_job_outcome.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_intake_plan_review.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_journal.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_limit_fallback_handoff.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_local_exec_provider.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_mcp_route_contract.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_memory_guard.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_model_policy.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_panel_help.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_panel_ticket_schedules.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_parallel_tickets.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_phase_timer.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_plan_new_command.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_plan_run_activity.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_pr_identity.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_prd_artifact.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_project_path_resolution.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_proof_readers.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_providers.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_recon_session_isolation.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_resume.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_router.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_run_auto_agent_only.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_run_outputs.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_run_verdict_is_honest.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_schedule_api.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_schedule_outputs_and_plans.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_schedule_tickets.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_scheduler.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_scheduler_transient_retry.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_self_report.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_service_token_warning.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_stale_panel_restart.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_swagger_command.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_task_file_and_plan_run.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_task_file_format_doc.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_board.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_cli.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_fields.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_run_resolve_by_id.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_schedule_and_agent.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ticket_speed_fixes.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_tier_flag_parity.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ui_gate.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_ui_lifespan.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_update_timer.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_updater_extras.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_updater_ignores_cwd.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_updater_pep668.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_updater_reports_the_truth.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_url_access.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_vps_health.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_vps_only_reporting.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_windows_loop_identity.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_windows_panel_task.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_windows_stop_and_pidfile.py +0 -0
- {devops_bot_sdk-1.7.6 → devops_bot_sdk-1.7.8}/tests/test_windows_task_paths.py +0 -0
- {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
|
"""AgentOS Desktop SDK — thin HTTPS/SSE client for the Electron app.
|
|
2
2
|
|
|
3
|
-
Version: 1.7.
|
|
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.
|
|
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
|
|
209
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 => ({ "&": "&", "<": "<", ">": ">", '"': """ }[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").
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|