@pjmendonca/devflow 1.9.0 → 1.10.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 (59) hide show
  1. package/.claude/commands/adversarial.md +10 -0
  2. package/.claude/commands/agent.md +10 -0
  3. package/.claude/commands/bugfix.md +8 -0
  4. package/.claude/commands/checkpoint.md +30 -0
  5. package/.claude/commands/collab.md +30 -0
  6. package/.claude/commands/costs.md +27 -0
  7. package/.claude/commands/develop.md +8 -0
  8. package/.claude/commands/devflow.md +6 -0
  9. package/.claude/commands/handoff.md +26 -0
  10. package/.claude/commands/memory.md +23 -0
  11. package/.claude/commands/pair.md +24 -0
  12. package/.claude/commands/personalize.md +15 -0
  13. package/.claude/commands/review.md +8 -0
  14. package/.claude/commands/route.md +26 -0
  15. package/.claude/commands/story.md +10 -0
  16. package/.claude/commands/swarm.md +22 -0
  17. package/.claude/skills/github-cli/SKILL.md +241 -0
  18. package/CHANGELOG.md +21 -1
  19. package/README.md +40 -122
  20. package/bin/create-devflow.js +141 -0
  21. package/lib/python-check.js +5 -5
  22. package/package.json +3 -1
  23. package/tooling/.automation/agents/dev.md +2 -2
  24. package/tooling/.automation/agents/reviewer.md +8 -8
  25. package/tooling/.automation/agents/sm.md +1 -1
  26. package/tooling/.automation/memory/knowledge/kg_integration-test.json +137 -1
  27. package/tooling/.automation/memory/knowledge/kg_test-story.json +438 -2
  28. package/tooling/.automation/memory/shared/shared_integration-test.json +25 -1
  29. package/tooling/.automation/memory/shared/shared_test-story.json +73 -1
  30. package/tooling/.automation/overrides/templates/reviewer/mentoring-reviewer.yaml +5 -5
  31. package/tooling/docs/DOC-STANDARD.md +21 -21
  32. package/tooling/docs/templates/bug-report.md +1 -1
  33. package/tooling/scripts/context_checkpoint.py +16 -16
  34. package/tooling/scripts/create-persona.py +7 -7
  35. package/tooling/scripts/create-persona.sh +4 -4
  36. package/tooling/scripts/init-project-workflow.sh +19 -19
  37. package/tooling/scripts/lib/__init__.py +1 -1
  38. package/tooling/scripts/lib/agent_handoff.py +4 -6
  39. package/tooling/scripts/lib/agent_router.py +6 -6
  40. package/tooling/scripts/lib/checkpoint-integration.sh +14 -14
  41. package/tooling/scripts/lib/claude-cli.sh +50 -50
  42. package/tooling/scripts/lib/cost_tracker.py +4 -4
  43. package/tooling/scripts/lib/errors.py +9 -9
  44. package/tooling/scripts/lib/pair_programming.py +5 -5
  45. package/tooling/scripts/lib/shared_memory.py +4 -4
  46. package/tooling/scripts/lib/swarm_orchestrator.py +18 -18
  47. package/tooling/scripts/new-doc.sh +12 -12
  48. package/tooling/scripts/personalize_agent.py +4 -4
  49. package/tooling/scripts/rollback-migration.sh +4 -4
  50. package/tooling/scripts/run-collab.ps1 +2 -2
  51. package/tooling/scripts/run-collab.py +13 -13
  52. package/tooling/scripts/run-story.py +1 -1
  53. package/tooling/scripts/run-story.sh +20 -20
  54. package/tooling/scripts/setup-checkpoint-service.sh +4 -4
  55. package/tooling/scripts/tech-debt-tracker.py +12 -12
  56. package/tooling/scripts/update_version.py +10 -10
  57. package/tooling/scripts/validate-overrides.py +10 -12
  58. package/tooling/scripts/validate-overrides.sh +7 -7
  59. package/tooling/scripts/validate_setup.py +8 -8
@@ -11,7 +11,7 @@ Orchestrates multiple agents working together with:
11
11
 
12
12
  Features:
13
13
  - Swarm mode: Multiple agents debate until consensus
14
- - Iteration loops: DEV REVIEWER DEV cycles
14
+ - Iteration loops: DEV -> REVIEWER -> DEV cycles
15
15
  - Parallel execution: Independent agents run simultaneously
16
16
  - Voting mechanisms for decisions
17
17
  - Automatic termination on convergence
@@ -171,9 +171,9 @@ class SwarmResult:
171
171
  ]
172
172
 
173
173
  if self.state == SwarmState.CONSENSUS:
174
- lines.append(" **Consensus reached!**")
174
+ lines.append(" **Consensus reached!**")
175
175
  elif self.state == SwarmState.MAX_ITERATIONS:
176
- lines.append("⚠️ **Max iterations reached without full consensus**")
176
+ lines.append(" **Max iterations reached without full consensus**")
177
177
 
178
178
  lines.append("")
179
179
  lines.append("### Final Output")
@@ -244,11 +244,11 @@ class SwarmOrchestrator:
244
244
  if self.config.verbose:
245
245
  timestamp = datetime.now().strftime("%H:%M:%S")
246
246
  emoji = {
247
- "INFO": "ℹ️",
248
- "SUCCESS": "",
249
- "WARNING": "⚠️",
250
- "ERROR": "",
251
- "DEBUG": "🔍",
247
+ "INFO": "[INFO]",
248
+ "SUCCESS": "",
249
+ "WARNING": "",
250
+ "ERROR": "",
251
+ "DEBUG": "",
252
252
  }.get(level, "•")
253
253
  print(f"[{timestamp}] {emoji} {message}")
254
254
 
@@ -326,7 +326,7 @@ class SwarmOrchestrator:
326
326
  issues = []
327
327
  patterns = [
328
328
  r"(?:issue|problem|bug|error|fix needed|must fix|should fix):\s*(.+)",
329
- r"❌\s*(.+)",
329
+ r"\s*(.+)",
330
330
  r"\[ISSUE\]\s*(.+)",
331
331
  r"- (?:Issue|Problem|Bug):\s*(.+)",
332
332
  ]
@@ -342,7 +342,7 @@ class SwarmOrchestrator:
342
342
  approvals = []
343
343
  patterns = [
344
344
  r"(?:lgtm|approved|looks good|well done|excellent)[\s:]*(.+)?",
345
- r"✅\s*(.+)",
345
+ r"\s*(.+)",
346
346
  r"\[APPROVED\]\s*(.+)?",
347
347
  ]
348
348
 
@@ -358,7 +358,7 @@ class SwarmOrchestrator:
358
358
  suggestions = []
359
359
  patterns = [
360
360
  r"(?:suggest|consider|recommend|might want to|could):\s*(.+)",
361
- r"💡\s*(.+)",
361
+ r"\s*(.+)",
362
362
  r"\[SUGGESTION\]\s*(.+)",
363
363
  ]
364
364
 
@@ -470,15 +470,15 @@ At the end, clearly indicate if you APPROVE or have ISSUES with the work.
470
470
  if r.issues_found:
471
471
  feedback_lines.append("**Issues found:**")
472
472
  for issue in r.issues_found:
473
- feedback_lines.append(f"-{issue}")
473
+ feedback_lines.append(f"- {issue}")
474
474
  if r.suggestions:
475
475
  feedback_lines.append("**Suggestions:**")
476
476
  for sug in r.suggestions:
477
- feedback_lines.append(f"- 💡 {sug}")
477
+ feedback_lines.append(f"- {sug}")
478
478
  if r.approvals:
479
479
  feedback_lines.append("**Approvals:**")
480
480
  for app in r.approvals:
481
- feedback_lines.append(f"-{app}")
481
+ feedback_lines.append(f"- {app}")
482
482
  feedback_lines.append("")
483
483
 
484
484
  prompt = f"""You are the {agent} agent. This is iteration {iteration + 1}.
@@ -573,7 +573,7 @@ At the end, clearly indicate if you APPROVE the current state or have remaining
573
573
  previous_responses = iter_responses
574
574
 
575
575
  self._log(f"Issues remaining: {len(issues_to_fix)}")
576
- self._log(f"Consensus: {' Yes' if consensus else ' No'}")
576
+ self._log(f"Consensus: {' Yes' if consensus else ' No'}")
577
577
 
578
578
  if consensus:
579
579
  self.state = SwarmState.CONSENSUS
@@ -630,7 +630,7 @@ At the end, clearly indicate if you APPROVE the current state or have remaining
630
630
  task: str,
631
631
  max_iterations: Optional[int] = None,
632
632
  ) -> SwarmResult:
633
- """Run a simple iteration loop between two agents (e.g., DEV REVIEWER DEV)."""
633
+ """Run a simple iteration loop between two agents (e.g., DEV -> REVIEWER -> DEV)."""
634
634
  return self.run_swarm(
635
635
  agents=[primary_agent, reviewer_agent], task=task, max_iterations=max_iterations
636
636
  )
@@ -647,7 +647,7 @@ def run_swarm(
647
647
 
648
648
 
649
649
  def run_dev_review_loop(story_key: str, task: str, max_iterations: int = 3) -> SwarmResult:
650
- """Run a DEV REVIEWER iteration loop."""
650
+ """Run a DEV -> REVIEWER iteration loop."""
651
651
  config = SwarmConfig(
652
652
  max_iterations=max_iterations, consensus_type=ConsensusType.REVIEWER_APPROVAL
653
653
  )
@@ -680,7 +680,7 @@ if __name__ == "__main__":
680
680
  )
681
681
  print(result.to_summary())
682
682
 
683
- # Simple DEV REVIEWER loop
683
+ # Simple DEV -> REVIEWER loop
684
684
  result = run_dev_review_loop(
685
685
  story_key="3-5",
686
686
  task="Implement login endpoint",
@@ -354,24 +354,24 @@ create_status_template() {
354
354
 
355
355
  | Component | Status | Notes |
356
356
  |-----------|--------|-------|
357
- | Component 1 |Complete | Working as expected |
358
- | Component 2 | 🚧 In Progress | 75% complete |
359
- | Component 3 |Not Started | Planned for next week |
357
+ | Component 1 | Complete | Working as expected |
358
+ | Component 2 | In Progress | 75% complete |
359
+ | Component 3 | Not Started | Planned for next week |
360
360
 
361
361
  ---
362
362
 
363
363
  ## What's Working
364
364
 
365
- Feature 1 - Fully operational
366
- Feature 2 - Deployed and tested
367
- Feature 3 - In production
365
+ Feature 1 - Fully operational
366
+ Feature 2 - Deployed and tested
367
+ Feature 3 - In production
368
368
 
369
369
  ---
370
370
 
371
371
  ## What's Not Working
372
372
 
373
- Issue 1 - Description
374
- ⚠️ Issue 2 - Description
373
+ Issue 1 - Description
374
+ Issue 2 - Description
375
375
 
376
376
  ---
377
377
 
@@ -379,9 +379,9 @@ create_status_template() {
379
379
 
380
380
  | Metric | Value | Target | Status |
381
381
  |--------|-------|--------|--------|
382
- | Coverage | 85% | 80% ||
383
- | Performance | 200ms | <300ms ||
384
- | Bugs | 3 | <5 ||
382
+ | Coverage | 85% | 80% | |
383
+ | Performance | 200ms | <300ms | |
384
+ | Bugs | 3 | <5 | |
385
385
 
386
386
  ---
387
387
 
@@ -521,7 +521,7 @@ main() {
521
521
  # Write file
522
522
  echo "$template" > "$output_file"
523
523
 
524
- echo -e "${GREEN} Created: $output_file${NC}"
524
+ echo -e "${GREEN} Created: $output_file${NC}"
525
525
  echo ""
526
526
  echo -e "${BLUE}Next steps:${NC}"
527
527
  echo " 1. Edit the document: $output_file"
@@ -84,7 +84,7 @@ def prompt_choice(prompt: str, options: list[str], default: int = 0) -> int:
84
84
  """Prompt user to choose from options."""
85
85
  print(f"{Colors.YELLOW}{prompt}{Colors.END}")
86
86
  for i, opt in enumerate(options):
87
- marker = "" if i == default else " "
87
+ marker = "->" if i == default else " "
88
88
  print(f" {marker} [{i + 1}] {opt}")
89
89
 
90
90
  while True:
@@ -305,7 +305,7 @@ def save_override(agent_name: str, override: dict):
305
305
  content += write_yaml(override)
306
306
 
307
307
  override_path.write_text(content)
308
- print(f"\n{Colors.GREEN} Saved: {override_path}{Colors.END}")
308
+ print(f"\n{Colors.GREEN} Saved: {override_path}{Colors.END}")
309
309
 
310
310
 
311
311
  def main():
@@ -345,7 +345,7 @@ def main():
345
345
  for key, value in values.items():
346
346
  content += f' {key}: "{value}"\n'
347
347
  profile_path.write_text(content)
348
- print(f"\n{Colors.GREEN} User profile saved{Colors.END}")
348
+ print(f"\n{Colors.GREEN} User profile saved{Colors.END}")
349
349
 
350
350
  # Determine agents to personalize
351
351
  agents = get_available_agents()
@@ -375,7 +375,7 @@ def main():
375
375
  if override:
376
376
  save_override(agent, override)
377
377
 
378
- print(f"\n{Colors.GREEN}{Colors.BOLD} Personalization complete!{Colors.END}")
378
+ print(f"\n{Colors.GREEN}{Colors.BOLD} Personalization complete!{Colors.END}")
379
379
  print(f"\nYour overrides are in: {OVERRIDES_DIR}")
380
380
  print("They will be applied automatically when running agents.")
381
381
  print("\nTo modify later, edit the .override.yaml files directly.")
@@ -48,20 +48,20 @@ print_header() {
48
48
  }
49
49
 
50
50
  error() {
51
- echo -e "${RED} ERROR:${NC} $1"
51
+ echo -e "${RED}[X] ERROR:${NC} $1"
52
52
  exit 1
53
53
  }
54
54
 
55
55
  warning() {
56
- echo -e "${YELLOW}WARNING:${NC} $1"
56
+ echo -e "${YELLOW}WARNING:${NC} $1"
57
57
  }
58
58
 
59
59
  success() {
60
- echo -e "${GREEN}✓${NC} $1"
60
+ echo -e "${GREEN}[OK]${NC} $1"
61
61
  }
62
62
 
63
63
  info() {
64
- echo -e "${BLUE}ℹ${NC} $1"
64
+ echo -e "${BLUE}[i]${NC} $1"
65
65
  }
66
66
 
67
67
  confirm() {
@@ -242,10 +242,10 @@ $exitCode = $LASTEXITCODE
242
242
  if ($exitCode -eq 0) {
243
243
  Write-Host ""
244
244
  Write-ColorOutput "════════════════════════════════════════════════════════════" -Color Green
245
- Write-ColorOutput " Collaboration complete!" -Color Green
245
+ Write-ColorOutput " Collaboration complete!" -Color Green
246
246
  } else {
247
247
  Write-Host ""
248
- Write-ColorOutput " Failed with exit code: $exitCode" -Color Red
248
+ Write-ColorOutput " Failed with exit code: $exitCode" -Color Red
249
249
  }
250
250
 
251
251
  exit $exitCode
@@ -218,7 +218,7 @@ def print_banner():
218
218
 
219
219
  def print_routing_decision(result: RoutingResult, router: AgentRouter):
220
220
  """Print the routing decision."""
221
- print(f"\n{Colors.BOLD}🎯 Routing Decision{Colors.END}")
221
+ print(f"\n{Colors.BOLD}Routing Decision{Colors.END}")
222
222
  print(router.explain_routing(result))
223
223
 
224
224
 
@@ -240,13 +240,13 @@ def run_auto_mode(story_key: str, task: str, args: argparse.Namespace):
240
240
 
241
241
  # Decide execution mode based on routing
242
242
  if result.workflow == "swarm":
243
- print(f"\n{Colors.YELLOW} Using swarm mode for multi-agent collaboration{Colors.END}")
243
+ print(f"\n{Colors.YELLOW}-> Using swarm mode for multi-agent collaboration{Colors.END}")
244
244
  return run_swarm_mode(story_key, task, result.agents, args)
245
245
  elif result.workflow == "pair":
246
- print(f"\n{Colors.YELLOW} Using pair programming mode{Colors.END}")
246
+ print(f"\n{Colors.YELLOW}-> Using pair programming mode{Colors.END}")
247
247
  return run_pair_mode(story_key, task, args)
248
248
  else:
249
- print(f"\n{Colors.YELLOW} Using sequential execution{Colors.END}")
249
+ print(f"\n{Colors.YELLOW}-> Using sequential execution{Colors.END}")
250
250
  return run_sequential_mode(story_key, task, result.agents, args)
251
251
 
252
252
 
@@ -299,7 +299,7 @@ def run_pair_mode(story_key: str, task: str, args: argparse.Namespace):
299
299
 
300
300
  def run_sequential_mode(story_key: str, task: str, agents: list[str], args: argparse.Namespace):
301
301
  """Run sequential agent execution with handoffs."""
302
- print_section("Sequential Mode", f"Pipeline: {' '.join(agents)}")
302
+ print_section("Sequential Mode", f"Pipeline: {' -> '.join(agents)}")
303
303
 
304
304
  get_shared_memory(story_key)
305
305
  get_knowledge_graph(story_key)
@@ -309,7 +309,7 @@ def run_sequential_mode(story_key: str, task: str, agents: list[str], args: argp
309
309
  previous_output = ""
310
310
 
311
311
  for i, agent in enumerate(agents):
312
- print(f"\n{Colors.CYAN} Running {agent}...{Colors.END}")
312
+ print(f"\n{Colors.CYAN}> Running {agent}...{Colors.END}")
313
313
 
314
314
  # Get context including handoffs
315
315
  context = handoff_gen.generate_context_for_agent(agent)
@@ -329,7 +329,7 @@ Complete your part of this task according to your role.
329
329
  """
330
330
 
331
331
  # Invoke agent (simplified - in real use would call Claude CLI)
332
- print(" Generating response...")
332
+ print(" -> Generating response...")
333
333
 
334
334
  # For demo, we'll note the handoff
335
335
  if i > 0:
@@ -340,7 +340,7 @@ Complete your part of this task according to your role.
340
340
  story_key=story_key,
341
341
  summary=f"Completed {prev_agent} phase, handing off to {agent}",
342
342
  )
343
- print(f" Handoff from {prev_agent}: {handoff.id}")
343
+ print(f" -> Handoff from {prev_agent}: {handoff.id}")
344
344
 
345
345
  # Record in shared memory
346
346
  share_learning(
@@ -351,7 +351,7 @@ Complete your part of this task according to your role.
351
351
  {"agent": agent, "status": "completed", "timestamp": datetime.now().isoformat()}
352
352
  )
353
353
 
354
- print(f"\n{Colors.GREEN} Sequential pipeline complete!{Colors.END}")
354
+ print(f"\n{Colors.GREEN} Sequential pipeline complete!{Colors.END}")
355
355
 
356
356
  # Save result
357
357
  save_result(story_key, "sequential", {"agents": agents, "results": results})
@@ -388,7 +388,7 @@ def save_result(story_key: str, mode: str, result: dict):
388
388
  ensure_ascii=False,
389
389
  )
390
390
 
391
- print(f"\n{Colors.CYAN}📁 Result saved to: {filepath}{Colors.END}")
391
+ print(f"\n{Colors.CYAN} Result saved to: {filepath}{Colors.END}")
392
392
 
393
393
 
394
394
  def show_memory(story_key: str):
@@ -586,14 +586,14 @@ def main():
586
586
  run_auto_mode(story_key, task, args)
587
587
 
588
588
  print(f"\n{Colors.GREEN}{'═' * 60}{Colors.END}")
589
- print(f"{Colors.GREEN} Collaboration complete!{Colors.END}")
589
+ print(f"{Colors.GREEN} Collaboration complete!{Colors.END}")
590
590
  return 0
591
591
 
592
592
  except KeyboardInterrupt:
593
- print(f"\n{Colors.YELLOW}⚠️ Interrupted by user{Colors.END}")
593
+ print(f"\n{Colors.YELLOW} Interrupted by user{Colors.END}")
594
594
  return 130
595
595
  except Exception as e:
596
- print(f"\n{Colors.RED} Error: {e}{Colors.END}")
596
+ print(f"\n{Colors.RED} Error: {e}{Colors.END}")
597
597
  if not args.quiet:
598
598
  import traceback
599
599
 
@@ -305,7 +305,7 @@ class NativeRunner:
305
305
  print(f"Review phase failed: {output[:200]}")
306
306
  return 1
307
307
 
308
- print("\n Story automation complete!")
308
+ print("\n[OK] Story automation complete!")
309
309
 
310
310
  # Show final costs
311
311
  if self.tracker:
@@ -252,7 +252,7 @@ main() {
252
252
 
253
253
  # Check for existing checkpoint and offer to resume
254
254
  if type has_checkpoint &>/dev/null && has_checkpoint "$story_key"; then
255
- echo -e "${CYAN}📂 Found existing checkpoint for story: $story_key${NC}"
255
+ echo -e "${CYAN} Found existing checkpoint for story: $story_key${NC}"
256
256
  echo -e "${YELLOW}Would you like to resume from the checkpoint? (y/n)${NC}"
257
257
  read -r RESUME_CHOICE
258
258
 
@@ -269,7 +269,7 @@ main() {
269
269
 
270
270
  # Create pre-start checkpoint
271
271
  if type create_story_checkpoint &>/dev/null; then
272
- echo -e "${CYAN}💾 Creating pre-start checkpoint...${NC}"
272
+ echo -e "${CYAN} Creating pre-start checkpoint...${NC}"
273
273
  create_story_checkpoint "$story_key" "pre-start" 2>&1 | grep -v "Could not export"
274
274
  echo ""
275
275
  fi
@@ -279,7 +279,7 @@ main() {
279
279
  # COLLABORATIVE MODES - Multi-agent collaboration
280
280
  # ═══════════════════════════════════════════════════════════════
281
281
  "swarm")
282
- echo -e "${YELLOW} Running swarm mode (multi-agent debate)...${NC}"
282
+ echo -e "${YELLOW}> Running swarm mode (multi-agent debate)...${NC}"
283
283
  echo ""
284
284
  local swarm_args="$story_key --swarm"
285
285
  if [[ -n "$collab_agents" ]]; then
@@ -294,7 +294,7 @@ main() {
294
294
  fi
295
295
  ;;
296
296
  "pair")
297
- echo -e "${YELLOW} Running pair programming mode (DEV + REVIEWER)...${NC}"
297
+ echo -e "${YELLOW}> Running pair programming mode (DEV + REVIEWER)...${NC}"
298
298
  echo ""
299
299
  python3 "$SCRIPT_DIR/run-collab.py" "$story_key" --pair --max-revisions "$max_iterations"
300
300
  local exit_code=$?
@@ -304,7 +304,7 @@ main() {
304
304
  fi
305
305
  ;;
306
306
  "auto-route")
307
- echo -e "${YELLOW} Running auto-route mode (intelligent agent selection)...${NC}"
307
+ echo -e "${YELLOW}> Running auto-route mode (intelligent agent selection)...${NC}"
308
308
  echo ""
309
309
  python3 "$SCRIPT_DIR/run-collab.py" "$story_key" --auto
310
310
  local exit_code=$?
@@ -318,7 +318,7 @@ main() {
318
318
  # GREENFIELD MODES - New feature development
319
319
  # ═══════════════════════════════════════════════════════════════
320
320
  "develop")
321
- echo -e "${YELLOW} Running development phase...${NC}"
321
+ echo -e "${YELLOW}> Running development phase...${NC}"
322
322
  echo ""
323
323
  invoke_dev_story "$story_key"
324
324
  local exit_code=$?
@@ -339,19 +339,19 @@ main() {
339
339
  fi
340
340
  ;;
341
341
  "review")
342
- echo -e "${YELLOW} Running review phase...${NC}"
342
+ echo -e "${YELLOW}> Running review phase...${NC}"
343
343
  echo ""
344
344
  invoke_sm_code_review "$story_key"
345
345
  exit_code=$?
346
346
  ;;
347
347
  "adversarial")
348
- echo -e "${YELLOW} Running adversarial review (Opus)...${NC}"
348
+ echo -e "${YELLOW}> Running adversarial review (Opus)...${NC}"
349
349
  echo ""
350
350
  invoke_adversarial_review "$story_key"
351
351
  exit_code=$?
352
352
  ;;
353
353
  "context")
354
- echo -e "${YELLOW} Creating story context...${NC}"
354
+ echo -e "${YELLOW}> Creating story context...${NC}"
355
355
  echo ""
356
356
  invoke_sm_story_context "$story_key"
357
357
  exit_code=$?
@@ -361,7 +361,7 @@ main() {
361
361
  # BROWNFIELD MODES - Existing codebase maintenance
362
362
  # ═══════════════════════════════════════════════════════════════
363
363
  "bugfix")
364
- echo -e "${YELLOW} Running bug fix workflow...${NC}"
364
+ echo -e "${YELLOW}> Running bug fix workflow...${NC}"
365
365
  echo ""
366
366
  invoke_bugfix "$story_key"
367
367
  exit_code=$?
@@ -372,7 +372,7 @@ main() {
372
372
  fi
373
373
  ;;
374
374
  "refactor")
375
- echo -e "${YELLOW} Running refactoring workflow...${NC}"
375
+ echo -e "${YELLOW}> Running refactoring workflow...${NC}"
376
376
  echo ""
377
377
  invoke_refactor "$story_key"
378
378
  exit_code=$?
@@ -383,14 +383,14 @@ main() {
383
383
  fi
384
384
  ;;
385
385
  "investigate")
386
- echo -e "${YELLOW} Running investigation workflow...${NC}"
386
+ echo -e "${YELLOW}> Running investigation workflow...${NC}"
387
387
  echo ""
388
388
  invoke_investigate "$story_key"
389
389
  exit_code=$?
390
390
  # No auto-commit for investigation (read-only)
391
391
  ;;
392
392
  "quickfix")
393
- echo -e "${YELLOW} Running quick fix...${NC}"
393
+ echo -e "${YELLOW}> Running quick fix...${NC}"
394
394
  echo ""
395
395
  invoke_quickfix "$story_key"
396
396
  exit_code=$?
@@ -401,7 +401,7 @@ main() {
401
401
  fi
402
402
  ;;
403
403
  "migrate")
404
- echo -e "${YELLOW} Running migration workflow...${NC}"
404
+ echo -e "${YELLOW}> Running migration workflow...${NC}"
405
405
  echo ""
406
406
  invoke_migrate "$story_key"
407
407
  exit_code=$?
@@ -412,7 +412,7 @@ main() {
412
412
  fi
413
413
  ;;
414
414
  "tech-debt")
415
- echo -e "${YELLOW} Running technical debt resolution...${NC}"
415
+ echo -e "${YELLOW}> Running technical debt resolution...${NC}"
416
416
  echo ""
417
417
  invoke_tech_debt "$story_key"
418
418
  exit_code=$?
@@ -427,7 +427,7 @@ main() {
427
427
  # DEFAULT - Full greenfield pipeline
428
428
  # ═══════════════════════════════════════════════════════════════
429
429
  *)
430
- echo -e "${YELLOW} Running full pipeline...${NC}"
430
+ echo -e "${YELLOW}> Running full pipeline...${NC}"
431
431
  echo ""
432
432
  run_full_pipeline "$story_key"
433
433
  exit_code=$?
@@ -437,7 +437,7 @@ main() {
437
437
  # Create completion checkpoint if successful
438
438
  if [[ $exit_code -eq 0 && "$mode" != "context" ]]; then
439
439
  if type create_story_checkpoint &>/dev/null; then
440
- echo -e "${CYAN}💾 Creating completion checkpoint...${NC}"
440
+ echo -e "${CYAN} Creating completion checkpoint...${NC}"
441
441
  create_story_checkpoint "$story_key" "complete" 2>&1 | grep -v "Could not export"
442
442
  echo ""
443
443
  fi
@@ -445,15 +445,15 @@ main() {
445
445
 
446
446
  # Cleanup old checkpoints (keep last 10)
447
447
  if type cleanup_old_checkpoints &>/dev/null; then
448
- cleanup_old_checkpoints 10 2>&1 | grep -E "^(🧹|✅|Deleted)"
448
+ cleanup_old_checkpoints 10 2>&1 | grep -E "^(||Deleted)"
449
449
  echo ""
450
450
  fi
451
451
 
452
452
  echo ""
453
453
  if [[ $exit_code -eq 0 ]]; then
454
- echo -e "${GREEN} Complete!${NC}"
454
+ echo -e "${GREEN} Complete!${NC}"
455
455
  else
456
- echo -e "${RED} Failed with exit code: $exit_code${NC}"
456
+ echo -e "${RED} Failed with exit code: $exit_code${NC}"
457
457
  fi
458
458
 
459
459
  echo ""
@@ -30,19 +30,19 @@ print_header() {
30
30
  }
31
31
 
32
32
  print_success() {
33
- echo -e "${GREEN} $1${NC}"
33
+ echo -e "${GREEN} $1${NC}"
34
34
  }
35
35
 
36
36
  print_error() {
37
- echo -e "${RED} $1${NC}"
37
+ echo -e "${RED} $1${NC}"
38
38
  }
39
39
 
40
40
  print_info() {
41
- echo -e "${BLUE}ℹ️ $1${NC}"
41
+ echo -e "${BLUE}$1${NC}"
42
42
  }
43
43
 
44
44
  print_warning() {
45
- echo -e "${YELLOW}⚠️ $1${NC}"
45
+ echo -e "${YELLOW} $1${NC}"
46
46
  }
47
47
 
48
48
  # Check if script exists
@@ -370,7 +370,7 @@ def print_dashboard(report: DebtReport, history: list[dict[str, Any]]):
370
370
  print()
371
371
 
372
372
  # Summary box
373
- print(f"{Colors.BOLD}📊 SUMMARY{Colors.NC}")
373
+ print(f"{Colors.BOLD} SUMMARY{Colors.NC}")
374
374
  print(f" ┌{'─' * 40}┐")
375
375
  print(f" │ {'Total Items:':<20} {report.total_count:>17} │")
376
376
  print(f" │ {'Debt Score:':<20} {report.debt_score:>17} │")
@@ -379,7 +379,7 @@ def print_dashboard(report: DebtReport, history: list[dict[str, Any]]):
379
379
  print()
380
380
 
381
381
  # Severity breakdown
382
- print(f"{Colors.BOLD}🎯 BY SEVERITY{Colors.NC}")
382
+ print(f"{Colors.BOLD}BY SEVERITY{Colors.NC}")
383
383
  severity_colors = {
384
384
  "critical": Colors.RED,
385
385
  "high": Colors.YELLOW,
@@ -395,7 +395,7 @@ def print_dashboard(report: DebtReport, history: list[dict[str, Any]]):
395
395
  print()
396
396
 
397
397
  # Category breakdown
398
- print(f"{Colors.BOLD}📁 BY CATEGORY{Colors.NC}")
398
+ print(f"{Colors.BOLD} BY CATEGORY{Colors.NC}")
399
399
  for category, count in sorted(report.by_category.items(), key=lambda x: -x[1]):
400
400
  bar_length = (
401
401
  int((count / max(report.by_category.values())) * 30) if report.by_category else 0
@@ -405,14 +405,14 @@ def print_dashboard(report: DebtReport, history: list[dict[str, Any]]):
405
405
  print()
406
406
 
407
407
  # Type breakdown
408
- print(f"{Colors.BOLD}🏷️ BY TYPE{Colors.NC}")
408
+ print(f"{Colors.BOLD}BY TYPE{Colors.NC}")
409
409
  for debt_type, count in sorted(report.by_type.items(), key=lambda x: -x[1]):
410
410
  print(f" {debt_type:>12}: {count}")
411
411
  print()
412
412
 
413
413
  # Trend (if history available)
414
414
  if len(history) > 1:
415
- print(f"{Colors.BOLD}📈 TREND (last 10 scans){Colors.NC}")
415
+ print(f"{Colors.BOLD}TREND (last 10 scans){Colors.NC}")
416
416
  recent = history[-10:]
417
417
  scores = [h.get("score", 0) for h in recent]
418
418
  max_score = max(scores) if scores else 1
@@ -428,17 +428,17 @@ def print_dashboard(report: DebtReport, history: list[dict[str, Any]]):
428
428
  if len(scores) >= 2:
429
429
  change = scores[-1] - scores[-2]
430
430
  if change > 0:
431
- print(f"\n {Colors.RED} Score increased by {change} (more debt){Colors.NC}")
431
+ print(f"\n {Colors.RED}[UP] Score increased by {change} (more debt){Colors.NC}")
432
432
  elif change < 0:
433
433
  print(
434
- f"\n {Colors.GREEN} Score decreased by {abs(change)} (less debt){Colors.NC}"
434
+ f"\n {Colors.GREEN}[DOWN] Score decreased by {abs(change)} (less debt){Colors.NC}"
435
435
  )
436
436
  else:
437
- print(f"\n {Colors.YELLOW} Score unchanged{Colors.NC}")
437
+ print(f"\n {Colors.YELLOW}-> Score unchanged{Colors.NC}")
438
438
  print()
439
439
 
440
440
  # Top offenders
441
- print(f"{Colors.BOLD}🔥 TOP 5 FILES WITH MOST DEBT{Colors.NC}")
441
+ print(f"{Colors.BOLD}TOP 5 FILES WITH MOST DEBT{Colors.NC}")
442
442
  file_counts: dict[str, int] = {}
443
443
  for item in report.items:
444
444
  file_counts[item.file_path] = file_counts.get(item.file_path, 0) + 1
@@ -469,7 +469,7 @@ def print_report(report: DebtReport):
469
469
  by_file[item.file_path].append(item)
470
470
 
471
471
  for file_path, items in sorted(by_file.items()):
472
- print(f"{Colors.BLUE}📄 {file_path}{Colors.NC}")
472
+ print(f"{Colors.BLUE}{file_path}{Colors.NC}")
473
473
  for item in items:
474
474
  severity_color = {
475
475
  "critical": Colors.RED,
@@ -485,9 +485,9 @@ def print_report(report: DebtReport):
485
485
 
486
486
  # Documented debt
487
487
  if report.documented_debt:
488
- print(f"{Colors.BOLD}📋 DOCUMENTED DEBT{Colors.NC}")
488
+ print(f"{Colors.BOLD} DOCUMENTED DEBT{Colors.NC}")
489
489
  for doc in report.documented_debt:
490
- print(f" 📄 {doc['file']}")
490
+ print(f" {doc['file']}")
491
491
  print()
492
492
 
493
493