@pjmendonca/devflow 1.13.2 → 1.18.0

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 (224) hide show
  1. package/.claude/commands/agent.md +1 -1
  2. package/.claude/commands/bugfix.md +21 -0
  3. package/.claude/commands/checkpoint.md +0 -1
  4. package/.claude/commands/collab.md +0 -1
  5. package/.claude/commands/costs.md +88 -18
  6. package/.claude/commands/devflow.md +26 -0
  7. package/.claude/commands/handoff.md +0 -1
  8. package/.claude/commands/init.md +287 -0
  9. package/.claude/commands/memory.md +0 -1
  10. package/.claude/commands/pair.md +0 -1
  11. package/.claude/commands/review.md +27 -0
  12. package/.claude/commands/route.md +0 -1
  13. package/.claude/commands/swarm.md +0 -1
  14. package/.claude/commands/validate.md +55 -0
  15. package/.claude/hooks/session-notification.sh +44 -0
  16. package/.claude/hooks/session-startup.sh +427 -0
  17. package/.claude/hooks/session-stop.sh +38 -0
  18. package/.claude/hooks/session_tracker.py +272 -0
  19. package/.claude/settings.json +38 -0
  20. package/.claude/skills/costs/SKILL.md +156 -0
  21. package/.claude/skills/validate/SKILL.md +101 -0
  22. package/CHANGELOG.md +243 -0
  23. package/README.md +207 -10
  24. package/bin/devflow-install.js +2 -1
  25. package/bin/devflow.js +4 -0
  26. package/lib/constants.js +0 -1
  27. package/lib/exec-python.js +1 -1
  28. package/package.json +1 -1
  29. package/tooling/.automation/.checkpoint_lock +1 -0
  30. package/tooling/.automation/agents/architect.md +19 -0
  31. package/tooling/.automation/agents/ba.md +19 -0
  32. package/tooling/.automation/agents/maintainer.md +19 -0
  33. package/tooling/.automation/agents/pm.md +19 -0
  34. package/tooling/.automation/agents/reviewer.md +1 -1
  35. package/tooling/.automation/agents/writer.md +19 -0
  36. package/tooling/.automation/benchmarks/benchmark_20251230_100119.json +314 -0
  37. package/tooling/.automation/benchmarks/benchmark_20251230_100216.json +314 -0
  38. package/tooling/.automation/costs/config.json +31 -0
  39. package/tooling/.automation/costs/sessions/2025-12-29_20251229_164128.json +22 -0
  40. package/tooling/.automation/memory/knowledge/kg_integration-test.json +707 -1
  41. package/tooling/.automation/memory/knowledge/kg_test-story.json +3273 -2
  42. package/tooling/.automation/memory/shared/shared_integration-test.json +181 -1
  43. package/tooling/.automation/memory/shared/shared_test-story.json +721 -1
  44. package/tooling/.automation/memory/shared/shared_test.json +1254 -0
  45. package/tooling/.automation/memory/shared/shared_validation-check.json +227 -0
  46. package/tooling/.automation/overrides/templates/architect/cloud-native.yaml +5 -5
  47. package/tooling/.automation/overrides/templates/architect/enterprise-architect.yaml +23 -5
  48. package/tooling/.automation/overrides/templates/architect/pragmatic-minimalist.yaml +24 -6
  49. package/tooling/.automation/overrides/templates/ba/agile-storyteller.yaml +4 -4
  50. package/tooling/.automation/overrides/templates/ba/domain-expert.yaml +4 -4
  51. package/tooling/.automation/overrides/templates/ba/requirements-engineer.yaml +4 -4
  52. package/tooling/.automation/overrides/templates/dev/performance-engineer.yaml +18 -0
  53. package/tooling/.automation/overrides/templates/dev/rapid-prototyper.yaml +19 -1
  54. package/tooling/.automation/overrides/templates/dev/security-focused.yaml +18 -0
  55. package/tooling/.automation/overrides/templates/dev/user-advocate.yaml +54 -0
  56. package/tooling/.automation/overrides/templates/maintainer/devops-maintainer.yaml +4 -4
  57. package/tooling/.automation/overrides/templates/maintainer/legacy-steward.yaml +4 -4
  58. package/tooling/.automation/overrides/templates/maintainer/oss-maintainer.yaml +4 -4
  59. package/tooling/.automation/overrides/templates/maintainer/reliability-engineer.yaml +55 -0
  60. package/tooling/.automation/overrides/templates/pm/agile-pm.yaml +4 -4
  61. package/tooling/.automation/overrides/templates/pm/hybrid-delivery.yaml +3 -3
  62. package/tooling/.automation/overrides/templates/pm/traditional-pm.yaml +4 -4
  63. package/tooling/.automation/overrides/templates/reviewer/quick-sanity.yaml +18 -0
  64. package/tooling/.automation/overrides/templates/reviewer/thorough-critic.yaml +18 -0
  65. package/tooling/.automation/overrides/templates/sm/agile-coach.yaml +2 -2
  66. package/tooling/.automation/overrides/templates/sm/startup-pm.yaml +3 -3
  67. package/tooling/.automation/overrides/templates/writer/api-documentarian.yaml +5 -5
  68. package/tooling/.automation/overrides/templates/writer/docs-as-code.yaml +4 -4
  69. package/tooling/.automation/overrides/templates/writer/user-guide-author.yaml +5 -5
  70. package/tooling/.automation/validation/history/2025-12-29_val_002a28c1.json +32 -0
  71. package/tooling/.automation/validation/history/2025-12-29_val_01273bb1.json +32 -0
  72. package/tooling/.automation/validation/history/2025-12-29_val_03369914.json +41 -0
  73. package/tooling/.automation/validation/history/2025-12-29_val_07a449ba.json +32 -0
  74. package/tooling/.automation/validation/history/2025-12-29_val_0df1f0a2.json +41 -0
  75. package/tooling/.automation/validation/history/2025-12-29_val_10ff3d34.json +41 -0
  76. package/tooling/.automation/validation/history/2025-12-29_val_110771d7.json +32 -0
  77. package/tooling/.automation/validation/history/2025-12-29_val_13f3a7f9.json +32 -0
  78. package/tooling/.automation/validation/history/2025-12-29_val_17ba9d21.json +41 -0
  79. package/tooling/.automation/validation/history/2025-12-29_val_22247089.json +32 -0
  80. package/tooling/.automation/validation/history/2025-12-29_val_227ea6a4.json +32 -0
  81. package/tooling/.automation/validation/history/2025-12-29_val_2335d5ae.json +32 -0
  82. package/tooling/.automation/validation/history/2025-12-29_val_246824bb.json +41 -0
  83. package/tooling/.automation/validation/history/2025-12-29_val_28b4b9cd.json +32 -0
  84. package/tooling/.automation/validation/history/2025-12-29_val_2abd12cc.json +32 -0
  85. package/tooling/.automation/validation/history/2025-12-29_val_2c801b2f.json +59 -0
  86. package/tooling/.automation/validation/history/2025-12-29_val_2c8cfa8e.json +32 -0
  87. package/tooling/.automation/validation/history/2025-12-29_val_2ce76eb0.json +32 -0
  88. package/tooling/.automation/validation/history/2025-12-29_val_30351948.json +41 -0
  89. package/tooling/.automation/validation/history/2025-12-29_val_30eb7229.json +41 -0
  90. package/tooling/.automation/validation/history/2025-12-29_val_34df0e77.json +41 -0
  91. package/tooling/.automation/validation/history/2025-12-29_val_376e4d6a.json +32 -0
  92. package/tooling/.automation/validation/history/2025-12-29_val_3a4e8a1a.json +59 -0
  93. package/tooling/.automation/validation/history/2025-12-29_val_3b77a628.json +32 -0
  94. package/tooling/.automation/validation/history/2025-12-29_val_3ea4e1cf.json +59 -0
  95. package/tooling/.automation/validation/history/2025-12-29_val_44aacdb4.json +59 -0
  96. package/tooling/.automation/validation/history/2025-12-29_val_457ddfa8.json +32 -0
  97. package/tooling/.automation/validation/history/2025-12-29_val_45af6238.json +41 -0
  98. package/tooling/.automation/validation/history/2025-12-29_val_4735dba1.json +41 -0
  99. package/tooling/.automation/validation/history/2025-12-29_val_486b203c.json +41 -0
  100. package/tooling/.automation/validation/history/2025-12-29_val_49dc56cd.json +59 -0
  101. package/tooling/.automation/validation/history/2025-12-29_val_4d863d6d.json +32 -0
  102. package/tooling/.automation/validation/history/2025-12-29_val_5149a808.json +59 -0
  103. package/tooling/.automation/validation/history/2025-12-29_val_52e0bb43.json +32 -0
  104. package/tooling/.automation/validation/history/2025-12-29_val_585d6319.json +59 -0
  105. package/tooling/.automation/validation/history/2025-12-29_val_5b2d859a.json +32 -0
  106. package/tooling/.automation/validation/history/2025-12-29_val_635a7081.json +41 -0
  107. package/tooling/.automation/validation/history/2025-12-29_val_64df4905.json +32 -0
  108. package/tooling/.automation/validation/history/2025-12-29_val_70634cee.json +41 -0
  109. package/tooling/.automation/validation/history/2025-12-29_val_714553f9.json +32 -0
  110. package/tooling/.automation/validation/history/2025-12-29_val_7f7bfdbf.json +41 -0
  111. package/tooling/.automation/validation/history/2025-12-29_val_7faad91d.json +32 -0
  112. package/tooling/.automation/validation/history/2025-12-29_val_81821f8f.json +41 -0
  113. package/tooling/.automation/validation/history/2025-12-29_val_8249f3c9.json +32 -0
  114. package/tooling/.automation/validation/history/2025-12-29_val_8422b50f.json +41 -0
  115. package/tooling/.automation/validation/history/2025-12-29_val_8446c134.json +32 -0
  116. package/tooling/.automation/validation/history/2025-12-29_val_879f4e26.json +59 -0
  117. package/tooling/.automation/validation/history/2025-12-29_val_8b6d5bd7.json +32 -0
  118. package/tooling/.automation/validation/history/2025-12-29_val_8c5cd787.json +32 -0
  119. package/tooling/.automation/validation/history/2025-12-29_val_91d20bc7.json +32 -0
  120. package/tooling/.automation/validation/history/2025-12-29_val_958a12b7.json +41 -0
  121. package/tooling/.automation/validation/history/2025-12-29_val_95d91108.json +41 -0
  122. package/tooling/.automation/validation/history/2025-12-29_val_980dbb74.json +32 -0
  123. package/tooling/.automation/validation/history/2025-12-29_val_9e40c79b.json +32 -0
  124. package/tooling/.automation/validation/history/2025-12-29_val_9f499b7c.json +32 -0
  125. package/tooling/.automation/validation/history/2025-12-29_val_9f7c3b57.json +32 -0
  126. package/tooling/.automation/validation/history/2025-12-29_val_a30d5bd4.json +32 -0
  127. package/tooling/.automation/validation/history/2025-12-29_val_a6eb09c7.json +32 -0
  128. package/tooling/.automation/validation/history/2025-12-29_val_a86f7b83.json +41 -0
  129. package/tooling/.automation/validation/history/2025-12-29_val_ad5347e1.json +41 -0
  130. package/tooling/.automation/validation/history/2025-12-29_val_b0a5a993.json +32 -0
  131. package/tooling/.automation/validation/history/2025-12-29_val_bcb0192e.json +32 -0
  132. package/tooling/.automation/validation/history/2025-12-29_val_bf3c9aaa.json +32 -0
  133. package/tooling/.automation/validation/history/2025-12-29_val_c461ff88.json +32 -0
  134. package/tooling/.automation/validation/history/2025-12-29_val_c4f4e258.json +41 -0
  135. package/tooling/.automation/validation/history/2025-12-29_val_c7f0fa6d.json +41 -0
  136. package/tooling/.automation/validation/history/2025-12-29_val_c911b0e6.json +32 -0
  137. package/tooling/.automation/validation/history/2025-12-29_val_cc581964.json +32 -0
  138. package/tooling/.automation/validation/history/2025-12-29_val_cdd5a33b.json +32 -0
  139. package/tooling/.automation/validation/history/2025-12-29_val_cfd42495.json +32 -0
  140. package/tooling/.automation/validation/history/2025-12-29_val_d1c7a4ee.json +41 -0
  141. package/tooling/.automation/validation/history/2025-12-29_val_d2280d0e.json +32 -0
  142. package/tooling/.automation/validation/history/2025-12-29_val_d2a6ff69.json +32 -0
  143. package/tooling/.automation/validation/history/2025-12-29_val_d8c53ab2.json +59 -0
  144. package/tooling/.automation/validation/history/2025-12-29_val_d9c1247a.json +41 -0
  145. package/tooling/.automation/validation/history/2025-12-29_val_d9d58569.json +32 -0
  146. package/tooling/.automation/validation/history/2025-12-29_val_dabb4fd9.json +32 -0
  147. package/tooling/.automation/validation/history/2025-12-29_val_dd8fe359.json +32 -0
  148. package/tooling/.automation/validation/history/2025-12-29_val_decdffc9.json +32 -0
  149. package/tooling/.automation/validation/history/2025-12-29_val_e3a95476.json +59 -0
  150. package/tooling/.automation/validation/history/2025-12-29_val_e776dfca.json +32 -0
  151. package/tooling/.automation/validation/history/2025-12-29_val_ea70969f.json +59 -0
  152. package/tooling/.automation/validation/history/2025-12-29_val_ef41ea95.json +32 -0
  153. package/tooling/.automation/validation/history/2025-12-29_val_f384f9b1.json +32 -0
  154. package/tooling/.automation/validation/history/2025-12-29_val_f8adc38c.json +41 -0
  155. package/tooling/.automation/validation/history/2025-12-29_val_fa40b69e.json +32 -0
  156. package/tooling/.automation/validation/history/2025-12-29_val_fc538d54.json +41 -0
  157. package/tooling/.automation/validation/history/2025-12-29_val_fe814665.json +32 -0
  158. package/tooling/.automation/validation/history/2025-12-29_val_ffea4b12.json +32 -0
  159. package/tooling/.automation/validation/history/2025-12-30_val_02d001e5.json +59 -0
  160. package/tooling/.automation/validation/history/2025-12-30_val_0b8966dc.json +32 -0
  161. package/tooling/.automation/validation/history/2025-12-30_val_15455fbf.json +59 -0
  162. package/tooling/.automation/validation/history/2025-12-30_val_157e34b9.json +32 -0
  163. package/tooling/.automation/validation/history/2025-12-30_val_28d1d933.json +32 -0
  164. package/tooling/.automation/validation/history/2025-12-30_val_3442a52c.json +32 -0
  165. package/tooling/.automation/validation/history/2025-12-30_val_37f1ce1e.json +32 -0
  166. package/tooling/.automation/validation/history/2025-12-30_val_4f1d8a93.json +32 -0
  167. package/tooling/.automation/validation/history/2025-12-30_val_56ff1de3.json +32 -0
  168. package/tooling/.automation/validation/history/2025-12-30_val_664fd4e2.json +41 -0
  169. package/tooling/.automation/validation/history/2025-12-30_val_66afb0a7.json +32 -0
  170. package/tooling/.automation/validation/history/2025-12-30_val_7634663c.json +41 -0
  171. package/tooling/.automation/validation/history/2025-12-30_val_8ea830c3.json +41 -0
  172. package/tooling/.automation/validation/history/2025-12-30_val_998957c2.json +32 -0
  173. package/tooling/.automation/validation/history/2025-12-30_val_a52177db.json +32 -0
  174. package/tooling/.automation/validation/history/2025-12-30_val_a5b65a63.json +32 -0
  175. package/tooling/.automation/validation/history/2025-12-30_val_ae391d0e.json +32 -0
  176. package/tooling/.automation/validation/history/2025-12-30_val_c7895339.json +41 -0
  177. package/tooling/.automation/validation/history/2025-12-30_val_ca416593.json +41 -0
  178. package/tooling/.automation/validation/history/2025-12-30_val_cee19422.json +32 -0
  179. package/tooling/.automation/validation/history/2025-12-30_val_ddd4f4e6.json +32 -0
  180. package/tooling/.automation/validation/history/2025-12-30_val_f2e1394b.json +32 -0
  181. package/tooling/.automation/validation/history/2025-12-30_val_f4a7fa06.json +41 -0
  182. package/tooling/.automation/validation/history/2025-12-30_val_ffea3369.json +32 -0
  183. package/tooling/.automation/validation-config.yaml +103 -0
  184. package/tooling/completions/DevflowCompletion.ps1 +21 -21
  185. package/tooling/completions/_run-story +3 -3
  186. package/tooling/completions/run-story-completion.bash +8 -8
  187. package/tooling/docs/DOC-STANDARD.md +14 -14
  188. package/tooling/docs/templates/migration-spec.md +4 -4
  189. package/tooling/scripts/context_checkpoint.py +5 -15
  190. package/tooling/scripts/cost_dashboard.py +610 -13
  191. package/tooling/scripts/create-persona.py +1 -12
  192. package/tooling/scripts/create-persona.sh +44 -44
  193. package/tooling/scripts/lib/__init__.py +12 -1
  194. package/tooling/scripts/lib/agent_handoff.py +11 -2
  195. package/tooling/scripts/lib/agent_router.py +31 -10
  196. package/tooling/scripts/lib/colors.py +106 -0
  197. package/tooling/scripts/lib/context_monitor.py +766 -0
  198. package/tooling/scripts/lib/cost_config.py +229 -10
  199. package/tooling/scripts/lib/cost_display.py +20 -45
  200. package/tooling/scripts/lib/cost_tracker.py +462 -15
  201. package/tooling/scripts/lib/currency_converter.py +28 -5
  202. package/tooling/scripts/lib/pair_programming.py +102 -3
  203. package/tooling/scripts/lib/personality_system.py +949 -0
  204. package/tooling/scripts/lib/platform.py +55 -0
  205. package/tooling/scripts/lib/shared_memory.py +9 -3
  206. package/tooling/scripts/lib/swarm_orchestrator.py +514 -75
  207. package/tooling/scripts/lib/validation_loop.py +1014 -0
  208. package/tooling/scripts/memory_summarize.py +9 -2
  209. package/tooling/scripts/new-doc.py +2 -9
  210. package/tooling/scripts/personalize_agent.py +1 -12
  211. package/tooling/scripts/rollback-migration.sh +60 -60
  212. package/tooling/scripts/run-collab.ps1 +16 -16
  213. package/tooling/scripts/run-collab.py +88 -53
  214. package/tooling/scripts/run-collab.sh +4 -4
  215. package/tooling/scripts/run-story.py +278 -20
  216. package/tooling/scripts/run-story.sh +3 -3
  217. package/tooling/scripts/setup-checkpoint-service.py +2 -9
  218. package/tooling/scripts/tech-debt-tracker.py +1 -12
  219. package/tooling/scripts/test_adversarial_swarm.py +452 -0
  220. package/tooling/scripts/validate-overrides.py +1 -10
  221. package/tooling/scripts/validate-overrides.sh +40 -40
  222. package/tooling/scripts/validate_loop.py +162 -0
  223. package/tooling/scripts/validate_setup.py +2 -30
  224. package/.claude/skills/init/SKILL.md +0 -496
@@ -29,11 +29,15 @@ SCRIPT_DIR = Path(__file__).parent.resolve()
29
29
  PROJECT_ROOT = SCRIPT_DIR.parent.parent
30
30
  MEMORY_DIR = PROJECT_ROOT / ".automation" / "memory"
31
31
 
32
+ # Pre-compiled regex patterns for performance
33
+ _ENTRY_WITH_TIMESTAMP_RE = re.compile(r"^-\s*(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}):\s*(.+)$")
34
+ _ENTRY_WITHOUT_TIMESTAMP_RE = re.compile(r"^-\s*(.+)$")
35
+
32
36
 
33
37
  def parse_memory_entry(line: str) -> tuple[Optional[datetime], str]:
34
38
  """Parse a memory entry line into timestamp and content."""
35
39
  # Format: - YYYY-MM-DD HH:MM: content
36
- match = re.match(r"^-\s*(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}):\s*(.+)$", line.strip())
40
+ match = _ENTRY_WITH_TIMESTAMP_RE.match(line.strip())
37
41
  if match:
38
42
  try:
39
43
  timestamp = datetime.strptime(match.group(1), "%Y-%m-%d %H:%M")
@@ -42,7 +46,7 @@ def parse_memory_entry(line: str) -> tuple[Optional[datetime], str]:
42
46
  pass
43
47
 
44
48
  # Format without timestamp: - content
45
- match = re.match(r"^-\s*(.+)$", line.strip())
49
+ match = _ENTRY_WITHOUT_TIMESTAMP_RE.match(line.strip())
46
50
  if match:
47
51
  return None, match.group(1).strip()
48
52
 
@@ -137,6 +141,9 @@ def find_duplicates(
137
141
 
138
142
  def summarize_group(entries: list[tuple[Optional[datetime], str]]) -> str:
139
143
  """Create a summary for a group of similar entries."""
144
+ if not entries:
145
+ return ""
146
+
140
147
  # Keep the most recent entry's content
141
148
  sorted_entries = sorted(entries, key=lambda x: x[0] or datetime.min, reverse=True)
142
149
  most_recent = sorted_entries[0][1]
@@ -19,16 +19,9 @@ import sys
19
19
  from pathlib import Path
20
20
 
21
21
  SCRIPT_DIR = Path(__file__).parent
22
+ sys.path.insert(0, str(SCRIPT_DIR / "lib"))
22
23
 
23
-
24
- def get_platform():
25
- """Detect the current platform."""
26
- if sys.platform == "win32":
27
- return "windows"
28
- elif sys.platform == "darwin":
29
- return "macos"
30
- else:
31
- return "linux"
24
+ from platform import get_platform
32
25
 
33
26
 
34
27
  def run_windows(args):
@@ -18,18 +18,7 @@ import sys
18
18
  from pathlib import Path
19
19
  from typing import Optional
20
20
 
21
-
22
- # Colors for terminal output
23
- class Colors:
24
- HEADER = "\033[95m"
25
- BLUE = "\033[94m"
26
- CYAN = "\033[96m"
27
- GREEN = "\033[92m"
28
- YELLOW = "\033[93m"
29
- RED = "\033[91m"
30
- END = "\033[0m"
31
- BOLD = "\033[1m"
32
-
21
+ from lib.colors import Colors
33
22
 
34
23
  # Find project paths
35
24
  SCRIPT_DIR = Path(__file__).parent.resolve()
@@ -82,16 +82,16 @@ create_rollback_point() {
82
82
  local timestamp=$(date '+%Y%m%d_%H%M%S')
83
83
  local rollback_name="${timestamp}_${name}"
84
84
  local rollback_path="$ROLLBACK_DIR/$rollback_name"
85
-
85
+
86
86
  mkdir -p "$rollback_path"
87
-
87
+
88
88
  echo -e "${CYAN}Creating rollback point: $rollback_name${NC}"
89
-
89
+
90
90
  # Save git state
91
91
  local current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
92
92
  local current_commit=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
93
93
  local has_changes=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
94
-
94
+
95
95
  # Create manifest
96
96
  cat > "$rollback_path/manifest.json" << EOF
97
97
  {
@@ -103,7 +103,7 @@ create_rollback_point() {
103
103
  "type": "migration-rollback"
104
104
  }
105
105
  EOF
106
-
106
+
107
107
  # Save uncommitted changes if any
108
108
  if [[ $has_changes -gt 0 ]]; then
109
109
  info "Saving uncommitted changes..."
@@ -111,33 +111,33 @@ EOF
111
111
  git stash show -p > "$rollback_path/uncommitted.patch" 2>/dev/null || true
112
112
  git stash pop 2>/dev/null || true
113
113
  fi
114
-
114
+
115
115
  # Save package state
116
116
  if [[ -f "$PROJECT_ROOT/package.json" ]]; then
117
117
  cp "$PROJECT_ROOT/package.json" "$rollback_path/"
118
118
  info "Saved package.json"
119
119
  fi
120
-
120
+
121
121
  if [[ -f "$PROJECT_ROOT/package-lock.json" ]]; then
122
122
  cp "$PROJECT_ROOT/package-lock.json" "$rollback_path/"
123
123
  info "Saved package-lock.json"
124
124
  fi
125
-
125
+
126
126
  if [[ -f "$PROJECT_ROOT/pubspec.yaml" ]]; then
127
127
  cp "$PROJECT_ROOT/pubspec.yaml" "$rollback_path/"
128
128
  info "Saved pubspec.yaml"
129
129
  fi
130
-
130
+
131
131
  if [[ -f "$PROJECT_ROOT/pubspec.lock" ]]; then
132
132
  cp "$PROJECT_ROOT/pubspec.lock" "$rollback_path/"
133
133
  info "Saved pubspec.lock"
134
134
  fi
135
-
135
+
136
136
  if [[ -f "$PROJECT_ROOT/requirements.txt" ]]; then
137
137
  cp "$PROJECT_ROOT/requirements.txt" "$rollback_path/"
138
138
  info "Saved requirements.txt"
139
139
  fi
140
-
140
+
141
141
  success "Rollback point created: $rollback_path"
142
142
  echo "$rollback_name"
143
143
  }
@@ -146,25 +146,25 @@ EOF
146
146
  list_rollback_points() {
147
147
  echo -e "${BOLD}Available Rollback Points:${NC}"
148
148
  echo ""
149
-
149
+
150
150
  if [[ ! -d "$ROLLBACK_DIR" ]] || [[ -z "$(ls -A "$ROLLBACK_DIR" 2>/dev/null)" ]]; then
151
151
  info "No rollback points found."
152
152
  return 0
153
153
  fi
154
-
154
+
155
155
  printf "%-25s %-20s %-15s %s\n" "NAME" "CREATED" "COMMIT" "BRANCH"
156
156
  printf "%s\n" "$(printf '─%.0s' {1..80})"
157
-
157
+
158
158
  for dir in "$ROLLBACK_DIR"/*/; do
159
159
  if [[ -d "$dir" ]]; then
160
160
  local name=$(basename "$dir")
161
161
  local manifest="$dir/manifest.json"
162
-
162
+
163
163
  if [[ -f "$manifest" ]]; then
164
164
  local created=$(grep '"created"' "$manifest" | sed 's/.*: *"\([^"]*\)".*/\1/' | cut -c1-19)
165
165
  local commit=$(grep '"commit"' "$manifest" | sed 's/.*: *"\([^"]*\)".*/\1/' | cut -c1-8)
166
166
  local branch=$(grep '"branch"' "$manifest" | sed 's/.*: *"\([^"]*\)".*/\1/')
167
-
167
+
168
168
  printf "%-25s %-20s %-15s %s\n" "$name" "$created" "$commit" "$branch"
169
169
  fi
170
170
  fi
@@ -175,17 +175,17 @@ list_rollback_points() {
175
175
  # Delete old rollback points (keep last N)
176
176
  cleanup_rollback_points() {
177
177
  local keep="${1:-10}"
178
-
178
+
179
179
  if [[ ! -d "$ROLLBACK_DIR" ]]; then
180
180
  return 0
181
181
  fi
182
-
182
+
183
183
  local count=$(ls -d "$ROLLBACK_DIR"/*/ 2>/dev/null | wc -l | tr -d ' ')
184
-
184
+
185
185
  if [[ $count -gt $keep ]]; then
186
186
  local to_delete=$((count - keep))
187
187
  info "Cleaning up $to_delete old rollback point(s)..."
188
-
188
+
189
189
  ls -d "$ROLLBACK_DIR"/*/ 2>/dev/null | head -n "$to_delete" | while read dir; do
190
190
  rm -rf "$dir"
191
191
  success "Deleted: $(basename "$dir")"
@@ -200,35 +200,35 @@ cleanup_rollback_points() {
200
200
  # Find migration spec file
201
201
  find_migration_spec() {
202
202
  local migration_id="$1"
203
-
203
+
204
204
  # Search in common locations
205
205
  local search_paths=(
206
206
  "$MIGRATIONS_DIR/${migration_id}.md"
207
207
  "$PROJECT_ROOT/docs/${migration_id}.md"
208
208
  "$PROJECT_ROOT/tooling/docs/migrations/${migration_id}.md"
209
209
  )
210
-
210
+
211
211
  for path in "${search_paths[@]}"; do
212
212
  if [[ -f "$path" ]]; then
213
213
  echo "$path"
214
214
  return 0
215
215
  fi
216
216
  done
217
-
217
+
218
218
  # Search by pattern
219
219
  local found=$(find "$PROJECT_ROOT" -name "*${migration_id}*.md" -path "*/migrations/*" 2>/dev/null | head -1)
220
220
  if [[ -n "$found" ]]; then
221
221
  echo "$found"
222
222
  return 0
223
223
  fi
224
-
224
+
225
225
  return 1
226
226
  }
227
227
 
228
228
  # Parse rollback steps from migration spec
229
229
  parse_rollback_steps() {
230
230
  local spec_file="$1"
231
-
231
+
232
232
  # Extract rollback steps section
233
233
  awk '/^### Rollback Steps/,/^##[^#]/' "$spec_file" 2>/dev/null | \
234
234
  grep -E '^\s*[0-9]+\.' | \
@@ -239,21 +239,21 @@ parse_rollback_steps() {
239
239
  rollback_to_commit() {
240
240
  local commit="$1"
241
241
  local dry_run="$2"
242
-
242
+
243
243
  if [[ "$dry_run" == "true" ]]; then
244
244
  info "Would reset to commit: $commit"
245
245
  git log --oneline -1 "$commit"
246
246
  return 0
247
247
  fi
248
-
248
+
249
249
  info "Rolling back to commit: $commit"
250
-
250
+
251
251
  # Check for uncommitted changes
252
252
  if [[ -n "$(git status --porcelain)" ]]; then
253
253
  warning "You have uncommitted changes. These will be stashed."
254
254
  git stash push -m "pre-rollback-$(date +%s)"
255
255
  fi
256
-
256
+
257
257
  # Perform rollback
258
258
  git checkout "$commit" -- .
259
259
  success "Rolled back to commit: $commit"
@@ -264,73 +264,73 @@ rollback_from_point() {
264
264
  local point_name="$1"
265
265
  local dry_run="$2"
266
266
  local point_path="$ROLLBACK_DIR/$point_name"
267
-
267
+
268
268
  if [[ ! -d "$point_path" ]]; then
269
269
  error "Rollback point not found: $point_name"
270
270
  fi
271
-
271
+
272
272
  local manifest="$point_path/manifest.json"
273
273
  if [[ ! -f "$manifest" ]]; then
274
274
  error "Invalid rollback point (no manifest): $point_name"
275
275
  fi
276
-
276
+
277
277
  local commit=$(grep '"commit"' "$manifest" | sed 's/.*: *"\([^"]*\)".*/\1/')
278
-
278
+
279
279
  echo ""
280
280
  info "Rollback Point Details:"
281
281
  cat "$manifest" | grep -E '"(name|created|branch|commit)"' | sed 's/^/ /'
282
282
  echo ""
283
-
283
+
284
284
  if [[ "$dry_run" == "true" ]]; then
285
285
  info "[DRY RUN] Would restore from rollback point: $point_name"
286
-
286
+
287
287
  if [[ -f "$point_path/package.json" ]]; then
288
288
  info "[DRY RUN] Would restore package.json"
289
289
  fi
290
290
  if [[ -f "$point_path/pubspec.yaml" ]]; then
291
291
  info "[DRY RUN] Would restore pubspec.yaml"
292
292
  fi
293
-
293
+
294
294
  return 0
295
295
  fi
296
-
296
+
297
297
  if ! confirm "This will rollback to the saved state. Continue?"; then
298
298
  info "Rollback cancelled."
299
299
  return 0
300
300
  fi
301
-
301
+
302
302
  # Restore files
303
303
  if [[ -f "$point_path/package.json" ]]; then
304
304
  cp "$point_path/package.json" "$PROJECT_ROOT/"
305
305
  success "Restored package.json"
306
306
  fi
307
-
307
+
308
308
  if [[ -f "$point_path/package-lock.json" ]]; then
309
309
  cp "$point_path/package-lock.json" "$PROJECT_ROOT/"
310
310
  success "Restored package-lock.json"
311
311
  fi
312
-
312
+
313
313
  if [[ -f "$point_path/pubspec.yaml" ]]; then
314
314
  cp "$point_path/pubspec.yaml" "$PROJECT_ROOT/"
315
315
  success "Restored pubspec.yaml"
316
316
  fi
317
-
317
+
318
318
  if [[ -f "$point_path/pubspec.lock" ]]; then
319
319
  cp "$point_path/pubspec.lock" "$PROJECT_ROOT/"
320
320
  success "Restored pubspec.lock"
321
321
  fi
322
-
322
+
323
323
  if [[ -f "$point_path/requirements.txt" ]]; then
324
324
  cp "$point_path/requirements.txt" "$PROJECT_ROOT/"
325
325
  success "Restored requirements.txt"
326
326
  fi
327
-
327
+
328
328
  # Rollback git if commit is available
329
329
  if [[ -n "$commit" && "$commit" != "unknown" ]]; then
330
330
  info "Rolling back git state..."
331
331
  rollback_to_commit "$commit" "false"
332
332
  fi
333
-
333
+
334
334
  # Reinstall dependencies
335
335
  echo ""
336
336
  info "Dependencies may need to be reinstalled:"
@@ -343,7 +343,7 @@ rollback_from_point() {
343
343
  if [[ -f "$PROJECT_ROOT/requirements.txt" ]]; then
344
344
  echo " pip install -r requirements.txt"
345
345
  fi
346
-
346
+
347
347
  echo ""
348
348
  success "Rollback complete!"
349
349
  }
@@ -353,43 +353,43 @@ rollback_migration() {
353
353
  local migration_id="$1"
354
354
  local dry_run="$2"
355
355
  local force="$3"
356
-
356
+
357
357
  echo -e "${BOLD}Rolling back migration: $migration_id${NC}"
358
358
  echo ""
359
-
359
+
360
360
  # Look for a rollback point for this migration
361
361
  local rollback_point=$(ls -d "$ROLLBACK_DIR"/*"$migration_id"* 2>/dev/null | tail -1)
362
-
362
+
363
363
  if [[ -n "$rollback_point" && -d "$rollback_point" ]]; then
364
364
  info "Found rollback point: $(basename "$rollback_point")"
365
365
  rollback_from_point "$(basename "$rollback_point")" "$dry_run"
366
366
  return 0
367
367
  fi
368
-
368
+
369
369
  # Look for migration spec with rollback instructions
370
370
  local spec_file=$(find_migration_spec "$migration_id")
371
-
371
+
372
372
  if [[ -n "$spec_file" ]]; then
373
373
  info "Found migration spec: $spec_file"
374
-
374
+
375
375
  local steps=$(parse_rollback_steps "$spec_file")
376
-
376
+
377
377
  if [[ -n "$steps" ]]; then
378
378
  echo ""
379
379
  echo -e "${BOLD}Rollback Steps:${NC}"
380
380
  echo "$steps" | nl
381
381
  echo ""
382
-
382
+
383
383
  if [[ "$dry_run" == "true" ]]; then
384
384
  info "[DRY RUN] Would execute the above rollback steps"
385
385
  return 0
386
386
  fi
387
-
387
+
388
388
  if ! confirm "Execute these rollback steps?"; then
389
389
  info "Rollback cancelled."
390
390
  return 0
391
391
  fi
392
-
392
+
393
393
  # Execute steps (basic implementation - just displays them)
394
394
  info "Please execute the following steps manually:"
395
395
  echo "$steps" | nl
@@ -399,7 +399,7 @@ rollback_migration() {
399
399
  else
400
400
  warning "No migration spec found for: $migration_id"
401
401
  fi
402
-
402
+
403
403
  # Offer git-based rollback
404
404
  echo ""
405
405
  info "You can also rollback using git:"
@@ -448,7 +448,7 @@ main() {
448
448
  local create_name=""
449
449
  local restore_point=""
450
450
  local cleanup_keep=""
451
-
451
+
452
452
  # Parse arguments
453
453
  while [[ $# -gt 0 ]]; do
454
454
  case "$1" in
@@ -498,12 +498,12 @@ main() {
498
498
  esac
499
499
  shift
500
500
  done
501
-
501
+
502
502
  print_header
503
-
503
+
504
504
  # Ensure rollback directory exists
505
505
  mkdir -p "$ROLLBACK_DIR"
506
-
506
+
507
507
  case "$command" in
508
508
  list)
509
509
  list_rollback_points
@@ -68,20 +68,20 @@
68
68
  param(
69
69
  [Parameter(Position=0)]
70
70
  [string]$StoryKey,
71
-
71
+
72
72
  [switch]$Swarm,
73
73
  [switch]$Pair,
74
74
  [switch]$Auto,
75
75
  [switch]$Sequential,
76
-
76
+
77
77
  [string]$Agents,
78
78
  [int]$MaxIterations = 3,
79
-
79
+
80
80
  [ValidateSet("opus", "sonnet", "haiku")]
81
81
  [string]$Model = "opus",
82
-
82
+
83
83
  [double]$Budget = 20.0,
84
-
84
+
85
85
  [switch]$Memory,
86
86
  [string]$Query,
87
87
  [switch]$RouteOnly,
@@ -140,11 +140,11 @@ function Show-Usage {
140
140
  # Build Python command arguments
141
141
  function Build-PythonArgs {
142
142
  $args = @()
143
-
143
+
144
144
  if ($StoryKey) {
145
145
  $args += $StoryKey
146
146
  }
147
-
147
+
148
148
  if ($Swarm) {
149
149
  $args += "--swarm"
150
150
  } elseif ($Pair) {
@@ -154,44 +154,44 @@ function Build-PythonArgs {
154
154
  } else {
155
155
  $args += "--auto"
156
156
  }
157
-
157
+
158
158
  if ($Agents) {
159
159
  $args += "--agents"
160
160
  $args += $Agents
161
161
  }
162
-
162
+
163
163
  if ($MaxIterations -ne 3) {
164
164
  $args += "--max-iterations"
165
165
  $args += $MaxIterations.ToString()
166
166
  }
167
-
167
+
168
168
  if ($Model -ne "opus") {
169
169
  $args += "--model"
170
170
  $args += $Model
171
171
  }
172
-
172
+
173
173
  if ($Budget -ne 20.0) {
174
174
  $args += "--budget"
175
175
  $args += $Budget.ToString()
176
176
  }
177
-
177
+
178
178
  if ($Memory) {
179
179
  $args += "--memory"
180
180
  }
181
-
181
+
182
182
  if ($Query) {
183
183
  $args += "--query"
184
184
  $args += $Query
185
185
  }
186
-
186
+
187
187
  if ($RouteOnly) {
188
188
  $args += "--route-only"
189
189
  }
190
-
190
+
191
191
  if ($Quiet) {
192
192
  $args += "--quiet"
193
193
  }
194
-
194
+
195
195
  return $args
196
196
  }
197
197