kin: KIN-083 Healthcheck claude CLI auth: перед запуском pipeline проверять что claude залогинен (быстрый claude -p 'ok' --output-format json, проверить is_error и 'Not logged in'). Если не залогинен — не запускать pipeline, а показать ошибку 'Claude CLI requires login' в GUI с инструкцией.

This commit is contained in:
Gros Frumos 2026-03-16 15:48:09 +02:00
parent a80679ae72
commit bfc8f1c0bb
18 changed files with 1390 additions and 57 deletions

View file

@ -179,12 +179,13 @@ class TestAutoApprove:
class TestAutoRerunOnPermissionDenied:
"""Runner повторяет шаг при permission issues, останавливается по лимиту (1 retry)."""
@patch("agents.runner._get_changed_files", return_value=[])
@patch("agents.runner._run_autocommit")
@patch("agents.runner._run_learning_extraction")
@patch("core.followup.generate_followups")
@patch("agents.runner.run_hooks")
@patch("agents.runner.subprocess.run")
def test_auto_mode_retries_on_permission_error(self, mock_run, mock_hooks, mock_followup, mock_learn, mock_autocommit, conn):
def test_auto_mode_retries_on_permission_error(self, mock_run, mock_hooks, mock_followup, mock_learn, mock_autocommit, mock_changed_files, conn):
"""Auto-режим: при permission denied runner делает 1 retry с allow_write=True."""
mock_run.side_effect = [
_mock_permission_denied(), # 1-й вызов: permission error
@ -261,12 +262,13 @@ class TestAutoRerunOnPermissionDenied:
task = models.get_task(conn, "VDOL-001")
assert task["status"] == "blocked"
@patch("agents.runner._get_changed_files", return_value=[])
@patch("agents.runner._run_autocommit")
@patch("agents.runner._run_learning_extraction")
@patch("core.followup.generate_followups")
@patch("agents.runner.run_hooks")
@patch("agents.runner.subprocess.run")
def test_subsequent_steps_use_allow_write_after_retry(self, mock_run, mock_hooks, mock_followup, mock_learn, mock_autocommit, conn):
def test_subsequent_steps_use_allow_write_after_retry(self, mock_run, mock_hooks, mock_followup, mock_learn, mock_autocommit, mock_changed_files, conn):
"""После успешного retry все следующие шаги тоже используют allow_write."""
mock_run.side_effect = [
_mock_permission_denied(), # Шаг 1: permission error