mapify-cli 3.0.0__tar.gz → 3.1.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.0.0 → mapify_cli-3.1.0}/.claude/skills/README.md +0 -2
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/.gitignore +2 -10
- mapify_cli-3.1.0/PKG-INFO +33 -0
- mapify_cli-3.1.0/README.md +1 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/pyproject.toml +3 -1
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/__init__.py +157 -107
- mapify_cli-3.1.0/src/mapify_cli/dependency_graph.py +347 -0
- mapify_cli-3.1.0/src/mapify_cli/intent_detector.py +69 -0
- mapify_cli-3.1.0/src/mapify_cli/ralph_state.py +473 -0
- mapify_cli-3.1.0/src/mapify_cli/repo_insight.py +203 -0
- mapify_cli-3.1.0/src/mapify_cli/schemas.py +498 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/CLAUDE.md +80 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/actor.md +134 -41
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/curator.md +2 -2
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/documentation-reviewer.md +2 -2
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/evaluator.md +3 -8
- mapify_cli-3.1.0/src/mapify_cli/templates/agents/final-verifier.md +178 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/monitor.md +119 -48
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/predictor.md +15 -15
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/reflector.md +3 -3
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/research-agent.md +54 -61
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/task-decomposer.md +184 -32
- mapify_cli-3.1.0/src/mapify_cli/templates/commands/map-check.md +460 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/commands/map-debate.md +46 -10
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/commands/map-debug.md +8 -10
- mapify_cli-3.1.0/src/mapify_cli/templates/commands/map-efficient.md +520 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/commands/map-fast.md +5 -5
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/commands/map-learn.md +7 -7
- mapify_cli-3.1.0/src/mapify_cli/templates/commands/map-plan.md +433 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/commands/map-release.md +0 -10
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/hooks/block-dangerous.sh +3 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/hooks/block-secrets.py +3 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/hooks/end-of-turn.sh +187 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/hooks/improve-prompt.py +2 -1
- mapify_cli-3.1.0/src/mapify_cli/templates/hooks/post-edit-reminder.py +71 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/hooks/ralph-context-pruner.py +262 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/hooks/ralph-iteration-logger.py +311 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/hooks/safety-guardrails.py +141 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/hooks/workflow-context-injector.py +245 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/hooks/workflow-gate.py +169 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/map/scripts/diagnostics.py +153 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/map/scripts/map_orchestrator.py +586 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/map/scripts/map_step_runner.py +368 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/ralph-loop-config.json +33 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/references/bash-guidelines.md +260 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/references/escalation-matrix.md +31 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/references/step-state-schema.md +79 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/references/workflow-state-schema.md +269 -0
- mapify_cli-3.1.0/src/mapify_cli/templates/settings.hooks.json +74 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/settings.json +5 -1
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/README.md +5 -8
- mapify_cli-3.1.0/src/mapify_cli/templates/skills/map-planning/templates/iteration_history.md +93 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-workflows-guide/SKILL.md +26 -32
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/agent-architecture.md +0 -1
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-efficient-deep-dive.md +2 -2
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-fast-deep-dive.md +41 -49
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-feature-deep-dive.md +1 -2
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/playbook-system.md +3 -4
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/workflow-rules.json +8 -9
- mapify_cli-3.1.0/src/mapify_cli/verification_recorder.py +367 -0
- mapify_cli-3.1.0/src/mapify_cli/workflow_finalizer.py +56 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/workflow_state.py +71 -2
- mapify_cli-3.0.0/PKG-INFO +0 -123
- mapify_cli-3.0.0/README.md +0 -93
- mapify_cli-3.0.0/docs/cipher-setup-guide/README.md +0 -51
- mapify_cli-3.0.0/src/mapify_cli/schemas.py +0 -201
- mapify_cli-3.0.0/src/mapify_cli/templates/commands/map-efficient.md +0 -589
- mapify_cli-3.0.0/src/mapify_cli/templates/hooks/end-of-turn.sh +0 -258
- mapify_cli-3.0.0/src/mapify_cli/templates/settings.hooks.json +0 -59
- mapify_cli-3.0.0/src/mapify_cli/templates/skills/map-workflows-guide/resources/cipher-integration.md +0 -291
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/contradiction_detector.py +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/entity_extractor.py +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/graph_query.py +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/relationship_detector.py +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/debate-arbiter.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/agents/synthesizer.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/commands/map-resume.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/commands/map-review.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/map/static-analysis/analyze.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/map/static-analysis/handlers/common.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/map/static-analysis/handlers/go.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/map/static-analysis/handlers/python.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/map/static-analysis/handlers/rust.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/map/static-analysis/handlers/typescript.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/references/decomposition-examples.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/references/mcp-usage-examples.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-cli-reference/SKILL.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-planning/SKILL.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-planning/scripts/check-complete.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-planning/scripts/get-plan-path.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-planning/scripts/init-session.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-planning/scripts/show-focus.sh +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-planning/templates/findings.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-planning/templates/progress.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-planning/templates/task_plan.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-debug-deep-dive.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/map-workflows-guide/resources/map-refactor-deep-dive.md +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/templates/skills/skill-rules.json +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/tools/__init__.py +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/tools/validate_dependencies.py +0 -0
- {mapify_cli-3.0.0 → mapify_cli-3.1.0}/src/mapify_cli/workflow_logger.py +0 -0
|
@@ -55,7 +55,6 @@ MAP: [Shows decision tree and comparison matrix]
|
|
|
55
55
|
- `map-refactor-deep-dive.md` - Dependency analysis
|
|
56
56
|
- `agent-architecture.md` - How 8 agents orchestrate
|
|
57
57
|
- `playbook-system.md` - Knowledge storage and search
|
|
58
|
-
- `cipher-integration.md` - Cross-project learning
|
|
59
58
|
|
|
60
59
|
---
|
|
61
60
|
|
|
@@ -126,7 +125,6 @@ Skills work seamlessly with the prompt improvement system:
|
|
|
126
125
|
├── map-refactor-deep-dive.md
|
|
127
126
|
├── agent-architecture.md
|
|
128
127
|
├── playbook-system.md
|
|
129
|
-
└── cipher-integration.md
|
|
130
128
|
```
|
|
131
129
|
|
|
132
130
|
---
|
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
.clinerules/cipher-rules.md
|
|
3
|
-
.kilocode/rules/cipher-rules.md
|
|
4
|
-
.roo/rules/cipher-rules.md
|
|
5
|
-
.windsurf/rules/cipher-rules.md
|
|
6
|
-
.cursor/rules/cipher-rules.mdc
|
|
7
|
-
.kiro/steering/cipher-rules.md
|
|
8
|
-
.qoder/rules/cipher-rules.md
|
|
9
|
-
.augment/rules/cipher-rules.md
|
|
10
2
|
.reviews
|
|
11
3
|
.coverage
|
|
12
4
|
|
|
@@ -59,9 +51,10 @@ coverage.json
|
|
|
59
51
|
.claude/metrics/
|
|
60
52
|
.claude/cache/
|
|
61
53
|
|
|
62
|
-
# MAP runtime files (but keep static-analysis scripts)
|
|
54
|
+
# MAP runtime files (but keep static-analysis and orchestrator scripts)
|
|
63
55
|
.map/*
|
|
64
56
|
!.map/static-analysis/
|
|
57
|
+
!.map/scripts/
|
|
65
58
|
|
|
66
59
|
# Temporary verification files
|
|
67
60
|
mapify_cli_verification_*.json
|
|
@@ -91,7 +84,6 @@ docs/claude-code-prompt-improver
|
|
|
91
84
|
|
|
92
85
|
# Local tool configs
|
|
93
86
|
.mcp.json
|
|
94
|
-
.chunkhound.json
|
|
95
87
|
.chunkhound/
|
|
96
88
|
docs/planning-with-files.txt
|
|
97
89
|
docs/research/
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mapify-cli
|
|
3
|
+
Version: 3.1.0
|
|
4
|
+
Summary: MAP Framework installer - Modular Agentic Planner for Claude Code
|
|
5
|
+
Project-URL: Homepage, https://github.com/azalio/map-framework
|
|
6
|
+
Project-URL: Repository, https://github.com/azalio/map-framework.git
|
|
7
|
+
Project-URL: Issues, https://github.com/azalio/map-framework/issues
|
|
8
|
+
Author: MAP Framework Contributors
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Requires-Dist: httpx>=0.25.0
|
|
11
|
+
Requires-Dist: platformdirs>=4.0.0
|
|
12
|
+
Requires-Dist: questionary>=2.0.0
|
|
13
|
+
Requires-Dist: readchar>=4.0.0
|
|
14
|
+
Requires-Dist: rich>=13.0.0
|
|
15
|
+
Requires-Dist: typer>=0.9.0
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: pyyaml>=6.0.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
24
|
+
Provides-Extra: ssl
|
|
25
|
+
Requires-Dist: truststore>=0.9.0; extra == 'ssl'
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
|
|
28
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == 'test'
|
|
29
|
+
Requires-Dist: pytest>=7.0.0; extra == 'test'
|
|
30
|
+
Requires-Dist: pyyaml>=6.0.0; extra == 'test'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
test
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mapify-cli"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.1.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"
|
|
@@ -20,11 +20,13 @@ test = [
|
|
|
20
20
|
"pytest>=7.0.0",
|
|
21
21
|
"pytest-cov>=4.0.0",
|
|
22
22
|
"pytest-mock>=3.10.0",
|
|
23
|
+
"pyyaml>=6.0.0",
|
|
23
24
|
]
|
|
24
25
|
dev = [
|
|
25
26
|
"pytest>=7.0.0",
|
|
26
27
|
"pytest-cov>=4.0.0",
|
|
27
28
|
"pytest-mock>=3.10.0",
|
|
29
|
+
"pyyaml>=6.0.0",
|
|
28
30
|
"black>=23.0.0",
|
|
29
31
|
"ruff>=0.1.0",
|
|
30
32
|
"mypy>=1.0.0",
|
|
@@ -23,7 +23,7 @@ Or install globally:
|
|
|
23
23
|
mapify check
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
__version__ = "3.
|
|
26
|
+
__version__ = "3.1.0"
|
|
27
27
|
|
|
28
28
|
import copy
|
|
29
29
|
import os
|
|
@@ -83,14 +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 (
|
|
86
|
+
"essential": "Essential (claude-reviewer, sequential-thinking)",
|
|
87
87
|
"docs": "Documentation (context7, deepwiki)",
|
|
88
88
|
"custom": "Select individually",
|
|
89
89
|
"none": "Skip MCP setup",
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
INDIVIDUAL_MCP_SERVERS = {
|
|
93
|
-
"cipher": "Knowledge management system",
|
|
94
93
|
"claude-reviewer": "Professional code review",
|
|
95
94
|
"sequential-thinking": "Chain-of-thought reasoning",
|
|
96
95
|
"context7": "Library documentation",
|
|
@@ -553,34 +552,25 @@ def create_agent_files(project_path: Path, mcp_servers: List[str]) -> None:
|
|
|
553
552
|
def create_task_decomposer_content(mcp_servers: List[str]) -> str:
|
|
554
553
|
"""Create task-decomposer agent content"""
|
|
555
554
|
mcp_section = ""
|
|
556
|
-
if any(
|
|
557
|
-
s in mcp_servers
|
|
558
|
-
for s in ["cipher", "sequential-thinking", "deepwiki", "context7"]
|
|
559
|
-
):
|
|
555
|
+
if any(s in mcp_servers for s in ["sequential-thinking", "deepwiki", "context7"]):
|
|
560
556
|
mcp_section = """
|
|
561
557
|
## MCP Integration
|
|
562
558
|
|
|
563
559
|
**ALWAYS use these MCP tools:**
|
|
564
|
-
"""
|
|
565
|
-
if "cipher" in mcp_servers:
|
|
566
|
-
mcp_section += """
|
|
567
|
-
1. **mcp__cipher__cipher_memory_search** - Search for similar features/patterns
|
|
568
|
-
- Query: "feature implementation [feature_name]"
|
|
569
|
-
- Query: "task decomposition [similar_goal]"
|
|
570
560
|
"""
|
|
571
561
|
if "sequential-thinking" in mcp_servers:
|
|
572
562
|
mcp_section += """
|
|
573
|
-
|
|
563
|
+
1. **mcp__sequential-thinking__sequentialthinking** - For complex planning
|
|
574
564
|
- Use when goal is ambiguous or has many dependencies
|
|
575
565
|
"""
|
|
576
566
|
if "deepwiki" in mcp_servers:
|
|
577
567
|
mcp_section += """
|
|
578
|
-
|
|
568
|
+
2. **mcp__deepwiki__ask_question** - Get insights from GitHub repositories
|
|
579
569
|
- Ask: "How does [repo] implement [feature]?"
|
|
580
570
|
"""
|
|
581
571
|
if "context7" in mcp_servers:
|
|
582
572
|
mcp_section += """
|
|
583
|
-
|
|
573
|
+
3. **mcp__context7__get-library-docs** - Get up-to-date library documentation
|
|
584
574
|
- First use resolve-library-id to find the library
|
|
585
575
|
"""
|
|
586
576
|
|
|
@@ -611,26 +601,20 @@ Return a valid JSON document with subtasks, dependencies, and acceptance criteri
|
|
|
611
601
|
def create_actor_content(mcp_servers: List[str]) -> str:
|
|
612
602
|
"""Create actor agent content"""
|
|
613
603
|
mcp_section = ""
|
|
614
|
-
if any(s in mcp_servers for s in ["
|
|
604
|
+
if any(s in mcp_servers for s in ["context7", "deepwiki"]):
|
|
615
605
|
mcp_section = """
|
|
616
606
|
# MCP INTEGRATION
|
|
617
607
|
|
|
618
608
|
**ALWAYS use these MCP tools:**
|
|
619
|
-
"""
|
|
620
|
-
if "cipher" in mcp_servers:
|
|
621
|
-
mcp_section += """
|
|
622
|
-
1. **mcp__cipher__cipher_memory_search** - Search for code patterns
|
|
623
|
-
- Query: "implementation pattern [feature_type]"
|
|
624
|
-
- Store successful implementations after validation
|
|
625
609
|
"""
|
|
626
610
|
if "context7" in mcp_servers:
|
|
627
611
|
mcp_section += """
|
|
628
|
-
|
|
612
|
+
1. **mcp__context7__get-library-docs** - Get current library documentation
|
|
629
613
|
- Essential when using external libraries/frameworks
|
|
630
614
|
"""
|
|
631
615
|
if "deepwiki" in mcp_servers:
|
|
632
616
|
mcp_section += """
|
|
633
|
-
|
|
617
|
+
2. **mcp__deepwiki__read_wiki_contents** - Study implementation patterns
|
|
634
618
|
- Learn from production code examples
|
|
635
619
|
"""
|
|
636
620
|
|
|
@@ -768,26 +752,20 @@ Return strictly valid JSON with validation results and specific issues.
|
|
|
768
752
|
def create_predictor_content(mcp_servers: List[str]) -> str:
|
|
769
753
|
"""Create predictor agent content"""
|
|
770
754
|
mcp_section = ""
|
|
771
|
-
if any(s in mcp_servers for s in ["
|
|
755
|
+
if any(s in mcp_servers for s in ["deepwiki", "context7"]):
|
|
772
756
|
mcp_section = """
|
|
773
757
|
## MCP Integration
|
|
774
758
|
|
|
775
759
|
**ALWAYS use these MCP tools:**
|
|
776
|
-
"""
|
|
777
|
-
if "cipher" in mcp_servers:
|
|
778
|
-
mcp_section += """
|
|
779
|
-
1. **mcp__cipher__cipher_memory_search** - Find similar impact patterns
|
|
780
|
-
- Query: "impact analysis [change_type]"
|
|
781
|
-
- Learn from past breaking changes
|
|
782
760
|
"""
|
|
783
761
|
if "deepwiki" in mcp_servers:
|
|
784
762
|
mcp_section += """
|
|
785
|
-
|
|
763
|
+
1. **mcp__deepwiki__ask_question** - Check how repos handle similar changes
|
|
786
764
|
- Ask: "What breaks when changing [component]?"
|
|
787
765
|
"""
|
|
788
766
|
if "context7" in mcp_servers:
|
|
789
767
|
mcp_section += """
|
|
790
|
-
|
|
768
|
+
2. **mcp__context7__get-library-docs** - Check library compatibility
|
|
791
769
|
- Verify API changes against current documentation
|
|
792
770
|
"""
|
|
793
771
|
|
|
@@ -846,16 +824,6 @@ Return JSON with scores, strengths, weaknesses, and recommendation (proceed|impr
|
|
|
846
824
|
def create_reflector_content(mcp_servers: List[str]) -> str:
|
|
847
825
|
"""Create reflector agent content"""
|
|
848
826
|
mcp_section = ""
|
|
849
|
-
if "cipher" in mcp_servers:
|
|
850
|
-
mcp_section = """
|
|
851
|
-
# MCP INTEGRATION
|
|
852
|
-
|
|
853
|
-
**ALWAYS use cipher for knowledge management:**
|
|
854
|
-
|
|
855
|
-
1. **mcp__cipher__cipher_memory_search** - Check existing patterns
|
|
856
|
-
- Query: "lesson learned [topic]"
|
|
857
|
-
- Avoid duplicating existing knowledge
|
|
858
|
-
"""
|
|
859
827
|
|
|
860
828
|
return f"""---
|
|
861
829
|
name: reflector
|
|
@@ -890,15 +858,6 @@ Return JSON with:
|
|
|
890
858
|
def create_curator_content(mcp_servers: List[str]) -> str:
|
|
891
859
|
"""Create curator agent content"""
|
|
892
860
|
mcp_section = ""
|
|
893
|
-
if "cipher" in mcp_servers:
|
|
894
|
-
mcp_section = """
|
|
895
|
-
# MCP INTEGRATION
|
|
896
|
-
|
|
897
|
-
**Use cipher for deduplication:**
|
|
898
|
-
|
|
899
|
-
1. **mcp__cipher__cipher_memory_search** - Check for duplicate patterns
|
|
900
|
-
- Prevents adding redundant playbook entries
|
|
901
|
-
"""
|
|
902
861
|
|
|
903
862
|
return f"""---
|
|
904
863
|
name: curator
|
|
@@ -940,27 +899,21 @@ Return JSON with:
|
|
|
940
899
|
def create_documentation_reviewer_content(mcp_servers: List[str]) -> str:
|
|
941
900
|
"""Create documentation-reviewer agent content"""
|
|
942
901
|
mcp_section = ""
|
|
943
|
-
if any(s in mcp_servers for s in ["
|
|
902
|
+
if any(s in mcp_servers for s in ["context7", "deepwiki"]):
|
|
944
903
|
mcp_section = """
|
|
945
904
|
# MCP INTEGRATION
|
|
946
905
|
|
|
947
906
|
**ALWAYS use these tools for documentation review:**
|
|
948
|
-
"""
|
|
949
|
-
if "cipher" in mcp_servers:
|
|
950
|
-
mcp_section += """
|
|
951
|
-
1. **mcp__cipher__cipher_memory_search** - Check for known patterns
|
|
952
|
-
- Query: "external dependency detection [technology]"
|
|
953
|
-
- Query: "CRD installation pattern [project]"
|
|
954
907
|
"""
|
|
955
908
|
if "context7" in mcp_servers:
|
|
956
909
|
mcp_section += """
|
|
957
|
-
|
|
910
|
+
1. **mcp__context7__get-library-docs** - Verify library requirements
|
|
958
911
|
- Check official docs for installation requirements
|
|
959
912
|
- Validate version compatibility
|
|
960
913
|
"""
|
|
961
914
|
if "deepwiki" in mcp_servers:
|
|
962
915
|
mcp_section += """
|
|
963
|
-
|
|
916
|
+
2. **mcp__deepwiki__ask_question** - Compare with similar projects
|
|
964
917
|
- Ask: "How do other projects handle [integration]?"
|
|
965
918
|
- Learn from successful implementations
|
|
966
919
|
"""
|
|
@@ -1123,7 +1076,7 @@ Use minimal workflow to implement:
|
|
|
1123
1076
|
$ARGUMENTS
|
|
1124
1077
|
|
|
1125
1078
|
Implement quickly with basic monitor validation only. No learning, no predictor.
|
|
1126
|
-
Use for
|
|
1079
|
+
Use for small, low-risk changes where speed matters.
|
|
1127
1080
|
""",
|
|
1128
1081
|
"map-learn": """---
|
|
1129
1082
|
description: Extract lessons from completed workflows
|
|
@@ -1185,41 +1138,48 @@ def create_skill_files(project_path: Path) -> int:
|
|
|
1185
1138
|
return count
|
|
1186
1139
|
|
|
1187
1140
|
|
|
1188
|
-
def
|
|
1189
|
-
|
|
1141
|
+
def _copy_map_subdir(
|
|
1142
|
+
map_template_dir: Path, map_dir: Path, subdir: str, executable_glob: str
|
|
1143
|
+
) -> int:
|
|
1144
|
+
"""Copy a subdirectory from map templates to .map/ and make scripts executable."""
|
|
1190
1145
|
import shutil
|
|
1191
1146
|
|
|
1147
|
+
src = map_template_dir / subdir
|
|
1148
|
+
if not src.exists():
|
|
1149
|
+
return 0
|
|
1150
|
+
|
|
1151
|
+
dest = map_dir / subdir
|
|
1152
|
+
if dest.exists():
|
|
1153
|
+
try:
|
|
1154
|
+
shutil.rmtree(dest)
|
|
1155
|
+
except (OSError, PermissionError) as e:
|
|
1156
|
+
import sys
|
|
1157
|
+
|
|
1158
|
+
print(
|
|
1159
|
+
f"Warning: Could not remove existing {dest}: {e}",
|
|
1160
|
+
file=sys.stderr,
|
|
1161
|
+
)
|
|
1162
|
+
shutil.copytree(src, dest, dirs_exist_ok=True)
|
|
1163
|
+
|
|
1164
|
+
count = 0
|
|
1165
|
+
for script in dest.rglob(executable_glob):
|
|
1166
|
+
script.chmod(script.stat().st_mode | 0o755)
|
|
1167
|
+
count += 1
|
|
1168
|
+
return count
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
def create_map_tools(project_path: Path) -> int:
|
|
1172
|
+
"""Create .map/ directory with static analysis tools and orchestrator scripts."""
|
|
1192
1173
|
map_dir = project_path / ".map"
|
|
1193
1174
|
map_dir.mkdir(parents=True, exist_ok=True)
|
|
1194
1175
|
|
|
1195
|
-
# Get templates directory
|
|
1196
1176
|
templates_dir = get_templates_dir()
|
|
1197
1177
|
map_template_dir = templates_dir / "map"
|
|
1198
1178
|
|
|
1199
1179
|
count = 0
|
|
1200
1180
|
if map_template_dir.exists():
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
if static_analysis_src.exists():
|
|
1204
|
-
static_analysis_dest = map_dir / "static-analysis"
|
|
1205
|
-
if static_analysis_dest.exists():
|
|
1206
|
-
try:
|
|
1207
|
-
shutil.rmtree(static_analysis_dest)
|
|
1208
|
-
except (OSError, PermissionError) as e:
|
|
1209
|
-
# Log warning but continue - old scripts may be in use
|
|
1210
|
-
import sys
|
|
1211
|
-
|
|
1212
|
-
print(
|
|
1213
|
-
f"Warning: Could not remove existing {static_analysis_dest}: {e}",
|
|
1214
|
-
file=sys.stderr,
|
|
1215
|
-
)
|
|
1216
|
-
shutil.copytree(
|
|
1217
|
-
static_analysis_src, static_analysis_dest, dirs_exist_ok=True
|
|
1218
|
-
)
|
|
1219
|
-
# Make scripts executable
|
|
1220
|
-
for script in static_analysis_dest.rglob("*.sh"):
|
|
1221
|
-
script.chmod(script.stat().st_mode | 0o755)
|
|
1222
|
-
count += 1
|
|
1181
|
+
count += _copy_map_subdir(map_template_dir, map_dir, "static-analysis", "*.sh")
|
|
1182
|
+
count += _copy_map_subdir(map_template_dir, map_dir, "scripts", "*.py")
|
|
1223
1183
|
|
|
1224
1184
|
return count
|
|
1225
1185
|
|
|
@@ -1308,12 +1268,16 @@ def configure_global_permissions() -> None:
|
|
|
1308
1268
|
|
|
1309
1269
|
|
|
1310
1270
|
def create_or_merge_project_settings_local(project_path: Path) -> None:
|
|
1311
|
-
"""Create/merge .claude/settings.local.json with safe project allowlist.
|
|
1271
|
+
"""Create/merge .claude/settings.local.json with safe project allowlist and hooks.
|
|
1312
1272
|
|
|
1313
1273
|
Claude Code supports per-project approvals via `.claude/settings.local.json`.
|
|
1314
1274
|
This file is user-local (should not be committed) and is merged by Claude Code
|
|
1315
1275
|
with global settings from `~/.claude/settings.json`.
|
|
1316
1276
|
|
|
1277
|
+
IMPORTANT: Claude Code only reads hooks from `settings.json` or `settings.local.json`.
|
|
1278
|
+
The separate `settings.hooks.json` file is NOT read by Claude Code. Therefore, this
|
|
1279
|
+
function merges hooks from the template `settings.hooks.json` into `settings.local.json`.
|
|
1280
|
+
|
|
1317
1281
|
We keep this allowlist intentionally narrow and focused on common safe actions
|
|
1318
1282
|
for local development workflows.
|
|
1319
1283
|
"""
|
|
@@ -1341,13 +1305,27 @@ def create_or_merge_project_settings_local(project_path: Path) -> None:
|
|
|
1341
1305
|
"Bash(make manifests)",
|
|
1342
1306
|
# Common git workflows
|
|
1343
1307
|
"Bash(git worktree add:*)",
|
|
1344
|
-
# Used by some test/dev scripts to produce
|
|
1308
|
+
# Used by some test/dev scripts to produce temporary dev certs
|
|
1345
1309
|
'Bash(openssl req -x509 -newkey rsa:512 -keyout /dev/null -out /dev/stdout -days 365 -nodes -subj "/CN=test" 2>/dev/null)',
|
|
1346
1310
|
],
|
|
1347
1311
|
"deny": [],
|
|
1348
1312
|
"ask": [],
|
|
1349
1313
|
}
|
|
1350
1314
|
|
|
1315
|
+
# Load hooks from template settings.hooks.json
|
|
1316
|
+
# Claude Code doesn't read hooks from settings.hooks.json, so we merge them here
|
|
1317
|
+
hooks_config: Dict[str, Any] = {}
|
|
1318
|
+
templates_dir = get_templates_dir()
|
|
1319
|
+
hooks_template_file = templates_dir / "settings.hooks.json"
|
|
1320
|
+
if hooks_template_file.exists():
|
|
1321
|
+
try:
|
|
1322
|
+
hooks_data = json.loads(hooks_template_file.read_text(encoding="utf-8"))
|
|
1323
|
+
hooks_config = hooks_data.get("hooks", {})
|
|
1324
|
+
except (json.JSONDecodeError, OSError) as e:
|
|
1325
|
+
console.print(
|
|
1326
|
+
f"[yellow]Warning:[/yellow] Could not read hooks template: {e}"
|
|
1327
|
+
)
|
|
1328
|
+
|
|
1351
1329
|
# Load existing settings if present
|
|
1352
1330
|
if settings_file.exists():
|
|
1353
1331
|
try:
|
|
@@ -1372,6 +1350,12 @@ def create_or_merge_project_settings_local(project_path: Path) -> None:
|
|
|
1372
1350
|
permissions.setdefault("deny", permissions.get("deny", []))
|
|
1373
1351
|
permissions.setdefault("ask", permissions.get("ask", []))
|
|
1374
1352
|
|
|
1353
|
+
# Replace hooks configuration from template
|
|
1354
|
+
# Always use template hooks to ensure correct $CLAUDE_PROJECT_DIR paths
|
|
1355
|
+
# User customizations should be done by editing the template or post-init
|
|
1356
|
+
if hooks_config:
|
|
1357
|
+
existing_settings["hooks"] = hooks_config
|
|
1358
|
+
|
|
1375
1359
|
settings_file.write_text(json.dumps(existing_settings, indent=2) + "\n")
|
|
1376
1360
|
|
|
1377
1361
|
|
|
@@ -1419,15 +1403,6 @@ def create_mcp_config(project_path: Path, mcp_servers: List[str]) -> None:
|
|
|
1419
1403
|
"hypothesis_verification": True,
|
|
1420
1404
|
},
|
|
1421
1405
|
},
|
|
1422
|
-
"cipher": {
|
|
1423
|
-
"enabled": True,
|
|
1424
|
-
"description": "Knowledge management system",
|
|
1425
|
-
"config": {
|
|
1426
|
-
"auto_store": True,
|
|
1427
|
-
"retrieval_limit": 5,
|
|
1428
|
-
"conflict_resolution": "manual",
|
|
1429
|
-
},
|
|
1430
|
-
},
|
|
1431
1406
|
"context7": {
|
|
1432
1407
|
"enabled": True,
|
|
1433
1408
|
"description": "Up-to-date library documentation",
|
|
@@ -1446,10 +1421,6 @@ def create_mcp_config(project_path: Path, mcp_servers: List[str]) -> None:
|
|
|
1446
1421
|
config["mcp_servers"][server] = server_configs[server]
|
|
1447
1422
|
|
|
1448
1423
|
# Update agent mappings based on selected servers
|
|
1449
|
-
if "cipher" in mcp_servers:
|
|
1450
|
-
for agent in config["agent_mcp_mappings"]:
|
|
1451
|
-
config["agent_mcp_mappings"][agent].append("cipher")
|
|
1452
|
-
|
|
1453
1424
|
if "sequential-thinking" in mcp_servers:
|
|
1454
1425
|
for agent in [
|
|
1455
1426
|
"task-decomposer",
|
|
@@ -1615,7 +1586,7 @@ def create_or_merge_project_mcp_json(
|
|
|
1615
1586
|
|
|
1616
1587
|
Args:
|
|
1617
1588
|
project_path: Project root directory
|
|
1618
|
-
mcp_servers: List of MCP server names to configure (e.g., ["
|
|
1589
|
+
mcp_servers: List of MCP server names to configure (e.g., ["context7", "deepwiki"])
|
|
1619
1590
|
|
|
1620
1591
|
Behavior:
|
|
1621
1592
|
- If mcp_servers is empty: No file created/modified (early return)
|
|
@@ -1895,6 +1866,73 @@ The filename becomes the command name (without the `.md` extension).
|
|
|
1895
1866
|
)
|
|
1896
1867
|
|
|
1897
1868
|
|
|
1869
|
+
def create_hook_files(project_path: Path) -> int:
|
|
1870
|
+
"""Create MAP hook files in .claude/hooks/
|
|
1871
|
+
|
|
1872
|
+
Returns:
|
|
1873
|
+
Number of hook files installed
|
|
1874
|
+
"""
|
|
1875
|
+
hooks_dir = project_path / ".claude" / "hooks"
|
|
1876
|
+
hooks_dir.mkdir(parents=True, exist_ok=True)
|
|
1877
|
+
|
|
1878
|
+
# Get templates directory
|
|
1879
|
+
templates_dir = get_templates_dir()
|
|
1880
|
+
hooks_template_dir = templates_dir / "hooks"
|
|
1881
|
+
|
|
1882
|
+
count = 0
|
|
1883
|
+
if hooks_template_dir.exists():
|
|
1884
|
+
import shutil
|
|
1885
|
+
|
|
1886
|
+
for hook_file in hooks_template_dir.iterdir():
|
|
1887
|
+
if hook_file.is_file():
|
|
1888
|
+
dest_file = hooks_dir / hook_file.name
|
|
1889
|
+
shutil.copy2(hook_file, dest_file)
|
|
1890
|
+
# Preserve executable permissions
|
|
1891
|
+
if hook_file.suffix in (".sh", ".py"):
|
|
1892
|
+
dest_file.chmod(0o755)
|
|
1893
|
+
count += 1
|
|
1894
|
+
|
|
1895
|
+
return count
|
|
1896
|
+
|
|
1897
|
+
|
|
1898
|
+
def create_config_files(project_path: Path) -> int:
|
|
1899
|
+
"""Create MAP config files in .claude/
|
|
1900
|
+
|
|
1901
|
+
Copies configuration files:
|
|
1902
|
+
- settings.json
|
|
1903
|
+
- settings.hooks.json
|
|
1904
|
+
- ralph-loop-config.json
|
|
1905
|
+
- workflow-rules.json
|
|
1906
|
+
|
|
1907
|
+
Returns:
|
|
1908
|
+
Number of config files installed
|
|
1909
|
+
"""
|
|
1910
|
+
claude_dir = project_path / ".claude"
|
|
1911
|
+
claude_dir.mkdir(parents=True, exist_ok=True)
|
|
1912
|
+
|
|
1913
|
+
# Get templates directory
|
|
1914
|
+
templates_dir = get_templates_dir()
|
|
1915
|
+
|
|
1916
|
+
config_files = [
|
|
1917
|
+
"settings.json",
|
|
1918
|
+
"settings.hooks.json",
|
|
1919
|
+
"ralph-loop-config.json",
|
|
1920
|
+
"workflow-rules.json",
|
|
1921
|
+
]
|
|
1922
|
+
|
|
1923
|
+
count = 0
|
|
1924
|
+
import shutil
|
|
1925
|
+
|
|
1926
|
+
for config_file in config_files:
|
|
1927
|
+
template_file = templates_dir / config_file
|
|
1928
|
+
if template_file.exists():
|
|
1929
|
+
dest_file = claude_dir / config_file
|
|
1930
|
+
shutil.copy2(template_file, dest_file)
|
|
1931
|
+
count += 1
|
|
1932
|
+
|
|
1933
|
+
return count
|
|
1934
|
+
|
|
1935
|
+
|
|
1898
1936
|
@app.command()
|
|
1899
1937
|
def init(
|
|
1900
1938
|
project_name: Optional[str] = typer.Argument(
|
|
@@ -1903,7 +1941,7 @@ def init(
|
|
|
1903
1941
|
mcp: str = typer.Option(
|
|
1904
1942
|
"all",
|
|
1905
1943
|
"--mcp",
|
|
1906
|
-
help="MCP server installation (default: all). Options: all, essential, docs, none, or comma-separated list (e.g.
|
|
1944
|
+
help="MCP server installation (default: all). Options: all, essential, docs, none, or comma-separated list (e.g. context7,deepwiki)",
|
|
1907
1945
|
),
|
|
1908
1946
|
no_git: bool = typer.Option(
|
|
1909
1947
|
False, "--no-git", help="Skip git repository initialization"
|
|
@@ -1931,7 +1969,7 @@ def init(
|
|
|
1931
1969
|
mapify init my-project # Installs all MCP servers
|
|
1932
1970
|
mapify init my-project --mcp none # Skip MCP installation
|
|
1933
1971
|
mapify init my-project --mcp essential
|
|
1934
|
-
mapify init my-project --mcp "
|
|
1972
|
+
mapify init my-project --mcp "context7,deepwiki"
|
|
1935
1973
|
mapify init .
|
|
1936
1974
|
mapify init . --force # Force init in non-empty current directory
|
|
1937
1975
|
mapify init --debug # Enable workflow logging
|
|
@@ -2029,7 +2067,7 @@ def init(
|
|
|
2029
2067
|
if mcp == "all":
|
|
2030
2068
|
selected_mcp_servers = list(INDIVIDUAL_MCP_SERVERS.keys())
|
|
2031
2069
|
elif mcp == "essential":
|
|
2032
|
-
selected_mcp_servers = ["
|
|
2070
|
+
selected_mcp_servers = ["claude-reviewer", "sequential-thinking"]
|
|
2033
2071
|
elif mcp == "docs":
|
|
2034
2072
|
selected_mcp_servers = ["context7", "deepwiki"]
|
|
2035
2073
|
elif mcp == "none":
|
|
@@ -2076,6 +2114,18 @@ def init(
|
|
|
2076
2114
|
tool_word = "script" if tool_count == 1 else "scripts"
|
|
2077
2115
|
tracker.complete("create-map-tools", f"{tool_count} {tool_word}")
|
|
2078
2116
|
|
|
2117
|
+
tracker.add("create-hooks", "Create MAP hooks")
|
|
2118
|
+
tracker.start("create-hooks")
|
|
2119
|
+
hook_count = create_hook_files(project_path)
|
|
2120
|
+
hook_word = "hook" if hook_count == 1 else "hooks"
|
|
2121
|
+
tracker.complete("create-hooks", f"{hook_count} {hook_word}")
|
|
2122
|
+
|
|
2123
|
+
tracker.add("create-configs", "Create config files")
|
|
2124
|
+
tracker.start("create-configs")
|
|
2125
|
+
config_count = create_config_files(project_path)
|
|
2126
|
+
config_word = "file" if config_count == 1 else "files"
|
|
2127
|
+
tracker.complete("create-configs", f"{config_count} {config_word}")
|
|
2128
|
+
|
|
2079
2129
|
if selected_mcp_servers:
|
|
2080
2130
|
# Create internal MCP config (for MAP Framework agent mappings)
|
|
2081
2131
|
tracker.add("mcp-config", "Create internal MCP config")
|