aiwcli 0.10.3 → 0.11.1

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 (191) hide show
  1. package/bin/run.js +1 -1
  2. package/dist/commands/clear.js +28 -131
  3. package/dist/commands/init/index.js +3 -3
  4. package/dist/lib/gitignore-manager.d.ts +32 -0
  5. package/dist/lib/gitignore-manager.js +141 -2
  6. package/dist/templates/CLAUDE.md +8 -8
  7. package/dist/templates/_shared/.claude/commands/handoff-resume.md +64 -0
  8. package/dist/templates/_shared/.claude/commands/handoff.md +16 -10
  9. package/dist/templates/_shared/.claude/settings.json +7 -7
  10. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -0
  11. package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -0
  12. package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -0
  13. package/dist/templates/_shared/hooks-ts/file-suggestion.ts +130 -0
  14. package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -0
  15. package/dist/templates/_shared/hooks-ts/session_end.ts +107 -0
  16. package/dist/templates/_shared/hooks-ts/session_start.ts +144 -0
  17. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -0
  18. package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -0
  19. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +83 -0
  20. package/dist/templates/_shared/lib-ts/CLAUDE.md +318 -0
  21. package/dist/templates/_shared/lib-ts/base/atomic-write.ts +12 -12
  22. package/dist/templates/_shared/lib-ts/base/constants.ts +22 -15
  23. package/dist/templates/_shared/lib-ts/base/git-state.ts +1 -1
  24. package/dist/templates/_shared/lib-ts/base/hook-utils.ts +129 -50
  25. package/dist/templates/_shared/lib-ts/base/inference.ts +28 -21
  26. package/dist/templates/_shared/lib-ts/base/logger.ts +15 -2
  27. package/dist/templates/_shared/lib-ts/base/state-io.ts +9 -7
  28. package/dist/templates/_shared/lib-ts/base/stop-words.ts +131 -131
  29. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +142 -0
  30. package/dist/templates/_shared/lib-ts/base/utils.ts +69 -69
  31. package/dist/templates/_shared/lib-ts/context/context-formatter.ts +30 -24
  32. package/dist/templates/_shared/lib-ts/context/context-selector.ts +50 -32
  33. package/dist/templates/_shared/lib-ts/context/context-store.ts +76 -48
  34. package/dist/templates/_shared/lib-ts/context/plan-manager.ts +43 -23
  35. package/dist/templates/_shared/lib-ts/context/task-tracker.ts +10 -6
  36. package/dist/templates/_shared/lib-ts/handoff/document-generator.ts +11 -10
  37. package/dist/templates/_shared/lib-ts/handoff/handoff-reader.ts +158 -0
  38. package/dist/templates/_shared/lib-ts/templates/formatters.ts +6 -4
  39. package/dist/templates/_shared/lib-ts/types.ts +68 -55
  40. package/dist/templates/_shared/scripts/resolve_context.ts +24 -0
  41. package/dist/templates/_shared/scripts/resume_handoff.ts +345 -0
  42. package/dist/templates/_shared/scripts/save_handoff.ts +3 -3
  43. package/dist/templates/_shared/scripts/status_line.ts +687 -0
  44. package/dist/templates/cc-native/.claude/settings.json +175 -185
  45. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +15 -17
  46. package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +0 -2
  47. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +109 -135
  48. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.ts +119 -0
  49. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +1027 -0
  50. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -0
  51. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +156 -0
  52. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +792 -0
  53. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +199 -0
  54. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -0
  55. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -0
  56. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -0
  57. package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +115 -0
  58. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +80 -0
  59. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +120 -0
  60. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -0
  61. package/dist/templates/cc-native/_cc-native/lib-ts/nul +3 -0
  62. package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +250 -0
  63. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +275 -0
  64. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/codex.ts +130 -0
  65. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/gemini.ts +107 -0
  66. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +10 -0
  67. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +23 -0
  68. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +240 -0
  69. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -0
  70. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +385 -0
  71. package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -0
  72. package/dist/templates/cc-native/_cc-native/plan-review.config.json +14 -1
  73. package/oclif.manifest.json +1 -1
  74. package/package.json +2 -2
  75. package/dist/templates/_shared/hooks/__init__.py +0 -16
  76. package/dist/templates/_shared/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  77. package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
  78. package/dist/templates/_shared/hooks/__pycache__/context_enforcer.cpython-313.pyc +0 -0
  79. package/dist/templates/_shared/hooks/__pycache__/context_monitor.cpython-313.pyc +0 -0
  80. package/dist/templates/_shared/hooks/__pycache__/file-suggestion.cpython-313.pyc +0 -0
  81. package/dist/templates/_shared/hooks/__pycache__/pre_compact.cpython-313.pyc +0 -0
  82. package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
  83. package/dist/templates/_shared/hooks/__pycache__/session_start.cpython-313.pyc +0 -0
  84. package/dist/templates/_shared/hooks/__pycache__/task_create_atomicity.cpython-313.pyc +0 -0
  85. package/dist/templates/_shared/hooks/__pycache__/task_create_capture.cpython-313.pyc +0 -0
  86. package/dist/templates/_shared/hooks/__pycache__/task_update_capture.cpython-313.pyc +0 -0
  87. package/dist/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
  88. package/dist/templates/_shared/hooks/archive_plan.py +0 -177
  89. package/dist/templates/_shared/hooks/context_monitor.py +0 -270
  90. package/dist/templates/_shared/hooks/file-suggestion.py +0 -215
  91. package/dist/templates/_shared/hooks/pre_compact.py +0 -104
  92. package/dist/templates/_shared/hooks/session_end.py +0 -173
  93. package/dist/templates/_shared/hooks/session_start.py +0 -206
  94. package/dist/templates/_shared/hooks/task_create_capture.py +0 -108
  95. package/dist/templates/_shared/hooks/task_update_capture.py +0 -145
  96. package/dist/templates/_shared/hooks/user_prompt_submit.py +0 -139
  97. package/dist/templates/_shared/lib/__init__.py +0 -1
  98. package/dist/templates/_shared/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  99. package/dist/templates/_shared/lib/base/__init__.py +0 -65
  100. package/dist/templates/_shared/lib/base/__pycache__/__init__.cpython-313.pyc +0 -0
  101. package/dist/templates/_shared/lib/base/__pycache__/atomic_write.cpython-313.pyc +0 -0
  102. package/dist/templates/_shared/lib/base/__pycache__/constants.cpython-313.pyc +0 -0
  103. package/dist/templates/_shared/lib/base/__pycache__/hook_utils.cpython-313.pyc +0 -0
  104. package/dist/templates/_shared/lib/base/__pycache__/inference.cpython-313.pyc +0 -0
  105. package/dist/templates/_shared/lib/base/__pycache__/logger.cpython-313.pyc +0 -0
  106. package/dist/templates/_shared/lib/base/__pycache__/stop_words.cpython-313.pyc +0 -0
  107. package/dist/templates/_shared/lib/base/__pycache__/subprocess_utils.cpython-313.pyc +0 -0
  108. package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
  109. package/dist/templates/_shared/lib/base/atomic_write.py +0 -180
  110. package/dist/templates/_shared/lib/base/constants.py +0 -358
  111. package/dist/templates/_shared/lib/base/hook_utils.py +0 -339
  112. package/dist/templates/_shared/lib/base/inference.py +0 -307
  113. package/dist/templates/_shared/lib/base/logger.py +0 -305
  114. package/dist/templates/_shared/lib/base/stop_words.py +0 -221
  115. package/dist/templates/_shared/lib/base/subprocess_utils.py +0 -46
  116. package/dist/templates/_shared/lib/base/utils.py +0 -263
  117. package/dist/templates/_shared/lib/context/__init__.py +0 -102
  118. package/dist/templates/_shared/lib/context/__pycache__/__init__.cpython-313.pyc +0 -0
  119. package/dist/templates/_shared/lib/context/__pycache__/cache.cpython-313.pyc +0 -0
  120. package/dist/templates/_shared/lib/context/__pycache__/context_extractor.cpython-313.pyc +0 -0
  121. package/dist/templates/_shared/lib/context/__pycache__/context_formatter.cpython-313.pyc +0 -0
  122. package/dist/templates/_shared/lib/context/__pycache__/context_manager.cpython-313.pyc +0 -0
  123. package/dist/templates/_shared/lib/context/__pycache__/context_selector.cpython-313.pyc +0 -0
  124. package/dist/templates/_shared/lib/context/__pycache__/context_store.cpython-313.pyc +0 -0
  125. package/dist/templates/_shared/lib/context/__pycache__/discovery.cpython-313.pyc +0 -0
  126. package/dist/templates/_shared/lib/context/__pycache__/event_log.cpython-313.pyc +0 -0
  127. package/dist/templates/_shared/lib/context/__pycache__/plan_archive.cpython-313.pyc +0 -0
  128. package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
  129. package/dist/templates/_shared/lib/context/__pycache__/task_sync.cpython-313.pyc +0 -0
  130. package/dist/templates/_shared/lib/context/__pycache__/task_tracker.cpython-313.pyc +0 -0
  131. package/dist/templates/_shared/lib/context/context_formatter.py +0 -317
  132. package/dist/templates/_shared/lib/context/context_selector.py +0 -508
  133. package/dist/templates/_shared/lib/context/context_store.py +0 -653
  134. package/dist/templates/_shared/lib/context/plan_manager.py +0 -303
  135. package/dist/templates/_shared/lib/context/task_tracker.py +0 -188
  136. package/dist/templates/_shared/lib/handoff/__init__.py +0 -22
  137. package/dist/templates/_shared/lib/handoff/__pycache__/__init__.cpython-313.pyc +0 -0
  138. package/dist/templates/_shared/lib/handoff/__pycache__/document_generator.cpython-313.pyc +0 -0
  139. package/dist/templates/_shared/lib/handoff/document_generator.py +0 -278
  140. package/dist/templates/_shared/lib/templates/README.md +0 -206
  141. package/dist/templates/_shared/lib/templates/__init__.py +0 -36
  142. package/dist/templates/_shared/lib/templates/__pycache__/__init__.cpython-313.pyc +0 -0
  143. package/dist/templates/_shared/lib/templates/__pycache__/formatters.cpython-313.pyc +0 -0
  144. package/dist/templates/_shared/lib/templates/__pycache__/persona_questions.cpython-313.pyc +0 -0
  145. package/dist/templates/_shared/lib/templates/__pycache__/plan_context.cpython-313.pyc +0 -0
  146. package/dist/templates/_shared/lib/templates/formatters.py +0 -146
  147. package/dist/templates/_shared/lib/templates/plan_context.py +0 -73
  148. package/dist/templates/_shared/scripts/__pycache__/save_handoff.cpython-313.pyc +0 -0
  149. package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
  150. package/dist/templates/_shared/scripts/save_handoff.py +0 -357
  151. package/dist/templates/_shared/scripts/status_line.py +0 -716
  152. package/dist/templates/cc-native/.claude/commands/cc-native/fresh-perspective.md +0 -8
  153. package/dist/templates/cc-native/.windsurf/workflows/cc-native/fresh-perspective.md +0 -8
  154. package/dist/templates/cc-native/MIGRATION.md +0 -86
  155. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc +0 -0
  156. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc +0 -0
  157. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/mark_questions_asked.cpython-313.pyc +0 -0
  158. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_accepted.cpython-313.pyc +0 -0
  159. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_questions_early.cpython-313.pyc +0 -0
  160. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/suggest-fresh-perspective.cpython-313.pyc +0 -0
  161. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.py +0 -130
  162. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +0 -954
  163. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.py +0 -81
  164. package/dist/templates/cc-native/_cc-native/hooks/suggest-fresh-perspective.py +0 -340
  165. package/dist/templates/cc-native/_cc-native/lib/CLAUDE.md +0 -265
  166. package/dist/templates/cc-native/_cc-native/lib/__init__.py +0 -53
  167. package/dist/templates/cc-native/_cc-native/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  168. package/dist/templates/cc-native/_cc-native/lib/__pycache__/atomic_write.cpython-313.pyc +0 -0
  169. package/dist/templates/cc-native/_cc-native/lib/__pycache__/constants.cpython-313.pyc +0 -0
  170. package/dist/templates/cc-native/_cc-native/lib/__pycache__/debug.cpython-313.pyc +0 -0
  171. package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
  172. package/dist/templates/cc-native/_cc-native/lib/__pycache__/state.cpython-313.pyc +0 -0
  173. package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
  174. package/dist/templates/cc-native/_cc-native/lib/constants.py +0 -45
  175. package/dist/templates/cc-native/_cc-native/lib/debug.py +0 -139
  176. package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +0 -362
  177. package/dist/templates/cc-native/_cc-native/lib/reviewers/__init__.py +0 -28
  178. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc +0 -0
  179. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/agent.cpython-313.pyc +0 -0
  180. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/base.cpython-313.pyc +0 -0
  181. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/codex.cpython-313.pyc +0 -0
  182. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/gemini.cpython-313.pyc +0 -0
  183. package/dist/templates/cc-native/_cc-native/lib/reviewers/agent.py +0 -215
  184. package/dist/templates/cc-native/_cc-native/lib/reviewers/base.py +0 -88
  185. package/dist/templates/cc-native/_cc-native/lib/reviewers/codex.py +0 -124
  186. package/dist/templates/cc-native/_cc-native/lib/reviewers/gemini.py +0 -108
  187. package/dist/templates/cc-native/_cc-native/lib/state.py +0 -268
  188. package/dist/templates/cc-native/_cc-native/lib/utils.py +0 -1071
  189. package/dist/templates/cc-native/_cc-native/scripts/__pycache__/aggregate_agents.cpython-313.pyc +0 -0
  190. package/dist/templates/cc-native/_cc-native/scripts/aggregate_agents.py +0 -168
  191. package/dist/templates/cc-native/_cc-native/workflows/fresh-perspective.md +0 -134
@@ -1,268 +0,0 @@
1
- """
2
- CC-Native State Management Module.
3
-
4
- Handles plan state file operations and iteration tracking for the review process.
5
-
6
- State files are stored adjacent to plan files (e.g., ~/.claude/plans/foo.state.json)
7
- to prevent state loss when session IDs change or temp files are cleaned up.
8
- """
9
-
10
- import json
11
- import sys
12
- from datetime import datetime
13
- from pathlib import Path
14
- from typing import Any, Dict, Optional
15
-
16
- try:
17
- from .constants import validate_plan_path, PLANS_DIR
18
- except ImportError:
19
- # When imported directly via sys.path (not as a package)
20
- from constants import validate_plan_path, PLANS_DIR
21
-
22
- # Import atomic_write from shared lib (canonical copy)
23
- try:
24
- from ...lib.base.atomic_write import atomic_write
25
- except ImportError:
26
- # Fallback for direct execution
27
- from pathlib import Path as _P
28
- _shared_lib = _P(__file__).resolve().parent.parent.parent / "_shared" / "lib"
29
- import importlib.util
30
- _spec = importlib.util.spec_from_file_location(
31
- "atomic_write", str(_shared_lib / "base" / "atomic_write.py")
32
- )
33
- _mod = importlib.util.module_from_spec(_spec)
34
- _spec.loader.exec_module(_mod)
35
- atomic_write = _mod.atomic_write
36
-
37
- # Import canonical eprint and logger from shared lib
38
- try:
39
- from ...lib.base.utils import eprint
40
- from ...lib.base.logger import log_debug, log_info, log_warn, log_error
41
- except ImportError:
42
- # Fallback for direct execution
43
- import sys as _sys
44
- from pathlib import Path as _Path
45
- _shared_lib = _Path(__file__).resolve().parent.parent.parent / "_shared" / "lib"
46
- _sys.path.insert(0, str(_shared_lib))
47
- from base.utils import eprint
48
- from base.logger import log_debug, log_info, log_warn, log_error
49
-
50
-
51
- # ---------------------------
52
- # Constants
53
- # ---------------------------
54
-
55
- STATE_SCHEMA_VERSION = "1.0.0"
56
-
57
- DEFAULT_REVIEW_ITERATIONS: Dict[str, int] = {
58
- "simple": 1,
59
- "medium": 1,
60
- "high": 2,
61
- }
62
-
63
-
64
- # ---------------------------
65
- # State File Management
66
- # ---------------------------
67
-
68
- def get_state_file_path(plan_path: str) -> Path:
69
- """Derive state file path from plan file path with security validation.
70
-
71
- The state file is stored adjacent to the plan file with a .state.json extension.
72
- This prevents state loss when session IDs change or temp files are cleaned up.
73
-
74
- Example: ~/.claude/plans/foo.md -> ~/.claude/plans/foo.state.json
75
-
76
- Raises:
77
- ValueError: If plan_path is invalid or insecure
78
- """
79
- # SECURITY: Validate path before any operations
80
- validated_path = validate_plan_path(plan_path)
81
-
82
- # State file is always adjacent to plan file
83
- return validated_path.with_suffix('.state.json')
84
-
85
-
86
- def load_state(plan_path: str) -> Optional[Dict[str, Any]]:
87
- """Load state file with schema validation and migration."""
88
- try:
89
- state_file = get_state_file_path(plan_path) # Validates path
90
-
91
- if not state_file.exists():
92
- return None
93
-
94
- state = json.loads(state_file.read_text(encoding="utf-8"))
95
-
96
- # Handle schema version (backward compatible)
97
- schema_version = state.get("schema_version")
98
-
99
- if schema_version is None:
100
- # Existing state files without version - auto-migrate
101
- state["schema_version"] = STATE_SCHEMA_VERSION
102
- log_info("state", f"Migrated state file to schema v{STATE_SCHEMA_VERSION}")
103
- elif schema_version != STATE_SCHEMA_VERSION:
104
- log_warn("state", f"Schema mismatch (expected {STATE_SCHEMA_VERSION}, got {schema_version})")
105
- # For now, accept with warning - add migration logic here if schema changes
106
-
107
- return state
108
-
109
- except ValueError as e:
110
- log_error("state", f"SECURITY: Invalid plan path: {e}")
111
- return None
112
- except Exception as e:
113
- log_error("state", f"Failed to load state: {e}")
114
- return None
115
-
116
-
117
- def save_state(plan_path: str, state: Dict[str, Any]) -> bool:
118
- """Save state file with schema version and validation.
119
-
120
- Returns True on success, False on failure.
121
- """
122
- try:
123
- state_file = get_state_file_path(plan_path) # Validates path
124
-
125
- state_with_version = {
126
- "schema_version": STATE_SCHEMA_VERSION,
127
- **state
128
- }
129
-
130
- # Use atomic write
131
- success, error = atomic_write(
132
- state_file,
133
- json.dumps(state_with_version, indent=2)
134
- )
135
-
136
- if not success:
137
- log_error("state", f"Failed to save state: {error}")
138
- return False
139
-
140
- return True
141
-
142
- except ValueError as e:
143
- log_error("state", f"SECURITY: Invalid plan path: {e}")
144
- return False
145
- except Exception as e:
146
- log_error("state", str(e))
147
- return False
148
-
149
-
150
- def delete_state(plan_path: str) -> bool:
151
- """Delete state file after successful archive.
152
-
153
- Returns True if deleted or didn't exist, False on error.
154
- """
155
- try:
156
- state_file = get_state_file_path(plan_path)
157
- if state_file.exists():
158
- state_file.unlink()
159
- log_info("state", f"Deleted state file: {state_file}")
160
- return True
161
- except ValueError as e:
162
- log_error("state", f"SECURITY: Invalid plan path in delete: {e}")
163
- return False
164
- except Exception as e:
165
- log_warn("state", f"Failed to delete state file: {e}")
166
- return False
167
-
168
-
169
- # ---------------------------
170
- # Iteration State Management
171
- # ---------------------------
172
-
173
- def get_iteration_state(
174
- state: Dict[str, Any],
175
- complexity: str,
176
- config: Optional[Dict[str, Any]] = None,
177
- ) -> Dict[str, Any]:
178
- """Get or initialize iteration state based on complexity.
179
-
180
- Args:
181
- state: The current plan state dict
182
- complexity: Plan complexity level (simple/medium/high)
183
- config: Optional config dict with reviewIterations settings
184
-
185
- Returns:
186
- Iteration dict with: current, max, complexity, history
187
- """
188
- if "iteration" in state:
189
- # Return existing iteration state
190
- return state["iteration"]
191
-
192
- # Initialize new iteration state
193
- review_iterations = DEFAULT_REVIEW_ITERATIONS.copy()
194
- if config:
195
- review_iterations.update(config.get("reviewIterations", {}))
196
- max_iterations = review_iterations.get(complexity, 1)
197
-
198
- return {
199
- "current": 1,
200
- "max": max_iterations,
201
- "complexity": complexity,
202
- "history": [],
203
- }
204
-
205
-
206
- def update_iteration_state(
207
- state: Dict[str, Any],
208
- iteration: Dict[str, Any],
209
- plan_hash: str,
210
- verdict: str,
211
- ) -> Dict[str, Any]:
212
- """Record review result in iteration history and update state.
213
-
214
- Args:
215
- state: The current plan state dict
216
- iteration: The iteration state dict
217
- plan_hash: Hash of the current plan content
218
- verdict: Review verdict (pass/warn/fail)
219
-
220
- Returns:
221
- Updated state dict with iteration data
222
- """
223
- # Add this review to history
224
- iteration["history"].append({
225
- "hash": plan_hash,
226
- "verdict": verdict,
227
- "timestamp": datetime.now().isoformat(),
228
- })
229
-
230
- # Update state with iteration data
231
- state["iteration"] = iteration
232
- return state
233
-
234
-
235
- def should_continue_iterating(
236
- iteration: Dict[str, Any],
237
- verdict: str,
238
- config: Optional[Dict[str, Any]] = None,
239
- ) -> bool:
240
- """Determine if more review iterations are needed.
241
-
242
- Args:
243
- iteration: The iteration state dict
244
- verdict: Current review verdict
245
- config: Optional config dict with earlyExitOnAllPass setting
246
-
247
- Returns:
248
- True if more iterations needed, False otherwise
249
- """
250
- current = iteration.get("current", 1)
251
- max_iter = iteration.get("max", 1)
252
-
253
- # At or past max iterations - no more iterations
254
- if current >= max_iter:
255
- log_info("state", f"At max iterations ({current}/{max_iter}), no more iterations")
256
- return False
257
-
258
- # Check early exit on all pass
259
- early_exit = True
260
- if config:
261
- early_exit = config.get("earlyExitOnAllPass", True)
262
- if early_exit and verdict == "pass":
263
- log_info("state", "All reviewers passed and earlyExitOnAllPass=true, exiting early")
264
- return False
265
-
266
- # More iterations available and verdict is not pass (or early exit disabled)
267
- log_info("state", f"Continuing to next iteration ({current + 1}/{max_iter}), verdict={verdict}")
268
- return True