refactorai-cli 0.4.12__tar.gz → 0.4.14__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.12 → refactorai_cli-0.4.14}/PKG-INFO +2 -2
  2. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/pyproject.toml +2 -2
  3. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/__init__.py +1 -1
  4. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/run_cmds.py +42 -3
  5. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli.egg-info/PKG-INFO +2 -2
  6. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli.egg-info/requires.txt +1 -1
  7. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/README.md +0 -0
  8. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/auth.py +0 -0
  9. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/client.py +0 -0
  10. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/cloud_rr.py +0 -0
  11. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/__init__.py +0 -0
  12. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/account_cmds.py +0 -0
  13. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/auth_cmds.py +0 -0
  14. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/branch_cmds.py +0 -0
  15. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/cloud_cmds.py +0 -0
  16. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/engine_cmds.py +0 -0
  17. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/hook_cmds.py +0 -0
  18. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/model_cmds.py +0 -0
  19. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/request_cmds.py +0 -0
  20. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/rules_cmds.py +0 -0
  21. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/runtime_cmds.py +0 -0
  22. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/runtime_proxy_cmds.py +0 -0
  23. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/setup_cmds.py +0 -0
  24. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/toolchains_cmds.py +0 -0
  25. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commands/watch_cmds.py +0 -0
  26. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/commit_queue.py +0 -0
  27. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/control_plane.py +0 -0
  28. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/credentials.py +0 -0
  29. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/dotenv_loader.py +0 -0
  30. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/git_scope.py +0 -0
  31. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/local_constitution.py +0 -0
  32. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/local_engine_runtime.py +0 -0
  33. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/local_paths.py +0 -0
  34. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/main.py +0 -0
  35. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/model_policy.py +0 -0
  36. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/refactor_branch_store.py +0 -0
  37. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/review_runner.py +0 -0
  38. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/runtime_manager.py +0 -0
  39. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/settings.py +0 -0
  40. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/setup_flow.py +0 -0
  41. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli/watch_state.py +0 -0
  42. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli.egg-info/SOURCES.txt +0 -0
  43. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli.egg-info/dependency_links.txt +0 -0
  44. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli.egg-info/entry_points.txt +0 -0
  45. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/refactorai_cli.egg-info/top_level.txt +0 -0
  46. {refactorai_cli-0.4.12 → refactorai_cli-0.4.14}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.4.12
3
+ Version: 0.4.14
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.7
11
+ Requires-Dist: refactorai-core>=3.2.8
12
12
 
13
13
  # refactorai-cli
14
14
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "refactorai-cli"
3
- version = "0.4.12"
3
+ version = "0.4.14"
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.7",
15
+ "refactorai-core>=3.2.8",
16
16
  ]
17
17
 
18
18
  [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.4.12"
8
+ __version__ = "0.4.14"
@@ -651,6 +651,26 @@ def _is_cloud_mode(constitution) -> bool:
651
651
  return bool(_cloud_execution_mode(constitution))
652
652
 
653
653
 
654
+ def _documents_digest(documents: list | None) -> str:
655
+ """Stable digest of the exact documents sent to the platform.
656
+
657
+ Folds each document's path + content so a commit-scoped review keys on the
658
+ code it actually reviews. Without this, two commits share the same
659
+ idempotency key (same account/stage/constitution/target) and the server
660
+ replays the FIRST commit's findings for the second commit -- re-suggesting
661
+ changes that were already applied/merged (docs/41 `R28`).
662
+ """
663
+ hasher = hashlib.sha256()
664
+ for doc in sorted(documents or [], key=lambda d: str((d or {}).get("path", ""))):
665
+ if not isinstance(doc, dict):
666
+ continue
667
+ hasher.update(str(doc.get("path", "")).encode("utf-8"))
668
+ hasher.update(b"\x00")
669
+ hasher.update(str(doc.get("content", "")).encode("utf-8"))
670
+ hasher.update(b"\x1f")
671
+ return hasher.hexdigest()
672
+
673
+
654
674
  def _stable_idempotency_key(
655
675
  *,
656
676
  account_id: str,
@@ -659,15 +679,29 @@ def _stable_idempotency_key(
659
679
  target: str,
660
680
  max_alerts: int,
661
681
  execution_mode: str,
682
+ scope_digest: str = "",
662
683
  ) -> str:
663
684
  """Deterministic idempotency key so retries replay instead of re-charging (C10).
664
685
 
665
- The key MUST change when inputs change (target/constitution/stage/mode) so
666
- distinct runs are not incorrectly deduplicated, and MUST be stable across
686
+ The key MUST change when inputs change (target/constitution/stage/mode/scope)
687
+ so distinct runs are not incorrectly deduplicated, and MUST be stable across
667
688
  retries of the same logical run so managed quota is not double-charged.
689
+
690
+ ``scope_digest`` folds the actual reviewed documents into the key so a
691
+ commit-scoped review of a different commit (or of changed code) produces a
692
+ distinct key and a fresh server run, instead of replaying an earlier commit's
693
+ cached findings.
668
694
  """
669
695
  seed = "|".join(
670
- [account_id, execution_mode, stage, constitution_hash, str(target), str(int(max_alerts))]
696
+ [
697
+ account_id,
698
+ execution_mode,
699
+ stage,
700
+ constitution_hash,
701
+ str(target),
702
+ str(int(max_alerts)),
703
+ scope_digest,
704
+ ]
671
705
  )
672
706
  return hashlib.sha256(seed.encode("utf-8")).hexdigest()
673
707
 
@@ -707,6 +741,10 @@ def _cloud_inference(
707
741
 
708
742
  execution_mode = _cloud_execution_mode(constitution) or "cloud_managed"
709
743
  auth_ctx = ensure_authenticated(project_root)
744
+ # Digest the exact documents so the idempotency key keys on the reviewed
745
+ # code, not just account/stage/target. (The backend independently recomputes
746
+ # a documents hash for its own replay guard, so this need not be sent.)
747
+ documents_hash = _documents_digest(documents)
710
748
  payload = {
711
749
  "stage": stage,
712
750
  "execution_mode": execution_mode,
@@ -728,6 +766,7 @@ def _cloud_inference(
728
766
  target=target,
729
767
  max_alerts=max_alerts,
730
768
  execution_mode=execution_mode,
769
+ scope_digest=documents_hash,
731
770
  )
732
771
  try:
733
772
  response = httpx.post(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: refactorai-cli
3
- Version: 0.4.12
3
+ Version: 0.4.14
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.7
11
+ Requires-Dist: refactorai-core>=3.2.8
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.7
5
+ refactorai-core>=3.2.8