refactorai-cli 0.7.20__tar.gz → 0.7.22__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.20 → refactorai_cli-0.7.22}/PKG-INFO +1 -1
  2. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/pyproject.toml +1 -1
  3. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/__init__.py +1 -1
  4. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/run_cmds.py +9 -21
  5. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/watch_state.py +47 -11
  6. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli.egg-info/PKG-INFO +1 -1
  7. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/README.md +0 -0
  8. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/auth.py +0 -0
  9. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/client.py +0 -0
  10. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/cloud_rr.py +0 -0
  11. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/__init__.py +0 -0
  12. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/account_cmds.py +0 -0
  13. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/auth_cmds.py +0 -0
  14. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/branch_cmds.py +0 -0
  15. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/cloud_cmds.py +0 -0
  16. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/engine_cmds.py +0 -0
  17. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/hook_cmds.py +0 -0
  18. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/model_cmds.py +0 -0
  19. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/policy_cmds.py +0 -0
  20. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/pre_push_cmds.py +0 -0
  21. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/request_cmds.py +0 -0
  22. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/rules_cmds.py +0 -0
  23. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/runtime_cmds.py +0 -0
  24. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/runtime_proxy_cmds.py +0 -0
  25. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/setup_cmds.py +0 -0
  26. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/toolchains_cmds.py +0 -0
  27. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/watch_cmds.py +0 -0
  28. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commands/workspace_cmds.py +0 -0
  29. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commit_queue.py +0 -0
  30. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/commit_telemetry.py +0 -0
  31. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/control_plane.py +0 -0
  32. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/credentials.py +0 -0
  33. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/dotenv_loader.py +0 -0
  34. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/git_scope.py +0 -0
  35. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/local_constitution.py +0 -0
  36. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/local_engine_runtime.py +0 -0
  37. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/local_paths.py +0 -0
  38. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/main.py +0 -0
  39. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/mode_sync.py +0 -0
  40. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/model_policy.py +0 -0
  41. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/pre_push_gate.py +0 -0
  42. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/refactor_branch_store.py +0 -0
  43. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/review_runner.py +0 -0
  44. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/runtime_manager.py +0 -0
  45. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/settings.py +0 -0
  46. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/setup_flow.py +0 -0
  47. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/watch_ledger.py +0 -0
  48. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli/watch_supervisor.py +0 -0
  49. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli.egg-info/SOURCES.txt +0 -0
  50. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli.egg-info/dependency_links.txt +0 -0
  51. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli.egg-info/entry_points.txt +0 -0
  52. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli.egg-info/requires.txt +0 -0
  53. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/refactorai_cli.egg-info/top_level.txt +0 -0
  54. {refactorai_cli-0.7.20 → refactorai_cli-0.7.22}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.7.20
3
+ Version: 0.7.22
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.7.20"
3
+ version = "0.7.22"
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.7.20"
8
+ __version__ = "0.7.22"
@@ -3329,28 +3329,16 @@ def review(
3329
3329
  sandbox_ctx = None
3330
3330
 
3331
3331
  try:
3332
- # Two orthogonal axes (docs/46): where the engine runs vs. where tests
3333
- # run. ``local_byok`` / ``local_managed`` use the remote (server) engine
3334
- # while verifying locally in the sandbox, so sandbox setup keys off
3335
- # verification location, and engine routing keys off engine location.
3332
+ # Engine routing keys off engine location (docs/46). Review is *read-only*
3333
+ # analysis: it produces findings / refactor requests and never executes
3334
+ # verification (tests) locally. The container sandbox exists for that
3335
+ # verification during ``code`` / ``refactor``, so provisioning + preflighting
3336
+ # it here only added container start + ``exec`` probe latency (and could hang
3337
+ # on the container runtime) for zero effect on the review result — the old
3338
+ # ``sandbox_ctx`` was consumed solely to print a preflight warning. Sandbox
3339
+ # readiness is therefore enforced lazily, when code is actually applied; use
3340
+ # ``refactor sandbox start`` to validate the toolchain ahead of time.
3336
3341
  engine_remote = _engine_is_remote(constitution)
3337
- verify_local = _verify_local(constitution)
3338
- if _sandbox_enabled(project_config):
3339
- if verify_local:
3340
- sandbox_ctx = _ensure_sandbox_ready(
3341
- project_root=project_root,
3342
- project_config=project_config,
3343
- stage="review",
3344
- auto_approve_install=False,
3345
- no_install=False,
3346
- continue_on_preflight_failure=True,
3347
- )
3348
- else:
3349
- variant = _execution_variant(constitution)
3350
- console.print(
3351
- f"[dim]review: sandbox.enabled is ignored in "
3352
- f"{variant} variant (verification runs in the cloud).[/dim]"
3353
- )
3354
3342
  if engine_remote:
3355
3343
  artifact = _cloud_inference(
3356
3344
  stage="review",
@@ -43,6 +43,10 @@ PHASE_FINALIZE = "finalize"
43
43
  PHASE_DONE = "done"
44
44
  PHASE_NONE = "none"
45
45
 
46
+ # Cap the live sub-step trail so a long review never overflows the node block.
47
+ # Older steps scroll off the top (the checklist keeps the most recent progress).
48
+ _MAX_SUBSTEPS = 6
49
+
46
50
 
47
51
  @dataclass
48
52
  class RRCommit:
@@ -121,9 +125,13 @@ class CommitNode:
121
125
  intent_summary: str = ""
122
126
  run_id: str = ""
123
127
  error: str = ""
124
- # Live sub-step label while REVIEWING (e.g. "batch 2/5", "security scan").
125
- # Volatile UI-only detail; not part of the persisted node contract.
128
+ # Live sub-step trail while REVIEWING, oldest first (e.g. "resolving scope",
129
+ # "reviewing batch 2/5", "security scan"). Rendered as a Cursor-style
130
+ # checklist: completed steps ticked, the last one spinning. Volatile UI-only
131
+ # detail; not part of the persisted node contract. ``substep`` mirrors the
132
+ # current (last) step for the compact single-line status fallback.
126
133
  substep: str = ""
134
+ substeps: list[str] = field(default_factory=list)
127
135
  finalize: "FinalizeInfo | None" = None
128
136
 
129
137
  @property
@@ -275,16 +283,24 @@ class WatchState:
275
283
  if node:
276
284
  node.state = REVIEWING
277
285
  node.substep = ""
286
+ node.substeps = []
278
287
 
279
288
  def set_substep(self, sha: str, label: str) -> None:
280
- """Update the live sub-step label for a reviewing node (UI-only).
289
+ """Append a new live sub-step to a reviewing node's trail (UI-only).
281
290
 
282
- No-op unless the node is currently ``REVIEWING`` so a stale progress line
283
- can never overwrite a finished node's status.
291
+ Consecutive duplicates are collapsed and the trail is capped at
292
+ :data:`_MAX_SUBSTEPS` (oldest scroll off). No-op unless the node is
293
+ currently ``REVIEWING`` so a stale progress line can never mutate a
294
+ finished node.
284
295
  """
285
296
  node = self._nodes.get(sha)
286
- if node and node.state == REVIEWING:
287
- node.substep = label
297
+ if not (node and node.state == REVIEWING):
298
+ return
299
+ if not node.substeps or node.substeps[-1] != label:
300
+ node.substeps.append(label)
301
+ if len(node.substeps) > _MAX_SUBSTEPS:
302
+ node.substeps = node.substeps[-_MAX_SUBSTEPS:]
303
+ node.substep = label
288
304
 
289
305
  def requeue(self, sha: str) -> None:
290
306
  """Reset a node to ``queued`` so the next pass re-reviews it (post-resolve)."""
@@ -297,6 +313,7 @@ class WatchState:
297
313
  node.rr_preview = []
298
314
  node.error = ""
299
315
  node.substep = ""
316
+ node.substeps = []
300
317
  node.finalize = None
301
318
  self.forced_review.discard(sha)
302
319
 
@@ -554,10 +571,29 @@ def _render_review_view(state: WatchState, *, now: datetime | None = None, width
554
571
  row2 = Text.from_markup(f"[cyan]|[/cyan] [yellow]{node.short_sha}[/yellow] ")
555
572
  row2.append(node.subject or "(no subject)")
556
573
  node_lines.append(row2)
557
- # Row 3: pipe + status.
558
- row3 = Text.from_markup("[cyan]|[/cyan] ")
559
- row3.append_text(Text.from_markup(_status_line(node)))
560
- node_lines.append(row3)
574
+ # Row 3: while reviewing, render a Cursor-style checklist of sub-steps
575
+ # (completed steps ticked, the current one spinning) so progress reads as
576
+ # advancing work instead of a single overwritten line. Falls back to the
577
+ # compact status line before the first step arrives / for other states.
578
+ if node.state == REVIEWING and node.substeps:
579
+ spinner = _spinner_frame(now)
580
+ last = len(node.substeps) - 1
581
+ for idx, label in enumerate(node.substeps):
582
+ row = Text.from_markup("[cyan]|[/cyan] ")
583
+ if idx == last:
584
+ row.append_text(Text.from_markup(f"[cyan]{spinner}[/cyan] "))
585
+ row.append(label)
586
+ if node.changed:
587
+ row.append(f" ({node.changed} files)", style="dim")
588
+ row.append(" …", style="dim")
589
+ else:
590
+ row.append_text(Text.from_markup("[green]✓[/green] "))
591
+ row.append(label, style="dim")
592
+ node_lines.append(row)
593
+ else:
594
+ row3 = Text.from_markup("[cyan]|[/cyan] ")
595
+ row3.append_text(Text.from_markup(_status_line(node)))
596
+ node_lines.append(row3)
561
597
  if node.state == REVIEWED and node.rr_preview:
562
598
  for item in node.rr_preview:
563
599
  req = Text.from_markup("[cyan]|[/cyan] ")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.7.20
3
+ Version: 0.7.22
4
4
  Summary: Local-first CLI for the refactor platform
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown