refactorai-cli 0.4.7__tar.gz → 0.4.9__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 (46) hide show
  1. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/PKG-INFO +1 -1
  2. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/pyproject.toml +1 -1
  3. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/__init__.py +1 -1
  4. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/watch_cmds.py +63 -8
  5. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/review_runner.py +18 -2
  6. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/watch_state.py +1 -1
  7. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli.egg-info/PKG-INFO +1 -1
  8. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/README.md +0 -0
  9. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/auth.py +0 -0
  10. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/client.py +0 -0
  11. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/cloud_rr.py +0 -0
  12. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/__init__.py +0 -0
  13. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/account_cmds.py +0 -0
  14. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/auth_cmds.py +0 -0
  15. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/branch_cmds.py +0 -0
  16. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/cloud_cmds.py +0 -0
  17. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/engine_cmds.py +0 -0
  18. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/hook_cmds.py +0 -0
  19. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/model_cmds.py +0 -0
  20. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/request_cmds.py +0 -0
  21. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/rules_cmds.py +0 -0
  22. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/run_cmds.py +0 -0
  23. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/runtime_cmds.py +0 -0
  24. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/runtime_proxy_cmds.py +0 -0
  25. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/setup_cmds.py +0 -0
  26. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commands/toolchains_cmds.py +0 -0
  27. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/commit_queue.py +0 -0
  28. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/control_plane.py +0 -0
  29. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/credentials.py +0 -0
  30. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/dotenv_loader.py +0 -0
  31. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/git_scope.py +0 -0
  32. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/local_constitution.py +0 -0
  33. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/local_engine_runtime.py +0 -0
  34. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/local_paths.py +0 -0
  35. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/main.py +0 -0
  36. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/model_policy.py +0 -0
  37. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/refactor_branch_store.py +0 -0
  38. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/runtime_manager.py +0 -0
  39. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/settings.py +0 -0
  40. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli/setup_flow.py +0 -0
  41. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli.egg-info/SOURCES.txt +0 -0
  42. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli.egg-info/dependency_links.txt +0 -0
  43. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli.egg-info/entry_points.txt +0 -0
  44. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli.egg-info/requires.txt +0 -0
  45. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/refactorai_cli.egg-info/top_level.txt +0 -0
  46. {refactorai_cli-0.4.7 → refactorai_cli-0.4.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.4.7
3
+ Version: 0.4.9
4
4
  Summary: Local-first CLI for the refactor platform
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "refactorai-cli"
3
- version = "0.4.7"
3
+ version = "0.4.9"
4
4
  description = "Local-first CLI for the refactor platform"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -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.4.7"
8
+ __version__ = "0.4.9"
@@ -79,6 +79,48 @@ def _preview_for_run(project_root: Path, run_id: str, *, limit: int = 3) -> list
79
79
  return lines
80
80
 
81
81
 
82
+ def _pending_for_run(
83
+ project_root: Path,
84
+ run_id: str,
85
+ *,
86
+ limit: int = 3,
87
+ ) -> tuple[int, list[str]]:
88
+ """Return ``(pending_count, preview_lines)`` for requests created by ``run_id``."""
89
+ if not run_id:
90
+ return 0, []
91
+ try:
92
+ from refactor_core.refactor_requests import IN_PROGRESS, PENDING, list_requests
93
+ except Exception:
94
+ return 0, []
95
+ try:
96
+ requests = list_requests(project_root)
97
+ except Exception:
98
+ return 0, []
99
+ matches = [
100
+ rr
101
+ for rr in requests
102
+ if str(getattr(rr, "created_by_run", "") or "") == run_id
103
+ and str(getattr(rr, "status", "") or "") in {PENDING, IN_PROGRESS}
104
+ ]
105
+ if not matches:
106
+ return 0, []
107
+ lines: list[str] = []
108
+ for rr in matches[: max(1, limit)]:
109
+ sev = str(getattr(rr, "severity", "medium") or "medium").lower()
110
+ location = str(getattr(rr, "location", "") or "").strip() or str(
111
+ getattr(rr, "file_path", "") or "(unknown location)"
112
+ )
113
+ rec = _truncate(
114
+ str(getattr(rr, "recommendation", "") or getattr(rr, "rationale", "") or "").strip(),
115
+ limit=100,
116
+ )
117
+ if rec:
118
+ lines.append(f"[{sev}] {location} - {rec}")
119
+ else:
120
+ lines.append(f"[{sev}] {location}")
121
+ return len(matches), lines
122
+
123
+
82
124
  def _resolve_repo(project_root: Path | None) -> Path:
83
125
  root = git_scope.repo_root(project_root or Path.cwd())
84
126
  if not root:
@@ -157,7 +199,11 @@ def process_pending(
157
199
  if on_update:
158
200
  on_update(state)
159
201
  intent = intent_for(node.sha) if intent_for else None
160
- outcome = runner.run(sha=node.sha, intent=intent)
202
+ outcome = runner.run(
203
+ sha=node.sha,
204
+ intent=intent,
205
+ yes_full_project=(node.scope_mode == "full"),
206
+ )
161
207
  if outcome.run_id:
162
208
  outcome.rr_preview = _preview_for_run(project_root, outcome.run_id)
163
209
  state.apply_outcome(node.sha, outcome)
@@ -171,7 +217,7 @@ def _read_key(timeout: float) -> str:
171
217
  """Non-blocking key read on a POSIX TTY, normalized to a token.
172
218
 
173
219
  Returns ``up``/``down`` for arrow keys, the raw character for normal keys
174
- (case preserved so ``[r]`` and ``[R]`` are distinguishable), ``esc`` for a
220
+ (used for hotkeys like ``[r]`` and ``[f]``), ``esc`` for a
175
221
  bare Escape, or ``""`` when nothing was pressed / the terminal is not
176
222
  interactive. Sleeps ``timeout`` in the non-interactive case so the caller's
177
223
  poll cadence is preserved.
@@ -222,7 +268,7 @@ def build_action_command(action: str, sha: str, *, executable: str = "refactor")
222
268
  # Commit-scoped so `[r]` resolves THIS commit's requests (docs/41 Phase 4).
223
269
  return [executable, "code", "--commit", sha]
224
270
  if action == "refresh":
225
- # `[R]` regenerates the requests for this commit before resolving.
271
+ # `[f]` regenerates the requests for this commit before resolving.
226
272
  return [executable, "code", "--commit", sha, "--refresh-requests"]
227
273
  if action == "diff":
228
274
  # Shows the pending refactor-request patch diffs (not the git diff).
@@ -276,10 +322,19 @@ def _run_action(live, project_root: Path, action: str, node, state: WatchState)
276
322
  console.print(f"\n[bold bright_cyan]watch:[/bold bright_cyan] {action} for "
277
323
  f"[yellow]{node.short_sha}[/yellow] ({node.branch or 'detached'})\n")
278
324
  _launch_interactive(cmd, project_root)
279
- if action in ("code", "refresh"):
280
- # Resolving/regenerating requests changes the tree; re-review this commit
281
- # to refresh its gate/RR counts on the next consume pass.
325
+ if action == "refresh":
326
+ # `[f]` explicitly regenerates requests, so re-review this commit on the
327
+ # next pass.
282
328
  state.requeue(node.sha)
329
+ elif action == "code":
330
+ # `[r]` is resolve/reuse. Do NOT auto re-review here (that can regenerate
331
+ # duplicate-looking findings); instead reflect current pending requests
332
+ # from the existing run in-place.
333
+ node_after = state.get(node.sha)
334
+ if node_after and node_after.run_id:
335
+ pending_count, preview = _pending_for_run(project_root, node_after.run_id)
336
+ node_after.rr_count = pending_count
337
+ node_after.rr_preview = preview
283
338
  console.print("\n[dim]watch: returning to the Refactor Terminal...[/dim]")
284
339
  live.start()
285
340
 
@@ -311,10 +366,10 @@ def _run_tui(project_root: Path, state: WatchState, runner: ReviewRunner) -> Non
311
366
  state.move_selection(-1)
312
367
  elif key in ("down", "j"):
313
368
  state.move_selection(+1)
314
- elif key in ("r", "R", "d", "m", "x"):
369
+ elif key in ("r", "f", "d", "m", "x"):
315
370
  action = {
316
371
  "r": "code",
317
- "R": "refresh",
372
+ "f": "refresh",
318
373
  "d": "diff",
319
374
  "m": "merge",
320
375
  "x": "drop",
@@ -52,7 +52,13 @@ class ReviewOutcome:
52
52
  class ReviewRunner(Protocol):
53
53
  """Runs a commit-scoped review and returns a structured outcome."""
54
54
 
55
- def run(self, *, sha: str, intent: str | None = None) -> ReviewOutcome: ...
55
+ def run(
56
+ self,
57
+ *,
58
+ sha: str,
59
+ intent: str | None = None,
60
+ yes_full_project: bool = False,
61
+ ) -> ReviewOutcome: ...
56
62
 
57
63
 
58
64
  def parse_review_output(sha: str, stdout: str, returncode: int) -> ReviewOutcome:
@@ -111,10 +117,20 @@ class SubprocessReviewRunner:
111
117
  self.timeout = timeout
112
118
  self.extra_args = list(extra_args or [])
113
119
 
114
- def run(self, *, sha: str, intent: str | None = None) -> ReviewOutcome:
120
+ def run(
121
+ self,
122
+ *,
123
+ sha: str,
124
+ intent: str | None = None,
125
+ yes_full_project: bool = False,
126
+ ) -> ReviewOutcome:
115
127
  cmd = [self.executable, "review", "--commit", sha, *self.extra_args]
116
128
  if intent and intent.strip():
117
129
  cmd += ["--intent", intent.strip()]
130
+ if yes_full_project:
131
+ # `watch` runs review in a captured subprocess. For root commits, force
132
+ # non-interactive confirmation so the loop never blocks on a hidden prompt.
133
+ cmd.append("--yes-full-project")
118
134
  # Wide, non-interactive output so rich does not wrap the status lines the
119
135
  # parser depends on.
120
136
  env = dict(os.environ, COLUMNS="200", NO_COLOR="1")
@@ -329,7 +329,7 @@ def render_graph(state: WatchState, *, now: datetime | None = None, width: int =
329
329
  _with_pad(
330
330
  Text.from_markup(
331
331
  "[dim]\\[↑/↓ or j/k][/dim] select [bold]\\[r][/bold] refactor "
332
- "[bold]\\[R][/bold] refresh [bold]\\[d][/bold] diff "
332
+ "[bold]\\[f][/bold] fresh review [bold]\\[d][/bold] diff "
333
333
  "[bold]\\[m][/bold] merge [bold]\\[x][/bold] drop "
334
334
  "[bold]\\[p][/bold] push [bold]\\[q][/bold] quit"
335
335
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.4.7
3
+ Version: 0.4.9
4
4
  Summary: Local-first CLI for the refactor platform
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
File without changes
File without changes