refactorai-cli 0.5.6__tar.gz → 0.5.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.
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/PKG-INFO +2 -2
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/pyproject.toml +2 -2
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/__init__.py +1 -1
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/pre_push_cmds.py +3 -2
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/run_cmds.py +69 -6
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/local_constitution.py +4 -0
- refactorai_cli-0.5.8/refactorai_cli/local_paths.py +76 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/refactor_branch_store.py +2 -2
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/watch_supervisor.py +2 -2
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli.egg-info/PKG-INFO +2 -2
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli.egg-info/requires.txt +1 -1
- refactorai_cli-0.5.6/refactorai_cli/local_paths.py +0 -40
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/README.md +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/auth.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/client.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/cloud_rr.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/__init__.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/account_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/auth_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/branch_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/cloud_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/engine_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/hook_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/model_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/request_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/rules_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/runtime_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/runtime_proxy_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/setup_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/toolchains_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commands/watch_cmds.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commit_queue.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/commit_telemetry.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/control_plane.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/credentials.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/dotenv_loader.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/git_scope.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/local_engine_runtime.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/main.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/model_policy.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/pre_push_gate.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/review_runner.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/runtime_manager.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/settings.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/setup_flow.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli/watch_state.py +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli.egg-info/SOURCES.txt +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli.egg-info/dependency_links.txt +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli.egg-info/entry_points.txt +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/refactorai_cli.egg-info/top_level.txt +0 -0
- {refactorai_cli-0.5.6 → refactorai_cli-0.5.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: refactorai-cli
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.8
|
|
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.2.
|
|
11
|
+
Requires-Dist: refactorai-core>=3.2.13
|
|
12
12
|
|
|
13
13
|
# refactorai-cli
|
|
14
14
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "refactorai-cli"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.8"
|
|
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.2.
|
|
15
|
+
"refactorai-core>=3.2.13",
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
[project.scripts]
|
|
@@ -72,9 +72,10 @@ def _count_requests(project_root: Path) -> tuple[int, int]:
|
|
|
72
72
|
|
|
73
73
|
def _record_skip(project_root: Path, *, reasons: list[str], reason: str) -> None:
|
|
74
74
|
try:
|
|
75
|
-
from refactor_core.paths import ensure_dir
|
|
75
|
+
from refactor_core.paths import ensure_dir
|
|
76
|
+
from refactor_core.store import resolve_store_dir
|
|
76
77
|
|
|
77
|
-
audit_path = ensure_dir(
|
|
78
|
+
audit_path = ensure_dir(resolve_store_dir(project_root)) / "pre_push_audit.jsonl"
|
|
78
79
|
entry = {
|
|
79
80
|
"at": datetime.now(timezone.utc).isoformat(),
|
|
80
81
|
"event": "pre_push_bypass",
|
|
@@ -90,8 +90,9 @@ from refactor_core.store import (
|
|
|
90
90
|
create_run,
|
|
91
91
|
head_run_dir,
|
|
92
92
|
list_runs,
|
|
93
|
-
project_store_dir,
|
|
94
93
|
prune_runs,
|
|
94
|
+
resolve_project_id as resolve_store_project_id,
|
|
95
|
+
resolve_store_dir,
|
|
95
96
|
read_findings,
|
|
96
97
|
read_report,
|
|
97
98
|
read_sandbox_install_history,
|
|
@@ -913,6 +914,50 @@ def _load_project() -> tuple[Path, object, object]:
|
|
|
913
914
|
return consti_path.parent, constitution, config
|
|
914
915
|
|
|
915
916
|
|
|
917
|
+
def _print_store_context(project_root) -> None:
|
|
918
|
+
"""Surface the resolved project id + central store dir for this run.
|
|
919
|
+
|
|
920
|
+
Makes the id-keyed store observable so a wrong/duplicate binding (or an
|
|
921
|
+
unexpectedly unbound folder) is obvious at a glance instead of surfacing as a
|
|
922
|
+
confusing "resumed old requests" symptom later.
|
|
923
|
+
"""
|
|
924
|
+
try:
|
|
925
|
+
pid = resolve_store_project_id(project_root)
|
|
926
|
+
store_dir = resolve_store_dir(project_root)
|
|
927
|
+
except Exception:
|
|
928
|
+
return
|
|
929
|
+
label = pid or "(unbound / local)"
|
|
930
|
+
console.print(f"[dim]project id:[/dim] {label} [dim]· store:[/dim] {store_dir}")
|
|
931
|
+
|
|
932
|
+
|
|
933
|
+
def _report_store_binding(project_root) -> None:
|
|
934
|
+
"""Doctor diagnostic: resolved project id, store dir, and binding mismatch.
|
|
935
|
+
|
|
936
|
+
A mismatch between the id resolved from ``refactor.config`` and the id stamped
|
|
937
|
+
on the on-disk store record is the fingerprint of a re-linked/duplicated
|
|
938
|
+
project; surfacing it here turns a silent state bug into an obvious check.
|
|
939
|
+
"""
|
|
940
|
+
try:
|
|
941
|
+
from refactor_core.store import project_record
|
|
942
|
+
|
|
943
|
+
pid = resolve_store_project_id(project_root)
|
|
944
|
+
store_dir = resolve_store_dir(project_root)
|
|
945
|
+
except Exception:
|
|
946
|
+
return
|
|
947
|
+
console.print(f"[bold]project id[/bold]: {pid or '(unbound / local)'}")
|
|
948
|
+
console.print(f"[bold]store[/bold]: {store_dir}")
|
|
949
|
+
try:
|
|
950
|
+
record = project_record(project_root) or {}
|
|
951
|
+
record_id = str(record.get("project_id", "") or "")
|
|
952
|
+
except Exception:
|
|
953
|
+
record_id = ""
|
|
954
|
+
if pid and record_id and record_id != pid:
|
|
955
|
+
console.print(
|
|
956
|
+
f"[yellow]store binding[/yellow]: on-disk record id '{record_id}' differs "
|
|
957
|
+
f"from resolved '{pid}'. The store will re-key to the resolved id."
|
|
958
|
+
)
|
|
959
|
+
|
|
960
|
+
|
|
916
961
|
def _warn_raw_key(constitution, config) -> None:
|
|
917
962
|
if has_raw_secret_literal(constitution) or bool(raw_secret_matches_config(config)):
|
|
918
963
|
console.print(
|
|
@@ -1105,7 +1150,9 @@ def init(
|
|
|
1105
1150
|
config_target.write_text(config_text, encoding="utf-8")
|
|
1106
1151
|
|
|
1107
1152
|
constitution = load_constitution(consti_target)
|
|
1108
|
-
record = register_project(
|
|
1153
|
+
record = register_project(
|
|
1154
|
+
project_root, constitution_hash=constitution.content_hash, project_id=project_id
|
|
1155
|
+
)
|
|
1109
1156
|
console.print(f"[green]Created[/green] {consti_target}")
|
|
1110
1157
|
console.print(f"[green]Created[/green] {config_target}")
|
|
1111
1158
|
account_note = f" (account {account_slug})" if account_slug else ""
|
|
@@ -1125,7 +1172,7 @@ def init(
|
|
|
1125
1172
|
"(mode=cloud_byok, env-key-first via provider_key; credential_ref is optional fallback)."
|
|
1126
1173
|
)
|
|
1127
1174
|
console.print(
|
|
1128
|
-
f"[green]Registered[/green] project in central store: {
|
|
1175
|
+
f"[green]Registered[/green] project in central store: {resolve_store_dir(project_root)}"
|
|
1129
1176
|
)
|
|
1130
1177
|
console.print(
|
|
1131
1178
|
f"Only {CONSTITUTION_FILENAME} and {CONFIG_FILENAME} are added to your repo; "
|
|
@@ -2787,7 +2834,14 @@ def review(
|
|
|
2787
2834
|
)
|
|
2788
2835
|
for warning in compliance_resolution.warnings:
|
|
2789
2836
|
console.print(f"[yellow]review: compliance warning:[/yellow] {warning}")
|
|
2790
|
-
|
|
2837
|
+
from refactorai_cli.commit_telemetry import resolve_project_id
|
|
2838
|
+
|
|
2839
|
+
register_project(
|
|
2840
|
+
project_root,
|
|
2841
|
+
constitution_hash=constitution.content_hash,
|
|
2842
|
+
project_id=resolve_project_id(project_root) or None,
|
|
2843
|
+
)
|
|
2844
|
+
_print_store_context(project_root)
|
|
2791
2845
|
_maybe_build_graph(project_root, project_config)
|
|
2792
2846
|
|
|
2793
2847
|
# Commit-scoped review (docs/41 `R28`). Works in every execution mode: local
|
|
@@ -3121,7 +3175,14 @@ def code(
|
|
|
3121
3175
|
)
|
|
3122
3176
|
for warning in compliance_resolution.warnings:
|
|
3123
3177
|
console.print(f"[yellow]code: compliance warning:[/yellow] {warning}")
|
|
3124
|
-
|
|
3178
|
+
from refactorai_cli.commit_telemetry import resolve_project_id
|
|
3179
|
+
|
|
3180
|
+
register_project(
|
|
3181
|
+
project_root,
|
|
3182
|
+
constitution_hash=constitution.content_hash,
|
|
3183
|
+
project_id=resolve_project_id(project_root) or None,
|
|
3184
|
+
)
|
|
3185
|
+
_print_store_context(project_root)
|
|
3125
3186
|
_maybe_build_graph(project_root, project_config)
|
|
3126
3187
|
|
|
3127
3188
|
# Commit-scoped resolve (docs/41 `R28`, Phase 4), symmetric to `review` and
|
|
@@ -4367,7 +4428,7 @@ def gc(
|
|
|
4367
4428
|
removed = prune_runs(project_root, keep=keep)
|
|
4368
4429
|
console.print(
|
|
4369
4430
|
f"[green]Pruned[/green] {len(removed)} run(s); kept {before - len(removed)} "
|
|
4370
|
-
f"under {
|
|
4431
|
+
f"under {resolve_store_dir(project_root)}."
|
|
4371
4432
|
)
|
|
4372
4433
|
|
|
4373
4434
|
|
|
@@ -4602,6 +4663,7 @@ def _cloud_doctor(
|
|
|
4602
4663
|
"""
|
|
4603
4664
|
console.print(f"[bold]project[/bold]: {project_root}")
|
|
4604
4665
|
console.print(f"[bold]mode[/bold]: {execution_mode}")
|
|
4666
|
+
_report_store_binding(project_root)
|
|
4605
4667
|
|
|
4606
4668
|
try:
|
|
4607
4669
|
auth_ctx = ensure_authenticated(project_root)
|
|
@@ -4835,6 +4897,7 @@ def doctor(
|
|
|
4835
4897
|
console.print(f"[bold]mode[/bold]: {mode}")
|
|
4836
4898
|
console.print(f"[bold]provider[/bold]: {provider_name}")
|
|
4837
4899
|
console.print(f"[bold]supported[/bold]: {', '.join(supported_providers())}")
|
|
4900
|
+
_report_store_binding(project_root)
|
|
4838
4901
|
|
|
4839
4902
|
try:
|
|
4840
4903
|
auth_ctx = ensure_authenticated(project_root)
|
|
@@ -46,11 +46,15 @@ def _search_root(start: Path | None = None) -> Path:
|
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
def find_config(start: Path | None = None) -> Path | None:
|
|
49
|
+
# Stop at the enclosing git repo root so we never adopt a parent directory's
|
|
50
|
+
# refactor.config (mirror of refactor_core.constitution discovery guard).
|
|
49
51
|
current = _search_root(start)
|
|
50
52
|
for candidate in [current, *current.parents]:
|
|
51
53
|
config = candidate / CONFIG_FILENAME
|
|
52
54
|
if config.is_file():
|
|
53
55
|
return config
|
|
56
|
+
if (candidate / ".git").exists():
|
|
57
|
+
return None
|
|
54
58
|
return None
|
|
55
59
|
|
|
56
60
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Local path helpers for the standalone CLI package.
|
|
2
|
+
|
|
3
|
+
These mirror the path helpers that were previously imported from ``refactor_core``
|
|
4
|
+
so the public ``refactorai-cli`` package can install without requiring a separate
|
|
5
|
+
``refactor-core`` wheel on PyPI.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import re
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def refactor_home() -> Path:
|
|
16
|
+
override = os.environ.get("REFACTOR_HOME")
|
|
17
|
+
if override:
|
|
18
|
+
return Path(override).expanduser()
|
|
19
|
+
return Path.home() / ".refactor"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def encode_project_path(project_root: Path | str) -> str:
|
|
23
|
+
resolved = str(Path(project_root).resolve())
|
|
24
|
+
return resolved.lstrip("/").replace("/", "-") or "root"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def sanitize_project_id(project_id: str | None) -> str:
|
|
28
|
+
"""Filesystem-safe project id, or ``""`` (mirror of core helper)."""
|
|
29
|
+
value = str(project_id or "").strip()
|
|
30
|
+
if not value or value in {".", ".."}:
|
|
31
|
+
return ""
|
|
32
|
+
safe = re.sub(r"[^A-Za-z0-9._-]+", "-", value).strip("-")
|
|
33
|
+
if safe in {"", ".", ".."}:
|
|
34
|
+
return ""
|
|
35
|
+
return safe[:128]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def project_store_dir_by_id(project_id: str) -> Path:
|
|
39
|
+
safe = sanitize_project_id(project_id)
|
|
40
|
+
if not safe:
|
|
41
|
+
raise ValueError("project_store_dir_by_id requires a non-empty project_id")
|
|
42
|
+
return refactor_home() / "projects" / safe
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def ensure_dir(path: Path, *, mode: int = 0o700) -> Path:
|
|
46
|
+
path.mkdir(parents=True, exist_ok=True, mode=mode)
|
|
47
|
+
return path
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def credentials_path() -> Path:
|
|
51
|
+
return refactor_home() / "credentials.json"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def validation_cache_dir() -> Path:
|
|
55
|
+
return refactor_home() / "cache" / "validation"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def project_store_dir(project_root: Path | str) -> Path:
|
|
59
|
+
"""Legacy path-encoded store dir (backward-compat reads + migration only)."""
|
|
60
|
+
return refactor_home() / "projects" / encode_project_path(project_root)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def resolve_store_dir(project_root: Path | str, *, project_id: str | None = None) -> Path:
|
|
64
|
+
"""Return the project's central store dir, keyed by ``project_id``.
|
|
65
|
+
|
|
66
|
+
Delegates to ``refactor_core.store.resolve_store_dir`` (the single source of
|
|
67
|
+
truth, which also migrates any legacy path-encoded dir) when the core package
|
|
68
|
+
is importable. Falls back to the legacy path-encoded dir for pip-only installs
|
|
69
|
+
without ``refactor_core`` on disk, preserving this module's standalone role.
|
|
70
|
+
"""
|
|
71
|
+
try:
|
|
72
|
+
from refactor_core.store import resolve_store_dir as _core_resolve
|
|
73
|
+
|
|
74
|
+
return _core_resolve(project_root, project_id=project_id)
|
|
75
|
+
except Exception:
|
|
76
|
+
return project_store_dir(project_root)
|
|
@@ -16,7 +16,7 @@ from dataclasses import dataclass
|
|
|
16
16
|
from datetime import datetime, timezone
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
|
|
19
|
-
from refactorai_cli.local_paths import ensure_dir,
|
|
19
|
+
from refactorai_cli.local_paths import ensure_dir, resolve_store_dir
|
|
20
20
|
|
|
21
21
|
_DIR = "refactor_branches"
|
|
22
22
|
|
|
@@ -67,7 +67,7 @@ def refactor_branch_name(
|
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
def _dir(project_root: Path | str) -> Path:
|
|
70
|
-
return
|
|
70
|
+
return resolve_store_dir(project_root) / _DIR
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
def _path(project_root: Path | str, branch: str) -> Path:
|
|
@@ -50,9 +50,9 @@ def lock_path(project_root: Path | str) -> Path:
|
|
|
50
50
|
directory = commit_queue.runs_dir(project_root)
|
|
51
51
|
if directory is None:
|
|
52
52
|
# Outside a git dir (or tests): fall back to the central project store.
|
|
53
|
-
from refactorai_cli.local_paths import
|
|
53
|
+
from refactorai_cli.local_paths import resolve_store_dir
|
|
54
54
|
|
|
55
|
-
directory =
|
|
55
|
+
directory = resolve_store_dir(project_root)
|
|
56
56
|
return Path(directory) / LOCK_FILENAME
|
|
57
57
|
|
|
58
58
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: refactorai-cli
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.8
|
|
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.2.
|
|
11
|
+
Requires-Dist: refactorai-core>=3.2.13
|
|
12
12
|
|
|
13
13
|
# refactorai-cli
|
|
14
14
|
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"""Local path helpers for the standalone CLI package.
|
|
2
|
-
|
|
3
|
-
These mirror the path helpers that were previously imported from ``refactor_core``
|
|
4
|
-
so the public ``refactorai-cli`` package can install without requiring a separate
|
|
5
|
-
``refactor-core`` wheel on PyPI.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import os
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def refactor_home() -> Path:
|
|
15
|
-
override = os.environ.get("REFACTOR_HOME")
|
|
16
|
-
if override:
|
|
17
|
-
return Path(override).expanduser()
|
|
18
|
-
return Path.home() / ".refactor"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def encode_project_path(project_root: Path | str) -> str:
|
|
22
|
-
resolved = str(Path(project_root).resolve())
|
|
23
|
-
return resolved.lstrip("/").replace("/", "-") or "root"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def ensure_dir(path: Path, *, mode: int = 0o700) -> Path:
|
|
27
|
-
path.mkdir(parents=True, exist_ok=True, mode=mode)
|
|
28
|
-
return path
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def credentials_path() -> Path:
|
|
32
|
-
return refactor_home() / "credentials.json"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def validation_cache_dir() -> Path:
|
|
36
|
-
return refactor_home() / "cache" / "validation"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def project_store_dir(project_root: Path | str) -> Path:
|
|
40
|
-
return refactor_home() / "projects" / encode_project_path(project_root)
|
|
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
|