claude-mpm 5.4.55__py3-none-any.whl → 5.4.85__py3-none-any.whl
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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +405 -0
- claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +63 -241
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
- claude_mpm/agents/PM_INSTRUCTIONS.md +36 -9
- claude_mpm/cli/__init__.py +5 -1
- claude_mpm/cli/commands/agents.py +2 -4
- claude_mpm/cli/commands/agents_reconcile.py +197 -0
- claude_mpm/cli/commands/configure.py +620 -21
- claude_mpm/cli/commands/skills.py +166 -14
- claude_mpm/cli/executor.py +1 -0
- claude_mpm/cli/interactive/__init__.py +10 -0
- claude_mpm/cli/interactive/agent_wizard.py +30 -50
- claude_mpm/cli/interactive/questionary_styles.py +65 -0
- claude_mpm/cli/interactive/skill_selector.py +481 -0
- claude_mpm/cli/parsers/base_parser.py +5 -0
- claude_mpm/cli/startup.py +223 -388
- claude_mpm/constants.py +1 -0
- claude_mpm/core/claude_runner.py +2 -2
- claude_mpm/core/interactive_session.py +7 -7
- claude_mpm/core/output_style_manager.py +21 -13
- claude_mpm/core/unified_config.py +50 -8
- claude_mpm/core/unified_paths.py +30 -13
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +8 -0
- claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
- claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +7 -4
- claude_mpm/services/agents/startup_sync.py +5 -2
- claude_mpm/services/pm_skills_deployer.py +4 -0
- claude_mpm/services/skills/git_skill_source_manager.py +24 -8
- claude_mpm/services/skills/selective_skill_deployer.py +82 -83
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
- claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
- claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
- claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
- claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
- claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md +167 -0
- claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md +113 -0
- claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md +124 -0
- claude_mpm/skills/bundled/pm/pm-teaching-mode/SKILL.md +657 -0
- claude_mpm/skills/bundled/pm/pm-ticketing-integration/SKILL.md +154 -0
- claude_mpm/skills/bundled/pm/pm-verification-protocols/SKILL.md +198 -0
- claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
- claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
- claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
- claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
- claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
- claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
- claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
- claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
- claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
- claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
- claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
- claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
- claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
- claude_mpm/utils/agent_dependency_loader.py +103 -4
- claude_mpm/utils/robust_installer.py +45 -24
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/METADATA +47 -23
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/RECORD +159 -47
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.55.dist-info → claude_mpm-5.4.85.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Startup Reconciliation Hook
|
|
3
|
+
|
|
4
|
+
This module provides a hook for performing agent/skill reconciliation
|
|
5
|
+
during application startup, ensuring deployed state matches configuration.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from claude_mpm.services.agents.deployment.startup_reconciliation import (
|
|
9
|
+
perform_startup_reconciliation
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
# In your startup code
|
|
13
|
+
perform_startup_reconciliation()
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Optional
|
|
18
|
+
|
|
19
|
+
from claude_mpm.core.logging_utils import get_logger
|
|
20
|
+
from claude_mpm.core.unified_config import UnifiedConfig
|
|
21
|
+
|
|
22
|
+
from .deployment_reconciler import DeploymentReconciler, DeploymentResult
|
|
23
|
+
|
|
24
|
+
logger = get_logger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def perform_startup_reconciliation(
|
|
28
|
+
project_path: Optional[Path] = None,
|
|
29
|
+
config: Optional[UnifiedConfig] = None,
|
|
30
|
+
silent: bool = False,
|
|
31
|
+
) -> tuple[DeploymentResult, DeploymentResult]:
|
|
32
|
+
"""
|
|
33
|
+
Perform agent and skill reconciliation during startup.
|
|
34
|
+
|
|
35
|
+
This ensures the deployed state (.claude/agents, .claude/skills) matches
|
|
36
|
+
the configuration (agents.enabled, skills.enabled lists).
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
project_path: Project directory (default: current directory)
|
|
40
|
+
config: Configuration instance (auto-loads if None)
|
|
41
|
+
silent: Suppress info logging (only errors)
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Tuple of (agent_result, skill_result)
|
|
45
|
+
"""
|
|
46
|
+
project_path = project_path or Path.cwd()
|
|
47
|
+
|
|
48
|
+
# Load config if not provided
|
|
49
|
+
if config is None:
|
|
50
|
+
config = UnifiedConfig()
|
|
51
|
+
|
|
52
|
+
# Initialize reconciler
|
|
53
|
+
reconciler = DeploymentReconciler(config)
|
|
54
|
+
|
|
55
|
+
if not silent:
|
|
56
|
+
logger.info("Performing startup reconciliation...")
|
|
57
|
+
|
|
58
|
+
# Reconcile agents
|
|
59
|
+
agent_result = reconciler.reconcile_agents(project_path)
|
|
60
|
+
|
|
61
|
+
if agent_result.deployed and not silent:
|
|
62
|
+
logger.info(f"Deployed agents: {', '.join(agent_result.deployed)}")
|
|
63
|
+
if agent_result.removed and not silent:
|
|
64
|
+
logger.info(f"Removed agents: {', '.join(agent_result.removed)}")
|
|
65
|
+
if agent_result.errors:
|
|
66
|
+
for error in agent_result.errors:
|
|
67
|
+
logger.error(f"Agent reconciliation error: {error}")
|
|
68
|
+
|
|
69
|
+
# Reconcile skills
|
|
70
|
+
skill_result = reconciler.reconcile_skills(project_path)
|
|
71
|
+
|
|
72
|
+
if skill_result.deployed and not silent:
|
|
73
|
+
logger.info(f"Deployed skills: {', '.join(skill_result.deployed)}")
|
|
74
|
+
if skill_result.removed and not silent:
|
|
75
|
+
logger.info(f"Removed skills: {', '.join(skill_result.removed)}")
|
|
76
|
+
if skill_result.errors:
|
|
77
|
+
for error in skill_result.errors:
|
|
78
|
+
logger.error(f"Skill reconciliation error: {error}")
|
|
79
|
+
|
|
80
|
+
if not silent:
|
|
81
|
+
total_errors = len(agent_result.errors) + len(skill_result.errors)
|
|
82
|
+
if total_errors == 0:
|
|
83
|
+
logger.info("Startup reconciliation complete")
|
|
84
|
+
else:
|
|
85
|
+
logger.warning(
|
|
86
|
+
f"Startup reconciliation complete with {total_errors} errors"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
return agent_result, skill_result
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def check_reconciliation_needed(
|
|
93
|
+
project_path: Optional[Path] = None, config: Optional[UnifiedConfig] = None
|
|
94
|
+
) -> bool:
|
|
95
|
+
"""
|
|
96
|
+
Check if reconciliation is needed (without performing it).
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
project_path: Project directory
|
|
100
|
+
config: Configuration instance
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
True if reconciliation would make changes
|
|
104
|
+
"""
|
|
105
|
+
project_path = project_path or Path.cwd()
|
|
106
|
+
|
|
107
|
+
if config is None:
|
|
108
|
+
config = UnifiedConfig()
|
|
109
|
+
|
|
110
|
+
reconciler = DeploymentReconciler(config)
|
|
111
|
+
view = reconciler.get_reconciliation_view(project_path)
|
|
112
|
+
|
|
113
|
+
agent_state = view["agents"]
|
|
114
|
+
skill_state = view["skills"]
|
|
115
|
+
|
|
116
|
+
# Check if any changes needed
|
|
117
|
+
return (
|
|
118
|
+
len(agent_state.to_deploy) > 0
|
|
119
|
+
or len(agent_state.to_remove) > 0
|
|
120
|
+
or len(skill_state.to_deploy) > 0
|
|
121
|
+
or len(skill_state.to_remove) > 0
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# Example integration in startup code:
|
|
126
|
+
#
|
|
127
|
+
# from claude_mpm.services.agents.deployment.startup_reconciliation import (
|
|
128
|
+
# perform_startup_reconciliation,
|
|
129
|
+
# check_reconciliation_needed
|
|
130
|
+
# )
|
|
131
|
+
#
|
|
132
|
+
# def startup():
|
|
133
|
+
# # Check if reconciliation needed
|
|
134
|
+
# if check_reconciliation_needed():
|
|
135
|
+
# logger.info("Reconciliation needed, performing...")
|
|
136
|
+
# perform_startup_reconciliation()
|
|
137
|
+
# else:
|
|
138
|
+
# logger.debug("No reconciliation needed")
|
|
@@ -1118,14 +1118,17 @@ class GitSourceSyncService:
|
|
|
1118
1118
|
deploy_filename = Path(agent_path).name
|
|
1119
1119
|
deploy_file = deployment_dir / deploy_filename
|
|
1120
1120
|
|
|
1121
|
-
# Check if update needed (compare
|
|
1121
|
+
# Check if update needed (compare content, not just mtime)
|
|
1122
|
+
# DESIGN: Use content hash comparison for reliable change detection
|
|
1123
|
+
# Mtime comparison can fail when cache downloads have older timestamps
|
|
1122
1124
|
should_deploy = force
|
|
1123
1125
|
was_existing = deploy_file.exists()
|
|
1124
1126
|
|
|
1125
1127
|
if not force and was_existing:
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1128
|
+
# Compare file contents using hash
|
|
1129
|
+
cache_content = cache_file.read_bytes()
|
|
1130
|
+
deploy_content = deploy_file.read_bytes()
|
|
1131
|
+
should_deploy = cache_content != deploy_content
|
|
1129
1132
|
|
|
1130
1133
|
if not should_deploy and was_existing:
|
|
1131
1134
|
results["skipped"].append(deploy_filename)
|
|
@@ -32,7 +32,9 @@ from claude_mpm.services.agents.sources.git_source_sync_service import (
|
|
|
32
32
|
logger = logging.getLogger(__name__)
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def sync_agents_on_startup(
|
|
35
|
+
def sync_agents_on_startup(
|
|
36
|
+
config: Optional[Dict[str, Any]] = None, force_refresh: bool = False
|
|
37
|
+
) -> Dict[str, Any]:
|
|
36
38
|
"""Synchronize agents from remote sources on Claude MPM startup.
|
|
37
39
|
|
|
38
40
|
Design Decision: Single-source support for Stage 1
|
|
@@ -44,6 +46,7 @@ def sync_agents_on_startup(config: Optional[Dict[str, Any]] = None) -> Dict[str,
|
|
|
44
46
|
|
|
45
47
|
Args:
|
|
46
48
|
config: Optional configuration dictionary. If None, loads from Config singleton.
|
|
49
|
+
force_refresh: Force download even if cache is fresh (bypasses ETag).
|
|
47
50
|
|
|
48
51
|
Returns:
|
|
49
52
|
Dictionary with sync results:
|
|
@@ -156,7 +159,7 @@ def sync_agents_on_startup(config: Optional[Dict[str, Any]] = None) -> Dict[str,
|
|
|
156
159
|
)
|
|
157
160
|
|
|
158
161
|
# Perform sync
|
|
159
|
-
sync_result = sync_service.sync_agents(force_refresh=
|
|
162
|
+
sync_result = sync_service.sync_agents(force_refresh=force_refresh)
|
|
160
163
|
|
|
161
164
|
# Aggregate results
|
|
162
165
|
result["sources_synced"] += 1
|
|
@@ -98,6 +98,7 @@ class VerificationResult:
|
|
|
98
98
|
missing_skills: List of missing skill names
|
|
99
99
|
outdated_skills: List of outdated skill names
|
|
100
100
|
message: Summary message
|
|
101
|
+
skill_count: Total number of deployed skills
|
|
101
102
|
"""
|
|
102
103
|
|
|
103
104
|
verified: bool
|
|
@@ -105,6 +106,7 @@ class VerificationResult:
|
|
|
105
106
|
missing_skills: List[str]
|
|
106
107
|
outdated_skills: List[str]
|
|
107
108
|
message: str
|
|
109
|
+
skill_count: int = 0
|
|
108
110
|
|
|
109
111
|
|
|
110
112
|
@dataclass
|
|
@@ -551,6 +553,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
551
553
|
missing_skills=missing_skills,
|
|
552
554
|
outdated_skills=outdated_skills,
|
|
553
555
|
message="PM skills not deployed. Run 'claude-mpm init' to deploy.",
|
|
556
|
+
skill_count=0,
|
|
554
557
|
)
|
|
555
558
|
|
|
556
559
|
# Check each registered skill exists
|
|
@@ -610,6 +613,7 @@ class PMSkillsDeployerService(LoggerMixin):
|
|
|
610
613
|
missing_skills=missing_skills,
|
|
611
614
|
outdated_skills=outdated_skills,
|
|
612
615
|
message=message,
|
|
616
|
+
skill_count=len(deployed_skills),
|
|
613
617
|
)
|
|
614
618
|
|
|
615
619
|
def get_deployed_skills(self, project_dir: Path) -> List[PMSkillInfo]:
|
|
@@ -991,12 +991,17 @@ class GitSkillSourceManager:
|
|
|
991
991
|
progress_callback=None,
|
|
992
992
|
skill_filter: Optional[Set[str]] = None,
|
|
993
993
|
) -> Dict[str, Any]:
|
|
994
|
-
"""Deploy skills from cache to target directory with flat structure.
|
|
994
|
+
"""Deploy skills from cache to target directory with flat structure and automatic cleanup.
|
|
995
995
|
|
|
996
996
|
Flattens nested Git repository structure into Claude Code compatible
|
|
997
997
|
flat directory structure. Each skill directory is copied with a
|
|
998
998
|
hyphen-separated name derived from its path.
|
|
999
999
|
|
|
1000
|
+
CRITICAL: When skill_filter is provided (agent-referenced skills), this function:
|
|
1001
|
+
1. Deploys ONLY the filtered skills
|
|
1002
|
+
2. REMOVES orphaned skills (deployed but not in filter)
|
|
1003
|
+
3. Returns removed_count and removed_skills in result
|
|
1004
|
+
|
|
1000
1005
|
Transformation Example:
|
|
1001
1006
|
Cache: collaboration/dispatching-parallel-agents/SKILL.md
|
|
1002
1007
|
Deploy: collaboration-dispatching-parallel-agents/SKILL.md
|
|
@@ -1006,8 +1011,8 @@ class GitSkillSourceManager:
|
|
|
1006
1011
|
force: Overwrite existing skills
|
|
1007
1012
|
progress_callback: Optional callback(increment: int) called for each skill deployed
|
|
1008
1013
|
skill_filter: Optional set of skill names to deploy (selective deployment).
|
|
1009
|
-
If None, deploys
|
|
1010
|
-
|
|
1014
|
+
If None, deploys ALL skills WITHOUT cleanup.
|
|
1015
|
+
If provided, deploys ONLY filtered skills AND removes orphans.
|
|
1011
1016
|
|
|
1012
1017
|
Returns:
|
|
1013
1018
|
Dict with deployment results:
|
|
@@ -1018,7 +1023,9 @@ class GitSkillSourceManager:
|
|
|
1018
1023
|
"deployed_skills": List[str],
|
|
1019
1024
|
"skipped_skills": List[str],
|
|
1020
1025
|
"errors": List[str],
|
|
1021
|
-
"filtered_count": int # Number of skills filtered out
|
|
1026
|
+
"filtered_count": int, # Number of skills filtered out
|
|
1027
|
+
"removed_count": int, # Number of orphaned skills removed
|
|
1028
|
+
"removed_skills": List[str] # Names of removed orphaned skills
|
|
1022
1029
|
}
|
|
1023
1030
|
|
|
1024
1031
|
Example:
|
|
@@ -1026,10 +1033,10 @@ class GitSkillSourceManager:
|
|
|
1026
1033
|
>>> result = manager.deploy_skills()
|
|
1027
1034
|
>>> print(f"Deployed {result['deployed_count']} skills")
|
|
1028
1035
|
|
|
1029
|
-
# Selective deployment based on agent requirements:
|
|
1036
|
+
# Selective deployment based on agent requirements (with cleanup):
|
|
1030
1037
|
>>> required = {"typescript-core", "react-patterns"}
|
|
1031
1038
|
>>> result = manager.deploy_skills(skill_filter=required)
|
|
1032
|
-
>>> print(f"Deployed {result['deployed_count']}
|
|
1039
|
+
>>> print(f"Deployed {result['deployed_count']}, removed {result['removed_count']} orphans")
|
|
1033
1040
|
"""
|
|
1034
1041
|
if target_dir is None:
|
|
1035
1042
|
target_dir = Path.home() / ".claude" / "skills"
|
|
@@ -1040,6 +1047,7 @@ class GitSkillSourceManager:
|
|
|
1040
1047
|
skipped = []
|
|
1041
1048
|
errors = []
|
|
1042
1049
|
filtered_count = 0
|
|
1050
|
+
removed_skills = [] # Track removed orphaned skills
|
|
1043
1051
|
|
|
1044
1052
|
# Get all skills from all sources
|
|
1045
1053
|
all_skills = self.get_all_skills()
|
|
@@ -1082,11 +1090,16 @@ class GitSkillSourceManager:
|
|
|
1082
1090
|
)
|
|
1083
1091
|
|
|
1084
1092
|
# Cleanup: Remove skills from target directory that aren't in the filtered set
|
|
1085
|
-
# This ensures only
|
|
1093
|
+
# This ensures only agent-referenced skills remain deployed
|
|
1086
1094
|
removed_skills = self._cleanup_unfiltered_skills(target_dir, all_skills)
|
|
1087
1095
|
if removed_skills:
|
|
1088
1096
|
self.logger.info(
|
|
1089
|
-
f"Removed {len(removed_skills)} skills not
|
|
1097
|
+
f"Removed {len(removed_skills)} orphaned skills not referenced by agents: {removed_skills[:10]}"
|
|
1098
|
+
+ (
|
|
1099
|
+
f" (and {len(removed_skills) - 10} more)"
|
|
1100
|
+
if len(removed_skills) > 10
|
|
1101
|
+
else ""
|
|
1102
|
+
)
|
|
1090
1103
|
)
|
|
1091
1104
|
|
|
1092
1105
|
self.logger.info(
|
|
@@ -1130,6 +1143,7 @@ class GitSkillSourceManager:
|
|
|
1130
1143
|
self.logger.info(
|
|
1131
1144
|
f"Deployment complete: {len(deployed)} deployed, "
|
|
1132
1145
|
f"{len(skipped)} skipped, {len(errors)} errors"
|
|
1146
|
+
+ (f", {len(removed_skills)} removed" if removed_skills else "")
|
|
1133
1147
|
)
|
|
1134
1148
|
|
|
1135
1149
|
return {
|
|
@@ -1140,6 +1154,8 @@ class GitSkillSourceManager:
|
|
|
1140
1154
|
"skipped_skills": skipped,
|
|
1141
1155
|
"errors": errors,
|
|
1142
1156
|
"filtered_count": filtered_count,
|
|
1157
|
+
"removed_count": len(removed_skills),
|
|
1158
|
+
"removed_skills": removed_skills,
|
|
1143
1159
|
}
|
|
1144
1160
|
|
|
1145
1161
|
def _cleanup_unfiltered_skills(
|
|
@@ -44,13 +44,56 @@ from typing import Any, Dict, List, Set, Tuple
|
|
|
44
44
|
import yaml
|
|
45
45
|
|
|
46
46
|
from claude_mpm.core.logging_config import get_logger
|
|
47
|
-
from claude_mpm.services.skills.skill_to_agent_mapper import SkillToAgentMapper
|
|
48
47
|
|
|
49
48
|
logger = get_logger(__name__)
|
|
50
49
|
|
|
51
50
|
# Deployment tracking index file
|
|
52
51
|
DEPLOYED_INDEX_FILE = ".mpm-deployed-skills.json"
|
|
53
52
|
|
|
53
|
+
# Core skills that are universally useful across all projects
|
|
54
|
+
# These are deployed when skill mapping returns too many skills (>60)
|
|
55
|
+
# Target: ~25-30 core skills for balanced functionality
|
|
56
|
+
CORE_SKILLS = {
|
|
57
|
+
# Universal debugging and verification (4 skills)
|
|
58
|
+
"universal-debugging-systematic-debugging",
|
|
59
|
+
"universal-debugging-verification-before-completion",
|
|
60
|
+
"universal-verification-pre-merge",
|
|
61
|
+
"universal-verification-screenshot",
|
|
62
|
+
# Universal testing patterns (2 skills)
|
|
63
|
+
"universal-testing-test-driven-development",
|
|
64
|
+
"universal-testing-testing-anti-patterns",
|
|
65
|
+
# Universal architecture and design (1 skill)
|
|
66
|
+
"universal-architecture-software-patterns",
|
|
67
|
+
# Universal infrastructure (3 skills)
|
|
68
|
+
"universal-infrastructure-env-manager",
|
|
69
|
+
"universal-infrastructure-docker",
|
|
70
|
+
"universal-infrastructure-github-actions",
|
|
71
|
+
# Universal collaboration (1 skill)
|
|
72
|
+
"universal-collaboration-stacked-prs",
|
|
73
|
+
# Universal emergency/operations (1 skill)
|
|
74
|
+
"toolchains-universal-emergency-release",
|
|
75
|
+
"toolchains-universal-dependency-audit",
|
|
76
|
+
# Common language toolchains (6 skills)
|
|
77
|
+
"toolchains-typescript-core",
|
|
78
|
+
"toolchains-python-core",
|
|
79
|
+
"toolchains-javascript-tooling-biome",
|
|
80
|
+
"toolchains-python-tooling-mypy",
|
|
81
|
+
"toolchains-typescript-testing-vitest",
|
|
82
|
+
"toolchains-python-frameworks-flask",
|
|
83
|
+
# Common web frameworks (4 skills)
|
|
84
|
+
"toolchains-javascript-frameworks-nextjs",
|
|
85
|
+
"toolchains-nextjs-core",
|
|
86
|
+
"toolchains-typescript-frameworks-nodejs-backend",
|
|
87
|
+
"toolchains-javascript-frameworks-react-state-machine",
|
|
88
|
+
# Common testing tools (2 skills)
|
|
89
|
+
"toolchains-javascript-testing-playwright",
|
|
90
|
+
"toolchains-typescript-testing-jest",
|
|
91
|
+
# Common data/UI tools (3 skills)
|
|
92
|
+
"universal-data-xlsx",
|
|
93
|
+
"toolchains-ui-styling-tailwind",
|
|
94
|
+
"toolchains-ui-components-headlessui",
|
|
95
|
+
}
|
|
96
|
+
|
|
54
97
|
|
|
55
98
|
def parse_agent_frontmatter(agent_file: Path) -> Dict[str, Any]:
|
|
56
99
|
"""Parse YAML frontmatter from agent markdown file.
|
|
@@ -140,22 +183,14 @@ def get_skills_from_agent(frontmatter: Dict[str, Any]) -> Set[str]:
|
|
|
140
183
|
def get_skills_from_mapping(agent_ids: List[str]) -> Set[str]:
|
|
141
184
|
"""Get skills for agents using SkillToAgentMapper inference.
|
|
142
185
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
CRITICAL DESIGN DECISION: This function ONLY returns skills for the DEPLOYED agents
|
|
147
|
-
provided in agent_ids. It does NOT return skills for all agents in the mapping
|
|
148
|
-
configuration (skill_to_agent_mapping.yaml lists 41 agents, but only 33 may be deployed).
|
|
186
|
+
DEPRECATED: This function is deprecated as of Phase 3 refactor.
|
|
187
|
+
Skills are now declared exclusively in agent frontmatter.
|
|
149
188
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
specialized agents exist, we skip "engineer" if specialized agents are present.
|
|
189
|
+
The static skill_to_agent_mapping.yaml is no longer used for skill deployment.
|
|
190
|
+
Each agent must declare its skills in frontmatter or it gets zero skills.
|
|
153
191
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
- User may only have 33 agents deployed in ~/.claude/agents/
|
|
157
|
-
- Without filtering, we'd deploy skills for all 41 agents (over-deployment)
|
|
158
|
-
- Solution: Only query skills for DEPLOYED agents (passed in agent_ids)
|
|
192
|
+
This function remains for backward compatibility but is NO LONGER CALLED
|
|
193
|
+
by get_required_skills_from_agents().
|
|
159
194
|
|
|
160
195
|
Args:
|
|
161
196
|
agent_ids: List of DEPLOYED agent identifiers (e.g., ["python-engineer", "typescript-engineer"])
|
|
@@ -163,67 +198,34 @@ def get_skills_from_mapping(agent_ids: List[str]) -> Set[str]:
|
|
|
163
198
|
|
|
164
199
|
Returns:
|
|
165
200
|
Set of unique skill names inferred from mapping configuration for DEPLOYED agents only
|
|
201
|
+
NOTE: This is now an empty set as the function is deprecated.
|
|
166
202
|
|
|
167
203
|
Example:
|
|
168
|
-
>>> #
|
|
204
|
+
>>> # DEPRECATED - use frontmatter instead
|
|
169
205
|
>>> deployed_agent_ids = ["python-engineer", "typescript-engineer", "qa"]
|
|
170
|
-
>>> skills = get_skills_from_mapping(deployed_agent_ids)
|
|
171
|
-
>>> print(f"Found {len(skills)} skills for {len(deployed_agent_ids)} deployed agents")
|
|
206
|
+
>>> skills = get_skills_from_mapping(deployed_agent_ids) # Returns empty set
|
|
172
207
|
"""
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
# agents like "python-engineer", "typescript-engineer", etc.
|
|
181
|
-
#
|
|
182
|
-
# Solution: Filter out "engineer" from agent_ids if specialized agents exist
|
|
183
|
-
specialized_engineers = [
|
|
184
|
-
aid for aid in agent_ids if aid.endswith("-engineer") and aid != "engineer"
|
|
185
|
-
]
|
|
186
|
-
|
|
187
|
-
# If specialized engineers exist, exclude generic "engineer" from skill mapping
|
|
188
|
-
# This prevents deploying 100+ skills when only a subset is needed
|
|
189
|
-
agents_to_query = agent_ids
|
|
190
|
-
if specialized_engineers and "engineer" in agent_ids:
|
|
191
|
-
agents_to_query = [aid for aid in agent_ids if aid != "engineer"]
|
|
192
|
-
logger.info(
|
|
193
|
-
f"Excluding generic 'engineer' agent from skill mapping "
|
|
194
|
-
f"(found {len(specialized_engineers)} specialized engineers: "
|
|
195
|
-
f"{', '.join(specialized_engineers[:5])}{'...' if len(specialized_engineers) > 5 else ''})"
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
# IMPORTANT: Only query skills for DEPLOYED agents (those in agent_ids)
|
|
199
|
-
# Do NOT query all agents from skill_to_agent_mapping.yaml (that's 41 agents)
|
|
200
|
-
for agent_id in agents_to_query:
|
|
201
|
-
agent_skills = mapper.get_skills_for_agent(agent_id)
|
|
202
|
-
if agent_skills:
|
|
203
|
-
all_skills.update(agent_skills)
|
|
204
|
-
logger.debug(f"Mapped {len(agent_skills)} skills to {agent_id}")
|
|
205
|
-
|
|
206
|
-
logger.info(
|
|
207
|
-
f"Mapped {len(all_skills)} unique skills for {len(agents_to_query)} deployed agents "
|
|
208
|
-
f"(out of {len(agent_ids)} total deployed, excluding generic 'engineer' if specialized exist)"
|
|
209
|
-
)
|
|
210
|
-
return all_skills
|
|
211
|
-
|
|
212
|
-
except Exception as e:
|
|
213
|
-
logger.warning(f"Failed to load SkillToAgentMapper: {e}")
|
|
214
|
-
logger.info("Falling back to frontmatter-only skill discovery")
|
|
215
|
-
return set()
|
|
208
|
+
# DEPRECATED: Return empty set
|
|
209
|
+
logger.warning(
|
|
210
|
+
"get_skills_from_mapping() is DEPRECATED and returns empty set. "
|
|
211
|
+
"Skills are now declared in agent frontmatter only. "
|
|
212
|
+
"Update your agents with 'skills:' field in frontmatter."
|
|
213
|
+
)
|
|
214
|
+
return set()
|
|
216
215
|
|
|
217
216
|
|
|
218
217
|
def get_required_skills_from_agents(agents_dir: Path) -> Set[str]:
|
|
219
218
|
"""Extract all skills referenced by deployed agents.
|
|
220
219
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
220
|
+
MAJOR CHANGE (Phase 3): Now ONLY uses frontmatter-declared skills.
|
|
221
|
+
The static skill_to_agent_mapping.yaml is DEPRECATED. Each agent must
|
|
222
|
+
declare its skills in frontmatter or it gets zero skills deployed.
|
|
224
223
|
|
|
225
|
-
This
|
|
226
|
-
|
|
224
|
+
This change:
|
|
225
|
+
- Eliminates dual-source complexity (frontmatter + mapping)
|
|
226
|
+
- Makes skill requirements explicit per agent
|
|
227
|
+
- Enables per-agent customization via frontmatter
|
|
228
|
+
- Removes dependency on static YAML mapping
|
|
227
229
|
|
|
228
230
|
Args:
|
|
229
231
|
agents_dir: Path to deployed agents directory (e.g., .claude/agents/)
|
|
@@ -244,13 +246,11 @@ def get_required_skills_from_agents(agents_dir: Path) -> Set[str]:
|
|
|
244
246
|
agent_files = list(agents_dir.glob("*.md"))
|
|
245
247
|
logger.debug(f"Scanning {len(agent_files)} agent files in {agents_dir}")
|
|
246
248
|
|
|
247
|
-
#
|
|
249
|
+
# ONLY use frontmatter skills - no more mapping inference
|
|
248
250
|
frontmatter_skills = set()
|
|
249
|
-
agent_ids = []
|
|
250
251
|
|
|
251
252
|
for agent_file in agent_files:
|
|
252
253
|
agent_id = agent_file.stem
|
|
253
|
-
agent_ids.append(agent_id)
|
|
254
254
|
|
|
255
255
|
frontmatter = parse_agent_frontmatter(agent_file)
|
|
256
256
|
agent_skills = get_skills_from_agent(frontmatter)
|
|
@@ -260,24 +260,23 @@ def get_required_skills_from_agents(agents_dir: Path) -> Set[str]:
|
|
|
260
260
|
logger.debug(
|
|
261
261
|
f"Agent {agent_id}: {len(agent_skills)} skills from frontmatter"
|
|
262
262
|
)
|
|
263
|
+
else:
|
|
264
|
+
logger.debug(f"Agent {agent_id}: No skills declared in frontmatter")
|
|
263
265
|
|
|
264
|
-
logger.info(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
# Combine both sources
|
|
270
|
-
required_skills = frontmatter_skills | mapped_skills
|
|
266
|
+
logger.info(
|
|
267
|
+
f"Found {len(frontmatter_skills)} unique skills from agent frontmatter "
|
|
268
|
+
f"(static mapping no longer used)"
|
|
269
|
+
)
|
|
271
270
|
|
|
272
271
|
# Normalize skill paths: convert slashes to dashes for compatibility with deployment
|
|
273
|
-
#
|
|
274
|
-
|
|
275
|
-
normalized_skills = {skill.replace("/", "-") for skill in required_skills}
|
|
272
|
+
# Some skills may use slash format, normalize to dashes
|
|
273
|
+
normalized_skills = {skill.replace("/", "-") for skill in frontmatter_skills}
|
|
276
274
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
275
|
+
if normalized_skills != frontmatter_skills:
|
|
276
|
+
logger.debug(
|
|
277
|
+
f"Normalized {len(frontmatter_skills)} skills to {len(normalized_skills)} "
|
|
278
|
+
"(converted slashes to dashes)"
|
|
279
|
+
)
|
|
281
280
|
|
|
282
281
|
return normalized_skills
|
|
283
282
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Brainstorming Ideas Into Designs
|
|
3
|
+
description: Interactive idea refinement using Socratic method to develop fully-formed designs
|
|
4
|
+
when_to_use: when partner describes any feature or project idea, before writing code or implementation plans
|
|
5
|
+
version: 2.2.0
|
|
6
|
+
progressive_disclosure:
|
|
7
|
+
level: 1
|
|
8
|
+
references: []
|
|
9
|
+
note: Already optimal at 75 lines - intentionally compact, no references needed
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Brainstorming Ideas Into Designs
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
Transform rough ideas into fully-formed designs through structured questioning and alternative exploration.
|
|
17
|
+
|
|
18
|
+
**Core principle:** Ask questions to understand, explore alternatives, present design incrementally for validation.
|
|
19
|
+
|
|
20
|
+
**Announce at start:** "I'm using the Brainstorming skill to refine your idea into a design."
|
|
21
|
+
|
|
22
|
+
## The Process
|
|
23
|
+
|
|
24
|
+
### Phase 1: Understanding
|
|
25
|
+
- Check current project state in working directory
|
|
26
|
+
- Ask ONE question at a time to refine the idea
|
|
27
|
+
- Prefer multiple choice when possible
|
|
28
|
+
- Gather: Purpose, constraints, success criteria
|
|
29
|
+
|
|
30
|
+
### Phase 2: Exploration
|
|
31
|
+
- Propose 2-3 different approaches
|
|
32
|
+
- For each: Core architecture, trade-offs, complexity assessment
|
|
33
|
+
- Ask your human partner which approach resonates
|
|
34
|
+
|
|
35
|
+
### Phase 3: Design Presentation
|
|
36
|
+
- Present in 200-300 word sections
|
|
37
|
+
- Cover: Architecture, components, data flow, error handling, testing
|
|
38
|
+
- Ask after each section: "Does this look right so far?"
|
|
39
|
+
|
|
40
|
+
### Phase 4: Worktree Setup (for implementation)
|
|
41
|
+
When design is approved and implementation will follow:
|
|
42
|
+
- Announce: "I'm using the Using Git Worktrees skill to set up an isolated workspace."
|
|
43
|
+
- Switch to skills/collaboration/using-git-worktrees
|
|
44
|
+
- Follow that skill's process for directory selection, safety verification, and setup
|
|
45
|
+
- Return here when worktree ready
|
|
46
|
+
|
|
47
|
+
### Phase 5: Planning Handoff
|
|
48
|
+
Ask: "Ready to create the implementation plan?"
|
|
49
|
+
|
|
50
|
+
When your human partner confirms (any affirmative response):
|
|
51
|
+
- Announce: "I'm using the Writing Plans skill to create the implementation plan."
|
|
52
|
+
- Switch to skills/collaboration/writing-plans skill
|
|
53
|
+
- Create detailed plan in the worktree
|
|
54
|
+
|
|
55
|
+
## When to Revisit Earlier Phases
|
|
56
|
+
|
|
57
|
+
**You can and should go backward when:**
|
|
58
|
+
- Partner reveals new constraint during Phase 2 or 3 → Return to Phase 1 to understand it
|
|
59
|
+
- Validation shows fundamental gap in requirements → Return to Phase 1
|
|
60
|
+
- Partner questions approach during Phase 3 → Return to Phase 2 to explore alternatives
|
|
61
|
+
- Something doesn't make sense → Go back and clarify
|
|
62
|
+
|
|
63
|
+
**Don't force forward linearly** when going backward would give better results.
|
|
64
|
+
|
|
65
|
+
## Related Skills
|
|
66
|
+
|
|
67
|
+
**During exploration:**
|
|
68
|
+
- When approaches have genuine trade-offs: skills/architecture/preserving-productive-tensions
|
|
69
|
+
|
|
70
|
+
**Before proposing changes to existing code:**
|
|
71
|
+
- Understand why it exists: skills/research/tracing-knowledge-lineages
|
|
72
|
+
|
|
73
|
+
## Remember
|
|
74
|
+
- One question per message during Phase 1
|
|
75
|
+
- Apply YAGNI ruthlessly
|
|
76
|
+
- Explore 2-3 alternatives before settling
|
|
77
|
+
- Present incrementally, validate as you go
|
|
78
|
+
- Go backward when needed - flexibility > rigid progression
|
|
79
|
+
- Announce skill usage at start
|