refactorai-cli 0.2.15__tar.gz → 0.2.16__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.
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/PKG-INFO +1 -1
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/pyproject.toml +1 -1
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/__init__.py +1 -1
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/run_cmds.py +67 -6
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/runtime_cmds.py +18 -1
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/runtime_manager.py +38 -5
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli.egg-info/PKG-INFO +1 -1
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/README.md +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/auth.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/client.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/__init__.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/auth_cmds.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/engine_cmds.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/model_cmds.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/rules_cmds.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/runtime_proxy_cmds.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/setup_cmds.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/control_plane.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/credentials.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/local_constitution.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/local_engine_runtime.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/local_paths.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/main.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/model_policy.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/settings.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/setup_flow.py +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli.egg-info/SOURCES.txt +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli.egg-info/dependency_links.txt +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli.egg-info/entry_points.txt +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli.egg-info/requires.txt +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli.egg-info/top_level.txt +0 -0
- {refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/setup.cfg +0 -0
|
@@ -50,6 +50,8 @@ from refactor_core.execution.structural_ops import structural_compatibility_matr
|
|
|
50
50
|
from refactor_core.gate import evaluate_gate
|
|
51
51
|
from refactor_core.refactor_requests import (
|
|
52
52
|
DEFERRED,
|
|
53
|
+
RequestSuppression,
|
|
54
|
+
RequestWarning,
|
|
53
55
|
clear_requests,
|
|
54
56
|
create_requests,
|
|
55
57
|
list_requests,
|
|
@@ -1555,9 +1557,13 @@ def review(
|
|
|
1555
1557
|
_print_findings(artifact.findings)
|
|
1556
1558
|
|
|
1557
1559
|
# A fresh review supersedes prior refactor requests: replace them with one
|
|
1558
|
-
# RR per finding (central-only; nothing is written into
|
|
1559
|
-
|
|
1560
|
-
|
|
1560
|
+
# RR per actionable finding (central-only; nothing is written into project tree).
|
|
1561
|
+
requests = _replace_requests_with_framework_guardrails(
|
|
1562
|
+
project_root=project_root,
|
|
1563
|
+
findings=artifact.findings,
|
|
1564
|
+
run_id=artifact.run_id,
|
|
1565
|
+
artifact=artifact,
|
|
1566
|
+
)
|
|
1561
1567
|
if requests:
|
|
1562
1568
|
console.print(
|
|
1563
1569
|
f"\n[bold]Created {len(requests)} refactor request(s).[/bold] "
|
|
@@ -1666,9 +1672,11 @@ def code(
|
|
|
1666
1672
|
review_store = create_run(project_root, run_id=review_artifact.run_id)
|
|
1667
1673
|
review_store.write_artifact(review_artifact, target=target, status="completed")
|
|
1668
1674
|
_print_findings(review_artifact.findings)
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1675
|
+
requests = _replace_requests_with_framework_guardrails(
|
|
1676
|
+
project_root=project_root,
|
|
1677
|
+
findings=review_artifact.findings,
|
|
1678
|
+
run_id=review_artifact.run_id,
|
|
1679
|
+
artifact=review_artifact,
|
|
1672
1680
|
)
|
|
1673
1681
|
console.print(f"[bold]Created {len(requests)} refactor request(s).[/bold]")
|
|
1674
1682
|
|
|
@@ -1848,6 +1856,59 @@ def _format_operation_scope(rr) -> str:
|
|
|
1848
1856
|
return "-"
|
|
1849
1857
|
|
|
1850
1858
|
|
|
1859
|
+
def _replace_requests_with_framework_guardrails(
|
|
1860
|
+
*,
|
|
1861
|
+
project_root: Path,
|
|
1862
|
+
findings: list[Finding],
|
|
1863
|
+
run_id: str,
|
|
1864
|
+
artifact: RunArtifact | None = None,
|
|
1865
|
+
) -> list:
|
|
1866
|
+
clear_requests(project_root)
|
|
1867
|
+
requests, suppressions, warnings = create_requests(
|
|
1868
|
+
project_root,
|
|
1869
|
+
findings,
|
|
1870
|
+
run_id=run_id,
|
|
1871
|
+
return_diagnostics=True,
|
|
1872
|
+
)
|
|
1873
|
+
_report_framework_suppressions(suppressions, artifact=artifact)
|
|
1874
|
+
_report_framework_warnings(warnings, artifact=artifact)
|
|
1875
|
+
return requests
|
|
1876
|
+
|
|
1877
|
+
|
|
1878
|
+
def _report_framework_suppressions(
|
|
1879
|
+
suppressions: list[RequestSuppression], *, artifact: RunArtifact | None = None
|
|
1880
|
+
) -> None:
|
|
1881
|
+
if not suppressions:
|
|
1882
|
+
return
|
|
1883
|
+
console.print(
|
|
1884
|
+
f"[yellow]warning:[/yellow] suppressed {len(suppressions)} finding(s) due to framework invariants."
|
|
1885
|
+
)
|
|
1886
|
+
for item in suppressions:
|
|
1887
|
+
console.print(
|
|
1888
|
+
f"[yellow]-[/yellow] {item.location}: {item.message} "
|
|
1889
|
+
f"[dim](framework={item.framework or 'unknown'}, rule={item.rule_id or 'unspecified'})[/dim]"
|
|
1890
|
+
)
|
|
1891
|
+
if artifact is not None:
|
|
1892
|
+
artifact.notes.append(item.note())
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
def _report_framework_warnings(
|
|
1896
|
+
warnings: list[RequestWarning], *, artifact: RunArtifact | None = None
|
|
1897
|
+
) -> None:
|
|
1898
|
+
if not warnings:
|
|
1899
|
+
return
|
|
1900
|
+
console.print(
|
|
1901
|
+
f"[yellow]warning:[/yellow] flagged {len(warnings)} finding(s) with framework caution."
|
|
1902
|
+
)
|
|
1903
|
+
for item in warnings:
|
|
1904
|
+
console.print(
|
|
1905
|
+
f"[yellow]-[/yellow] {item.location}: {item.message} "
|
|
1906
|
+
f"[dim](framework={item.framework or 'unknown'}, rule={item.rule_id or 'unspecified'})[/dim]"
|
|
1907
|
+
)
|
|
1908
|
+
if artifact is not None:
|
|
1909
|
+
artifact.notes.append(item.note())
|
|
1910
|
+
|
|
1911
|
+
|
|
1851
1912
|
def apply(
|
|
1852
1913
|
force: bool = typer.Option(False, "--force", help="Apply even if the quality gate blocks."),
|
|
1853
1914
|
) -> None:
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import typer
|
|
6
6
|
from rich.console import Console
|
|
7
|
+
from rich.progress import BarColumn, DownloadColumn, Progress, TaskID, TextColumn, TimeRemainingColumn, TransferSpeedColumn
|
|
7
8
|
|
|
8
9
|
from refactorai_cli.auth import AuthError, ensure_authenticated
|
|
9
10
|
from refactorai_cli.control_plane import ensure_lease, heartbeat, read_cached_lease, resolve_policy
|
|
@@ -62,7 +63,23 @@ def update(
|
|
|
62
63
|
f"[bold]resolved manifest[/bold]: version={manifest.runtime_version} "
|
|
63
64
|
f"channel={channel}"
|
|
64
65
|
)
|
|
65
|
-
|
|
66
|
+
progress_columns = (
|
|
67
|
+
TextColumn("[progress.description]{task.description}"),
|
|
68
|
+
BarColumn(),
|
|
69
|
+
DownloadColumn(),
|
|
70
|
+
TransferSpeedColumn(),
|
|
71
|
+
TimeRemainingColumn(),
|
|
72
|
+
)
|
|
73
|
+
with Progress(*progress_columns, console=console, transient=True) as progress:
|
|
74
|
+
task_id: TaskID = progress.add_task("Downloading runtime artifact", total=None)
|
|
75
|
+
|
|
76
|
+
def _on_progress(downloaded: int, total: int | None) -> None:
|
|
77
|
+
update_kwargs = {"completed": int(max(downloaded, 0))}
|
|
78
|
+
if total is not None and total > 0:
|
|
79
|
+
update_kwargs["total"] = total
|
|
80
|
+
progress.update(task_id, **update_kwargs)
|
|
81
|
+
|
|
82
|
+
artifact = download_artifact(manifest.artifact_url, progress_cb=_on_progress)
|
|
66
83
|
console.print(f"[bold]downloaded artifact[/bold]: {len(artifact)} bytes")
|
|
67
84
|
if dry_run:
|
|
68
85
|
# Verification happens in activate_runtime; dry-run still checks
|
|
@@ -14,6 +14,7 @@ import platform
|
|
|
14
14
|
from dataclasses import dataclass
|
|
15
15
|
from datetime import datetime, timezone
|
|
16
16
|
from pathlib import Path
|
|
17
|
+
from typing import Callable
|
|
17
18
|
from urllib.parse import urlparse
|
|
18
19
|
|
|
19
20
|
import httpx
|
|
@@ -153,17 +154,49 @@ def resolve_runtime_manifest(*, channel: str = "stable", timeout: float = 20.0)
|
|
|
153
154
|
return manifest
|
|
154
155
|
|
|
155
156
|
|
|
156
|
-
def download_artifact(
|
|
157
|
+
def download_artifact(
|
|
158
|
+
url: str,
|
|
159
|
+
*,
|
|
160
|
+
timeout: float = 60.0,
|
|
161
|
+
progress_cb: Callable[[int, int | None], None] | None = None,
|
|
162
|
+
) -> bytes:
|
|
157
163
|
headers: dict[str, str] = {}
|
|
158
164
|
if _should_send_runtime_auth(url):
|
|
159
165
|
headers["Authorization"] = _runtime_auth_header()
|
|
166
|
+
resolved_timeout = max(float(timeout), 300.0)
|
|
167
|
+
if progress_cb is None:
|
|
168
|
+
try:
|
|
169
|
+
response = httpx.get(url, headers=headers, timeout=resolved_timeout)
|
|
170
|
+
except httpx.HTTPError as exc:
|
|
171
|
+
raise RuntimeError(f"Could not download runtime artifact: {exc}") from exc
|
|
172
|
+
if response.status_code >= 400:
|
|
173
|
+
raise RuntimeError(f"Runtime artifact download failed ({response.status_code})")
|
|
174
|
+
return response.content
|
|
160
175
|
try:
|
|
161
|
-
|
|
176
|
+
with httpx.stream("GET", url, headers=headers, timeout=resolved_timeout) as response:
|
|
177
|
+
if response.status_code >= 400:
|
|
178
|
+
raise RuntimeError(f"Runtime artifact download failed ({response.status_code})")
|
|
179
|
+
total: int | None = None
|
|
180
|
+
total_header = str(response.headers.get("Content-Length") or "").strip()
|
|
181
|
+
if total_header:
|
|
182
|
+
try:
|
|
183
|
+
parsed_total = int(total_header)
|
|
184
|
+
except ValueError:
|
|
185
|
+
parsed_total = -1
|
|
186
|
+
if parsed_total > 0:
|
|
187
|
+
total = parsed_total
|
|
188
|
+
downloaded = 0
|
|
189
|
+
chunks: list[bytes] = []
|
|
190
|
+
progress_cb(downloaded, total)
|
|
191
|
+
for chunk in response.iter_bytes(chunk_size=64 * 1024):
|
|
192
|
+
if not chunk:
|
|
193
|
+
continue
|
|
194
|
+
chunks.append(chunk)
|
|
195
|
+
downloaded += len(chunk)
|
|
196
|
+
progress_cb(downloaded, total)
|
|
162
197
|
except httpx.HTTPError as exc:
|
|
163
198
|
raise RuntimeError(f"Could not download runtime artifact: {exc}") from exc
|
|
164
|
-
|
|
165
|
-
raise RuntimeError(f"Runtime artifact download failed ({response.status_code})")
|
|
166
|
-
return response.content
|
|
199
|
+
return b"".join(chunks)
|
|
167
200
|
|
|
168
201
|
|
|
169
202
|
def _should_send_runtime_auth(url: str) -> bool:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli/commands/runtime_proxy_cmds.py
RENAMED
|
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
|
{refactorai_cli-0.2.15 → refactorai_cli-0.2.16}/refactorai_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|