refactorai-cli 0.7.16__tar.gz → 0.7.17__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 (54) hide show
  1. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/PKG-INFO +2 -2
  2. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/pyproject.toml +2 -2
  3. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/mode_sync.py +90 -19
  4. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli.egg-info/PKG-INFO +2 -2
  5. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli.egg-info/requires.txt +1 -1
  6. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/README.md +0 -0
  7. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/__init__.py +0 -0
  8. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/auth.py +0 -0
  9. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/client.py +0 -0
  10. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/cloud_rr.py +0 -0
  11. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/__init__.py +0 -0
  12. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/account_cmds.py +0 -0
  13. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/auth_cmds.py +0 -0
  14. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/branch_cmds.py +0 -0
  15. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/cloud_cmds.py +0 -0
  16. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/engine_cmds.py +0 -0
  17. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/hook_cmds.py +0 -0
  18. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/model_cmds.py +0 -0
  19. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/policy_cmds.py +0 -0
  20. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/pre_push_cmds.py +0 -0
  21. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/request_cmds.py +0 -0
  22. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/rules_cmds.py +0 -0
  23. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/run_cmds.py +0 -0
  24. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/runtime_cmds.py +0 -0
  25. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/runtime_proxy_cmds.py +0 -0
  26. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/setup_cmds.py +0 -0
  27. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/toolchains_cmds.py +0 -0
  28. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/watch_cmds.py +0 -0
  29. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commands/workspace_cmds.py +0 -0
  30. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commit_queue.py +0 -0
  31. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/commit_telemetry.py +0 -0
  32. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/control_plane.py +0 -0
  33. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/credentials.py +0 -0
  34. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/dotenv_loader.py +0 -0
  35. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/git_scope.py +0 -0
  36. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/local_constitution.py +0 -0
  37. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/local_engine_runtime.py +0 -0
  38. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/local_paths.py +0 -0
  39. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/main.py +0 -0
  40. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/model_policy.py +0 -0
  41. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/pre_push_gate.py +0 -0
  42. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/refactor_branch_store.py +0 -0
  43. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/review_runner.py +0 -0
  44. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/runtime_manager.py +0 -0
  45. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/settings.py +0 -0
  46. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/setup_flow.py +0 -0
  47. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/watch_ledger.py +0 -0
  48. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/watch_state.py +0 -0
  49. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli/watch_supervisor.py +0 -0
  50. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli.egg-info/SOURCES.txt +0 -0
  51. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli.egg-info/dependency_links.txt +0 -0
  52. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli.egg-info/entry_points.txt +0 -0
  53. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/refactorai_cli.egg-info/top_level.txt +0 -0
  54. {refactorai_cli-0.7.16 → refactorai_cli-0.7.17}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.7.16
3
+ Version: 0.7.17
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.23
11
+ Requires-Dist: refactorai-core>=3.2.24
12
12
 
13
13
  # refactorai-cli
14
14
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "refactorai-cli"
3
- version = "0.7.16"
3
+ version = "0.7.17"
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.23",
15
+ "refactorai-core>=3.2.24",
16
16
  ]
17
17
 
18
18
  [project.scripts]
@@ -17,9 +17,10 @@ from typing import Callable
17
17
 
18
18
  from refactor_core.constitution import (
19
19
  CONFIG_FILENAME,
20
+ MANAGED_BLOCK_BEGIN,
21
+ MANAGED_BLOCK_END,
20
22
  MANAGED_KEYS,
21
23
  find_project_files,
22
- load_config,
23
24
  upsert_managed_block,
24
25
  )
25
26
  from refactor_core.execution_variant import normalize_execution_variant
@@ -38,33 +39,90 @@ def _local_config_path(project_root: Path) -> Path | None:
38
39
 
39
40
 
40
41
  def _current_managed_values(project_root: Path) -> dict:
41
- """Current values of the managed keys as parsed from refactor.config."""
42
+ """Current values from the raw managed block (no env interpolation)."""
42
43
  config_path = _local_config_path(project_root)
43
44
  if config_path is None:
44
45
  return {}
45
46
  try:
46
- settings = getattr(load_config(config_path), "settings", {}) or {}
47
- except Exception:
47
+ text = config_path.read_text(encoding="utf-8")
48
+ except OSError:
49
+ return {}
50
+ begin = text.find(MANAGED_BLOCK_BEGIN)
51
+ if begin == -1:
52
+ return {}
53
+ end = text.find(MANAGED_BLOCK_END, begin)
54
+ if end == -1:
48
55
  return {}
56
+ body = text[begin + len(MANAGED_BLOCK_BEGIN) : end]
49
57
  values: dict = {}
50
- for key in MANAGED_KEYS:
51
- raw = settings.get(key)
52
- if raw is None:
58
+ for line in body.splitlines():
59
+ stripped = line.strip()
60
+ if not stripped or stripped.startswith("#") or ":" not in stripped:
53
61
  continue
54
- text = str(raw).strip()
55
- if text:
56
- values[key] = text
62
+ key, raw = stripped.split(":", 1)
63
+ key = key.strip()
64
+ if key not in MANAGED_KEYS:
65
+ continue
66
+ value = raw.strip()
67
+ if value:
68
+ values[key] = value
57
69
  return values
58
70
 
59
71
 
72
+ _LOCAL_BYOK_ENV_DEFAULTS: dict[str, dict[str, str]] = {
73
+ "openai": {
74
+ "provider_key": "${OPENAI_API_KEY}",
75
+ "model_id": "${OPENAI_MODEL_ID}",
76
+ "base_url": "${OPENAI_BASE_URL}",
77
+ },
78
+ "anthropic": {
79
+ "provider_key": "${ANTHROPIC_API_KEY}",
80
+ "model_id": "${ANTHROPIC_MODEL_ID}",
81
+ },
82
+ "openrouter": {
83
+ "provider_key": "${OPENROUTER_API_KEY}",
84
+ "model_id": "${OPENROUTER_MODEL_ID}",
85
+ "base_url": "${OPENROUTER_BASE_URL}",
86
+ },
87
+ "nvidia": {
88
+ "provider_key": "${NVIDIA_API_KEY}",
89
+ "model_id": "${NVIDIA_MODEL_ID}",
90
+ "base_url": "${NVIDIA_BASE_URL}",
91
+ },
92
+ "azure_openai": {
93
+ "provider_key": "${AZURE_OPENAI_API_KEY}",
94
+ "model_id": "${AZURE_OPENAI_DEPLOYMENT}",
95
+ "base_url": "${AZURE_OPENAI_ENDPOINT}",
96
+ "api_version": "${AZURE_OPENAI_API_VERSION}",
97
+ },
98
+ "vertex_ai": {
99
+ "provider_key": "${GOOGLE_OAUTH_ACCESS_TOKEN}",
100
+ "model_id": "${VERTEX_MODEL_ID}",
101
+ "project": "${GOOGLE_CLOUD_PROJECT}",
102
+ "region": "${GOOGLE_CLOUD_LOCATION}",
103
+ },
104
+ "bedrock": {
105
+ "provider_key": "${AWS_BEARER_TOKEN_BEDROCK}",
106
+ "model_id": "${BEDROCK_MODEL_ID}",
107
+ "region": "${AWS_REGION}",
108
+ },
109
+ "ollama": {
110
+ "model_id": "${OLLAMA_MODEL_ID}",
111
+ "base_url": "${OLLAMA_BASE_URL}",
112
+ },
113
+ }
114
+
115
+
60
116
  def _desired_managed_fields(record: dict, current: dict, server_variant: str) -> dict:
61
117
  """Compute the managed-block fields from the server record (server-wins).
62
118
 
63
119
  When the server carries a remote provider (BYOK/managed set from the UI), the
64
- provider/model/credential come from the server and any local ``base_url`` is
65
- dropped. Otherwise (heuristic / terminal-set local_model, where the server has
66
- no provider) the local provider/model/base_url are preserved and only the
67
- variant is reconciled.
120
+ provider/model/credential come from the server. Provider-local extras
121
+ (``provider_key`` env token, region/project/base_url/api_version) are preserved
122
+ from the local managed block so sync does not strip local BYOK readiness.
123
+ Otherwise (heuristic / terminal-set local_model, where the server has no
124
+ provider) local provider-scoped values are preserved and only the variant is
125
+ reconciled.
68
126
  """
69
127
  provider = str(record.get("inference_provider") or "").strip()
70
128
  model_id = str(record.get("model_id") or "").strip()
@@ -77,8 +135,20 @@ def _desired_managed_fields(record: dict, current: dict, server_variant: str) ->
77
135
  fields["model_id"] = model_id
78
136
  if credential_ref:
79
137
  fields["credential_ref"] = credential_ref
138
+ # Preserve local provider-scoped values when server record doesn't carry
139
+ # them. This keeps local BYOK config/env wiring stable across syncs.
140
+ for key in ("model_id", "provider_key", "base_url", "region", "project", "api_version"):
141
+ if key not in fields and current.get(key):
142
+ fields[key] = current[key]
143
+ # Local BYOK should be immediately runnable from env after sync. Seed
144
+ # provider-specific env-token placeholders when missing.
145
+ if server_variant == "local_byok":
146
+ defaults = _LOCAL_BYOK_ENV_DEFAULTS.get(provider, {})
147
+ for key, value in defaults.items():
148
+ if not str(fields.get(key) or "").strip():
149
+ fields[key] = value
80
150
  else:
81
- for key in ("provider", "model_id", "base_url", "credential_ref"):
151
+ for key in ("provider", "model_id", "provider_key", "base_url", "region", "project", "api_version", "credential_ref"):
82
152
  if current.get(key):
83
153
  fields[key] = current[key]
84
154
  return fields
@@ -92,10 +162,11 @@ def sync_execution_variant_from_server(
92
162
  ) -> str | None:
93
163
  """Pull the server project's execution settings into the managed config block.
94
164
 
95
- Server-wins for the managed keys (execution_variant / provider / model_id /
96
- credential_ref). Secrets (``provider_key``) are never written -- they stay in
97
- the environment. Returns the applied variant when the local config changed,
98
- else ``None`` (already in sync, offline, unauthenticated, or unbound project).
165
+ Server-wins for mode/provider identity, while preserving provider-local env
166
+ wiring in the managed block. ``provider_key`` is written only as an env token
167
+ placeholder (for example ``${OPENAI_API_KEY}``) and never as a raw secret.
168
+ Returns the applied variant when the local config changed, else ``None``
169
+ (already in sync, offline, unauthenticated, or unbound project).
99
170
  """
100
171
  try:
101
172
  project_id = resolve_project_id(project_root)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.7.16
3
+ Version: 0.7.17
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.23
11
+ Requires-Dist: refactorai-core>=3.2.24
12
12
 
13
13
  # refactorai-cli
14
14
 
@@ -2,4 +2,4 @@ typer>=0.12.0
2
2
  httpx>=0.27.0
3
3
  rich>=13.7.0
4
4
  PyYAML>=6.0.1
5
- refactorai-core>=3.2.23
5
+ refactorai-core>=3.2.24