mapify-cli 3.2.0__tar.gz → 3.3.0__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 (101) hide show
  1. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/.claude/skills/README.md +2 -4
  2. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/.gitignore +0 -17
  3. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/PKG-INFO +1 -1
  4. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/pyproject.toml +1 -1
  5. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/__init__.py +33 -158
  6. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/dependency_graph.py +116 -0
  7. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/schemas.py +1 -195
  8. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/CLAUDE.md +1 -2
  9. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/actor.md +45 -151
  10. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/documentation-reviewer.md +0 -25
  11. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/evaluator.md +10 -33
  12. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/monitor.md +84 -105
  13. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/predictor.md +70 -161
  14. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/reflector.md +28 -92
  15. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/research-agent.md +0 -21
  16. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/task-decomposer.md +34 -45
  17. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-debate.md +92 -71
  18. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-debug.md +1 -9
  19. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-efficient.md +146 -48
  20. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-fast.md +4 -5
  21. mapify_cli-3.3.0/src/mapify_cli/templates/commands/map-learn.md +246 -0
  22. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-plan.md +36 -0
  23. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-release.md +2 -14
  24. mapify_cli-3.3.0/src/mapify_cli/templates/commands/map-review.md +307 -0
  25. mapify_cli-3.3.0/src/mapify_cli/templates/hooks/block-dangerous.sh +173 -0
  26. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/block-secrets.py +43 -13
  27. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/post-edit-reminder.py +7 -2
  28. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/ralph-context-pruner.py +5 -2
  29. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/safety-guardrails.py +26 -17
  30. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/workflow-context-injector.py +19 -3
  31. mapify_cli-3.3.0/src/mapify_cli/templates/hooks/workflow-gate.py +269 -0
  32. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/scripts/map_orchestrator.py +315 -6
  33. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/scripts/map_step_runner.py +89 -1
  34. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/mcp-usage-examples.md +2 -29
  35. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/step-state-schema.md +1 -2
  36. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/workflow-state-schema.md +10 -13
  37. mapify_cli-3.3.0/src/mapify_cli/templates/settings.json +118 -0
  38. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/README.md +2 -4
  39. mapify_cli-3.3.0/src/mapify_cli/templates/skills/map-cli-reference/SKILL.md +124 -0
  40. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-cli-reference/scripts/check-command.sh +9 -18
  41. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/SKILL.md +8 -46
  42. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/agent-architecture.md +7 -20
  43. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-debug-deep-dive.md +2 -5
  44. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-efficient-deep-dive.md +12 -16
  45. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-fast-deep-dive.md +3 -9
  46. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-feature-deep-dive.md +11 -17
  47. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-refactor-deep-dive.md +0 -5
  48. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/skill-rules.json +3 -4
  49. mapify_cli-3.2.0/src/mapify_cli/contradiction_detector.py +0 -735
  50. mapify_cli-3.2.0/src/mapify_cli/entity_extractor.py +0 -882
  51. mapify_cli-3.2.0/src/mapify_cli/graph_query.py +0 -787
  52. mapify_cli-3.2.0/src/mapify_cli/relationship_detector.py +0 -771
  53. mapify_cli-3.2.0/src/mapify_cli/templates/agents/curator.md +0 -1296
  54. mapify_cli-3.2.0/src/mapify_cli/templates/commands/map-learn.md +0 -472
  55. mapify_cli-3.2.0/src/mapify_cli/templates/commands/map-review.md +0 -182
  56. mapify_cli-3.2.0/src/mapify_cli/templates/hooks/block-dangerous.sh +0 -114
  57. mapify_cli-3.2.0/src/mapify_cli/templates/hooks/workflow-gate.py +0 -178
  58. mapify_cli-3.2.0/src/mapify_cli/templates/settings.hooks.json +0 -74
  59. mapify_cli-3.2.0/src/mapify_cli/templates/settings.json +0 -38
  60. mapify_cli-3.2.0/src/mapify_cli/templates/skills/map-cli-reference/SKILL.md +0 -202
  61. mapify_cli-3.2.0/src/mapify_cli/templates/skills/map-workflows-guide/resources/playbook-system.md +0 -301
  62. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/README.md +0 -0
  63. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/intent_detector.py +0 -0
  64. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/ralph_state.py +0 -0
  65. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/repo_insight.py +0 -0
  66. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/debate-arbiter.md +0 -0
  67. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/final-verifier.md +0 -0
  68. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/synthesizer.md +0 -0
  69. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-check.md +0 -0
  70. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-resume.md +0 -0
  71. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/end-of-turn.sh +0 -0
  72. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/improve-prompt.py +0 -0
  73. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/ralph-iteration-logger.py +0 -0
  74. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/scripts/diagnostics.py +0 -0
  75. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/analyze.sh +0 -0
  76. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/common.sh +0 -0
  77. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/go.sh +0 -0
  78. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/python.sh +0 -0
  79. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/rust.sh +0 -0
  80. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/typescript.sh +0 -0
  81. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/ralph-loop-config.json +0 -0
  82. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/bash-guidelines.md +0 -0
  83. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/decomposition-examples.md +0 -0
  84. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/escalation-matrix.md +0 -0
  85. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/SKILL.md +0 -0
  86. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/scripts/check-complete.sh +0 -0
  87. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/scripts/get-plan-path.sh +0 -0
  88. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/scripts/init-session.sh +0 -0
  89. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/scripts/show-focus.sh +0 -0
  90. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/templates/findings.md +0 -0
  91. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/templates/iteration_history.md +0 -0
  92. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/templates/progress.md +0 -0
  93. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/templates/task_plan.md +0 -0
  94. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/scripts/validate-workflow-choice.py +0 -0
  95. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/workflow-rules.json +0 -0
  96. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/tools/__init__.py +0 -0
  97. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/tools/validate_dependencies.py +0 -0
  98. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/verification_recorder.py +0 -0
  99. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/workflow_finalizer.py +0 -0
  100. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/workflow_logger.py +0 -0
  101. {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/workflow_state.py +0 -0
@@ -54,7 +54,6 @@ MAP: [Shows decision tree and comparison matrix]
54
54
  - `map-feature-deep-dive.md` - Full validation workflow (PLANNED)
55
55
  - `map-refactor-deep-dive.md` - Dependency analysis (PLANNED)
56
56
  - `agent-architecture.md` - How 12 agents orchestrate
57
- - `playbook-system.md` - Knowledge storage and search
58
57
 
59
58
  ---
60
59
 
@@ -124,7 +123,6 @@ Skills work seamlessly with the prompt improvement system:
124
123
  ├── map-debug-deep-dive.md
125
124
  ├── map-refactor-deep-dive.md
126
125
  ├── agent-architecture.md
127
- ├── playbook-system.md
128
126
  ```
129
127
 
130
128
  ---
@@ -154,12 +152,12 @@ Skills work seamlessly with the prompt improvement system:
154
152
 
155
153
  **Check:**
156
154
  1. `skill-rules.json` has correct triggers
157
- 2. `improve-prompt.py` hook is enabled in `settings.hooks.json`
155
+ 2. `improve-prompt.py` hook is enabled in `.claude/settings.json`
158
156
  3. Hook processes UserPromptSubmit events
159
157
 
160
158
  **Fix:**
161
159
  - Update trigger patterns in `skill-rules.json`
162
- - Verify hook configuration in `.claude/settings.hooks.json`
160
+ - Verify hook configuration in `.claude/settings.json`
163
161
 
164
162
  ### Skill content too long
165
163
 
@@ -27,15 +27,7 @@ wheels/
27
27
  data/
28
28
  htmlcov/
29
29
 
30
- # ACE Playbook - user-specific data
31
30
  .claude/embeddings_cache/
32
- # LEGACY: playbook.json entries for migration support (ignore old format files)
33
- .claude/playbook.json
34
- .claude/playbook.json.backup.*
35
- # Current format: SQLite database
36
- .claude/playbook.db
37
- .claude/playbook.db-shm
38
- .claude/playbook.db-wal
39
31
  .claude/mcp_config.json
40
32
  .claude/settings.local.json
41
33
 
@@ -66,15 +58,6 @@ docs/claude-code-infrastructure-showcase
66
58
  docs/claude-code-subagents
67
59
 
68
60
 
69
- # Curator temporary files
70
- .claude/curator_delta_operations.json
71
- .claude/curator_integration_report.json
72
- .claude/curator_operations.json
73
- .claude/*_integration_report.json
74
- .claude/apply_*_deltas.py
75
- .claude/insert_*_bullets.sql
76
- curator_operations*.json
77
- curator_final_report.json
78
61
  docs/claude-code-prompt-improver
79
62
 
80
63
  # macOS system files
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapify-cli
3
- Version: 3.2.0
3
+ Version: 3.3.0
4
4
  Summary: MAP Framework installer - Modular Agentic Planner for Claude Code
5
5
  Project-URL: Homepage, https://github.com/azalio/map-framework
6
6
  Project-URL: Repository, https://github.com/azalio/map-framework.git
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mapify-cli"
3
- version = "3.2.0"
3
+ version = "3.3.0"
4
4
  description = "MAP Framework installer - Modular Agentic Planner for Claude Code"
5
5
  authors = [{ name = "MAP Framework Contributors" }]
6
6
  readme = "README.md"
@@ -23,7 +23,7 @@ Or install globally:
23
23
  mapify check
24
24
  """
25
25
 
26
- __version__ = "3.2.0"
26
+ __version__ = "3.3.0"
27
27
 
28
28
  import copy
29
29
  import os
@@ -83,16 +83,13 @@ ssl_context = create_ssl_context()
83
83
  # Constants
84
84
  MCP_SERVER_CHOICES = {
85
85
  "all": "All available MCP servers",
86
- "essential": "Essential (claude-reviewer, sequential-thinking)",
87
- "docs": "Documentation (context7, deepwiki)",
86
+ "essential": "Essential (sequential-thinking, deepwiki)",
88
87
  "custom": "Select individually",
89
88
  "none": "Skip MCP setup",
90
89
  }
91
90
 
92
91
  INDIVIDUAL_MCP_SERVERS = {
93
- "claude-reviewer": "Professional code review",
94
92
  "sequential-thinking": "Chain-of-thought reasoning",
95
- "context7": "Library documentation",
96
93
  "deepwiki": "GitHub repository intelligence",
97
94
  }
98
95
 
@@ -538,7 +535,6 @@ def create_agent_files(project_path: Path, mcp_servers: List[str]) -> None:
538
535
  "predictor": create_predictor_content(mcp_servers),
539
536
  "evaluator": create_evaluator_content(mcp_servers),
540
537
  "reflector": create_reflector_content(mcp_servers),
541
- "curator": create_curator_content(mcp_servers),
542
538
  "documentation-reviewer": create_documentation_reviewer_content(
543
539
  mcp_servers
544
540
  ),
@@ -552,7 +548,7 @@ def create_agent_files(project_path: Path, mcp_servers: List[str]) -> None:
552
548
  def create_task_decomposer_content(mcp_servers: List[str]) -> str:
553
549
  """Create task-decomposer agent content"""
554
550
  mcp_section = ""
555
- if any(s in mcp_servers for s in ["sequential-thinking", "deepwiki", "context7"]):
551
+ if any(s in mcp_servers for s in ["sequential-thinking", "deepwiki"]):
556
552
  mcp_section = """
557
553
  ## MCP Integration
558
554
 
@@ -568,11 +564,6 @@ def create_task_decomposer_content(mcp_servers: List[str]) -> str:
568
564
  2. **mcp__deepwiki__ask_question** - Get insights from GitHub repositories
569
565
  - Ask: "How does [repo] implement [feature]?"
570
566
  """
571
- if "context7" in mcp_servers:
572
- mcp_section += """
573
- 3. **mcp__context7__get-library-docs** - Get up-to-date library documentation
574
- - First use resolve-library-id to find the library
575
- """
576
567
 
577
568
  return f"""---
578
569
  name: task-decomposer
@@ -601,20 +592,13 @@ Return a valid JSON document with subtasks, dependencies, and acceptance criteri
601
592
  def create_actor_content(mcp_servers: List[str]) -> str:
602
593
  """Create actor agent content"""
603
594
  mcp_section = ""
604
- if any(s in mcp_servers for s in ["context7", "deepwiki"]):
595
+ if "deepwiki" in mcp_servers:
605
596
  mcp_section = """
606
597
  # MCP INTEGRATION
607
598
 
608
599
  **ALWAYS use these MCP tools:**
609
- """
610
- if "context7" in mcp_servers:
611
- mcp_section += """
612
- 1. **mcp__context7__get-library-docs** - Get current library documentation
613
- - Essential when using external libraries/frameworks
614
- """
615
- if "deepwiki" in mcp_servers:
616
- mcp_section += """
617
- 2. **mcp__deepwiki__read_wiki_contents** - Study implementation patterns
600
+
601
+ 1. **mcp__deepwiki__read_wiki_contents** - Study implementation patterns
618
602
  - Learn from production code examples
619
603
  """
620
604
 
@@ -684,18 +668,7 @@ Provide implementation with approach, code changes, trade-offs, and testing cons
684
668
 
685
669
  def create_monitor_content(mcp_servers: List[str]) -> str:
686
670
  """Create monitor agent content"""
687
- mcp_section = ""
688
- if "claude-reviewer" in mcp_servers:
689
- mcp_section = """
690
- # MCP INTEGRATION
691
-
692
- **ALWAYS use these MCP tools for comprehensive review:**
693
-
694
- 1. **mcp__claude-reviewer__request_review** - Get professional AI code review
695
- - Use FIRST to get baseline review, then add your analysis
696
- """
697
-
698
- return f"""---
671
+ return """---
699
672
  name: monitor
700
673
  description: Reviews code for correctness, standards, security, and testability (MAP)
701
674
  tools: Read, Grep, Bash, Glob
@@ -705,7 +678,7 @@ model: sonnet
705
678
  # IDENTITY
706
679
 
707
680
  You are a meticulous code reviewer and security expert. Your mission is to catch bugs, vulnerabilities, and violations before code reaches production.
708
- {mcp_section}
681
+
709
682
  # REVIEW CHECKLIST
710
683
 
711
684
  Work through: Correctness, Security, Code Quality, Performance, Testability, Maintainability
@@ -752,22 +725,15 @@ Return strictly valid JSON with validation results and specific issues.
752
725
  def create_predictor_content(mcp_servers: List[str]) -> str:
753
726
  """Create predictor agent content"""
754
727
  mcp_section = ""
755
- if any(s in mcp_servers for s in ["deepwiki", "context7"]):
728
+ if "deepwiki" in mcp_servers:
756
729
  mcp_section = """
757
730
  ## MCP Integration
758
731
 
759
732
  **ALWAYS use these MCP tools:**
760
- """
761
- if "deepwiki" in mcp_servers:
762
- mcp_section += """
733
+
763
734
  1. **mcp__deepwiki__ask_question** - Check how repos handle similar changes
764
735
  - Ask: "What breaks when changing [component]?"
765
736
  """
766
- if "context7" in mcp_servers:
767
- mcp_section += """
768
- 2. **mcp__context7__get-library-docs** - Check library compatibility
769
- - Verify API changes against current documentation
770
- """
771
737
 
772
738
  return f"""---
773
739
  name: predictor
@@ -827,7 +793,7 @@ def create_reflector_content(mcp_servers: List[str]) -> str:
827
793
 
828
794
  return f"""---
829
795
  name: reflector
830
- description: Extracts structured lessons from execution attempts (ACE)
796
+ description: Extracts structured lessons from execution attempts
831
797
  tools: Read, Grep, Glob
832
798
  model: sonnet
833
799
  ---
@@ -850,70 +816,24 @@ Return JSON with:
850
816
  - key_insight: Main lesson learned
851
817
  - success_patterns: What worked well
852
818
  - failure_patterns: What went wrong
853
- - suggested_new_bullets: Playbook entries to add
819
+ - suggested_new_patterns: Pattern entries to add
854
820
  - confidence: How reliable this insight is
855
821
  """
856
822
 
857
823
 
858
- def create_curator_content(mcp_servers: List[str]) -> str:
859
- """Create curator agent content"""
860
- mcp_section = ""
861
-
862
- return f"""---
863
- name: curator
864
- description: Manages structured playbook with incremental updates (ACE)
865
- tools: Read, Write, Edit
866
- model: sonnet
867
- ---
868
-
869
- # IDENTITY
870
-
871
- You are a knowledge curator who maintains the ACE playbook by integrating Reflector insights.
872
- {mcp_section}
873
- # ROLE
874
-
875
- Integrate Reflector insights into playbook using delta operations:
876
- - ADD: New pattern bullets
877
- - UPDATE: Increment helpful/harmful counters
878
- - DEPRECATE: Remove harmful patterns
879
-
880
- ## Quality Gates
881
-
882
- - Content length ≥ 100 characters
883
- - Code examples for technical patterns
884
- - Deduplication via semantic similarity
885
- - Technology-specific (not generic advice)
886
-
887
- ## Output Format (JSON)
888
-
889
- Return JSON with:
890
- - reasoning: Why these operations improve playbook
891
- - operations: Array of ADD/UPDATE/DEPRECATE operations
892
- - deduplication_check: What duplicates were found
893
- """
894
-
895
-
896
824
  # Note: test-generator agent removed
897
825
 
898
826
 
899
827
  def create_documentation_reviewer_content(mcp_servers: List[str]) -> str:
900
828
  """Create documentation-reviewer agent content"""
901
829
  mcp_section = ""
902
- if any(s in mcp_servers for s in ["context7", "deepwiki"]):
830
+ if "deepwiki" in mcp_servers:
903
831
  mcp_section = """
904
832
  # MCP INTEGRATION
905
833
 
906
834
  **ALWAYS use these tools for documentation review:**
907
- """
908
- if "context7" in mcp_servers:
909
- mcp_section += """
910
- 1. **mcp__context7__get-library-docs** - Verify library requirements
911
- - Check official docs for installation requirements
912
- - Validate version compatibility
913
- """
914
- if "deepwiki" in mcp_servers:
915
- mcp_section += """
916
- 2. **mcp__deepwiki__ask_question** - Compare with similar projects
835
+
836
+ 1. **mcp__deepwiki__ask_question** - Compare with similar projects
917
837
  - Ask: "How do other projects handle [integration]?"
918
838
  - Learn from successful implementations
919
839
  """
@@ -1086,7 +1006,7 @@ Extract and preserve lessons from recent workflow:
1086
1006
 
1087
1007
  $ARGUMENTS
1088
1008
 
1089
- Call Reflector to extract patterns, then Curator to update playbook.
1009
+ Call Reflector to extract patterns from recent workflow.
1090
1010
  """,
1091
1011
  }
1092
1012
 
@@ -1269,15 +1189,16 @@ def configure_global_permissions() -> None:
1269
1189
 
1270
1190
 
1271
1191
  def create_or_merge_project_settings_local(project_path: Path) -> None:
1272
- """Create/merge .claude/settings.local.json with safe project allowlist and hooks.
1192
+ """Create/merge .claude/settings.local.json with safe project allowlist.
1273
1193
 
1274
1194
  Claude Code supports per-project approvals via `.claude/settings.local.json`.
1275
1195
  This file is user-local (should not be committed) and is merged by Claude Code
1276
1196
  with global settings from `~/.claude/settings.json`.
1277
1197
 
1278
- IMPORTANT: Claude Code only reads hooks from `settings.json` or `settings.local.json`.
1279
- The separate `settings.hooks.json` file is NOT read by Claude Code. Therefore, this
1280
- function merges hooks from the template `settings.hooks.json` into `settings.local.json`.
1198
+ IMPORTANT:
1199
+ - Shared, repo-committed hooks MUST be configured in `.claude/settings.json`.
1200
+ - `.claude/settings.local.json` is for user-local approvals/allowlists and should
1201
+ not be used as the primary distribution mechanism for project hooks.
1281
1202
 
1282
1203
  We keep this allowlist intentionally narrow and focused on common safe actions
1283
1204
  for local development workflows.
@@ -1288,8 +1209,6 @@ def create_or_merge_project_settings_local(project_path: Path) -> None:
1288
1209
 
1289
1210
  default_permissions: Dict[str, Any] = {
1290
1211
  "allow": [
1291
- # Allow all mem0 MCP tools (project-scoped)
1292
- "mcp__mem0__*",
1293
1212
  # SourceCraft MCP helpers (project-scoped)
1294
1213
  "mcp__sourcecraft__list_pull_request_comments",
1295
1214
  # Common safe Go workflows (project-scoped)
@@ -1313,20 +1232,6 @@ def create_or_merge_project_settings_local(project_path: Path) -> None:
1313
1232
  "ask": [],
1314
1233
  }
1315
1234
 
1316
- # Load hooks from template settings.hooks.json
1317
- # Claude Code doesn't read hooks from settings.hooks.json, so we merge them here
1318
- hooks_config: Dict[str, Any] = {}
1319
- templates_dir = get_templates_dir()
1320
- hooks_template_file = templates_dir / "settings.hooks.json"
1321
- if hooks_template_file.exists():
1322
- try:
1323
- hooks_data = json.loads(hooks_template_file.read_text(encoding="utf-8"))
1324
- hooks_config = hooks_data.get("hooks", {})
1325
- except (json.JSONDecodeError, OSError) as e:
1326
- console.print(
1327
- f"[yellow]Warning:[/yellow] Could not read hooks template: {e}"
1328
- )
1329
-
1330
1235
  # Load existing settings if present
1331
1236
  if settings_file.exists():
1332
1237
  try:
@@ -1339,6 +1244,14 @@ def create_or_merge_project_settings_local(project_path: Path) -> None:
1339
1244
  else:
1340
1245
  existing_settings = {}
1341
1246
 
1247
+ if isinstance(existing_settings, dict) and existing_settings.get("hooks"):
1248
+ console.print(
1249
+ "[yellow]Warning:[/yellow] .claude/settings.local.json contains hooks. "
1250
+ "Claude Code loads hooks from BOTH .claude/settings.json and .claude/settings.local.json, "
1251
+ "so this can cause duplicate hook executions. "
1252
+ "Move shared hooks to .claude/settings.json and remove the hooks section from settings.local.json."
1253
+ )
1254
+
1342
1255
  existing_settings.setdefault("permissions", {})
1343
1256
  permissions = existing_settings["permissions"]
1344
1257
 
@@ -1351,12 +1264,6 @@ def create_or_merge_project_settings_local(project_path: Path) -> None:
1351
1264
  permissions.setdefault("deny", permissions.get("deny", []))
1352
1265
  permissions.setdefault("ask", permissions.get("ask", []))
1353
1266
 
1354
- # Replace hooks configuration from template
1355
- # Always use template hooks to ensure correct $CLAUDE_PROJECT_DIR paths
1356
- # User customizations should be done by editing the template or post-init
1357
- if hooks_config:
1358
- existing_settings["hooks"] = hooks_config
1359
-
1360
1267
  settings_file.write_text(json.dumps(existing_settings, indent=2) + "\n")
1361
1268
 
1362
1269
 
@@ -1371,7 +1278,6 @@ def create_mcp_config(project_path: Path, mcp_servers: List[str]) -> None:
1371
1278
  "predictor": [],
1372
1279
  "evaluator": [],
1373
1280
  "reflector": [],
1374
- "curator": [],
1375
1281
  "documentation-reviewer": [],
1376
1282
  "debate-arbiter": [],
1377
1283
  "synthesizer": [],
@@ -1389,15 +1295,6 @@ def create_mcp_config(project_path: Path, mcp_servers: List[str]) -> None:
1389
1295
 
1390
1296
  # Add server configurations
1391
1297
  server_configs = {
1392
- "claude-reviewer": {
1393
- "enabled": True,
1394
- "description": "Professional AI code review",
1395
- "config": {
1396
- "auto_review": True,
1397
- "focus_areas": ["security", "performance", "testing"],
1398
- "severity_threshold": "medium",
1399
- },
1400
- },
1401
1298
  "sequential-thinking": {
1402
1299
  "enabled": True,
1403
1300
  "description": "Chain-of-thought reasoning",
@@ -1407,11 +1304,6 @@ def create_mcp_config(project_path: Path, mcp_servers: List[str]) -> None:
1407
1304
  "hypothesis_verification": True,
1408
1305
  },
1409
1306
  },
1410
- "context7": {
1411
- "enabled": True,
1412
- "description": "Up-to-date library documentation",
1413
- "config": {"tokens": 5000, "auto_resolve": True, "cache_duration": 3600},
1414
- },
1415
1307
  "deepwiki": {
1416
1308
  "enabled": True,
1417
1309
  "description": "GitHub repository intelligence",
@@ -1436,15 +1328,6 @@ def create_mcp_config(project_path: Path, mcp_servers: List[str]) -> None:
1436
1328
  if agent in config["agent_mcp_mappings"]:
1437
1329
  config["agent_mcp_mappings"][agent].append("sequential-thinking")
1438
1330
 
1439
- if "claude-reviewer" in mcp_servers:
1440
- for agent in ["monitor", "evaluator", "final-verifier"]:
1441
- if agent in config["agent_mcp_mappings"]:
1442
- config["agent_mcp_mappings"][agent].append("claude-reviewer")
1443
-
1444
- if "context7" in mcp_servers:
1445
- for agent in config["agent_mcp_mappings"]:
1446
- config["agent_mcp_mappings"][agent].append("context7")
1447
-
1448
1331
  if "deepwiki" in mcp_servers:
1449
1332
  for agent in config["agent_mcp_mappings"]:
1450
1333
  config["agent_mcp_mappings"][agent].append("deepwiki")
@@ -1474,10 +1357,6 @@ def build_standard_mcp_servers() -> Dict[str, Dict[str, Any]]:
1474
1357
  "command": "npx",
1475
1358
  "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"],
1476
1359
  },
1477
- "context7": {
1478
- "type": "http",
1479
- "url": "https://mcp.context7.com/mcp",
1480
- },
1481
1360
  "deepwiki": {
1482
1361
  "type": "http",
1483
1362
  "url": "https://mcp.deepwiki.com/mcp",
@@ -1590,7 +1469,7 @@ def create_or_merge_project_mcp_json(
1590
1469
 
1591
1470
  Args:
1592
1471
  project_path: Project root directory
1593
- mcp_servers: List of MCP server names to configure (e.g., ["context7", "deepwiki"])
1472
+ mcp_servers: List of MCP server names to configure (e.g., ["sequential-thinking", "deepwiki"])
1594
1473
 
1595
1474
  Behavior:
1596
1475
  - If mcp_servers is empty: No file created/modified (early return)
@@ -1904,7 +1783,6 @@ def create_config_files(project_path: Path) -> int:
1904
1783
 
1905
1784
  Copies configuration files:
1906
1785
  - settings.json
1907
- - settings.hooks.json
1908
1786
  - ralph-loop-config.json
1909
1787
  - workflow-rules.json
1910
1788
 
@@ -1919,7 +1797,6 @@ def create_config_files(project_path: Path) -> int:
1919
1797
 
1920
1798
  config_files = [
1921
1799
  "settings.json",
1922
- "settings.hooks.json",
1923
1800
  "ralph-loop-config.json",
1924
1801
  "workflow-rules.json",
1925
1802
  ]
@@ -1945,7 +1822,7 @@ def init(
1945
1822
  mcp: str = typer.Option(
1946
1823
  "all",
1947
1824
  "--mcp",
1948
- help="MCP server installation (default: all). Options: all, essential, docs, none, or comma-separated list (e.g. context7,deepwiki)",
1825
+ help="MCP server installation (default: all). Options: all, essential, none, or comma-separated list (e.g. sequential-thinking,deepwiki)",
1949
1826
  ),
1950
1827
  no_git: bool = typer.Option(
1951
1828
  False, "--no-git", help="Skip git repository initialization"
@@ -1973,7 +1850,7 @@ def init(
1973
1850
  mapify init my-project # Installs all MCP servers
1974
1851
  mapify init my-project --mcp none # Skip MCP installation
1975
1852
  mapify init my-project --mcp essential
1976
- mapify init my-project --mcp "context7,deepwiki"
1853
+ mapify init my-project --mcp "sequential-thinking,deepwiki"
1977
1854
  mapify init .
1978
1855
  mapify init . --force # Force init in non-empty current directory
1979
1856
  mapify init --debug # Enable workflow logging
@@ -2071,9 +1948,7 @@ def init(
2071
1948
  if mcp == "all":
2072
1949
  selected_mcp_servers = list(INDIVIDUAL_MCP_SERVERS.keys())
2073
1950
  elif mcp == "essential":
2074
- selected_mcp_servers = ["claude-reviewer", "sequential-thinking"]
2075
- elif mcp == "docs":
2076
- selected_mcp_servers = ["context7", "deepwiki"]
1951
+ selected_mcp_servers = ["sequential-thinking", "deepwiki"]
2077
1952
  elif mcp == "none":
2078
1953
  selected_mcp_servers = []
2079
1954
  else:
@@ -327,6 +327,122 @@ class DependencyGraph:
327
327
 
328
328
  return result
329
329
 
330
+ def compute_waves(self) -> Optional[List[List[str]]]:
331
+ """
332
+ Compute execution waves from the dependency DAG using Kahn's algorithm.
333
+
334
+ Each wave contains subtasks whose dependencies are all satisfied by
335
+ prior waves. Within a wave, subtasks can execute in parallel.
336
+
337
+ Returns:
338
+ List of waves (each wave is a list of subtask IDs), or None if
339
+ cycle detected. Empty graph returns [].
340
+
341
+ Performance: O(V+E) where V = nodes, E = edges
342
+
343
+ Example:
344
+ >>> graph = DependencyGraph()
345
+ >>> graph.add_node(SubtaskNode(id="ST-001", dependencies=[]))
346
+ >>> graph.add_node(SubtaskNode(id="ST-002", dependencies=["ST-001"]))
347
+ >>> graph.add_node(SubtaskNode(id="ST-003", dependencies=["ST-001"]))
348
+ >>> graph.add_node(SubtaskNode(id="ST-004", dependencies=["ST-002", "ST-003"]))
349
+ >>> graph.compute_waves()
350
+ [['ST-001'], ['ST-002', 'ST-003'], ['ST-004']]
351
+ """
352
+ if not self.nodes:
353
+ return []
354
+
355
+ # Compute in-degree for each node (only count edges to nodes in graph)
356
+ in_degree: Dict[str, int] = {nid: 0 for nid in self.nodes}
357
+ for nid, node in self.nodes.items():
358
+ for dep_id in node.dependencies:
359
+ if dep_id in self.nodes:
360
+ in_degree[nid] += 1
361
+
362
+ # Collect initial zero-in-degree nodes as wave 0
363
+ waves: List[List[str]] = []
364
+ current_wave = sorted([nid for nid, deg in in_degree.items() if deg == 0])
365
+
366
+ processed = 0
367
+ while current_wave:
368
+ waves.append(current_wave)
369
+ processed += len(current_wave)
370
+ next_wave_set: Set[str] = set()
371
+
372
+ for nid in current_wave:
373
+ # Decrement in-degree for all dependents
374
+ for dependent_id in self.get_dependents(nid):
375
+ in_degree[dependent_id] -= 1
376
+ if in_degree[dependent_id] == 0:
377
+ next_wave_set.add(dependent_id)
378
+
379
+ current_wave = sorted(next_wave_set)
380
+
381
+ # If not all nodes processed, there's a cycle
382
+ if processed != len(self.nodes):
383
+ return None
384
+
385
+ return waves
386
+
387
+ def split_wave_by_file_conflicts(
388
+ self, wave: List[str], affected_files_map: Dict[str, Set[str]]
389
+ ) -> List[List[str]]:
390
+ """
391
+ Split a single wave into sub-waves where no two subtasks share files.
392
+
393
+ Uses greedy coloring: each subtask is placed in the first sub-wave
394
+ that has no file overlap. Subtasks with empty/unknown affected_files
395
+ are treated as conflicting with all others (placed alone).
396
+
397
+ Args:
398
+ wave: List of subtask IDs in one wave
399
+ affected_files_map: Dict mapping subtask_id -> set of affected file paths
400
+
401
+ Returns:
402
+ List of sub-waves where no two subtasks in the same sub-wave share files
403
+
404
+ Example:
405
+ >>> graph = DependencyGraph()
406
+ >>> wave = ["ST-002", "ST-003", "ST-004"]
407
+ >>> files = {"ST-002": {"a.py"}, "ST-003": {"b.py"}, "ST-004": {"a.py"}}
408
+ >>> graph.split_wave_by_file_conflicts(wave, files)
409
+ [['ST-002', 'ST-003'], ['ST-004']]
410
+ """
411
+ if len(wave) <= 1:
412
+ return [wave] if wave else []
413
+
414
+ sub_waves: List[List[str]] = []
415
+ sub_wave_files: List[Set[str]] = []
416
+
417
+ for subtask_id in wave:
418
+ files = affected_files_map.get(subtask_id, set())
419
+
420
+ # Empty/unknown files = conflict with everything, place alone
421
+ if not files:
422
+ sub_waves.append([subtask_id])
423
+ sub_wave_files.append(set()) # placeholder
424
+ continue
425
+
426
+ placed = False
427
+ for i, sw_files in enumerate(sub_wave_files):
428
+ # Skip sub-waves that contain an "unknown files" subtask
429
+ # (those have empty sw_files but exist in sub_waves)
430
+ if not sw_files and sub_waves[i]:
431
+ # This sub-wave has a subtask with unknown files
432
+ continue
433
+ # Check for file overlap
434
+ if not files & sw_files:
435
+ sub_waves[i].append(subtask_id)
436
+ sub_wave_files[i] |= files
437
+ placed = True
438
+ break
439
+
440
+ if not placed:
441
+ sub_waves.append([subtask_id])
442
+ sub_wave_files.append(set(files))
443
+
444
+ return sub_waves
445
+
330
446
  def clear(self) -> None:
331
447
  """
332
448
  Remove all nodes from graph.