mapify-cli 3.8.0__tar.gz → 3.9.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.8.0 → mapify_cli-3.9.0}/PKG-INFO +1 -1
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/pyproject.toml +1 -1
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/__init__.py +270 -200
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/cli_ui.py +1 -1
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/delivery/__init__.py +4 -0
- mapify_cli-3.9.0/src/mapify_cli/delivery/codex_copier.py +167 -0
- mapify_cli-3.9.0/src/mapify_cli/delivery/providers.py +89 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/AGENTS.md +38 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/agents/decomposer.toml +832 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/agents/monitor.toml +1135 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/agents/researcher.toml +74 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/config.toml +17 -0
- {mapify_cli-3.8.0/src/mapify_cli/templates → mapify_cli-3.9.0/src/mapify_cli/templates/codex}/hooks/workflow-gate.py +21 -3
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/hooks.json +16 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/skills/map-check/SKILL.md +21 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/skills/map-fast/SKILL.md +22 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/codex/skills/map-plan/SKILL.md +624 -0
- mapify_cli-3.9.0/src/mapify_cli/templates/hooks/workflow-gate.py +291 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/.claude/skills/README.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/.gitignore +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/README.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/config/__init__.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/config/mcp.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/config/project_config.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/config/settings.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/delivery/agent_generator.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/delivery/file_copier.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/delivery/managed_file_copier.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/dependency_graph.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/intent_detector.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/ralph_state.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/repo_insight.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/schemas.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/CLAUDE.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/actor.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/debate-arbiter.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/documentation-reviewer.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/evaluator.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/final-verifier.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/monitor.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/predictor.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/reflector.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/research-agent.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/synthesizer.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/agents/task-decomposer.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-check.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-debug.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-efficient.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-fast.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-plan.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-release.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-resume.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-review.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-task.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/commands/map-tdd.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/hooks/end-of-turn.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/hooks/post-compact-context.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/hooks/pre-compact-save-transcript.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/hooks/ralph-context-pruner.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/hooks/ralph-iteration-logger.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/hooks/safety-guardrails.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/hooks/workflow-context-injector.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/scripts/diagnostics.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/scripts/map_orchestrator.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/scripts/map_step_runner.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/scripts/map_utils.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/static-analysis/analyze.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/static-analysis/handlers/common.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/static-analysis/handlers/go.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/static-analysis/handlers/python.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/static-analysis/handlers/rust.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/map/static-analysis/handlers/typescript.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/ralph-loop-config.json +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/references/bash-guidelines.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/references/decomposition-examples.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/references/escalation-matrix.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/references/mcp-usage-examples.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/references/step-state-schema.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/references/workflow-state-schema.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/rules/learned/README.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/settings.json +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/README.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-learn/SKILL.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-learn/templates/example-rules.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-learn/templates/rules-unconditional.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-learn/templates/rules-with-paths.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/SKILL.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/scripts/check-complete.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/scripts/get-plan-path.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/scripts/init-session.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/scripts/show-focus.sh +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/templates/findings.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/templates/iteration_history.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/templates/progress.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/map-planning/templates/task_plan.md +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/skills/skill-rules.json +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/templates/workflow-rules.json +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/tools/__init__.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/tools/validate_dependencies.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/verification_recorder.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/workflow_finalizer.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/workflow_logger.py +0 -0
- {mapify_cli-3.8.0 → mapify_cli-3.9.0}/src/mapify_cli/workflow_state.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mapify-cli
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.9.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.9.0"
|
|
27
27
|
|
|
28
28
|
import os
|
|
29
29
|
import subprocess
|
|
@@ -76,8 +76,6 @@ from mapify_cli.delivery import (
|
|
|
76
76
|
create_hook_files,
|
|
77
77
|
create_config_files,
|
|
78
78
|
create_commands_dir as create_commands_dir,
|
|
79
|
-
create_map_tools,
|
|
80
|
-
create_rules_dir,
|
|
81
79
|
)
|
|
82
80
|
from mapify_cli.config import (
|
|
83
81
|
configure_global_permissions,
|
|
@@ -265,14 +263,28 @@ def count_project_markdown_files(
|
|
|
265
263
|
|
|
266
264
|
|
|
267
265
|
def is_map_initialized(project_path: Path) -> bool:
|
|
268
|
-
"""Return True when the current directory looks like a MAP project.
|
|
269
|
-
|
|
266
|
+
"""Return True when the current directory looks like a MAP project.
|
|
267
|
+
|
|
268
|
+
Recognises both Claude Code layout (.claude/) and Codex layout (.codex/).
|
|
269
|
+
"""
|
|
270
|
+
claude_paths = [
|
|
270
271
|
project_path / ".claude" / "agents",
|
|
271
272
|
project_path / ".claude" / "commands",
|
|
272
273
|
project_path / ".claude" / "settings.json",
|
|
273
274
|
project_path / ".claude" / "workflow-rules.json",
|
|
274
275
|
]
|
|
275
|
-
|
|
276
|
+
codex_paths = [
|
|
277
|
+
project_path / ".codex" / "config.toml",
|
|
278
|
+
project_path / ".codex" / "skills",
|
|
279
|
+
]
|
|
280
|
+
return all(p.exists() for p in claude_paths) or all(p.exists() for p in codex_paths)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def _detect_provider(project_path: Path) -> str:
|
|
284
|
+
"""Detect which provider was used to initialise this project."""
|
|
285
|
+
if (project_path / ".codex" / "config.toml").exists():
|
|
286
|
+
return "codex"
|
|
287
|
+
return "claude"
|
|
276
288
|
|
|
277
289
|
|
|
278
290
|
def get_project_health(project_path: Path) -> Dict[str, Any]:
|
|
@@ -280,13 +292,25 @@ def get_project_health(project_path: Path) -> Dict[str, Any]:
|
|
|
280
292
|
agent_exclude = {"README.md", "CHANGELOG.md", "MCP-PATTERNS.md"}
|
|
281
293
|
current_branch = sanitize_identifier(get_current_branch_name())
|
|
282
294
|
branch_dir = project_path / ".map" / current_branch
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
295
|
+
detected = _detect_provider(project_path)
|
|
296
|
+
|
|
297
|
+
if detected == "codex":
|
|
298
|
+
required_paths = {
|
|
299
|
+
".codex/config.toml": project_path / ".codex" / "config.toml",
|
|
300
|
+
".codex/skills": project_path / ".codex" / "skills",
|
|
301
|
+
".codex/agents": project_path / ".codex" / "agents",
|
|
302
|
+
".map/scripts": project_path / ".map" / "scripts",
|
|
303
|
+
}
|
|
304
|
+
else:
|
|
305
|
+
required_paths = {
|
|
306
|
+
".claude/agents": project_path / ".claude" / "agents",
|
|
307
|
+
".claude/commands": project_path / ".claude" / "commands",
|
|
308
|
+
".claude/settings.json": project_path / ".claude" / "settings.json",
|
|
309
|
+
".claude/workflow-rules.json": project_path
|
|
310
|
+
/ ".claude"
|
|
311
|
+
/ "workflow-rules.json",
|
|
312
|
+
".map/scripts": project_path / ".map" / "scripts",
|
|
313
|
+
}
|
|
290
314
|
missing_paths = [name for name, path in required_paths.items() if not path.exists()]
|
|
291
315
|
|
|
292
316
|
agents_dir = project_path / ".claude" / "agents"
|
|
@@ -617,6 +641,11 @@ def init(
|
|
|
617
641
|
debug: bool = typer.Option(
|
|
618
642
|
False, "--debug", help="Enable debug logging (creates .map/logs/workflow_*.log)"
|
|
619
643
|
),
|
|
644
|
+
provider: str = typer.Option(
|
|
645
|
+
"claude",
|
|
646
|
+
"--provider",
|
|
647
|
+
help="Delivery provider: claude (default) or codex",
|
|
648
|
+
),
|
|
620
649
|
):
|
|
621
650
|
"""
|
|
622
651
|
Initialize a new MAP Framework project.
|
|
@@ -656,6 +685,15 @@ def init(
|
|
|
656
685
|
metadata={"debug": debug, "mcp": mcp},
|
|
657
686
|
)
|
|
658
687
|
|
|
688
|
+
# Validate provider
|
|
689
|
+
valid_providers = ("claude", "codex")
|
|
690
|
+
if provider not in valid_providers:
|
|
691
|
+
console.print(
|
|
692
|
+
f"[red]Error:[/red] Invalid provider '{provider}'. "
|
|
693
|
+
f"Valid providers: {', '.join(valid_providers)}"
|
|
694
|
+
)
|
|
695
|
+
raise typer.Exit(1)
|
|
696
|
+
|
|
659
697
|
# Handle '.' as shorthand for current directory
|
|
660
698
|
use_current_dir = project_name == "."
|
|
661
699
|
|
|
@@ -707,122 +745,110 @@ def init(
|
|
|
707
745
|
tracker.start("check-tools")
|
|
708
746
|
|
|
709
747
|
git_available = check_tool("git")
|
|
710
|
-
claude_available = check_tool("claude")
|
|
711
748
|
|
|
712
|
-
if
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
749
|
+
if provider == "codex":
|
|
750
|
+
codex_available = check_tool("codex")
|
|
751
|
+
if codex_available:
|
|
752
|
+
tracker.complete("check-tools", "git, codex" if git_available else "codex")
|
|
753
|
+
elif git_available:
|
|
754
|
+
tracker.complete("check-tools", "git")
|
|
755
|
+
else:
|
|
756
|
+
tracker.complete("check-tools", "minimal")
|
|
716
757
|
else:
|
|
717
|
-
|
|
758
|
+
claude_available = check_tool("claude")
|
|
759
|
+
if claude_available:
|
|
760
|
+
tracker.complete("check-tools", "git, claude")
|
|
761
|
+
elif git_available:
|
|
762
|
+
tracker.complete("check-tools", "git")
|
|
763
|
+
else:
|
|
764
|
+
tracker.complete("check-tools", "minimal")
|
|
718
765
|
|
|
719
|
-
#
|
|
720
|
-
tracker.add("ai-select", "Select
|
|
721
|
-
selected_ai =
|
|
766
|
+
# Select provider
|
|
767
|
+
tracker.add("ai-select", "Select provider")
|
|
768
|
+
selected_ai = provider
|
|
722
769
|
tracker.complete("ai-select", selected_ai)
|
|
723
770
|
|
|
724
|
-
# Select MCP servers
|
|
725
|
-
tracker.add("mcp-select", "Select MCP servers")
|
|
726
|
-
tracker.start("mcp-select")
|
|
727
|
-
|
|
771
|
+
# Select MCP servers (Claude only — Codex uses TOML agent config)
|
|
728
772
|
selected_mcp_servers = []
|
|
729
773
|
|
|
730
|
-
if
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
agent_count = create_agent_files(project_path, selected_mcp_servers)
|
|
753
|
-
agent_word = "agent" if agent_count == 1 else "agents"
|
|
754
|
-
tracker.complete("create-agents", f"{agent_count} {agent_word}")
|
|
755
|
-
|
|
756
|
-
tracker.add("create-commands", "Create slash commands")
|
|
757
|
-
tracker.start("create-commands")
|
|
758
|
-
command_count = create_command_files(project_path)
|
|
759
|
-
command_word = "command" if command_count == 1 else "commands"
|
|
760
|
-
tracker.complete("create-commands", f"{command_count} {command_word}")
|
|
761
|
-
|
|
762
|
-
tracker.add("create-skills", "Create skills")
|
|
763
|
-
tracker.start("create-skills")
|
|
764
|
-
skill_count = create_skill_files(project_path)
|
|
765
|
-
skill_word = "skill" if skill_count == 1 else "skills"
|
|
766
|
-
tracker.complete("create-skills", f"{skill_count} {skill_word}")
|
|
767
|
-
|
|
768
|
-
tracker.add("create-references", "Create reference files")
|
|
769
|
-
tracker.start("create-references")
|
|
770
|
-
ref_count = create_reference_files(project_path)
|
|
771
|
-
ref_word = "file" if ref_count == 1 else "files"
|
|
772
|
-
tracker.complete("create-references", f"{ref_count} {ref_word}")
|
|
773
|
-
|
|
774
|
-
tracker.add("create-map-tools", "Create MAP tools")
|
|
775
|
-
tracker.start("create-map-tools")
|
|
776
|
-
tool_count = create_map_tools(project_path)
|
|
777
|
-
tool_word = "script" if tool_count == 1 else "scripts"
|
|
778
|
-
tracker.complete("create-map-tools", f"{tool_count} {tool_word}")
|
|
779
|
-
|
|
780
|
-
tracker.add("create-hooks", "Create MAP hooks")
|
|
781
|
-
tracker.start("create-hooks")
|
|
782
|
-
hook_count = create_hook_files(project_path)
|
|
783
|
-
hook_word = "hook" if hook_count == 1 else "hooks"
|
|
784
|
-
tracker.complete("create-hooks", f"{hook_count} {hook_word}")
|
|
785
|
-
|
|
786
|
-
tracker.add("create-configs", "Create config files")
|
|
787
|
-
tracker.start("create-configs")
|
|
788
|
-
config_count = create_config_files(project_path)
|
|
789
|
-
config_word = "file" if config_count == 1 else "files"
|
|
790
|
-
tracker.complete("create-configs", f"{config_count} {config_word}")
|
|
791
|
-
|
|
792
|
-
# Create default .map/config.yaml (project-level settings)
|
|
793
|
-
tracker.add("map-config", "Create .map/config.yaml")
|
|
794
|
-
tracker.start("map-config")
|
|
795
|
-
try:
|
|
796
|
-
from mapify_cli.config.project_config import write_default_config
|
|
797
|
-
|
|
798
|
-
config_path = write_default_config(project_path)
|
|
799
|
-
tracker.complete("map-config", str(config_path.relative_to(project_path)))
|
|
800
|
-
except Exception as e:
|
|
801
|
-
tracker.error("map-config", f"skipped: {e}")
|
|
802
|
-
|
|
803
|
-
# Create .claude/rules/learned/ directory for /map-learn persistence
|
|
804
|
-
tracker.add("rules-dir", "Create learned rules directory")
|
|
805
|
-
tracker.start("rules-dir")
|
|
806
|
-
rules_count = create_rules_dir(project_path)
|
|
807
|
-
tracker.complete(
|
|
808
|
-
"rules-dir",
|
|
809
|
-
f"{rules_count} file" if rules_count <= 1 else f"{rules_count} files",
|
|
810
|
-
)
|
|
774
|
+
if provider != "codex":
|
|
775
|
+
tracker.add("mcp-select", "Select MCP servers")
|
|
776
|
+
tracker.start("mcp-select")
|
|
777
|
+
|
|
778
|
+
if mcp == "all":
|
|
779
|
+
selected_mcp_servers = list(INDIVIDUAL_MCP_SERVERS.keys())
|
|
780
|
+
elif mcp == "essential":
|
|
781
|
+
selected_mcp_servers = ["sequential-thinking", "deepwiki"]
|
|
782
|
+
elif mcp == "none":
|
|
783
|
+
selected_mcp_servers = []
|
|
784
|
+
else:
|
|
785
|
+
# Parse comma-separated list
|
|
786
|
+
requested = [s.strip() for s in mcp.split(",") if s.strip()]
|
|
787
|
+
invalid = [s for s in requested if s not in INDIVIDUAL_MCP_SERVERS]
|
|
788
|
+
if invalid:
|
|
789
|
+
console.print(
|
|
790
|
+
f"[yellow]Warning:[/yellow] Unrecognized MCP servers ignored: {', '.join(invalid)}"
|
|
791
|
+
)
|
|
792
|
+
console.print(
|
|
793
|
+
f"Valid servers: {', '.join(INDIVIDUAL_MCP_SERVERS.keys())}"
|
|
794
|
+
)
|
|
795
|
+
selected_mcp_servers = [s for s in requested if s in INDIVIDUAL_MCP_SERVERS]
|
|
811
796
|
|
|
812
|
-
|
|
813
|
-
# Create internal MCP config (for MAP Framework agent mappings)
|
|
814
|
-
tracker.add("mcp-config", "Create internal MCP config")
|
|
815
|
-
tracker.start("mcp-config")
|
|
816
|
-
create_mcp_config(project_path, selected_mcp_servers)
|
|
817
|
-
tracker.complete("mcp-config", f"{len(selected_mcp_servers)} servers")
|
|
797
|
+
tracker.complete("mcp-select", f"{len(selected_mcp_servers)} servers")
|
|
818
798
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
create_or_merge_project_mcp_json(project_path, selected_mcp_servers)
|
|
823
|
-
tracker.complete("mcp-project", "Claude Code MCP config")
|
|
799
|
+
if provider == "codex":
|
|
800
|
+
# Codex provider: install .codex/ files + .map/scripts/ (skip-if-exists)
|
|
801
|
+
from mapify_cli.delivery.providers import CodexProvider
|
|
824
802
|
|
|
825
|
-
|
|
803
|
+
tracker.add("create-codex", "Create Codex files")
|
|
804
|
+
tracker.start("create-codex")
|
|
805
|
+
codex_provider = CodexProvider()
|
|
806
|
+
counts = codex_provider.install(project_path)
|
|
807
|
+
total = sum(counts.values())
|
|
808
|
+
tracker.complete("create-codex", f"{total} files")
|
|
809
|
+
else:
|
|
810
|
+
# Claude provider: use ClaudeProvider abstraction
|
|
811
|
+
from mapify_cli.delivery.providers import ClaudeProvider
|
|
812
|
+
|
|
813
|
+
tracker.add("create-claude", "Create Claude Code files")
|
|
814
|
+
tracker.start("create-claude")
|
|
815
|
+
claude_provider = ClaudeProvider()
|
|
816
|
+
claude_counts = claude_provider.install(
|
|
817
|
+
project_path, mcp_servers=selected_mcp_servers
|
|
818
|
+
)
|
|
819
|
+
total_claude = sum(claude_counts.values())
|
|
820
|
+
tracker.complete("create-claude", f"{total_claude} files")
|
|
821
|
+
|
|
822
|
+
# Create default .map/config.yaml (project-level settings)
|
|
823
|
+
tracker.add("map-config", "Create .map/config.yaml")
|
|
824
|
+
tracker.start("map-config")
|
|
825
|
+
try:
|
|
826
|
+
from mapify_cli.config.project_config import write_default_config
|
|
827
|
+
|
|
828
|
+
config_path = write_default_config(project_path)
|
|
829
|
+
tracker.complete("map-config", str(config_path.relative_to(project_path)))
|
|
830
|
+
except Exception as e:
|
|
831
|
+
tracker.error("map-config", f"skipped: {e}")
|
|
832
|
+
|
|
833
|
+
if selected_mcp_servers:
|
|
834
|
+
# Create internal MCP config (for MAP Framework agent mappings)
|
|
835
|
+
tracker.add("mcp-config", "Create internal MCP config")
|
|
836
|
+
tracker.start("mcp-config")
|
|
837
|
+
create_mcp_config(project_path, selected_mcp_servers)
|
|
838
|
+
tracker.complete("mcp-config", f"{len(selected_mcp_servers)} servers")
|
|
839
|
+
|
|
840
|
+
# Create/merge project .mcp.json (for Claude Code MCP server registration)
|
|
841
|
+
tracker.add("mcp-project", "Create/merge .mcp.json")
|
|
842
|
+
tracker.start("mcp-project")
|
|
843
|
+
create_or_merge_project_mcp_json(project_path, selected_mcp_servers)
|
|
844
|
+
tracker.complete("mcp-project", "Claude Code MCP config")
|
|
845
|
+
|
|
846
|
+
tracker.add("project-permissions", "Configure project approvals")
|
|
847
|
+
tracker.start("project-permissions")
|
|
848
|
+
create_or_merge_project_settings_local(project_path)
|
|
849
|
+
tracker.complete("project-permissions", ".claude/settings.local.json")
|
|
850
|
+
|
|
851
|
+
# Initialize git (shared, provider-agnostic)
|
|
826
852
|
if not no_git and git_available:
|
|
827
853
|
tracker.add("git", "Initialize git repository")
|
|
828
854
|
tracker.start("git")
|
|
@@ -834,17 +860,13 @@ def init(
|
|
|
834
860
|
else:
|
|
835
861
|
tracker.error("git", "failed")
|
|
836
862
|
|
|
837
|
-
tracker.add("project-permissions", "Configure project approvals")
|
|
838
|
-
tracker.start("project-permissions")
|
|
839
|
-
create_or_merge_project_settings_local(project_path)
|
|
840
|
-
tracker.complete("project-permissions", ".claude/settings.local.json")
|
|
841
|
-
|
|
842
863
|
tracker.add("finalize", "Finalize")
|
|
843
864
|
tracker.complete("finalize", "project ready")
|
|
844
865
|
|
|
845
|
-
# Configure global permissions for read-only commands
|
|
846
|
-
|
|
847
|
-
|
|
866
|
+
# Configure global permissions for read-only commands (Claude only)
|
|
867
|
+
if provider != "codex":
|
|
868
|
+
console.print() # Add spacing
|
|
869
|
+
configure_global_permissions()
|
|
848
870
|
|
|
849
871
|
# Show final tree
|
|
850
872
|
with Live(tracker.render(), console=console, transient=True) as live:
|
|
@@ -864,20 +886,31 @@ def init(
|
|
|
864
886
|
steps_lines.append("1. You're already in the project directory!")
|
|
865
887
|
step_num = 2
|
|
866
888
|
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
" • [cyan]
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
" • [cyan]
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
889
|
+
if provider == "codex":
|
|
890
|
+
steps_lines.append(f"{step_num}. Start using MAP skills with Codex:")
|
|
891
|
+
steps_lines.append(" • [cyan]$map-plan[/] - Plan and decompose complex tasks")
|
|
892
|
+
steps_lines.append(
|
|
893
|
+
" • [cyan]$map-fast[/] - Quick implementation with minimal validation"
|
|
894
|
+
)
|
|
895
|
+
steps_lines.append(" • [cyan]$map-check[/] - Quality gates and verification")
|
|
896
|
+
steps_lines.append(
|
|
897
|
+
f"{step_num + 1}. Trust this project in Codex settings for .codex/ config to take effect"
|
|
898
|
+
)
|
|
899
|
+
else:
|
|
900
|
+
steps_lines.append(f"{step_num}. Start using MAP commands with Claude Code:")
|
|
901
|
+
steps_lines.append(
|
|
902
|
+
" • [cyan]/map-efficient[/] - Implement features with optimized workflow (recommended)"
|
|
903
|
+
)
|
|
904
|
+
steps_lines.append(" • [cyan]/map-debug[/] - Debug issue using MAP analysis")
|
|
905
|
+
steps_lines.append(
|
|
906
|
+
" • [cyan]/map-fast[/] - Quick implementation with minimal validation"
|
|
907
|
+
)
|
|
908
|
+
steps_lines.append(
|
|
909
|
+
" • [cyan]/map-learn[/] - Extract lessons from completed workflows"
|
|
910
|
+
)
|
|
911
|
+
steps_lines.append(
|
|
912
|
+
f"{step_num + 1}. Run [cyan]/map-plan[/cyan] first when you want branch-scoped research, spec, and plan artifacts in `.map/<branch>/`"
|
|
913
|
+
)
|
|
881
914
|
|
|
882
915
|
steps_panel = Panel(
|
|
883
916
|
"\n".join(steps_lines), title="Next Steps", border_style="cyan", padding=(1, 2)
|
|
@@ -906,10 +939,17 @@ def check(debug: bool = typer.Option(False, "--debug", help="Enable debug loggin
|
|
|
906
939
|
|
|
907
940
|
tracker = StepTracker("Check Available Tools")
|
|
908
941
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
942
|
+
detected = _detect_provider(Path.cwd())
|
|
943
|
+
if detected == "codex":
|
|
944
|
+
tools = [
|
|
945
|
+
("git", "Git version control"),
|
|
946
|
+
("codex", "Codex CLI"),
|
|
947
|
+
]
|
|
948
|
+
else:
|
|
949
|
+
tools = [
|
|
950
|
+
("git", "Git version control"),
|
|
951
|
+
("claude", "Claude Code CLI"),
|
|
952
|
+
]
|
|
913
953
|
|
|
914
954
|
# Add tools to tracker
|
|
915
955
|
for tool, description in tools:
|
|
@@ -929,7 +969,7 @@ def check(debug: bool = typer.Option(False, "--debug", help="Enable debug loggin
|
|
|
929
969
|
|
|
930
970
|
tracker.add("project", "Detect MAP project")
|
|
931
971
|
if health["initialized"]:
|
|
932
|
-
tracker.complete("project", "initialized")
|
|
972
|
+
tracker.complete("project", f"initialized ({detected} provider)")
|
|
933
973
|
else:
|
|
934
974
|
tracker.error("project", "not initialized")
|
|
935
975
|
|
|
@@ -942,9 +982,10 @@ def check(debug: bool = typer.Option(False, "--debug", help="Enable debug loggin
|
|
|
942
982
|
else:
|
|
943
983
|
tracker.error("templates", "missing bundled templates")
|
|
944
984
|
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
985
|
+
if detected != "codex":
|
|
986
|
+
tracker.add("mcp", "Check supported MCP servers")
|
|
987
|
+
supported_servers = sorted(build_standard_mcp_servers().keys())
|
|
988
|
+
tracker.complete("mcp", ", ".join(supported_servers) or "none")
|
|
948
989
|
|
|
949
990
|
console.print(tracker.render())
|
|
950
991
|
console.print()
|
|
@@ -957,7 +998,9 @@ def check(debug: bool = typer.Option(False, "--debug", help="Enable debug loggin
|
|
|
957
998
|
console.print("[yellow]MAP environment needs attention:[/yellow]")
|
|
958
999
|
if not results.get("git"):
|
|
959
1000
|
console.print(" • Install git: https://git-scm.com/downloads")
|
|
960
|
-
if not results.get("
|
|
1001
|
+
if detected == "codex" and not results.get("codex"):
|
|
1002
|
+
console.print(" • Install Codex CLI: https://github.com/openai/codex")
|
|
1003
|
+
elif not results.get("claude"):
|
|
961
1004
|
console.print(
|
|
962
1005
|
" • Install Claude Code: https://docs.anthropic.com/en/docs/claude-code/setup"
|
|
963
1006
|
)
|
|
@@ -984,13 +1027,16 @@ def doctor(debug: bool = typer.Option(False, "--debug", help="Enable debug loggi
|
|
|
984
1027
|
console.print("[bold]Running MAP doctor...[/bold]\n")
|
|
985
1028
|
|
|
986
1029
|
project_path = Path.cwd()
|
|
1030
|
+
detected = _detect_provider(project_path)
|
|
987
1031
|
health = get_project_health(project_path)
|
|
988
1032
|
tracker = StepTracker("MAP Doctor")
|
|
989
1033
|
|
|
990
|
-
|
|
991
|
-
("git", "Git version control"),
|
|
992
|
-
|
|
993
|
-
|
|
1034
|
+
if detected == "codex":
|
|
1035
|
+
tool_list = [("git", "Git version control"), ("codex", "Codex CLI")]
|
|
1036
|
+
else:
|
|
1037
|
+
tool_list = [("git", "Git version control"), ("claude", "Claude Code CLI")]
|
|
1038
|
+
|
|
1039
|
+
for tool_name, description in tool_list:
|
|
994
1040
|
tracker.add(tool_name, description)
|
|
995
1041
|
if check_tool(tool_name):
|
|
996
1042
|
tracker.complete(tool_name, "available")
|
|
@@ -998,27 +1044,41 @@ def doctor(debug: bool = typer.Option(False, "--debug", help="Enable debug loggi
|
|
|
998
1044
|
tracker.error(tool_name, "not found")
|
|
999
1045
|
|
|
1000
1046
|
tracker.add("project", "MAP project structure")
|
|
1001
|
-
if
|
|
1047
|
+
if detected == "codex":
|
|
1048
|
+
codex_dir = project_path / ".codex"
|
|
1049
|
+
codex_checks = {
|
|
1050
|
+
".codex/config.toml": codex_dir / "config.toml",
|
|
1051
|
+
".codex/skills": codex_dir / "skills",
|
|
1052
|
+
".codex/agents": codex_dir / "agents",
|
|
1053
|
+
".map/scripts": project_path / ".map" / "scripts",
|
|
1054
|
+
}
|
|
1055
|
+
codex_missing = [n for n, p in codex_checks.items() if not p.exists()]
|
|
1056
|
+
if not codex_missing:
|
|
1057
|
+
tracker.complete("project", "all core paths present (codex)")
|
|
1058
|
+
else:
|
|
1059
|
+
tracker.error("project", f"missing {len(codex_missing)} path(s)")
|
|
1060
|
+
elif not health["missing_paths"]:
|
|
1002
1061
|
tracker.complete("project", "all core paths present")
|
|
1003
1062
|
else:
|
|
1004
1063
|
tracker.error("project", f"missing {len(health['missing_paths'])} path(s)")
|
|
1005
1064
|
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1065
|
+
if detected != "codex":
|
|
1066
|
+
tracker.add("templates", "Installed template counts")
|
|
1067
|
+
if (
|
|
1068
|
+
health["installed_agents"] == health["expected_agents"]
|
|
1069
|
+
and health["installed_commands"] == health["expected_commands"]
|
|
1070
|
+
):
|
|
1071
|
+
tracker.complete(
|
|
1072
|
+
"templates",
|
|
1073
|
+
f"{health['installed_agents']}/{health['expected_agents']} agents, "
|
|
1074
|
+
f"{health['installed_commands']}/{health['expected_commands']} commands",
|
|
1075
|
+
)
|
|
1076
|
+
else:
|
|
1077
|
+
tracker.error(
|
|
1078
|
+
"templates",
|
|
1079
|
+
f"agents {health['installed_agents']}/{health['expected_agents']}, "
|
|
1080
|
+
f"commands {health['installed_commands']}/{health['expected_commands']}",
|
|
1081
|
+
)
|
|
1022
1082
|
|
|
1023
1083
|
tracker.add("planning", "Branch workspace artifacts")
|
|
1024
1084
|
if health["branch_workspace_exists"]:
|
|
@@ -1029,16 +1089,17 @@ def doctor(debug: bool = typer.Option(False, "--debug", help="Enable debug loggi
|
|
|
1029
1089
|
else:
|
|
1030
1090
|
tracker.error("planning", f"missing .map/{health['current_branch']}")
|
|
1031
1091
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
if health["
|
|
1035
|
-
|
|
1092
|
+
if detected != "codex":
|
|
1093
|
+
tracker.add("mcp", "Project MCP configuration")
|
|
1094
|
+
if health["has_project_mcp"]:
|
|
1095
|
+
if health["project_mcp_valid"]:
|
|
1096
|
+
tracker.complete("mcp", ".mcp.json valid")
|
|
1097
|
+
else:
|
|
1098
|
+
tracker.error("mcp", ".mcp.json unreadable")
|
|
1099
|
+
elif health["has_internal_mcp"]:
|
|
1100
|
+
tracker.complete("mcp", "internal config only")
|
|
1036
1101
|
else:
|
|
1037
|
-
tracker.
|
|
1038
|
-
elif health["has_internal_mcp"]:
|
|
1039
|
-
tracker.complete("mcp", "internal config only")
|
|
1040
|
-
else:
|
|
1041
|
-
tracker.complete("mcp", "no MCP config")
|
|
1102
|
+
tracker.complete("mcp", "no MCP config")
|
|
1042
1103
|
|
|
1043
1104
|
console.print(tracker.render())
|
|
1044
1105
|
console.print()
|
|
@@ -1051,21 +1112,22 @@ def doctor(debug: bool = typer.Option(False, "--debug", help="Enable debug loggi
|
|
|
1051
1112
|
"Project",
|
|
1052
1113
|
"OK" if health["initialized"] else "Needs init",
|
|
1053
1114
|
(
|
|
1054
|
-
".
|
|
1115
|
+
f".{detected} + workflow configs detected"
|
|
1055
1116
|
if health["initialized"]
|
|
1056
1117
|
else "Run `mapify init .`"
|
|
1057
1118
|
),
|
|
1058
1119
|
)
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1120
|
+
if detected != "codex":
|
|
1121
|
+
details.add_row(
|
|
1122
|
+
"Agents",
|
|
1123
|
+
f"{health['installed_agents']}/{health['expected_agents']}",
|
|
1124
|
+
"Installed vs bundled agent templates",
|
|
1125
|
+
)
|
|
1126
|
+
details.add_row(
|
|
1127
|
+
"Commands",
|
|
1128
|
+
f"{health['installed_commands']}/{health['expected_commands']}",
|
|
1129
|
+
"Installed vs bundled slash commands",
|
|
1130
|
+
)
|
|
1069
1131
|
details.add_row(
|
|
1070
1132
|
"Planning",
|
|
1071
1133
|
(
|
|
@@ -1075,15 +1137,16 @@ def doctor(debug: bool = typer.Option(False, "--debug", help="Enable debug loggi
|
|
|
1075
1137
|
),
|
|
1076
1138
|
f"Current branch workspace: .map/{health['current_branch']}/",
|
|
1077
1139
|
)
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1140
|
+
if detected != "codex":
|
|
1141
|
+
details.add_row(
|
|
1142
|
+
"MCP",
|
|
1143
|
+
(
|
|
1144
|
+
"valid"
|
|
1145
|
+
if health["project_mcp_valid"]
|
|
1146
|
+
else ("present" if health["has_project_mcp"] else "not configured")
|
|
1147
|
+
),
|
|
1148
|
+
".mcp.json status",
|
|
1149
|
+
)
|
|
1087
1150
|
console.print(details)
|
|
1088
1151
|
|
|
1089
1152
|
if health["missing_paths"]:
|
|
@@ -1106,6 +1169,13 @@ def upgrade():
|
|
|
1106
1169
|
console.print("Run: [cyan]mapify init .[/cyan]")
|
|
1107
1170
|
raise typer.Exit(0)
|
|
1108
1171
|
|
|
1172
|
+
if _detect_provider(project_path) == "codex":
|
|
1173
|
+
console.print(
|
|
1174
|
+
"[yellow]Codex projects: re-run "
|
|
1175
|
+
"[cyan]mapify init . --provider codex --force[/cyan] to refresh.[/yellow]"
|
|
1176
|
+
)
|
|
1177
|
+
raise typer.Exit(0)
|
|
1178
|
+
|
|
1109
1179
|
console.print("[cyan]Checking for updates...[/cyan]")
|
|
1110
1180
|
latest_release = get_latest_release("azalio", "map-framework")
|
|
1111
1181
|
latest_version = None
|