refactorai-cli 0.2.14__tar.gz → 0.2.15__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.14 → refactorai_cli-0.2.15}/PKG-INFO +1 -1
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/pyproject.toml +1 -1
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/__init__.py +1 -1
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/run_cmds.py +189 -17
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli.egg-info/PKG-INFO +1 -1
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/README.md +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/auth.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/client.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/__init__.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/auth_cmds.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/engine_cmds.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/model_cmds.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/rules_cmds.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/runtime_cmds.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/runtime_proxy_cmds.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/commands/setup_cmds.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/control_plane.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/credentials.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/local_constitution.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/local_engine_runtime.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/local_paths.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/main.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/model_policy.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/runtime_manager.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/settings.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli/setup_flow.py +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli.egg-info/SOURCES.txt +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli.egg-info/dependency_links.txt +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli.egg-info/entry_points.txt +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli.egg-info/requires.txt +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli.egg-info/top_level.txt +0 -0
- {refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/setup.cfg +0 -0
|
@@ -46,13 +46,18 @@ from refactor_core.budgeting import compute_budget
|
|
|
46
46
|
from refactor_core.capabilities import resolve_capabilities
|
|
47
47
|
from refactor_core.execution import resolve_mode, run_with_mode
|
|
48
48
|
from refactor_core.execution.rr_executor import run_refactor_requests
|
|
49
|
+
from refactor_core.execution.structural_ops import structural_compatibility_matrix
|
|
49
50
|
from refactor_core.gate import evaluate_gate
|
|
50
51
|
from refactor_core.refactor_requests import (
|
|
52
|
+
DEFERRED,
|
|
51
53
|
clear_requests,
|
|
52
54
|
create_requests,
|
|
53
55
|
list_requests,
|
|
56
|
+
load_request,
|
|
54
57
|
pending_requests,
|
|
58
|
+
save_request,
|
|
55
59
|
)
|
|
60
|
+
from refactor_core.refactor_ops import remediation_hint
|
|
56
61
|
from refactor_core.indexing import index_target
|
|
57
62
|
from refactor_core.models import Finding, GeneratedTest, PatchGroup, RunArtifact
|
|
58
63
|
from refactor_core.pipeline import build_refactor_prompt, build_review_prompt
|
|
@@ -486,6 +491,20 @@ def _rr_progress_logger(status=None) -> Callable[[dict], None]:
|
|
|
486
491
|
elif ev == "run_done":
|
|
487
492
|
if status:
|
|
488
493
|
status.update("[green]code[/green] completed.")
|
|
494
|
+
elif ev == "rr_deferred":
|
|
495
|
+
if status:
|
|
496
|
+
status.update("[yellow]code[/yellow] deferred unsupported operation...")
|
|
497
|
+
reason = str(event.get("reason", "") or "")[:300]
|
|
498
|
+
hint = remediation_hint(reason)
|
|
499
|
+
suffix = f" [dim]hint: {hint}[/dim]" if hint else ""
|
|
500
|
+
console.print(f"[yellow] ↷ deferred:[/yellow] {reason}{suffix}")
|
|
501
|
+
elif ev == "rr_failed":
|
|
502
|
+
if status:
|
|
503
|
+
status.update("[red]code[/red] failed unsupported operation.")
|
|
504
|
+
reason = str(event.get("reason", "") or "")[:300]
|
|
505
|
+
hint = remediation_hint(reason)
|
|
506
|
+
suffix = f" [dim]hint: {hint}[/dim]" if hint else ""
|
|
507
|
+
console.print(f"[red] ✗ failed:[/red] {reason}{suffix}")
|
|
489
508
|
|
|
490
509
|
return _log
|
|
491
510
|
|
|
@@ -1573,6 +1592,16 @@ def code(
|
|
|
1573
1592
|
"--auto-approve",
|
|
1574
1593
|
help="Skip interactive issue approvals in agentic code mode.",
|
|
1575
1594
|
),
|
|
1595
|
+
on_rr_failure: str = typer.Option(
|
|
1596
|
+
"stop",
|
|
1597
|
+
"--on-rr-failure",
|
|
1598
|
+
help="RR failure behavior: stop | continue | defer.",
|
|
1599
|
+
),
|
|
1600
|
+
equivalence: str = typer.Option(
|
|
1601
|
+
"strict",
|
|
1602
|
+
"--equivalence",
|
|
1603
|
+
help="Equivalence policy: strict | balanced.",
|
|
1604
|
+
),
|
|
1576
1605
|
) -> None:
|
|
1577
1606
|
"""Work through refactor requests one by one, applying & verifying each.
|
|
1578
1607
|
|
|
@@ -1656,19 +1685,21 @@ def code(
|
|
|
1656
1685
|
return
|
|
1657
1686
|
|
|
1658
1687
|
with console.status("[cyan]code[/cyan] running...", spinner="dots") as status:
|
|
1688
|
+
rr_config = (
|
|
1689
|
+
dict(getattr(project_config, "settings", {}) or {})
|
|
1690
|
+
| ({"sandbox": {"enabled": True}} if sandbox_on else {})
|
|
1691
|
+
| ({"_sandbox_context": sandbox_ctx} if sandbox_ctx else {})
|
|
1692
|
+
) or dict(getattr(constitution, "settings", {}) or {})
|
|
1659
1693
|
artifact = run_refactor_requests(
|
|
1660
1694
|
project_root=project_root,
|
|
1661
1695
|
constitution=constitution,
|
|
1662
1696
|
provider=selected_provider,
|
|
1663
1697
|
requests=requests,
|
|
1664
|
-
config=
|
|
1665
|
-
dict(getattr(project_config, "settings", {}) or {})
|
|
1666
|
-
| ({"sandbox": {"enabled": True}} if sandbox_on else {})
|
|
1667
|
-
| ({"_sandbox_context": sandbox_ctx} if sandbox_ctx else {})
|
|
1668
|
-
)
|
|
1669
|
-
or dict(getattr(constitution, "settings", {}) or {}),
|
|
1698
|
+
config=rr_config,
|
|
1670
1699
|
progress_cb=_rr_progress_logger(status=status),
|
|
1671
1700
|
approval_cb=_rr_approval_prompt(auto_approve=auto_approve),
|
|
1701
|
+
on_rr_failure=on_rr_failure,
|
|
1702
|
+
equivalence_mode=equivalence,
|
|
1672
1703
|
)
|
|
1673
1704
|
except Exception as exc:
|
|
1674
1705
|
console.print(f"[red]Refactor failed:[/red] {exc}")
|
|
@@ -1686,32 +1717,137 @@ def code(
|
|
|
1686
1717
|
)
|
|
1687
1718
|
|
|
1688
1719
|
|
|
1689
|
-
def requests(
|
|
1690
|
-
|
|
1720
|
+
def requests(
|
|
1721
|
+
show_operation: bool = typer.Option(
|
|
1722
|
+
False,
|
|
1723
|
+
"--show-operation",
|
|
1724
|
+
help="Show operation scope details (source/target/split map).",
|
|
1725
|
+
),
|
|
1726
|
+
retry_deferred: bool = typer.Option(
|
|
1727
|
+
False,
|
|
1728
|
+
"--retry-deferred",
|
|
1729
|
+
help="Re-run deferred requests immediately.",
|
|
1730
|
+
),
|
|
1731
|
+
provider: str | None = typer.Option(
|
|
1732
|
+
None,
|
|
1733
|
+
"--provider",
|
|
1734
|
+
help="Provider override when --retry-deferred is used.",
|
|
1735
|
+
),
|
|
1736
|
+
auto_approve: bool = typer.Option(
|
|
1737
|
+
False,
|
|
1738
|
+
"--auto-approve",
|
|
1739
|
+
help="Auto-approve retry-deferred proposals.",
|
|
1740
|
+
),
|
|
1741
|
+
on_rr_failure: str = typer.Option(
|
|
1742
|
+
"stop",
|
|
1743
|
+
"--on-rr-failure",
|
|
1744
|
+
help="RR failure behavior for retry: stop | continue | defer.",
|
|
1745
|
+
),
|
|
1746
|
+
equivalence: str = typer.Option(
|
|
1747
|
+
"strict",
|
|
1748
|
+
"--equivalence",
|
|
1749
|
+
help="Equivalence policy for retry: strict | balanced.",
|
|
1750
|
+
),
|
|
1751
|
+
) -> None:
|
|
1752
|
+
"""List refactor requests and optionally re-run deferred requests."""
|
|
1691
1753
|
_require_auth()
|
|
1692
|
-
project_root,
|
|
1754
|
+
project_root, constitution, project_config = _load_project()
|
|
1755
|
+
if retry_deferred:
|
|
1756
|
+
deferred_rrs = [rr for rr in list_requests(project_root) if rr.status == DEFERRED]
|
|
1757
|
+
if not deferred_rrs:
|
|
1758
|
+
console.print("[dim]No deferred requests to retry.[/dim]")
|
|
1759
|
+
else:
|
|
1760
|
+
selected_provider = get_provider(
|
|
1761
|
+
constitution, project_root=project_root, provider_name=provider
|
|
1762
|
+
)
|
|
1763
|
+
for rr in deferred_rrs:
|
|
1764
|
+
rr.status = "pending"
|
|
1765
|
+
loaded = load_request(project_root, rr.rr_id)
|
|
1766
|
+
if loaded is not None:
|
|
1767
|
+
loaded.status = "pending"
|
|
1768
|
+
save_request(project_root, loaded)
|
|
1769
|
+
with console.status("[cyan]requests[/cyan] retrying deferred...", spinner="dots") as status:
|
|
1770
|
+
_ = run_refactor_requests(
|
|
1771
|
+
project_root=project_root,
|
|
1772
|
+
constitution=constitution,
|
|
1773
|
+
provider=selected_provider,
|
|
1774
|
+
requests=[rr for rr in list_requests(project_root) if rr.status == "pending"],
|
|
1775
|
+
config=dict(getattr(project_config, "settings", {}) or {}),
|
|
1776
|
+
progress_cb=_rr_progress_logger(status=status),
|
|
1777
|
+
approval_cb=_rr_approval_prompt(auto_approve=auto_approve),
|
|
1778
|
+
on_rr_failure=on_rr_failure,
|
|
1779
|
+
equivalence_mode=equivalence,
|
|
1780
|
+
)
|
|
1693
1781
|
rrs = list_requests(project_root)
|
|
1694
1782
|
if not rrs:
|
|
1695
1783
|
console.print("[dim]No refactor requests. Run `refactor review` to create them.[/dim]")
|
|
1696
1784
|
return
|
|
1697
1785
|
table = Table(title="Refactor requests", show_lines=False)
|
|
1698
1786
|
table.add_column("issue")
|
|
1787
|
+
table.add_column("operation", no_wrap=True)
|
|
1788
|
+
if show_operation:
|
|
1789
|
+
table.add_column("scope")
|
|
1699
1790
|
table.add_column("severity", no_wrap=True)
|
|
1700
1791
|
table.add_column("category")
|
|
1701
1792
|
table.add_column("status", no_wrap=True)
|
|
1702
1793
|
table.add_column("attempts", no_wrap=True)
|
|
1703
|
-
color = {
|
|
1794
|
+
color = {
|
|
1795
|
+
"applied": "green",
|
|
1796
|
+
"denied": "yellow",
|
|
1797
|
+
"failed": "red",
|
|
1798
|
+
"deferred": "yellow",
|
|
1799
|
+
"pending": "cyan",
|
|
1800
|
+
"in_progress": "cyan",
|
|
1801
|
+
}
|
|
1704
1802
|
for rr in rrs:
|
|
1705
|
-
|
|
1803
|
+
row = [
|
|
1706
1804
|
rr.location,
|
|
1707
|
-
rr.
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1805
|
+
rr.operation_type,
|
|
1806
|
+
]
|
|
1807
|
+
if show_operation:
|
|
1808
|
+
row.append(_format_operation_scope(rr))
|
|
1809
|
+
row.extend(
|
|
1810
|
+
[
|
|
1811
|
+
rr.severity,
|
|
1812
|
+
rr.category,
|
|
1813
|
+
f"[{color.get(rr.status, 'white')}]{rr.status}[/{color.get(rr.status, 'white')}]",
|
|
1814
|
+
str(rr.attempt_count),
|
|
1815
|
+
]
|
|
1711
1816
|
)
|
|
1817
|
+
table.add_row(*row)
|
|
1712
1818
|
console.print(table)
|
|
1713
1819
|
|
|
1714
1820
|
|
|
1821
|
+
def _format_operation_scope(rr) -> str:
|
|
1822
|
+
scope = getattr(rr, "scope", None)
|
|
1823
|
+
if scope is None:
|
|
1824
|
+
return "-"
|
|
1825
|
+
source = str(getattr(scope, "source_path", "") or "").strip()
|
|
1826
|
+
target = str(getattr(scope, "target_path", "") or "").strip()
|
|
1827
|
+
split_map = dict(getattr(scope, "split_map", {}) or {})
|
|
1828
|
+
symbol = str(getattr(scope, "symbol", "") or "").strip()
|
|
1829
|
+
new_name = str(getattr(scope, "new_name", "") or "").strip()
|
|
1830
|
+
if split_map:
|
|
1831
|
+
if "__sources__" in split_map:
|
|
1832
|
+
srcs = ", ".join(str(item) for item in split_map.get("__sources__", []))
|
|
1833
|
+
return f"merge: [{srcs}] -> {target or '?'}"
|
|
1834
|
+
chunks = []
|
|
1835
|
+
for dst, symbols in split_map.items():
|
|
1836
|
+
if symbols:
|
|
1837
|
+
chunks.append(f"{dst}({','.join(str(s) for s in symbols)})")
|
|
1838
|
+
else:
|
|
1839
|
+
chunks.append(str(dst))
|
|
1840
|
+
src_label = source or "?"
|
|
1841
|
+
return f"split: {src_label} -> {', '.join(chunks)}"
|
|
1842
|
+
if source or target:
|
|
1843
|
+
if source and target:
|
|
1844
|
+
return f"{source} -> {target}"
|
|
1845
|
+
return source or target
|
|
1846
|
+
if symbol and new_name:
|
|
1847
|
+
return f"{symbol} -> {new_name}"
|
|
1848
|
+
return "-"
|
|
1849
|
+
|
|
1850
|
+
|
|
1715
1851
|
def apply(
|
|
1716
1852
|
force: bool = typer.Option(False, "--force", help="Apply even if the quality gate blocks."),
|
|
1717
1853
|
) -> None:
|
|
@@ -2113,6 +2249,7 @@ def doctor(
|
|
|
2113
2249
|
)
|
|
2114
2250
|
|
|
2115
2251
|
_report_intelligence(project_root)
|
|
2252
|
+
_report_structural_readiness(project_root, project_config)
|
|
2116
2253
|
|
|
2117
2254
|
if skip_ping:
|
|
2118
2255
|
console.print("[dim]Skipping provider live ping (--skip-ping).[/dim]")
|
|
@@ -2246,6 +2383,39 @@ def _report_sandbox(project_root: Path, config) -> None:
|
|
|
2246
2383
|
console.print(f" [dim]latest command results: {len(latest.get('results', []))} (failures={failures})[/dim]")
|
|
2247
2384
|
|
|
2248
2385
|
|
|
2386
|
+
def _report_structural_readiness(project_root: Path, config) -> None:
|
|
2387
|
+
settings = dict(getattr(config, "settings", {}) or {})
|
|
2388
|
+
refactor_cfg = settings.get("refactor", {})
|
|
2389
|
+
if not isinstance(refactor_cfg, dict):
|
|
2390
|
+
refactor_cfg = {}
|
|
2391
|
+
structural = refactor_cfg.get("structural", {})
|
|
2392
|
+
if not isinstance(structural, dict):
|
|
2393
|
+
structural = {}
|
|
2394
|
+
eq_mode = str(structural.get("equivalence_mode", "strict") or "strict")
|
|
2395
|
+
rr_policy = str(structural.get("on_rr_failure", "stop") or "stop")
|
|
2396
|
+
rewrite_mode = str(structural.get("reference_rewrite", "auto") or "auto")
|
|
2397
|
+
langs = structural.get("languages", [])
|
|
2398
|
+
rollout = str(structural.get("rollout", "default") or "default")
|
|
2399
|
+
canary_percent = int(structural.get("canary_percent", 20) or 20)
|
|
2400
|
+
if not isinstance(langs, list):
|
|
2401
|
+
langs = []
|
|
2402
|
+
console.print(
|
|
2403
|
+
f"[bold]structural mode[/bold]: equivalence={eq_mode} on_rr_failure={rr_policy} "
|
|
2404
|
+
f"rollout={rollout} canary_percent={canary_percent}"
|
|
2405
|
+
)
|
|
2406
|
+
console.print(f"[bold]reference rewrite[/bold]: {rewrite_mode} [{', '.join(str(x) for x in langs) or 'defaults'}]")
|
|
2407
|
+
matrix = structural_compatibility_matrix()
|
|
2408
|
+
enabled_langs = [name for name, ok in matrix.items() if ok]
|
|
2409
|
+
disabled_langs = [name for name, ok in matrix.items() if not ok]
|
|
2410
|
+
console.print(
|
|
2411
|
+
f"[bold]adapter matrix[/bold]: enabled={', '.join(enabled_langs) or '-'}; "
|
|
2412
|
+
f"degraded={', '.join(disabled_langs) or '-'}"
|
|
2413
|
+
)
|
|
2414
|
+
rrs = list_requests(project_root)
|
|
2415
|
+
deferred = sum(1 for rr in rrs if rr.status == DEFERRED)
|
|
2416
|
+
console.print(f"[bold]deferred requests[/bold]: {deferred}")
|
|
2417
|
+
|
|
2418
|
+
|
|
2249
2419
|
def _maybe_build_graph(project_root: Path, config) -> None:
|
|
2250
2420
|
"""Build + persist the symbol graph when intelligence.graph is enabled."""
|
|
2251
2421
|
settings = dict(getattr(config, "settings", {}) or {})
|
|
@@ -2275,20 +2445,22 @@ def _print_rr_summary(artifact) -> None:
|
|
|
2275
2445
|
return
|
|
2276
2446
|
table = Table(title="Refactor request outcomes", show_lines=False)
|
|
2277
2447
|
table.add_column("issue")
|
|
2448
|
+
table.add_column("operation", no_wrap=True)
|
|
2278
2449
|
table.add_column("outcome", no_wrap=True)
|
|
2279
2450
|
table.add_column("attempts", no_wrap=True)
|
|
2280
|
-
color = {"applied": "green", "denied": "yellow", "failed": "red"}
|
|
2451
|
+
color = {"applied": "green", "denied": "yellow", "failed": "red", "deferred": "yellow"}
|
|
2281
2452
|
for o in outcomes:
|
|
2282
2453
|
outcome = str(o.get("outcome", "?"))
|
|
2283
2454
|
table.add_row(
|
|
2284
2455
|
str(o.get("location", "?")),
|
|
2456
|
+
str(o.get("operation_type", "content_patch")),
|
|
2285
2457
|
f"[{color.get(outcome, 'white')}]{outcome}[/{color.get(outcome, 'white')}]",
|
|
2286
2458
|
str(o.get("attempts", 0)),
|
|
2287
2459
|
)
|
|
2288
2460
|
console.print(table)
|
|
2289
2461
|
console.print(
|
|
2290
2462
|
f"[dim]applied={trace.get('applied', 0)} denied={trace.get('denied', 0)} "
|
|
2291
|
-
f"failed={trace.get('failed', 0)}[/dim]"
|
|
2463
|
+
f"failed={trace.get('failed', 0)} deferred={trace.get('deferred', 0)}[/dim]"
|
|
2292
2464
|
)
|
|
2293
2465
|
|
|
2294
2466
|
|
|
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.14 → refactorai_cli-0.2.15}/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
|
|
File without changes
|
{refactorai_cli-0.2.14 → refactorai_cli-0.2.15}/refactorai_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|