refactorai-cli 0.2.0__tar.gz → 0.2.3__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.
Files changed (31) hide show
  1. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/PKG-INFO +5 -2
  2. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/README.md +4 -0
  3. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/pyproject.toml +1 -2
  4. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/__init__.py +1 -1
  5. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/auth.py +1 -1
  6. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/commands/engine_cmds.py +1 -1
  7. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/commands/model_cmds.py +1 -1
  8. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/control_plane.py +1 -1
  9. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/credentials.py +2 -2
  10. refactorai_cli-0.2.3/refactorai_cli/local_constitution.py +76 -0
  11. refactorai_cli-0.2.3/refactorai_cli/local_engine_runtime.py +243 -0
  12. refactorai_cli-0.2.3/refactorai_cli/local_paths.py +40 -0
  13. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/main.py +2 -19
  14. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/runtime_manager.py +1 -1
  15. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/settings.py +1 -1
  16. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/setup_flow.py +2 -2
  17. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli.egg-info/PKG-INFO +5 -2
  18. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli.egg-info/SOURCES.txt +3 -0
  19. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli.egg-info/requires.txt +0 -1
  20. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/client.py +0 -0
  21. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/commands/__init__.py +0 -0
  22. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/commands/auth_cmds.py +0 -0
  23. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/commands/rules_cmds.py +0 -0
  24. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/commands/run_cmds.py +0 -0
  25. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/commands/runtime_cmds.py +0 -0
  26. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/commands/setup_cmds.py +0 -0
  27. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli/model_policy.py +0 -0
  28. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli.egg-info/dependency_links.txt +0 -0
  29. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli.egg-info/entry_points.txt +0 -0
  30. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/refactorai_cli.egg-info/top_level.txt +0 -0
  31. {refactorai_cli-0.2.0 → refactorai_cli-0.2.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.2.0
3
+ Version: 0.2.3
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,6 @@ 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: refactor-core>=0.1.0
12
11
 
13
12
  # refactorai-cli
14
13
 
@@ -18,6 +17,10 @@ Public CLI package for Refactor.
18
17
  - Installed command: `refactor`
19
18
  - Python module package: `refactorai_cli`
20
19
 
20
+ By default, the CLI targets `https://api.refactorai.codes`.
21
+ Use `REFACTOR_PLATFORM_URL` only when you need to override the control-plane URL
22
+ (for self-hosted or local development environments).
23
+
21
24
  ## Local development install
22
25
 
23
26
  From repository root:
@@ -6,6 +6,10 @@ Public CLI package for Refactor.
6
6
  - Installed command: `refactor`
7
7
  - Python module package: `refactorai_cli`
8
8
 
9
+ By default, the CLI targets `https://api.refactorai.codes`.
10
+ Use `REFACTOR_PLATFORM_URL` only when you need to override the control-plane URL
11
+ (for self-hosted or local development environments).
12
+
9
13
  ## Local development install
10
14
 
11
15
  From repository root:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "refactorai-cli"
3
- version = "0.2.0"
3
+ version = "0.2.3"
4
4
  description = "Local-first CLI for the refactor platform"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -9,7 +9,6 @@ dependencies = [
9
9
  "httpx>=0.27.0",
10
10
  "rich>=13.7.0",
11
11
  "PyYAML>=6.0.1",
12
- "refactor-core>=0.1.0",
13
12
  ]
14
13
 
15
14
  [project.scripts]
@@ -5,4 +5,4 @@ the shared `refactor_core` pipeline from a project folder while staying
5
5
  authenticated to the hosted platform via a developer key.
6
6
  """
7
7
 
8
- __version__ = "0.2.0"
8
+ __version__ = "0.2.3"
@@ -11,7 +11,7 @@ from dataclasses import dataclass
11
11
  from datetime import datetime, timezone
12
12
  from pathlib import Path
13
13
 
14
- from refactor_core.paths import ensure_dir, validation_cache_dir
14
+ from refactorai_cli.local_paths import ensure_dir, validation_cache_dir
15
15
 
16
16
  from refactorai_cli.client import PlatformClient, PlatformError
17
17
  from refactorai_cli.credentials import ResolvedKey, resolve_developer_key
@@ -7,7 +7,7 @@ import os
7
7
  import typer
8
8
  from rich.console import Console
9
9
 
10
- from refactor_core.engine_runtime import (
10
+ from refactorai_cli.local_engine_runtime import (
11
11
  DEFAULT_ENGINE_CONTAINER,
12
12
  DEFAULT_ENGINE_IMAGE,
13
13
  DEFAULT_ENGINE_PORT,
@@ -6,7 +6,7 @@ import typer
6
6
  from rich.console import Console
7
7
  from rich.table import Table
8
8
 
9
- from refactor_core.engine_runtime import DEFAULT_ENGINE_CONTAINER, probe_model, read_engine_state, resolve_runtime
9
+ from refactorai_cli.local_engine_runtime import DEFAULT_ENGINE_CONTAINER, probe_model, read_engine_state, resolve_runtime
10
10
 
11
11
  from refactorai_cli.model_policy import (
12
12
  detect_machine_profile,
@@ -12,7 +12,7 @@ from pathlib import Path
12
12
 
13
13
  import httpx
14
14
 
15
- from refactor_core.paths import ensure_dir, refactor_home
15
+ from refactorai_cli.local_paths import ensure_dir, refactor_home
16
16
 
17
17
  from refactorai_cli.credentials import resolve_developer_key
18
18
  from refactorai_cli.settings import platform_url, policy_signing_key
@@ -13,8 +13,8 @@ import os
13
13
  from dataclasses import dataclass
14
14
  from pathlib import Path
15
15
 
16
- from refactor_core.constitution import find_config, load_config
17
- from refactor_core.paths import credentials_path, ensure_dir, refactor_home
16
+ from refactorai_cli.local_constitution import find_config, load_config
17
+ from refactorai_cli.local_paths import credentials_path, ensure_dir, refactor_home
18
18
 
19
19
  from refactorai_cli.settings import env_api_key
20
20
 
@@ -0,0 +1,76 @@
1
+ """Lightweight config discovery/parsing helpers for the CLI package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import re
7
+ from dataclasses import dataclass, field
8
+ from pathlib import Path
9
+
10
+ import yaml
11
+
12
+ CONFIG_FILENAME = "refactor.config"
13
+ _ENV_TOKEN = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}")
14
+
15
+
16
+ @dataclass
17
+ class RefactorConfig:
18
+ settings: dict = field(default_factory=dict)
19
+ raw: str = ""
20
+ path: Path | None = None
21
+
22
+ def get_setting(self, key: str, default=None):
23
+ return self.settings.get(key, default)
24
+
25
+
26
+ def _interpolate_env(value):
27
+ if isinstance(value, str):
28
+ return _ENV_TOKEN.sub(lambda m: os.environ.get(m.group(1), ""), value)
29
+ if isinstance(value, dict):
30
+ return {k: _interpolate_env(v) for k, v in value.items()}
31
+ if isinstance(value, list):
32
+ return [_interpolate_env(v) for v in value]
33
+ return value
34
+
35
+
36
+ def _search_root(start: Path | None = None) -> Path:
37
+ if start is not None:
38
+ try:
39
+ return Path(start).resolve()
40
+ except OSError:
41
+ return Path.home().resolve()
42
+ try:
43
+ return Path.cwd().resolve()
44
+ except OSError:
45
+ return Path.home().resolve()
46
+
47
+
48
+ def find_config(start: Path | None = None) -> Path | None:
49
+ current = _search_root(start)
50
+ for candidate in [current, *current.parents]:
51
+ config = candidate / CONFIG_FILENAME
52
+ if config.is_file():
53
+ return config
54
+ return None
55
+
56
+
57
+ def parse_config(text: str, *, path: Path | None = None) -> RefactorConfig:
58
+ normalized = text.replace("\r\n", "\n")
59
+ try:
60
+ loaded = yaml.safe_load(normalized)
61
+ except yaml.YAMLError:
62
+ loaded = {}
63
+ if isinstance(loaded, dict):
64
+ if isinstance(loaded.get("settings"), dict):
65
+ settings = dict(loaded.get("settings") or {})
66
+ else:
67
+ settings = dict(loaded)
68
+ else:
69
+ settings = {}
70
+ settings = _interpolate_env(settings)
71
+ return RefactorConfig(settings=settings, raw=text, path=path)
72
+
73
+
74
+ def load_config(path: Path) -> RefactorConfig:
75
+ text = Path(path).read_text(encoding="utf-8")
76
+ return parse_config(text, path=Path(path))
@@ -0,0 +1,243 @@
1
+ """Local engine runtime helpers shipped with the CLI package.
2
+
3
+ These are copied from the shared runtime helpers so setup/engine/model commands
4
+ remain usable without a separate ``refactor-core`` package dependency.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import shutil
11
+ import subprocess
12
+ from datetime import datetime, timezone
13
+ from pathlib import Path
14
+
15
+ from refactorai_cli.local_paths import ensure_dir, refactor_home
16
+
17
+ DEFAULT_ENGINE_IMAGE = "docker.io/library/alpine:3.20"
18
+ DEFAULT_ENGINE_CONTAINER = "refactor-engine"
19
+ DEFAULT_ENGINE_PORT = 17777
20
+ DEFAULT_ENGINE_PROFILE = "cpu-small"
21
+ ENGINE_DIR = "engine"
22
+ ENGINE_STATE_FILE = "engine.json"
23
+ ENGINE_MODELS_DIR = "models"
24
+ ENGINE_CACHE_DIR = "cache/ollama"
25
+
26
+
27
+ def _now_iso() -> str:
28
+ return datetime.now(timezone.utc).isoformat()
29
+
30
+
31
+ def engine_store_dir() -> Path:
32
+ return refactor_home() / ENGINE_DIR
33
+
34
+
35
+ def engine_state_path() -> Path:
36
+ return engine_store_dir() / ENGINE_STATE_FILE
37
+
38
+
39
+ def _default_state() -> dict:
40
+ return {
41
+ "runtime": "podman",
42
+ "container_name": DEFAULT_ENGINE_CONTAINER,
43
+ "image": DEFAULT_ENGINE_IMAGE,
44
+ "port": DEFAULT_ENGINE_PORT,
45
+ "profile": DEFAULT_ENGINE_PROFILE,
46
+ "status": "down",
47
+ "updated_at": "",
48
+ }
49
+
50
+
51
+ def read_engine_state() -> dict:
52
+ path = engine_state_path()
53
+ if not path.is_file():
54
+ return _default_state()
55
+ try:
56
+ data = json.loads(path.read_text(encoding="utf-8"))
57
+ except (json.JSONDecodeError, OSError):
58
+ return _default_state()
59
+ out = _default_state()
60
+ out.update({k: data.get(k, v) for k, v in out.items()})
61
+ return out
62
+
63
+
64
+ def write_engine_state(state: dict) -> None:
65
+ ensure_dir(engine_store_dir())
66
+ merged = _default_state()
67
+ merged.update(state or {})
68
+ merged["updated_at"] = _now_iso()
69
+ path = engine_state_path()
70
+ tmp = path.with_suffix(path.suffix + ".tmp")
71
+ tmp.write_text(json.dumps(merged, indent=2), encoding="utf-8")
72
+ tmp.replace(path)
73
+
74
+
75
+ def resolve_runtime(preferred: str = "podman") -> tuple[str | None, str]:
76
+ pref = (preferred or "podman").strip().lower()
77
+ candidates: list[str] = ["podman"] if pref in {"", "auto", "podman"} else [pref]
78
+ for runtime in candidates:
79
+ if shutil.which(runtime):
80
+ return runtime, ""
81
+ return None, "Podman not found. Install podman and retry (`refactor engine up`)."
82
+
83
+
84
+ def _run(cmd: list[str]) -> subprocess.CompletedProcess:
85
+ return subprocess.run(cmd, capture_output=True, text=True)
86
+
87
+
88
+ def _exists(runtime: str, name: str) -> bool:
89
+ proc = _run([runtime, "container", "exists", name])
90
+ return proc.returncode == 0
91
+
92
+
93
+ def _running(runtime: str, name: str) -> bool:
94
+ proc = _run([runtime, "inspect", "-f", "{{.State.Running}}", name])
95
+ return proc.returncode == 0 and proc.stdout.strip().lower() == "true"
96
+
97
+
98
+ def _health(runtime: str, name: str) -> bool:
99
+ proc = _run([runtime, "exec", name, "sh", "-lc", "command -v ollama >/dev/null 2>&1"])
100
+ return proc.returncode == 0
101
+
102
+
103
+ def ensure_engine_up(
104
+ *,
105
+ runtime: str,
106
+ image: str = DEFAULT_ENGINE_IMAGE,
107
+ container_name: str = DEFAULT_ENGINE_CONTAINER,
108
+ profile: str = DEFAULT_ENGINE_PROFILE,
109
+ port: int = DEFAULT_ENGINE_PORT,
110
+ rebuild: bool = False,
111
+ ) -> tuple[bool, str, dict]:
112
+ models_dir = ensure_dir(refactor_home() / ENGINE_MODELS_DIR)
113
+ cache_dir = ensure_dir(refactor_home() / ENGINE_CACHE_DIR)
114
+ if rebuild and _exists(runtime, container_name):
115
+ _run([runtime, "rm", "-f", container_name])
116
+ if not _exists(runtime, container_name):
117
+ proc = _run(
118
+ [
119
+ runtime,
120
+ "run",
121
+ "-d",
122
+ "--name",
123
+ container_name,
124
+ "-p",
125
+ f"127.0.0.1:{int(port)}:{int(port)}",
126
+ "-v",
127
+ f"{models_dir}:/root/.ollama/models:Z",
128
+ "-v",
129
+ f"{cache_dir}:/root/.cache/ollama:Z",
130
+ image,
131
+ "sleep",
132
+ "infinity",
133
+ ]
134
+ )
135
+ if proc.returncode != 0:
136
+ detail = (proc.stderr or proc.stdout or "").strip()
137
+ return False, f"Failed to create engine container: {detail}", {}
138
+ elif not _running(runtime, container_name):
139
+ proc = _run([runtime, "start", container_name])
140
+ if proc.returncode != 0:
141
+ detail = (proc.stderr or proc.stdout or "").strip()
142
+ return False, f"Failed to start engine container: {detail}", {}
143
+ state = {
144
+ "runtime": runtime,
145
+ "container_name": container_name,
146
+ "image": image,
147
+ "port": int(port),
148
+ "profile": profile,
149
+ "status": "ready" if _health(runtime, container_name) else "degraded",
150
+ }
151
+ write_engine_state(state)
152
+ return True, "Engine ready.", state
153
+
154
+
155
+ def stop_engine(*, runtime: str, container_name: str = DEFAULT_ENGINE_CONTAINER) -> tuple[bool, str]:
156
+ if not _exists(runtime, container_name):
157
+ write_engine_state({"runtime": runtime, "container_name": container_name, "status": "down"})
158
+ return False, "Engine container does not exist."
159
+ if not _running(runtime, container_name):
160
+ write_engine_state({"runtime": runtime, "container_name": container_name, "status": "down"})
161
+ return True, "Engine already stopped."
162
+ proc = _run([runtime, "stop", container_name])
163
+ if proc.returncode != 0:
164
+ detail = (proc.stderr or proc.stdout or "").strip()
165
+ return False, f"Failed to stop engine: {detail}"
166
+ write_engine_state({"runtime": runtime, "container_name": container_name, "status": "down"})
167
+ return True, "Engine stopped."
168
+
169
+
170
+ def engine_status(*, runtime: str | None = None, container_name: str = DEFAULT_ENGINE_CONTAINER) -> dict:
171
+ state = read_engine_state()
172
+ resolved_runtime = runtime or str(state.get("runtime") or "podman")
173
+ exists = False
174
+ running = False
175
+ healthy = False
176
+ status = "error"
177
+ try:
178
+ exists = _exists(resolved_runtime, container_name)
179
+ running = _running(resolved_runtime, container_name) if exists else False
180
+ healthy = _health(resolved_runtime, container_name) if running else False
181
+ if running and healthy:
182
+ status = "ready"
183
+ elif running and not healthy:
184
+ status = "degraded"
185
+ else:
186
+ status = "down"
187
+ except Exception:
188
+ status = "error"
189
+ merged = {
190
+ "runtime": resolved_runtime,
191
+ "container_name": container_name,
192
+ "image": state.get("image", DEFAULT_ENGINE_IMAGE),
193
+ "port": int(state.get("port", DEFAULT_ENGINE_PORT)),
194
+ "profile": state.get("profile", DEFAULT_ENGINE_PROFILE),
195
+ "status": status,
196
+ "exists": exists,
197
+ "running": running,
198
+ "healthy": healthy,
199
+ "updated_at": state.get("updated_at", ""),
200
+ }
201
+ return merged
202
+
203
+
204
+ def run_engine_logs(*, runtime: str, container_name: str, follow: bool = False, tail: int = 200) -> int:
205
+ cmd = [runtime, "logs", "--tail", str(max(1, int(tail)))]
206
+ if follow:
207
+ cmd.append("-f")
208
+ cmd.append(container_name)
209
+ return subprocess.call(cmd)
210
+
211
+
212
+ def pull_model(*, runtime: str, container_name: str, model_id: str) -> tuple[bool, str]:
213
+ if not model_id.strip():
214
+ return False, "Model id is required."
215
+ if not _exists(runtime, container_name):
216
+ return False, "Engine container does not exist. Run `refactor engine up` first."
217
+ if not _running(runtime, container_name):
218
+ started = _run([runtime, "start", container_name])
219
+ if started.returncode != 0:
220
+ detail = (started.stderr or started.stdout or "").strip()
221
+ return False, f"Failed to start engine container: {detail}"
222
+ probe = _run([runtime, "exec", container_name, "sh", "-lc", "command -v ollama >/dev/null 2>&1"])
223
+ if probe.returncode != 0:
224
+ return False, "Engine image does not include `ollama`; use a model-capable engine image."
225
+ proc = _run([runtime, "exec", container_name, "sh", "-lc", f"ollama pull {model_id}"])
226
+ text = (proc.stdout or proc.stderr or "").strip()
227
+ if proc.returncode != 0:
228
+ return False, text or "Model pull failed."
229
+ return True, text or "Model pull complete."
230
+
231
+
232
+ def probe_model(*, runtime: str, container_name: str, model_id: str) -> tuple[bool, str]:
233
+ if not model_id.strip():
234
+ return False, "Model id is required."
235
+ if not _exists(runtime, container_name):
236
+ return False, "Engine container does not exist. Run `refactor engine up` first."
237
+ if not _running(runtime, container_name):
238
+ return False, "Engine container is not running. Run `refactor engine up` first."
239
+ proc = _run([runtime, "exec", container_name, "sh", "-lc", f"ollama show {model_id}"])
240
+ text = (proc.stdout or proc.stderr or "").strip()
241
+ if proc.returncode != 0:
242
+ return False, text or "model not found in engine"
243
+ return True, "model is available in engine"
@@ -0,0 +1,40 @@
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)
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import typer
6
6
 
7
7
  from refactorai_cli import __version__
8
- from refactorai_cli.commands import auth_cmds, engine_cmds, model_cmds, rules_cmds, run_cmds, runtime_cmds, setup_cmds
8
+ from refactorai_cli.commands import auth_cmds, engine_cmds, model_cmds, runtime_cmds, setup_cmds
9
9
 
10
10
  app = typer.Typer(
11
11
  name="refactor",
@@ -39,26 +39,9 @@ def main(
39
39
  app.command()(auth_cmds.login)
40
40
  app.command()(auth_cmds.whoami)
41
41
 
42
- # Project / run surface (R7.0 scaffolding; auth-guarded where required)
43
- app.command()(run_cmds.init)
44
- app.command()(run_cmds.start)
45
- app.command()(run_cmds.stop)
46
- app.command()(run_cmds.shell)
47
- app.command()(run_cmds.review)
48
- app.command()(run_cmds.code)
49
- app.command()(run_cmds.requests)
50
- app.command()(run_cmds.apply)
51
- app.command()(run_cmds.revert)
52
- app.command()(run_cmds.status)
53
- app.command()(run_cmds.diff)
54
- app.command()(run_cmds.gc)
55
- app.command()(run_cmds.check)
56
- app.command()(run_cmds.doctor)
57
- app.command()(run_cmds.config)
58
42
  app.command()(setup_cmds.setup)
59
43
 
60
- # Rule policy introspection (R12)
61
- app.add_typer(rules_cmds.app, name="rules")
44
+ # Runtime/engine/model operations.
62
45
  app.add_typer(runtime_cmds.app, name="runtime")
63
46
  app.add_typer(engine_cmds.app, name="engine")
64
47
  app.add_typer(model_cmds.app, name="model")
@@ -17,7 +17,7 @@ from pathlib import Path
17
17
 
18
18
  import httpx
19
19
 
20
- from refactor_core.paths import ensure_dir, refactor_home
20
+ from refactorai_cli.local_paths import ensure_dir, refactor_home
21
21
 
22
22
  from refactorai_cli.control_plane import ensure_lease
23
23
  from refactorai_cli.credentials import resolve_developer_key
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import os
6
6
 
7
- DEFAULT_PLATFORM_URL = "http://localhost:8000"
7
+ DEFAULT_PLATFORM_URL = "https://api.refactorai.codes"
8
8
  ENV_API_KEY = "REFACTOR_API_KEY"
9
9
  ENV_PLATFORM_URL = "REFACTOR_PLATFORM_URL"
10
10
  ENV_POLICY_SIGNING_KEY = "REFACTOR_POLICY_SIGNING_KEY"
@@ -9,14 +9,14 @@ from datetime import datetime, timezone
9
9
  from pathlib import Path
10
10
  from typing import Callable
11
11
 
12
- from refactor_core.engine_runtime import (
12
+ from refactorai_cli.local_engine_runtime import (
13
13
  DEFAULT_ENGINE_CONTAINER,
14
14
  engine_status,
15
15
  ensure_engine_up,
16
16
  pull_model,
17
17
  resolve_runtime as resolve_engine_runtime,
18
18
  )
19
- from refactor_core.paths import ensure_dir, refactor_home
19
+ from refactorai_cli.local_paths import ensure_dir, refactor_home
20
20
 
21
21
  from refactorai_cli.auth import ensure_authenticated
22
22
  from refactorai_cli.control_plane import ensure_lease, heartbeat, resolve_policy
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.2.0
3
+ Version: 0.2.3
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,6 @@ 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: refactor-core>=0.1.0
12
11
 
13
12
  # refactorai-cli
14
13
 
@@ -18,6 +17,10 @@ Public CLI package for Refactor.
18
17
  - Installed command: `refactor`
19
18
  - Python module package: `refactorai_cli`
20
19
 
20
+ By default, the CLI targets `https://api.refactorai.codes`.
21
+ Use `REFACTOR_PLATFORM_URL` only when you need to override the control-plane URL
22
+ (for self-hosted or local development environments).
23
+
21
24
  ## Local development install
22
25
 
23
26
  From repository root:
@@ -5,6 +5,9 @@ refactorai_cli/auth.py
5
5
  refactorai_cli/client.py
6
6
  refactorai_cli/control_plane.py
7
7
  refactorai_cli/credentials.py
8
+ refactorai_cli/local_constitution.py
9
+ refactorai_cli/local_engine_runtime.py
10
+ refactorai_cli/local_paths.py
8
11
  refactorai_cli/main.py
9
12
  refactorai_cli/model_policy.py
10
13
  refactorai_cli/runtime_manager.py
@@ -2,4 +2,3 @@ typer>=0.12.0
2
2
  httpx>=0.27.0
3
3
  rich>=13.7.0
4
4
  PyYAML>=6.0.1
5
- refactor-core>=0.1.0
File without changes