refactorai-cli 0.3.1__tar.gz → 0.3.2__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.3.1 → refactorai_cli-0.3.2}/PKG-INFO +3 -3
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/README.md +1 -1
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/pyproject.toml +2 -2
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/__init__.py +1 -1
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/run_cmds.py +202 -82
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli.egg-info/PKG-INFO +3 -3
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli.egg-info/requires.txt +1 -1
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/auth.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/client.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/__init__.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/auth_cmds.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/cloud_cmds.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/engine_cmds.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/model_cmds.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/rules_cmds.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/runtime_cmds.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/runtime_proxy_cmds.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/commands/setup_cmds.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/control_plane.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/credentials.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/local_constitution.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/local_engine_runtime.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/local_paths.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/main.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/model_policy.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/runtime_manager.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/settings.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli/setup_flow.py +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli.egg-info/SOURCES.txt +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli.egg-info/dependency_links.txt +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli.egg-info/entry_points.txt +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/refactorai_cli.egg-info/top_level.txt +0 -0
- {refactorai_cli-0.3.1 → refactorai_cli-0.3.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: refactorai-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Local-first CLI for the refactor platform
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -8,7 +8,7 @@ Requires-Dist: typer>=0.12.0
|
|
|
8
8
|
Requires-Dist: httpx>=0.27.0
|
|
9
9
|
Requires-Dist: rich>=13.7.0
|
|
10
10
|
Requires-Dist: PyYAML>=6.0.1
|
|
11
|
-
Requires-Dist: refactorai-core>=3.0.
|
|
11
|
+
Requires-Dist: refactorai-core>=3.0.2
|
|
12
12
|
|
|
13
13
|
# refactorai-cli
|
|
14
14
|
|
|
@@ -54,7 +54,7 @@ python -m twine upload ./refactorai-cli/dist/*
|
|
|
54
54
|
## Install test (local)
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
python -m pip install ./refactorai-cli/dist/refactorai_cli-0.3.
|
|
57
|
+
python -m pip install ./refactorai-cli/dist/refactorai_cli-0.3.2-py3-none-any.whl
|
|
58
58
|
refactor --version
|
|
59
59
|
```
|
|
60
60
|
|
|
@@ -42,7 +42,7 @@ python -m twine upload ./refactorai-cli/dist/*
|
|
|
42
42
|
## Install test (local)
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
python -m pip install ./refactorai-cli/dist/refactorai_cli-0.3.
|
|
45
|
+
python -m pip install ./refactorai-cli/dist/refactorai_cli-0.3.2-py3-none-any.whl
|
|
46
46
|
refactor --version
|
|
47
47
|
```
|
|
48
48
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "refactorai-cli"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.2"
|
|
4
4
|
description = "Local-first CLI for the refactor platform"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -12,7 +12,7 @@ dependencies = [
|
|
|
12
12
|
"httpx>=0.27.0",
|
|
13
13
|
"rich>=13.7.0",
|
|
14
14
|
"PyYAML>=6.0.1",
|
|
15
|
-
"refactorai-core>=3.0.
|
|
15
|
+
"refactorai-core>=3.0.2",
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
[project.scripts]
|
|
@@ -665,29 +665,7 @@ def _cloud_inference(
|
|
|
665
665
|
}
|
|
666
666
|
|
|
667
667
|
if execution_mode == "cloud_byok":
|
|
668
|
-
|
|
669
|
-
provider_key = str(constitution.get_setting("provider_key", "") or "").strip()
|
|
670
|
-
credential_ref = str(constitution.get_setting("credential_ref", "") or "").strip()
|
|
671
|
-
|
|
672
|
-
# Env-key-first BYOK path: when provider_key is configured (typically via
|
|
673
|
-
# ${ENV_VAR} interpolation), prefer it over credential_ref.
|
|
674
|
-
if provider_key:
|
|
675
|
-
if not provider_name or provider_name.lower() == "cloud":
|
|
676
|
-
raise RuntimeError(
|
|
677
|
-
"cloud_byok with provider_key requires an explicit provider "
|
|
678
|
-
"(e.g. provider: openai)."
|
|
679
|
-
)
|
|
680
|
-
payload["provider_key"] = provider_key
|
|
681
|
-
payload["provider"] = provider_name
|
|
682
|
-
elif credential_ref:
|
|
683
|
-
payload["credential_ref"] = credential_ref
|
|
684
|
-
if provider_name and provider_name.lower() != "cloud":
|
|
685
|
-
payload["provider"] = provider_name
|
|
686
|
-
else:
|
|
687
|
-
raise RuntimeError(
|
|
688
|
-
"cloud_byok requires either `provider_key` (preferred env-key path) "
|
|
689
|
-
"or `credential_ref` (platform-stored credential path) in refactor.config."
|
|
690
|
-
)
|
|
668
|
+
_apply_byok_payload(payload, constitution)
|
|
691
669
|
|
|
692
670
|
idempotency_key = _stable_idempotency_key(
|
|
693
671
|
account_id=auth_ctx.account_id,
|
|
@@ -764,6 +742,185 @@ def _cloud_inference(
|
|
|
764
742
|
)
|
|
765
743
|
|
|
766
744
|
|
|
745
|
+
def _apply_byok_payload(payload: dict, constitution) -> None:
|
|
746
|
+
"""Populate BYOK provider fields on a cloud inference ``payload`` in place.
|
|
747
|
+
|
|
748
|
+
Env-key-first: prefer ``provider_key`` (typically ``${ENV_VAR}``) over a
|
|
749
|
+
platform-stored ``credential_ref``. Shared by the review/refactor path and
|
|
750
|
+
the per-RR proposal path so BYOK resolution stays consistent.
|
|
751
|
+
"""
|
|
752
|
+
provider_name = str(constitution.get_setting("provider", "") or "").strip()
|
|
753
|
+
provider_key = str(constitution.get_setting("provider_key", "") or "").strip()
|
|
754
|
+
credential_ref = str(constitution.get_setting("credential_ref", "") or "").strip()
|
|
755
|
+
|
|
756
|
+
if provider_key:
|
|
757
|
+
if not provider_name or provider_name.lower() == "cloud":
|
|
758
|
+
raise RuntimeError(
|
|
759
|
+
"cloud_byok with provider_key requires an explicit provider "
|
|
760
|
+
"(e.g. provider: openai)."
|
|
761
|
+
)
|
|
762
|
+
payload["provider_key"] = provider_key
|
|
763
|
+
payload["provider"] = provider_name
|
|
764
|
+
elif credential_ref:
|
|
765
|
+
payload["credential_ref"] = credential_ref
|
|
766
|
+
if provider_name and provider_name.lower() != "cloud":
|
|
767
|
+
payload["provider"] = provider_name
|
|
768
|
+
else:
|
|
769
|
+
raise RuntimeError(
|
|
770
|
+
"cloud_byok requires either `provider_key` (preferred env-key path) "
|
|
771
|
+
"or `credential_ref` (platform-stored credential path) in refactor.config."
|
|
772
|
+
)
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
def _post_cloud_inference(*, payload: dict, idempotency_key: str, auth_ctx, execution_mode: str) -> dict:
|
|
776
|
+
"""POST a cloud inference request and return the parsed JSON body.
|
|
777
|
+
|
|
778
|
+
Centralizes transport + status-code error mapping so the per-RR proposal
|
|
779
|
+
path surfaces the same remediation messages as review/refactor.
|
|
780
|
+
"""
|
|
781
|
+
try:
|
|
782
|
+
response = httpx.post(
|
|
783
|
+
f"{platform_url()}/v1/inference/refactor",
|
|
784
|
+
headers={
|
|
785
|
+
"Authorization": f"Bearer {auth_ctx.key.key}",
|
|
786
|
+
"Content-Type": "application/json",
|
|
787
|
+
"Idempotency-Key": idempotency_key,
|
|
788
|
+
},
|
|
789
|
+
json=payload,
|
|
790
|
+
timeout=45.0,
|
|
791
|
+
)
|
|
792
|
+
except httpx.HTTPError as exc:
|
|
793
|
+
raise RuntimeError(f"Could not reach cloud inference service: {exc}") from exc
|
|
794
|
+
|
|
795
|
+
if response.status_code == 401:
|
|
796
|
+
raise RuntimeError("Cloud inference unauthorized (developer key invalid or revoked).")
|
|
797
|
+
if response.status_code == 402:
|
|
798
|
+
if execution_mode == "cloud_byok":
|
|
799
|
+
raise RuntimeError(
|
|
800
|
+
"Cloud BYOK is not enabled for this account (missing `run:byok`). "
|
|
801
|
+
"Contact your admin to enable BYOK cloud execution."
|
|
802
|
+
)
|
|
803
|
+
raise RuntimeError("Cloud inference requires paid tier (`mode: cloud_managed`).")
|
|
804
|
+
if response.status_code == 404 and execution_mode == "cloud_byok":
|
|
805
|
+
raise RuntimeError(
|
|
806
|
+
"BYOK credential not found or not owned by this account. "
|
|
807
|
+
"Check `refactor cloud credentials list` and your `credential_ref`."
|
|
808
|
+
)
|
|
809
|
+
if response.status_code == 429:
|
|
810
|
+
raise RuntimeError("Cloud inference quota exhausted or rate-limited.")
|
|
811
|
+
if response.status_code >= 400:
|
|
812
|
+
raise RuntimeError(f"Cloud inference failed ({response.status_code}): {response.text[:500]}")
|
|
813
|
+
|
|
814
|
+
return response.json() if response.content else {}
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
class _CloudRRProvider:
|
|
818
|
+
"""Lightweight provider stub for cloud RR execution (R22).
|
|
819
|
+
|
|
820
|
+
The executor reads ``provider.model_id`` for the artifact and would call
|
|
821
|
+
``provider.complete(...)`` for proposals/tests. In cloud mode the proposal
|
|
822
|
+
and test-gen hooks are supplied, so ``complete`` is never invoked; it raises
|
|
823
|
+
to make any accidental local-prompt path explicit rather than silent.
|
|
824
|
+
"""
|
|
825
|
+
|
|
826
|
+
def __init__(self, *, model_id: str) -> None:
|
|
827
|
+
self.model_id = model_id
|
|
828
|
+
self.provider_name = "cloud"
|
|
829
|
+
self.supports_refactor = True
|
|
830
|
+
|
|
831
|
+
def complete(self, system: str, user: str) -> str: # pragma: no cover - guard
|
|
832
|
+
raise RuntimeError(
|
|
833
|
+
"cloud RR execution must use server-side proposal hooks; "
|
|
834
|
+
"provider.complete should not be called."
|
|
835
|
+
)
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
def _cloud_rr_hooks(
|
|
839
|
+
*,
|
|
840
|
+
project_root: Path,
|
|
841
|
+
constitution,
|
|
842
|
+
model_hint: str | None,
|
|
843
|
+
) -> tuple[Callable, Callable, str]:
|
|
844
|
+
"""Build (propose_fn, gen_test_fn, model_id) for cloud per-RR execution (R22).
|
|
845
|
+
|
|
846
|
+
The returned callables match the executor's hook contract. They send the
|
|
847
|
+
single RR's context + current source to the platform, which builds the
|
|
848
|
+
proprietary prompts server-side and returns a proposal / characterization
|
|
849
|
+
test. Idempotency keys include the RR id and attempt so retries of distinct
|
|
850
|
+
RRs/attempts never collapse into a replayed result.
|
|
851
|
+
"""
|
|
852
|
+
execution_mode = _cloud_execution_mode(constitution) or "cloud_managed"
|
|
853
|
+
auth_ctx = ensure_authenticated(project_root)
|
|
854
|
+
constitution_body = getattr(constitution, "body", "") or ""
|
|
855
|
+
resolved_model = model_hint or str(
|
|
856
|
+
constitution.get_setting("model_id", "managed-default") or "managed-default"
|
|
857
|
+
)
|
|
858
|
+
|
|
859
|
+
def _rr_context(rr) -> dict:
|
|
860
|
+
return {
|
|
861
|
+
"location": getattr(rr, "location", ""),
|
|
862
|
+
"file_path": getattr(rr, "file_path", ""),
|
|
863
|
+
"category": getattr(rr, "category", ""),
|
|
864
|
+
"severity": getattr(rr, "severity", ""),
|
|
865
|
+
"recommendation": getattr(rr, "recommendation", ""),
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
def _base_payload(stage: str, rr, source: str) -> dict:
|
|
869
|
+
payload = {
|
|
870
|
+
"stage": stage,
|
|
871
|
+
"execution_mode": execution_mode,
|
|
872
|
+
"constitution_hash": constitution.content_hash,
|
|
873
|
+
"constitution_body": constitution_body,
|
|
874
|
+
"rr_context": _rr_context(rr),
|
|
875
|
+
"source": source,
|
|
876
|
+
"max_alerts": int(constitution.get_setting("max_alerts_per_run", 5) or 5),
|
|
877
|
+
"model_hint": resolved_model,
|
|
878
|
+
}
|
|
879
|
+
if execution_mode == "cloud_byok":
|
|
880
|
+
_apply_byok_payload(payload, constitution)
|
|
881
|
+
return payload
|
|
882
|
+
|
|
883
|
+
def _idempotency(stage: str, rr, attempt: int) -> str:
|
|
884
|
+
seed = "|".join(
|
|
885
|
+
[
|
|
886
|
+
auth_ctx.account_id,
|
|
887
|
+
execution_mode,
|
|
888
|
+
stage,
|
|
889
|
+
constitution.content_hash,
|
|
890
|
+
str(getattr(rr, "rr_id", "")),
|
|
891
|
+
str(int(attempt)),
|
|
892
|
+
]
|
|
893
|
+
)
|
|
894
|
+
return hashlib.sha256(seed.encode("utf-8")).hexdigest()
|
|
895
|
+
|
|
896
|
+
def propose_fn(rr, source: str, prior_failures: list[str]) -> dict:
|
|
897
|
+
# Attempt number is derived from prior failures so each retry gets a
|
|
898
|
+
# distinct idempotency key (1-based).
|
|
899
|
+
attempt = len(prior_failures or []) + 1
|
|
900
|
+
payload = _base_payload("rr_propose", rr, source)
|
|
901
|
+
payload["prior_failures"] = list(prior_failures or [])
|
|
902
|
+
data = _post_cloud_inference(
|
|
903
|
+
payload=payload,
|
|
904
|
+
idempotency_key=_idempotency("rr_propose", rr, attempt),
|
|
905
|
+
auth_ctx=auth_ctx,
|
|
906
|
+
execution_mode=execution_mode,
|
|
907
|
+
)
|
|
908
|
+
proposal = data.get("proposal") or {}
|
|
909
|
+
if not isinstance(proposal, dict):
|
|
910
|
+
return {}
|
|
911
|
+
return proposal
|
|
912
|
+
|
|
913
|
+
def gen_test_fn(rr, source: str) -> dict:
|
|
914
|
+
# Server-side characterization-test generation is not part of Phase 1.
|
|
915
|
+
# Returning no test makes the executor fall back to the configured test
|
|
916
|
+
# command for behavioral verification (parity with a local run that has
|
|
917
|
+
# no generated test). This keeps cloud RR execution safe today and lets
|
|
918
|
+
# a future phase add a dedicated server test-gen stage.
|
|
919
|
+
return {}
|
|
920
|
+
|
|
921
|
+
return propose_fn, gen_test_fn, resolved_model
|
|
922
|
+
|
|
923
|
+
|
|
767
924
|
def _load_project() -> tuple[Path, object, object]:
|
|
768
925
|
files = find_project_files()
|
|
769
926
|
if not files:
|
|
@@ -1802,7 +1959,8 @@ def review(
|
|
|
1802
1959
|
if _sandbox_enabled(project_config):
|
|
1803
1960
|
if cloud:
|
|
1804
1961
|
console.print(
|
|
1805
|
-
"[dim]review: sandbox.enabled is ignored in
|
|
1962
|
+
f"[dim]review: sandbox.enabled is ignored in "
|
|
1963
|
+
f"{_cloud_execution_mode(constitution)} mode.[/dim]"
|
|
1806
1964
|
)
|
|
1807
1965
|
else:
|
|
1808
1966
|
sandbox_ctx = _ensure_sandbox_ready(
|
|
@@ -2029,7 +2187,8 @@ def code(
|
|
|
2029
2187
|
if _sandbox_enabled(project_config):
|
|
2030
2188
|
if cloud:
|
|
2031
2189
|
console.print(
|
|
2032
|
-
"[dim]code: sandbox.enabled is ignored in
|
|
2190
|
+
f"[dim]code: sandbox.enabled is ignored in "
|
|
2191
|
+
f"{_cloud_execution_mode(constitution)} mode.[/dim]"
|
|
2033
2192
|
)
|
|
2034
2193
|
else:
|
|
2035
2194
|
sandbox_ctx = _ensure_sandbox_ready(
|
|
@@ -2133,64 +2292,23 @@ def code(
|
|
|
2133
2292
|
console.print("[green]No issues to refactor.[/green]")
|
|
2134
2293
|
return
|
|
2135
2294
|
|
|
2136
|
-
|
|
2137
|
-
# Cloud modes generate patches via the platform inference API rather
|
|
2138
|
-
# than the local RR interactive loop. Reuse prior review findings as
|
|
2139
|
-
# prompt context; fall back to the latest stored review findings when
|
|
2140
|
-
# requests were carried over from an earlier run.
|
|
2141
|
-
if not cloud_review_findings:
|
|
2142
|
-
existing_dir = head_run_dir(project_root)
|
|
2143
|
-
if existing_dir is not None:
|
|
2144
|
-
try:
|
|
2145
|
-
cloud_review_findings = [
|
|
2146
|
-
Finding.model_validate(item) for item in (read_findings(existing_dir) or [])
|
|
2147
|
-
]
|
|
2148
|
-
except Exception:
|
|
2149
|
-
cloud_review_findings = []
|
|
2150
|
-
with console.status("[cyan]code[/cyan] generating patches (cloud)...", spinner="dots"):
|
|
2151
|
-
artifact = _cloud_inference(
|
|
2152
|
-
stage="refactor",
|
|
2153
|
-
project_root=project_root,
|
|
2154
|
-
constitution=constitution,
|
|
2155
|
-
target=target,
|
|
2156
|
-
model_hint=provider,
|
|
2157
|
-
findings=cloud_review_findings,
|
|
2158
|
-
)
|
|
2159
|
-
cloud_store = create_run(project_root, run_id=artifact.run_id)
|
|
2160
|
-
cloud_store.write_artifact(artifact, target=target, status="completed")
|
|
2295
|
+
from refactor_core.execution.rr_executor import run_refactor_requests
|
|
2161
2296
|
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2297
|
+
# Cloud and local both drive the SAME per-RR interactive loop (R22 cloud
|
|
2298
|
+
# RR parity). The only difference is where proposals come from: cloud
|
|
2299
|
+
# passes server-side proposal hooks; local uses the local provider and
|
|
2300
|
+
# client-side prompt builders. This guarantees identical UX (proposal
|
|
2301
|
+
# diff + approval prompt), status transitions, and outcomes table.
|
|
2302
|
+
cloud_propose_fn = None
|
|
2303
|
+
cloud_gen_test_fn = None
|
|
2304
|
+
rr_provider = selected_provider
|
|
2305
|
+
if cloud:
|
|
2306
|
+
cloud_propose_fn, cloud_gen_test_fn, cloud_model_id = _cloud_rr_hooks(
|
|
2307
|
+
project_root=project_root,
|
|
2308
|
+
constitution=constitution,
|
|
2309
|
+
model_hint=provider,
|
|
2169
2310
|
)
|
|
2170
|
-
|
|
2171
|
-
if apply:
|
|
2172
|
-
gate_mode = str(constitution.get_setting("gate_mode", "strict") or "strict")
|
|
2173
|
-
diffs = [p.diff_text for p in (artifact.patches or [])]
|
|
2174
|
-
if not diffs:
|
|
2175
|
-
console.print("[dim]No patches to apply.[/dim]")
|
|
2176
|
-
else:
|
|
2177
|
-
_apply_diffs(
|
|
2178
|
-
project_root,
|
|
2179
|
-
cloud_store.run_dir,
|
|
2180
|
-
diffs,
|
|
2181
|
-
artifact.gate.status,
|
|
2182
|
-
gate_mode,
|
|
2183
|
-
force,
|
|
2184
|
-
project_config,
|
|
2185
|
-
)
|
|
2186
|
-
elif artifact.patches:
|
|
2187
|
-
console.print(
|
|
2188
|
-
"[dim]Review patches with `refactor diff`, then apply with "
|
|
2189
|
-
"`refactor code --apply` or `refactor apply`.[/dim]"
|
|
2190
|
-
)
|
|
2191
|
-
return
|
|
2192
|
-
|
|
2193
|
-
from refactor_core.execution.rr_executor import run_refactor_requests
|
|
2311
|
+
rr_provider = _CloudRRProvider(model_id=cloud_model_id)
|
|
2194
2312
|
|
|
2195
2313
|
with console.status("[cyan]code[/cyan] running...", spinner="dots") as status:
|
|
2196
2314
|
rr_config = (
|
|
@@ -2201,13 +2319,15 @@ def code(
|
|
|
2201
2319
|
artifact = run_refactor_requests(
|
|
2202
2320
|
project_root=project_root,
|
|
2203
2321
|
constitution=constitution,
|
|
2204
|
-
provider=
|
|
2322
|
+
provider=rr_provider,
|
|
2205
2323
|
requests=requests,
|
|
2206
2324
|
config=rr_config,
|
|
2207
2325
|
progress_cb=_rr_progress_logger(status=status),
|
|
2208
2326
|
approval_cb=_rr_approval_prompt(auto_approve=auto_approve),
|
|
2209
2327
|
on_rr_failure=on_rr_failure,
|
|
2210
2328
|
equivalence_mode=equivalence,
|
|
2329
|
+
propose_fn=cloud_propose_fn,
|
|
2330
|
+
gen_test_fn=cloud_gen_test_fn,
|
|
2211
2331
|
)
|
|
2212
2332
|
except typer.Exit:
|
|
2213
2333
|
# Intentional exits (e.g. gate-blocked apply) keep their own code/message.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: refactorai-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Local-first CLI for the refactor platform
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -8,7 +8,7 @@ Requires-Dist: typer>=0.12.0
|
|
|
8
8
|
Requires-Dist: httpx>=0.27.0
|
|
9
9
|
Requires-Dist: rich>=13.7.0
|
|
10
10
|
Requires-Dist: PyYAML>=6.0.1
|
|
11
|
-
Requires-Dist: refactorai-core>=3.0.
|
|
11
|
+
Requires-Dist: refactorai-core>=3.0.2
|
|
12
12
|
|
|
13
13
|
# refactorai-cli
|
|
14
14
|
|
|
@@ -54,7 +54,7 @@ python -m twine upload ./refactorai-cli/dist/*
|
|
|
54
54
|
## Install test (local)
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
python -m pip install ./refactorai-cli/dist/refactorai_cli-0.3.
|
|
57
|
+
python -m pip install ./refactorai-cli/dist/refactorai_cli-0.3.2-py3-none-any.whl
|
|
58
58
|
refactor --version
|
|
59
59
|
```
|
|
60
60
|
|
|
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
|