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.
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/.claude/skills/README.md +2 -4
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/.gitignore +0 -17
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/PKG-INFO +1 -1
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/pyproject.toml +1 -1
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/__init__.py +33 -158
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/dependency_graph.py +116 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/schemas.py +1 -195
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/CLAUDE.md +1 -2
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/actor.md +45 -151
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/documentation-reviewer.md +0 -25
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/evaluator.md +10 -33
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/monitor.md +84 -105
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/predictor.md +70 -161
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/reflector.md +28 -92
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/research-agent.md +0 -21
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/task-decomposer.md +34 -45
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-debate.md +92 -71
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-debug.md +1 -9
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-efficient.md +146 -48
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-fast.md +4 -5
- mapify_cli-3.3.0/src/mapify_cli/templates/commands/map-learn.md +246 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-plan.md +36 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-release.md +2 -14
- mapify_cli-3.3.0/src/mapify_cli/templates/commands/map-review.md +307 -0
- mapify_cli-3.3.0/src/mapify_cli/templates/hooks/block-dangerous.sh +173 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/block-secrets.py +43 -13
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/post-edit-reminder.py +7 -2
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/ralph-context-pruner.py +5 -2
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/safety-guardrails.py +26 -17
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/workflow-context-injector.py +19 -3
- mapify_cli-3.3.0/src/mapify_cli/templates/hooks/workflow-gate.py +269 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/scripts/map_orchestrator.py +315 -6
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/scripts/map_step_runner.py +89 -1
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/mcp-usage-examples.md +2 -29
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/step-state-schema.md +1 -2
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/workflow-state-schema.md +10 -13
- mapify_cli-3.3.0/src/mapify_cli/templates/settings.json +118 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/README.md +2 -4
- mapify_cli-3.3.0/src/mapify_cli/templates/skills/map-cli-reference/SKILL.md +124 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-cli-reference/scripts/check-command.sh +9 -18
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/SKILL.md +8 -46
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/agent-architecture.md +7 -20
- {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
- {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
- {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
- {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
- {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
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/skill-rules.json +3 -4
- mapify_cli-3.2.0/src/mapify_cli/contradiction_detector.py +0 -735
- mapify_cli-3.2.0/src/mapify_cli/entity_extractor.py +0 -882
- mapify_cli-3.2.0/src/mapify_cli/graph_query.py +0 -787
- mapify_cli-3.2.0/src/mapify_cli/relationship_detector.py +0 -771
- mapify_cli-3.2.0/src/mapify_cli/templates/agents/curator.md +0 -1296
- mapify_cli-3.2.0/src/mapify_cli/templates/commands/map-learn.md +0 -472
- mapify_cli-3.2.0/src/mapify_cli/templates/commands/map-review.md +0 -182
- mapify_cli-3.2.0/src/mapify_cli/templates/hooks/block-dangerous.sh +0 -114
- mapify_cli-3.2.0/src/mapify_cli/templates/hooks/workflow-gate.py +0 -178
- mapify_cli-3.2.0/src/mapify_cli/templates/settings.hooks.json +0 -74
- mapify_cli-3.2.0/src/mapify_cli/templates/settings.json +0 -38
- mapify_cli-3.2.0/src/mapify_cli/templates/skills/map-cli-reference/SKILL.md +0 -202
- mapify_cli-3.2.0/src/mapify_cli/templates/skills/map-workflows-guide/resources/playbook-system.md +0 -301
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/README.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/intent_detector.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/ralph_state.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/repo_insight.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/debate-arbiter.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/final-verifier.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/agents/synthesizer.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-check.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/commands/map-resume.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/end-of-turn.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/improve-prompt.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/hooks/ralph-iteration-logger.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/scripts/diagnostics.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/analyze.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/common.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/go.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/python.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/rust.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/map/static-analysis/handlers/typescript.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/ralph-loop-config.json +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/bash-guidelines.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/decomposition-examples.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/references/escalation-matrix.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/SKILL.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/scripts/check-complete.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/scripts/get-plan-path.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/scripts/init-session.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/scripts/show-focus.sh +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/templates/findings.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/templates/iteration_history.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/templates/progress.md +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/skills/map-planning/templates/task_plan.md +0 -0
- {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
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/templates/workflow-rules.json +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/tools/__init__.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/tools/validate_dependencies.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/verification_recorder.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/workflow_finalizer.py +0 -0
- {mapify_cli-3.2.0 → mapify_cli-3.3.0}/src/mapify_cli/workflow_logger.py +0 -0
- {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
|
|
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.
|
|
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.
|
|
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
|
|
@@ -23,7 +23,7 @@ Or install globally:
|
|
|
23
23
|
mapify check
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
__version__ = "3.
|
|
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 (
|
|
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"
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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:
|
|
1279
|
-
|
|
1280
|
-
|
|
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., ["
|
|
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,
|
|
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 "
|
|
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 = ["
|
|
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.
|