|
-- ๐ [**Quick Start Guide**](Docs/Getting-Started/quick-start.md)
+- ๐ [**Quick Start Guide**](docs/Getting-Started/quick-start.md)
*Get up and running fast*
-- ๐พ [**Installation Guide**](Docs/Getting-Started/installation.md)
+- ๐พ [**Installation Guide**](docs/Getting-Started/installation.md)
*Detailed setup instructions*
|
-- ๐ฏ [**Commands Reference**](Docs/User-Guide/commands.md)
+- ๐ฏ [**Commands Reference**](docs/User-Guide/commands.md)
*All 25 slash commands*
-- ๐ค [**Agents Guide**](Docs/User-Guide/agents.md)
+- ๐ค [**Agents Guide**](docs/User-Guide/agents.md)
*15 specialized agents*
-- ๐จ [**Behavioral Modes**](Docs/User-Guide/modes.md)
+- ๐จ [**Behavioral Modes**](docs/User-Guide/modes.md)
*7 adaptive modes*
-- ๐ฉ [**Flags Guide**](Docs/User-Guide/flags.md)
+- ๐ฉ [**Flags Guide**](docs/User-Guide/flags.md)
*Control behaviors*
-- ๐ง [**MCP Servers**](Docs/User-Guide/mcp-servers.md)
+- ๐ง [**MCP Servers**](docs/User-Guide/mcp-servers.md)
*7 server integrations*
-- ๐ผ [**Session Management**](Docs/User-Guide/session-management.md)
+- ๐ผ [**Session Management**](docs/User-Guide/session-management.md)
*Save & restore state*
|
-- ๐๏ธ [**Technical Architecture**](Docs/Developer-Guide/technical-architecture.md)
+- ๐๏ธ [**Technical Architecture**](docs/Developer-Guide/technical-architecture.md)
*System design details*
-- ๐ป [**Contributing Code**](Docs/Developer-Guide/contributing-code.md)
+- ๐ป [**Contributing Code**](docs/Developer-Guide/contributing-code.md)
*Development workflow*
-- ๐งช [**Testing & Debugging**](Docs/Developer-Guide/testing-debugging.md)
+- ๐งช [**Testing & Debugging**](docs/Developer-Guide/testing-debugging.md)
*Quality assurance*
|
-- ๐ [**Examples Cookbook**](Docs/Reference/examples-cookbook.md)
+- ๐ [**Examples Cookbook**](docs/Reference/examples-cookbook.md)
*Real-world recipes*
-- ๐ [**Troubleshooting**](Docs/Reference/troubleshooting.md)
+- ๐ [**Troubleshooting**](docs/Reference/troubleshooting.md)
*Common issues & fixes*
|
diff --git a/SECURITY.md b/SECURITY.md
index ecd5caf..9439983 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -631,7 +631,7 @@ For critical vulnerabilities requiring immediate attention:
**General Security Questions:**
- **GitHub Discussions**: https://github.com/SuperClaude-Org/SuperClaude_Framework/discussions
- **Community Forums**: Security-focused discussion threads
-- **Documentation**: [Security Best Practices](Docs/Reference/quick-start-practices.md#security-practices)
+- **Documentation**: [Security Best Practices](docs/Reference/quick-start-practices.md#security-practices)
- **Issue Tracker**: Non-sensitive security configuration questions
**Technical Security Support:**
@@ -663,25 +663,25 @@ For organizations requiring dedicated security support:
### Security-Related Documentation
**Framework Security Documentation:**
-- [Quick Start Practices Guide](Docs/Reference/quick-start-practices.md) - Security-focused usage patterns
-- [Technical Architecture](Docs/Developer-Guide/technical-architecture.md) - Security design principles
-- [Contributing Code Guide](Docs/Developer-Guide/contributing-code.md) - Secure development practices
-- [Testing & Debugging Guide](Docs/Developer-Guide/testing-debugging.md) - Security testing procedures
+- [Quick Start Practices Guide](docs/Reference/quick-start-practices.md) - Security-focused usage patterns
+- [Technical Architecture](docs/Developer-Guide/technical-architecture.md) - Security design principles
+- [Contributing Code Guide](docs/Developer-Guide/contributing-code.md) - Secure development practices
+- [Testing & Debugging Guide](docs/Developer-Guide/testing-debugging.md) - Security testing procedures
**MCP Server Security:**
-- [MCP Servers Guide](Docs/User-Guide/mcp-servers.md) - Server security configuration
-- [Troubleshooting Guide](Docs/Reference/troubleshooting.md) - Security-related issue resolution
+- [MCP Servers Guide](docs/User-Guide/mcp-servers.md) - Server security configuration
+- [Troubleshooting Guide](docs/Reference/troubleshooting.md) - Security-related issue resolution
- MCP Server Documentation - Individual server security considerations
- Configuration Security - Secure MCP setup and credential management
**Agent Security:**
-- [Agents Guide](Docs/User-Guide/agents.md) - Agent security boundaries and coordination
+- [Agents Guide](docs/User-Guide/agents.md) - Agent security boundaries and coordination
- Agent Development - Security considerations for agent implementation
- Behavioral Modes - Security implications of different operational modes
- Command Security - Security aspects of command execution and validation
**Session Management Security:**
-- [Session Management Guide](Docs/User-Guide/session-management.md) - Secure session handling
+- [Session Management Guide](docs/User-Guide/session-management.md) - Secure session handling
- Memory Security - Secure handling of persistent session data
- Project Isolation - Security boundaries between different projects
- Context Security - Secure context loading and validation
diff --git a/SuperClaude/Commands/pm.md b/SuperClaude/Commands/pm.md
deleted file mode 100644
index 3c52e66..0000000
--- a/SuperClaude/Commands/pm.md
+++ /dev/null
@@ -1,291 +0,0 @@
----
-name: pm
-description: "Project Manager Agent - Default orchestration agent that coordinates all sub-agents and manages workflows seamlessly"
-category: orchestration
-complexity: meta
-mcp-servers: [sequential, context7, magic, playwright, morphllm, serena, tavily, chrome-devtools]
-personas: [pm-agent]
----
-
-# /sc:pm - Project Manager Agent
-
-> **Default Orchestration Mode**: PM Agent is the default entry point for all user interactions. It automatically delegates to appropriate specialist agents based on task analysis without requiring manual agent selection.
-
-## Triggers
-- **Auto-Activation**: All user requests default to PM Agent unless explicit sub-agent override
-- Vague project requests: "ไฝใใใ", "ๅฎ่ฃ
ใใใ", "ใฉใใใใฐ"
-- Multi-domain tasks requiring cross-functional coordination
-- Ambiguous requirements needing discovery before implementation
-- Complex projects requiring systematic planning and execution
-
-## Context Trigger Pattern
-```
-# Default (no command needed - PM Agent handles all interactions)
-"Build authentication system for my app"
-
-# Explicit PM Agent invocation (optional)
-/sc:pm [request] [--strategy brainstorm|direct|wave] [--verbose]
-
-# Override to specific sub-agent (optional)
-/sc:implement "user profile" --agent backend
-```
-
-## Behavioral Flow
-1. **Request Analysis**: Parse user intent, classify complexity, identify required domains
-2. **Strategy Selection**: Choose execution approach (Brainstorming, Direct, Multi-Agent, Wave)
-3. **Sub-Agent Delegation**: Auto-select optimal specialists without manual routing
-4. **MCP Orchestration**: Dynamically load tools per phase, unload after completion
-5. **Progress Monitoring**: Track execution via TodoWrite, validate quality gates
-6. **Self-Improvement**: Document continuously (implementations, mistakes, patterns)
-
-Key behaviors:
-- **Seamless Orchestration**: Users interact only with PM Agent, sub-agents work transparently
-- **Auto-Delegation**: Intelligent routing to domain specialists based on task analysis
-- **Zero-Token Efficiency**: Dynamic MCP tool loading via Docker Gateway integration
-- **Self-Documenting**: Automatic knowledge capture in project docs and CLAUDE.md
-
-## MCP Integration (Docker Gateway Pattern)
-
-### Zero-Token Baseline
-- **Start**: No MCP tools loaded (gateway URL only)
-- **Load**: On-demand tool activation per execution phase
-- **Unload**: Tool removal after phase completion
-- **Cache**: Strategic tool retention for sequential phases
-
-### Phase-Based Tool Loading
-```yaml
-Discovery Phase:
- Load: [sequential, context7]
- Execute: Requirements analysis, pattern research
- Unload: After requirements complete
-
-Design Phase:
- Load: [sequential, magic]
- Execute: Architecture planning, UI mockups
- Unload: After design approval
-
-Implementation Phase:
- Load: [context7, magic, morphllm]
- Execute: Code generation, bulk transformations
- Unload: After implementation complete
-
-Testing Phase:
- Load: [playwright, sequential]
- Execute: E2E testing, quality validation
- Unload: After tests pass
-```
-
-## Sub-Agent Orchestration Patterns
-
-### Vague Feature Request Pattern
-```
-User: "ใขใใชใซ่ช่จผๆฉ่ฝไฝใใใ"
-
-PM Agent Workflow:
- 1. Activate Brainstorming Mode
- โ Socratic questioning to discover requirements
- 2. Delegate to requirements-analyst
- โ Create formal PRD with acceptance criteria
- 3. Delegate to system-architect
- โ Architecture design (JWT, OAuth, Supabase Auth)
- 4. Delegate to security-engineer
- โ Threat modeling, security patterns
- 5. Delegate to backend-architect
- โ Implement authentication middleware
- 6. Delegate to quality-engineer
- โ Security testing, integration tests
- 7. Delegate to technical-writer
- โ Documentation, update CLAUDE.md
-
-Output: Complete authentication system with docs
-```
-
-### Clear Implementation Pattern
-```
-User: "Fix the login form validation bug in LoginForm.tsx:45"
-
-PM Agent Workflow:
- 1. Load: [context7] for validation patterns
- 2. Analyze: Read LoginForm.tsx, identify root cause
- 3. Delegate to refactoring-expert
- โ Fix validation logic, add missing tests
- 4. Delegate to quality-engineer
- โ Validate fix, run regression tests
- 5. Document: Update self-improvement-workflow.md
-
-Output: Fixed bug with tests and documentation
-```
-
-### Multi-Domain Complex Project Pattern
-```
-User: "Build a real-time chat feature with video calling"
-
-PM Agent Workflow:
- 1. Delegate to requirements-analyst
- โ User stories, acceptance criteria
- 2. Delegate to system-architect
- โ Architecture (Supabase Realtime, WebRTC)
- 3. Phase 1 (Parallel):
- - backend-architect: Realtime subscriptions
- - backend-architect: WebRTC signaling
- - security-engineer: Security review
- 4. Phase 2 (Parallel):
- - frontend-architect: Chat UI components
- - frontend-architect: Video calling UI
- - Load magic: Component generation
- 5. Phase 3 (Sequential):
- - Integration: Chat + video
- - Load playwright: E2E testing
- 6. Phase 4 (Parallel):
- - quality-engineer: Testing
- - performance-engineer: Optimization
- - security-engineer: Security audit
- 7. Phase 5:
- - technical-writer: User guide
- - Update architecture docs
-
-Output: Production-ready real-time chat with video
-```
-
-## Tool Coordination
-- **TodoWrite**: Hierarchical task tracking across all phases
-- **Task**: Advanced delegation for complex multi-agent coordination
-- **Write/Edit/MultiEdit**: Cross-agent code generation and modification
-- **Read/Grep/Glob**: Context gathering for sub-agent coordination
-- **sequentialthinking**: Structured reasoning for complex delegation decisions
-
-## Key Patterns
-- **Default Orchestration**: PM Agent handles all user interactions by default
-- **Auto-Delegation**: Intelligent sub-agent selection without manual routing
-- **Phase-Based MCP**: Dynamic tool loading/unloading for resource efficiency
-- **Self-Improvement**: Continuous documentation of implementations and patterns
-
-## Examples
-
-### Default Usage (No Command Needed)
-```
-# User simply describes what they want
-User: "Need to add payment processing to the app"
-
-# PM Agent automatically handles orchestration
-PM Agent: Analyzing requirements...
- โ Delegating to requirements-analyst for specification
- โ Coordinating backend-architect + security-engineer
- โ Engaging payment processing implementation
- โ Quality validation with testing
- โ Documentation update
-
-Output: Complete payment system implementation
-```
-
-### Explicit Strategy Selection
-```
-/sc:pm "Improve application security" --strategy wave
-
-# Wave mode for large-scale security audit
-PM Agent: Initiating comprehensive security analysis...
- โ Wave 1: Security engineer audits (authentication, authorization)
- โ Wave 2: Backend architect reviews (API security, data validation)
- โ Wave 3: Quality engineer tests (penetration testing, vulnerability scanning)
- โ Wave 4: Documentation (security policies, incident response)
-
-Output: Comprehensive security improvements with documentation
-```
-
-### Brainstorming Mode
-```
-User: "Maybe we could improve the user experience?"
-
-PM Agent: Activating Brainstorming Mode...
- ๐ค Discovery Questions:
- - What specific UX challenges are users facing?
- - Which workflows are most problematic?
- - Have you gathered user feedback or analytics?
- - What are your improvement priorities?
-
- ๐ Brief: [Generate structured improvement plan]
-
-Output: Clear UX improvement roadmap with priorities
-```
-
-### Manual Sub-Agent Override (Optional)
-```
-# User can still specify sub-agents directly if desired
-/sc:implement "responsive navbar" --agent frontend
-
-# PM Agent delegates to specified agent
-PM Agent: Routing to frontend-architect...
- โ Frontend specialist handles implementation
- โ PM Agent monitors progress and quality gates
-
-Output: Frontend-optimized implementation
-```
-
-## Self-Improvement Integration
-
-### Implementation Documentation
-```yaml
-After each successful implementation:
- - Update docs/ with new patterns discovered
- - Document architecture decisions in ADR format
- - Add working examples to project documentation
- - Update CLAUDE.md with new best practices
-```
-
-### Mistake Recording
-```yaml
-When errors occur:
- - Capture error in self-improvement-workflow.md
- - Document root cause analysis
- - Create prevention checklist
- - Update anti-patterns documentation
-```
-
-### Monthly Maintenance
-```yaml
-Regular documentation health:
- - Remove outdated patterns and deprecated approaches
- - Merge duplicate documentation
- - Update version numbers and dependencies
- - Prune noise, keep essential knowledge
-```
-
-## Boundaries
-
-**Will:**
-- Orchestrate all user interactions and automatically delegate to appropriate specialists
-- Provide seamless experience without requiring manual agent selection
-- Dynamically load/unload MCP tools for resource efficiency
-- Continuously document implementations, mistakes, and patterns
-- Transparently report delegation decisions and progress
-
-**Will Not:**
-- Bypass quality gates or compromise standards for speed
-- Make unilateral technical decisions without appropriate sub-agent expertise
-- Execute without proper planning for complex multi-domain projects
-- Skip documentation or self-improvement recording steps
-
-**User Control:**
-- Default: PM Agent auto-delegates (seamless)
-- Override: Explicit `--agent [name]` for direct sub-agent access
-- Both options available simultaneously (no user downside)
-
-## Performance Optimization
-
-### Resource Efficiency
-- **Zero-Token Baseline**: Start with no MCP tools (gateway only)
-- **Dynamic Loading**: Load tools only when needed per phase
-- **Strategic Unloading**: Remove tools after phase completion
-- **Parallel Execution**: Concurrent sub-agent delegation when independent
-
-### Quality Assurance
-- **Domain Expertise**: Route to specialized agents for quality
-- **Cross-Validation**: Multiple agent perspectives for complex decisions
-- **Quality Gates**: Systematic validation at phase transitions
-- **User Feedback**: Incorporate user guidance throughout execution
-
-### Continuous Learning
-- **Pattern Recognition**: Identify recurring successful patterns
-- **Mistake Prevention**: Document errors with prevention checklist
-- **Documentation Pruning**: Monthly cleanup to remove noise
-- **Knowledge Synthesis**: Codify learnings in CLAUDE.md and docs/
diff --git a/bin/checkEnv.js b/bin/check_env.js
similarity index 100%
rename from bin/checkEnv.js
rename to bin/check_env.js
diff --git a/bin/checkUpdate.js b/bin/check_update.js
similarity index 100%
rename from bin/checkUpdate.js
rename to bin/check_update.js
diff --git a/bin/cli.js b/bin/cli.js
index 9d5bcb1..f46d39f 100644
--- a/bin/cli.js
+++ b/bin/cli.js
@@ -1,7 +1,7 @@
#!/usr/bin/env node
const { spawnSync } = require("child_process");
-const { detectPython, detectPip } = require("./checkEnv");
-const { checkAndNotify } = require("./checkUpdate");
+const { detectPython, detectPip } = require("./check_env");
+const { checkAndNotify } = require("./check_update");
let pythonCmd = detectPython();
if (!pythonCmd) {
diff --git a/bin/install.js b/bin/install.js
index e9b5253..fd73310 100644
--- a/bin/install.js
+++ b/bin/install.js
@@ -1,5 +1,5 @@
#!/usr/bin/env node
-const { run, detectPython, detectPip, detectPipx, isSuperClaudeInstalled, isSuperClaudeInstalledPipx, checkPythonEnvironment } = require("./checkEnv");
+const { run, detectPython, detectPip, detectPipx, isSuperClaudeInstalled, isSuperClaudeInstalledPipx, checkPythonEnvironment } = require("./check_env");
console.log("๐ Checking environment...");
diff --git a/bin/update.js b/bin/update.js
index 5d75143..7ac5496 100644
--- a/bin/update.js
+++ b/bin/update.js
@@ -1,5 +1,5 @@
#!/usr/bin/env node
-const { run, detectPip, detectPipx, isSuperClaudeInstalledPipx, checkPythonEnvironment } = require("./checkEnv");
+const { run, detectPip, detectPipx, isSuperClaudeInstalledPipx, checkPythonEnvironment } = require("./check_env");
console.log("๐ Checking for SuperClaude updates...");
diff --git a/Docs/Developer-Guide/README.md b/docs/Developer-Guide/README.md
similarity index 100%
rename from Docs/Developer-Guide/README.md
rename to docs/Developer-Guide/README.md
diff --git a/Docs/Developer-Guide/contributing-code.md b/docs/Developer-Guide/contributing-code.md
similarity index 98%
rename from Docs/Developer-Guide/contributing-code.md
rename to docs/Developer-Guide/contributing-code.md
index f8ae93d..d47603c 100644
--- a/Docs/Developer-Guide/contributing-code.md
+++ b/docs/Developer-Guide/contributing-code.md
@@ -57,14 +57,14 @@ SuperClaude is a **Context-Oriented Configuration Framework** - not executing so
```
SuperClaude_Framework/
-โโโ SuperClaude/ # Framework components (the source of truth)
+โโโ superclaude/ # Framework components (the source of truth)
โ โโโ Core/ # PRINCIPLES.md, RULES.md, FLAGS.md
โ โโโ Agents/ # 15 specialized domain experts
โ โโโ Commands/ # 21 context trigger patterns (/sc: behavioral instructions)
โ โโโ Modes/ # 6 behavioral modification patterns
โ โโโ MCP/ # 6 MCP server configurations
โโโ setup/ # Python installation system
-โโโ Docs/ # Documentation (what you're reading)
+โโโ docs/ # Documentation (what you're reading)
โโโ tests/ # File validation scripts
```
@@ -82,7 +82,7 @@ User Input โ Claude Code โ Reads SuperClaude Context โ Modified Behavior
```
1. User types `/sc:implement "auth system"` **in Claude Code conversation** (not terminal)
-2. Claude Code reads `SuperClaude/Commands/implement.md`
+2. Claude Code reads `superclaude/Commands/implement.md`
3. Command activates security-engineer agent context
4. Context7 MCP provides authentication patterns
5. Claude generates complete, secure implementation
@@ -208,7 +208,7 @@ Brief description of context file changes
**Agent Development Process:**
1. Identify domain expertise gap
-2. Create agent file in `SuperClaude/Agents/`
+2. Create agent file in `superclaude/Agents/`
3. Define triggers, behaviors, and boundaries
4. Test with various Claude Code scenarios
5. Document usage patterns and examples
diff --git a/Docs/Developer-Guide/documentation-index.md b/docs/Developer-Guide/documentation-index.md
similarity index 100%
rename from Docs/Developer-Guide/documentation-index.md
rename to docs/Developer-Guide/documentation-index.md
diff --git a/Docs/Developer-Guide/technical-architecture.md b/docs/Developer-Guide/technical-architecture.md
similarity index 100%
rename from Docs/Developer-Guide/technical-architecture.md
rename to docs/Developer-Guide/technical-architecture.md
diff --git a/Docs/Developer-Guide/testing-debugging.md b/docs/Developer-Guide/testing-debugging.md
similarity index 100%
rename from Docs/Developer-Guide/testing-debugging.md
rename to docs/Developer-Guide/testing-debugging.md
diff --git a/docs/Development/ARCHITECTURE.md b/docs/Development/ARCHITECTURE.md
new file mode 100644
index 0000000..2039eb6
--- /dev/null
+++ b/docs/Development/ARCHITECTURE.md
@@ -0,0 +1,529 @@
+# SuperClaude Architecture
+
+**Last Updated**: 2025-10-14
+**Version**: 4.1.5
+
+## ๐ Table of Contents
+
+1. [System Overview](#system-overview)
+2. [Core Architecture](#core-architecture)
+3. [PM Agent Mode: The Meta-Layer](#pm-agent-mode-the-meta-layer)
+4. [Component Relationships](#component-relationships)
+5. [Serena MCP Integration](#serena-mcp-integration)
+6. [PDCA Engine](#pdca-engine)
+7. [Data Flow](#data-flow)
+8. [Extension Points](#extension-points)
+
+---
+
+## System Overview
+
+### What is SuperClaude?
+
+SuperClaude is a **Context-Oriented Configuration Framework** that transforms Claude Code into a structured development platform. It is NOT standalone software with running processes - it is a collection of `.md` instruction files that Claude Code reads to adopt specialized behaviors.
+
+### Key Components
+
+```
+SuperClaude Framework
+โโโ Commands (26) โ Workflow patterns
+โโโ Agents (16) โ Domain expertise
+โโโ Modes (7) โ Behavioral modifiers
+โโโ MCP Servers (8) โ External tool integrations
+โโโ PM Agent Mode โ Meta-layer orchestration (Always-Active)
+```
+
+### Version Information
+
+- **Current Version**: 4.1.5
+- **Commands**: 26 slash commands (`/sc:*`)
+- **Agents**: 16 specialized domain experts
+- **Modes**: 7 behavioral modes
+- **MCP Servers**: 8 integrations (Context7, Sequential, Magic, Playwright, Morphllm, Serena, Tavily, Chrome DevTools)
+
+---
+
+## Core Architecture
+
+### Context-Oriented Configuration
+
+SuperClaude's architecture is built on a simple principle: **behavioral modification through structured context files**.
+
+```
+User Input
+ โ
+Context Loading (CLAUDE.md imports)
+ โ
+Command Detection (/sc:* pattern)
+ โ
+Agent Activation (manual or auto)
+ โ
+Mode Application (flags or triggers)
+ โ
+MCP Tool Coordination
+ โ
+Output Generation
+```
+
+### Directory Structure
+
+```
+~/.claude/
+โโโ CLAUDE.md # Main context with @imports
+โโโ FLAGS.md # Flag definitions
+โโโ RULES.md # Core behavioral rules
+โโโ PRINCIPLES.md # Guiding principles
+โโโ MODE_*.md # 7 behavioral modes
+โโโ MCP_*.md # 8 MCP server integrations
+โโโ agents/ # 16 specialized agents
+โ โโโ pm-agent.md # ๐ Meta-layer orchestrator
+โ โโโ backend-architect.md
+โ โโโ frontend-architect.md
+โ โโโ security-engineer.md
+โ โโโ ... (13 more)
+โโโ commands/sc/ # 26 workflow commands
+ โโโ pm.md # ๐ PM Agent command
+ โโโ implement.md
+ โโโ analyze.md
+ โโโ ... (23 more)
+```
+
+---
+
+## PM Agent Mode: The Meta-Layer
+
+### Position in Architecture
+
+PM Agent operates as a **meta-layer** above all other components:
+
+```
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ PM Agent Mode (Meta-Layer) โ
+โ โข Always Active (Session Start) โ
+โ โข Context Preservation โ
+โ โข PDCA Self-Evaluation โ
+โ โข Knowledge Management โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ Specialist Agents (16) โ
+โ backend-architect, security-engineer, etc. โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ Commands & Modes โ
+โ /sc:implement, /sc:analyze, etc. โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ MCP Tool Layer โ
+โ Context7, Sequential, Magic, etc. โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+```
+
+### PM Agent Responsibilities
+
+1. **Session Lifecycle Management**
+ - Auto-activation at session start
+ - Context restoration from Serena MCP memory
+ - User report generation (ๅๅ/้ฒๆ/ไปๅ/่ชฒ้ก)
+
+2. **PDCA Cycle Execution**
+ - Plan: Hypothesis generation
+ - Do: Experimentation with checkpoints
+ - Check: Self-evaluation
+ - Act: Knowledge extraction
+
+3. **Documentation Strategy**
+ - Temporary documentation (`docs/temp/`)
+ - Formal patterns (`docs/patterns/`)
+ - Mistake records (`docs/mistakes/`)
+ - Knowledge evolution to CLAUDE.md
+
+4. **Sub-Agent Orchestration**
+ - Auto-delegation to specialists
+ - Context coordination
+ - Quality gate validation
+ - Progress monitoring
+
+---
+
+## Component Relationships
+
+### Commands โ Agents โ Modes โ MCP
+
+```
+User: "/sc:implement authentication" --security
+ โ
+ [Command Layer]
+ commands/sc/implement.md
+ โ
+ [Agent Auto-Activation]
+ agents/security-engineer.md
+ agents/backend-architect.md
+ โ
+ [Mode Application]
+ MODE_Task_Management.md (TodoWrite)
+ โ
+ [MCP Tool Coordination]
+ Context7 (auth patterns)
+ Sequential (complex analysis)
+ โ
+ [PM Agent Meta-Layer]
+ Document learnings โ docs/patterns/
+```
+
+### Activation Flow
+
+1. **Explicit Command**: User types `/sc:implement`
+ - Loads `commands/sc/implement.md`
+ - Activates related agents (backend-architect, etc.)
+
+2. **Agent Activation**: `@agent-security` or auto-detected
+ - Loads agent expertise context
+ - May activate related MCP servers
+
+3. **Mode Application**: `--brainstorm` flag or keywords
+ - Modifies interaction style
+ - Enables specific behaviors
+
+4. **PM Agent Meta-Layer**: Always active
+ - Monitors all interactions
+ - Documents learnings
+ - Preserves context across sessions
+
+---
+
+## Serena MCP Integration
+
+### Memory Operations
+
+Serena MCP provides semantic code analysis and session persistence through memory operations:
+
+```
+Session Start:
+ PM Agent โ list_memories()
+ PM Agent โ read_memory("pm_context")
+ PM Agent โ read_memory("last_session")
+ PM Agent โ read_memory("next_actions")
+ PM Agent โ Report to User
+
+During Work (every 30min):
+ PM Agent โ write_memory("checkpoint", progress)
+ PM Agent โ write_memory("decision", rationale)
+
+Session End:
+ PM Agent โ write_memory("last_session", summary)
+ PM Agent โ write_memory("next_actions", todos)
+ PM Agent โ write_memory("pm_context", complete_state)
+```
+
+### Memory Structure
+
+```json
+{
+ "pm_context": {
+ "project": "SuperClaude_Framework",
+ "current_phase": "Phase 1: Documentation",
+ "active_tasks": ["ARCHITECTURE.md", "ROADMAP.md"],
+ "architecture": "Context-Oriented Configuration",
+ "patterns": ["PDCA Cycle", "Session Lifecycle"]
+ },
+ "last_session": {
+ "date": "2025-10-14",
+ "accomplished": ["PM Agent mode design", "Salvaged implementations"],
+ "issues": ["Serena MCP not configured"],
+ "learned": ["Session Lifecycle pattern", "PDCA automation"]
+ },
+ "next_actions": [
+ "Create docs/Development/ structure",
+ "Write ARCHITECTURE.md",
+ "Configure Serena MCP server"
+ ]
+}
+```
+
+---
+
+## PDCA Engine
+
+### Continuous Improvement Cycle
+
+```
+โโโโโโโโโโโโโโโ
+โ Plan โ โ write_memory("plan", goal)
+โ (ไปฎ่ชฌ) โ โ docs/temp/hypothesis-YYYY-MM-DD.md
+โโโโโโโโฌโโโโโโโ
+ โ
+โโโโโโโโโโโโโโโ
+โ Do โ โ TodoWrite tracking
+โ (ๅฎ้จ) โ โ write_memory("checkpoint", progress)
+โโโโโโโโฌโโโโโโโ โ docs/temp/experiment-YYYY-MM-DD.md
+ โ
+โโโโโโโโโโโโโโโ
+โ Check โ โ think_about_task_adherence()
+โ (่ฉไพก) โ โ think_about_whether_you_are_done()
+โโโโโโโโฌโโโโโโโ โ docs/temp/lessons-YYYY-MM-DD.md
+ โ
+โโโโโโโโโโโโโโโ
+โ Act โ โ Success: docs/patterns/[name].md
+โ (ๆนๅ) โ โ Failure: docs/mistakes/mistake-*.md
+โโโโโโโโฌโโโโโโโ โ Update CLAUDE.md
+ โ
+ [Repeat]
+```
+
+### Documentation Evolution
+
+```
+Trial-and-Error (docs/temp/)
+ โ
+Success โ Formal Pattern (docs/patterns/)
+ โ
+Accumulate Knowledge
+ โ
+Extract Best Practices โ CLAUDE.md (Global Rules)
+```
+
+```
+Mistake Detection (docs/temp/)
+ โ
+Root Cause Analysis โ docs/mistakes/
+ โ
+Prevention Checklist
+ โ
+Update Anti-Patterns โ CLAUDE.md
+```
+
+---
+
+## Data Flow
+
+### Session Lifecycle Data Flow
+
+```
+Session Start:
+โโโโโโโโโโโโโโโโ
+โ Claude Code โ
+โ Startup โ
+โโโโโโโโฌโโโโโโโโ
+ โ
+โโโโโโโโโโโโโโโโ
+โ PM Agent โ list_memories()
+โ Activation โ read_memory("pm_context")
+โโโโโโโโฌโโโโโโโโ
+ โ
+โโโโโโโโโโโโโโโโ
+โ Serena โ Return: pm_context,
+โ MCP โ last_session,
+โโโโโโโโฌโโโโโโโโ next_actions
+ โ
+โโโโโโโโโโโโโโโโ
+โ Context โ Restore project state
+โ Restoration โ Generate user report
+โโโโโโโโฌโโโโโโโโ
+ โ
+โโโโโโโโโโโโโโโโ
+โ User โ ๅๅ: [summary]
+โ Report โ ้ฒๆ: [status]
+โโโโโโโโโโโโโโโโ ไปๅ: [actions]
+ ่ชฒ้ก: [blockers]
+```
+
+### Implementation Data Flow
+
+```
+User Request โ PM Agent Analyzes
+ โ
+PM Agent โ Delegate to Specialist Agents
+ โ
+Specialist Agents โ Execute Implementation
+ โ
+Implementation Complete โ PM Agent Documents
+ โ
+PM Agent โ write_memory("checkpoint", progress)
+PM Agent โ docs/temp/experiment-*.md
+ โ
+Success โ docs/patterns/ | Failure โ docs/mistakes/
+ โ
+Update CLAUDE.md (if global pattern)
+```
+
+---
+
+## Extension Points
+
+### Adding New Components
+
+#### 1. New Command
+```markdown
+File: ~/.claude/commands/sc/new-command.md
+Structure:
+ - Metadata (name, category, complexity)
+ - Triggers (when to use)
+ - Workflow Pattern (step-by-step)
+ - Examples
+
+Integration:
+ - Auto-loads when user types /sc:new-command
+ - Can activate related agents
+ - PM Agent automatically documents usage patterns
+```
+
+#### 2. New Agent
+```markdown
+File: ~/.claude/agents/new-specialist.md
+Structure:
+ - Metadata (name, category)
+ - Triggers (keywords, file types)
+ - Behavioral Mindset
+ - Focus Areas
+
+Integration:
+ - Auto-activates on trigger keywords
+ - Manual activation: @agent-new-specialist
+ - PM Agent orchestrates with other agents
+```
+
+#### 3. New Mode
+```markdown
+File: ~/.claude/MODE_NewMode.md
+Structure:
+ - Activation Triggers (flags, keywords)
+ - Behavioral Modifications
+ - Interaction Patterns
+
+Integration:
+ - Flag: --new-mode
+ - Auto-activation on complexity threshold
+ - Modifies all agent behaviors
+```
+
+#### 4. New MCP Server
+```json
+File: ~/.claude/.claude.json
+{
+ "mcpServers": {
+ "new-server": {
+ "command": "npx",
+ "args": ["-y", "new-server-mcp@latest"]
+ }
+ }
+}
+```
+
+```markdown
+File: ~/.claude/MCP_NewServer.md
+Structure:
+ - Purpose (what this server provides)
+ - Triggers (when to use)
+ - Integration (how to coordinate with other tools)
+```
+
+### PM Agent Integration for Extensions
+
+All new components automatically integrate with PM Agent meta-layer:
+
+1. **Session Lifecycle**: New components' usage tracked across sessions
+2. **PDCA Cycle**: Patterns extracted from new component usage
+3. **Documentation**: Learnings automatically documented
+4. **Orchestration**: PM Agent coordinates new components with existing ones
+
+---
+
+## Architecture Principles
+
+### 1. Simplicity First
+- No executing code, only context files
+- No performance systems, only instructional patterns
+- No detection engines, Claude Code does pattern matching
+
+### 2. Context-Oriented
+- Behavior modification through structured context
+- Import system for modular context loading
+- Clear trigger patterns for activation
+
+### 3. Meta-Layer Design
+- PM Agent orchestrates without interfering
+- Specialist agents work transparently
+- Users interact with cohesive system
+
+### 4. Knowledge Accumulation
+- Every experience generates learnings
+- Mistakes documented with prevention
+- Patterns extracted to reusable knowledge
+
+### 5. Session Continuity
+- Context preserved across sessions
+- No re-explanation needed
+- Seamless resumption from last checkpoint
+
+---
+
+## Technical Considerations
+
+### Performance
+- Framework is pure context (no runtime overhead)
+- Token efficiency through dynamic MCP loading
+- Strategic context caching for related phases
+
+### Scalability
+- Unlimited commands/agents/modes through context files
+- Modular architecture supports independent development
+- PM Agent meta-layer handles coordination complexity
+
+### Maintainability
+- Clear separation of concerns (Commands/Agents/Modes)
+- Self-documenting through PDCA cycle
+- Living documentation evolves with usage
+
+### Extensibility
+- Drop-in new contexts without code changes
+- MCP servers add capabilities externally
+- PM Agent auto-integrates new components
+
+---
+
+## Future Architecture
+
+### Planned Enhancements
+
+1. **Auto-Activation System**
+ - PM Agent activates automatically at session start
+ - No manual invocation needed
+
+2. **Enhanced Memory Operations**
+ - Full Serena MCP integration
+ - Cross-project knowledge sharing
+ - Pattern recognition across sessions
+
+3. **PDCA Automation**
+ - Automatic documentation lifecycle
+ - AI-driven pattern extraction
+ - Self-improving knowledge base
+
+4. **Multi-Project Orchestration**
+ - PM Agent coordinates across projects
+ - Shared learnings and patterns
+ - Unified knowledge management
+
+---
+
+## Summary
+
+SuperClaude's architecture is elegantly simple: **structured context files** that Claude Code reads to adopt sophisticated behaviors. The addition of PM Agent mode as a meta-layer transforms this from a collection of tools into a **continuously learning, self-improving development platform**.
+
+**Key Architectural Innovation**: PM Agent meta-layer provides:
+- Always-active foundation layer
+- Context preservation across sessions
+- PDCA self-evaluation and learning
+- Systematic knowledge management
+- Seamless orchestration of specialist agents
+
+This architecture enables SuperClaude to function as a **ๆ้ซๅธไปคๅฎ (Supreme Commander)** that orchestrates all development activities while continuously learning and improving from every interaction.
+
+---
+
+**Last Verified**: 2025-10-14
+**Next Review**: 2025-10-21 (1 week)
+**Version**: 4.1.5
diff --git a/docs/Development/PROJECT_STATUS.md b/docs/Development/PROJECT_STATUS.md
new file mode 100644
index 0000000..01f5cde
--- /dev/null
+++ b/docs/Development/PROJECT_STATUS.md
@@ -0,0 +1,172 @@
+# SuperClaude Project Status
+
+**Last Updated**: 2025-10-14
+**Version**: 4.1.5
+**Phase**: Phase 1 - Documentation Structure
+
+---
+
+## ๐ Quick Overview
+
+| Metric | Status | Progress |
+|--------|--------|----------|
+| **Overall Completion** | ๐ In Progress | 35% |
+| **Phase 1 (Documentation)** | ๐ In Progress | 66% |
+| **Phase 2 (PM Agent)** | ๐ In Progress | 30% |
+| **Phase 3 (Serena MCP)** | โณ Not Started | 0% |
+| **Phase 4 (Doc Strategy)** | โณ Not Started | 0% |
+| **Phase 5 (Auto-Activation)** | ๐ฌ Research | 0% |
+
+---
+
+## ๐ฏ Current Sprint
+
+**Sprint**: Phase 1 - Documentation Structure
+**Timeline**: 2025-10-14 ~ 2025-10-20
+**Status**: ๐ 66% Complete
+
+### This Week's Focus
+- [ ] Complete Phase 1 documentation (TASKS.md, PROJECT_STATUS.md, pm-agent-integration.md)
+- [ ] Commit Phase 1 changes
+- [ ] Commit PM Agent Mode improvements
+
+---
+
+## โ
Completed Features
+
+### Core Framework (v4.1.5)
+- โ
**26 Commands**: `/sc:*` namespace
+- โ
**16 Agents**: Specialized domain experts
+- โ
**7 Modes**: Behavioral modifiers
+- โ
**8 MCP Servers**: External tool integrations
+
+### PM Agent Mode (Design Phase)
+- โ
Session Lifecycle design
+- โ
PDCA Cycle design
+- โ
Documentation Strategy design
+- โ
Commands/pm.md updated
+- โ
Agents/pm-agent.md updated
+
+### Documentation
+- โ
docs/Development/ARCHITECTURE.md
+- โ
docs/Development/ROADMAP.md
+- โ
docs/Development/TASKS.md
+- โ
docs/Development/PROJECT_STATUS.md
+- โ
docs/pm-agent-implementation-status.md
+
+---
+
+## ๐ In Progress
+
+### Phase 1: Documentation Structure (66%)
+- [x] ARCHITECTURE.md
+- [x] ROADMAP.md
+- [x] TASKS.md
+- [x] PROJECT_STATUS.md
+- [ ] pm-agent-integration.md
+
+### Phase 2: PM Agent Mode (30%)
+- [ ] superclaude/Core/session_lifecycle.py
+- [ ] superclaude/Core/pdca_engine.py
+- [ ] superclaude/Core/memory_ops.py
+- [ ] Unit tests
+- [ ] Integration tests
+
+---
+
+## โณ Pending
+
+### Phase 3: Serena MCP Integration (0%)
+- Serena MCP server configuration
+- Memory operations implementation
+- Think operations implementation
+- Cross-session persistence testing
+
+### Phase 4: Documentation Strategy (0%)
+- Directory templates creation
+- Lifecycle automation
+- Migration scripts
+- Knowledge management
+
+### Phase 5: Auto-Activation (0%)
+- Claude Code initialization hooks research
+- Auto-activation implementation
+- Context restoration
+- Performance optimization
+
+---
+
+## ๐ซ Blockers
+
+### Critical
+- **Serena MCP Not Configured**: Blocks Phase 3 (Memory Operations)
+- **Auto-Activation Hooks Unknown**: Blocks Phase 5 (Research needed)
+
+### Non-Critical
+- Documentation directory structure (in progress - Phase 1)
+
+---
+
+## ๐ Metrics Dashboard
+
+### Development Velocity
+- **Phase 1**: 6 days estimated, on track for 7 days completion
+- **Phase 2**: 14 days estimated, not yet started full implementation
+- **Overall**: 35% complete, on schedule for 8-week timeline
+
+### Code Quality
+- **Test Coverage**: 0% (implementation not started)
+- **Documentation Coverage**: 40% (4/10 major docs complete)
+
+### Component Status
+- **Commands**: โ
26/26 functional
+- **Agents**: โ
16/16 functional, 1 (PM Agent) enhanced
+- **Modes**: โ
7/7 functional
+- **MCP Servers**: โ ๏ธ 7/8 functional (Serena pending)
+
+---
+
+## ๐ฏ Upcoming Milestones
+
+### Week 1 (Current)
+- โ
Complete Phase 1 documentation
+- โ
Commit changes to repository
+
+### Week 2-3
+- [ ] Implement PM Agent Core (session_lifecycle, pdca_engine, memory_ops)
+- [ ] Write unit tests
+- [ ] Update User-Guide documentation
+
+### Week 4-5
+- [ ] Configure Serena MCP server
+- [ ] Implement memory operations
+- [ ] Test cross-session persistence
+
+---
+
+## ๐ Recent Changes
+
+### 2025-10-14
+- Created docs/Development/ structure
+- Wrote ARCHITECTURE.md (system overview)
+- Wrote ROADMAP.md (5-phase development plan)
+- Wrote TASKS.md (task tracking)
+- Wrote PROJECT_STATUS.md (this file)
+- Salvaged PM Agent mode changes from ~/.claude
+- Updated Commands/pm.md and Agents/pm-agent.md
+
+---
+
+## ๐ฎ Next Steps
+
+1. **Complete pm-agent-integration.md** (Phase 1 final doc)
+2. **Commit Phase 1 documentation** (establish foundation)
+3. **Commit PM Agent Mode improvements** (design complete)
+4. **Begin Phase 2 implementation** (Core components)
+5. **Configure Serena MCP** (unblock Phase 3)
+
+---
+
+**Last Verified**: 2025-10-14
+**Next Review**: 2025-10-17 (Mid-week check)
+**Version**: 4.1.5
diff --git a/docs/Development/ROADMAP.md b/docs/Development/ROADMAP.md
new file mode 100644
index 0000000..47a2414
--- /dev/null
+++ b/docs/Development/ROADMAP.md
@@ -0,0 +1,349 @@
+# SuperClaude Development Roadmap
+
+**Last Updated**: 2025-10-14
+**Version**: 4.1.5
+
+## ๐ฏ Vision
+
+Transform SuperClaude into a self-improving development platform with PM Agent mode as the always-active meta-layer, enabling continuous context preservation, systematic knowledge management, and intelligent orchestration of all development activities.
+
+---
+
+## ๐ Phase Overview
+
+| Phase | Status | Timeline | Focus |
+|-------|--------|----------|-------|
+| **Phase 1** | โ
Completed | Week 1 | Documentation Structure |
+| **Phase 2** | ๐ In Progress | Week 2-3 | PM Agent Mode Integration |
+| **Phase 3** | โณ Planned | Week 4-5 | Serena MCP Integration |
+| **Phase 4** | โณ Planned | Week 6-7 | Documentation Strategy |
+| **Phase 5** | ๐ฌ Research | Week 8+ | Auto-Activation System |
+
+---
+
+## Phase 1: Documentation Structure โ
+
+**Goal**: Create comprehensive documentation foundation for development
+
+**Timeline**: Week 1 (2025-10-14 ~ 2025-10-20)
+
+**Status**: โ
Completed
+
+### Tasks
+
+- [x] Create `docs/Development/` directory structure
+- [x] Write `ARCHITECTURE.md` - System overview with PM Agent position
+- [x] Write `ROADMAP.md` - Phase-based development plan with checkboxes
+- [ ] Write `TASKS.md` - Current task tracking system
+- [ ] Write `PROJECT_STATUS.md` - Implementation status dashboard
+- [ ] Write `pm-agent-integration.md` - Integration guide and procedures
+
+### Deliverables
+
+- [x] **docs/Development/ARCHITECTURE.md** - Complete system architecture
+- [x] **docs/Development/ROADMAP.md** - This file (development roadmap)
+- [ ] **docs/Development/TASKS.md** - Task management with checkboxes
+- [ ] **docs/Development/PROJECT_STATUS.md** - Current status and metrics
+- [ ] **docs/Development/pm-agent-integration.md** - Integration procedures
+
+### Success Criteria
+
+- [x] Documentation structure established
+- [x] Architecture clearly documented
+- [ ] Roadmap with phase breakdown complete
+- [ ] Task tracking system functional
+- [ ] Status dashboard provides visibility
+
+---
+
+## Phase 2: PM Agent Mode Integration ๐
+
+**Goal**: Integrate PM Agent mode as always-active meta-layer
+
+**Timeline**: Week 2-3 (2025-10-21 ~ 2025-11-03)
+
+**Status**: ๐ In Progress (30% complete)
+
+### Tasks
+
+#### Documentation Updates
+- [x] Update `superclaude/Commands/pm.md` with Session Lifecycle
+- [x] Update `superclaude/Agents/pm-agent.md` with PDCA Cycle
+- [x] Create `docs/pm-agent-implementation-status.md`
+- [ ] Update `docs/User-Guide/agents.md` - Add PM Agent section
+- [ ] Update `docs/User-Guide/commands.md` - Add /sc:pm command
+
+#### Core Implementation
+- [ ] Implement `superclaude/Core/session_lifecycle.py`
+ - [ ] Session start hooks
+ - [ ] Context restoration logic
+ - [ ] User report generation
+ - [ ] Error handling and fallback
+- [ ] Implement `superclaude/Core/pdca_engine.py`
+ - [ ] Plan phase automation
+ - [ ] Do phase tracking
+ - [ ] Check phase self-evaluation
+ - [ ] Act phase documentation
+- [ ] Implement `superclaude/Core/memory_ops.py`
+ - [ ] Serena MCP wrapper
+ - [ ] Memory operation abstractions
+ - [ ] Checkpoint management
+ - [ ] Session state handling
+
+#### Testing
+- [ ] Unit tests for session_lifecycle.py
+- [ ] Unit tests for pdca_engine.py
+- [ ] Unit tests for memory_ops.py
+- [ ] Integration tests for PM Agent flow
+- [ ] Test auto-activation at session start
+
+### Deliverables
+
+- [x] **Updated pm.md and pm-agent.md** - Design documentation
+- [x] **pm-agent-implementation-status.md** - Status tracking
+- [ ] **superclaude/Core/session_lifecycle.py** - Session management
+- [ ] **superclaude/Core/pdca_engine.py** - PDCA automation
+- [ ] **superclaude/Core/memory_ops.py** - Memory operations
+- [ ] **tests/test_pm_agent.py** - Comprehensive test suite
+
+### Success Criteria
+
+- [ ] PM Agent mode loads at session start
+- [ ] Session Lifecycle functional
+- [ ] PDCA Cycle automated
+- [ ] Memory operations working
+- [ ] All tests passing (>90% coverage)
+
+---
+
+## Phase 3: Serena MCP Integration โณ
+
+**Goal**: Full Serena MCP integration for session persistence
+
+**Timeline**: Week 4-5 (2025-11-04 ~ 2025-11-17)
+
+**Status**: โณ Planned
+
+### Tasks
+
+#### MCP Configuration
+- [ ] Install and configure Serena MCP server
+- [ ] Update `~/.claude/.claude.json` with Serena config
+- [ ] Test basic Serena operations
+- [ ] Troubleshoot connection issues
+
+#### Memory Operations Implementation
+- [ ] Implement `list_memories()` integration
+- [ ] Implement `read_memory(key)` integration
+- [ ] Implement `write_memory(key, value)` integration
+- [ ] Implement `delete_memory(key)` integration
+- [ ] Test memory persistence across sessions
+
+#### Think Operations Implementation
+- [ ] Implement `think_about_task_adherence()` hook
+- [ ] Implement `think_about_collected_information()` hook
+- [ ] Implement `think_about_whether_you_are_done()` hook
+- [ ] Integrate with TodoWrite completion tracking
+- [ ] Test self-evaluation triggers
+
+#### Cross-Session Testing
+- [ ] Test context restoration after restart
+- [ ] Test checkpoint save/restore
+- [ ] Test memory persistence durability
+- [ ] Test multi-project memory isolation
+- [ ] Performance testing (memory operations latency)
+
+### Deliverables
+
+- [ ] **Serena MCP Server** - Configured and operational
+- [ ] **superclaude/Core/serena_client.py** - Serena MCP client wrapper
+- [ ] **superclaude/Core/think_operations.py** - Think hooks implementation
+- [ ] **docs/troubleshooting/serena-setup.md** - Setup guide
+- [ ] **tests/test_serena_integration.py** - Integration test suite
+
+### Success Criteria
+
+- [ ] Serena MCP server operational
+- [ ] All memory operations functional
+- [ ] Think operations trigger correctly
+- [ ] Cross-session persistence verified
+- [ ] Performance acceptable (<100ms per operation)
+
+---
+
+## Phase 4: Documentation Strategy โณ
+
+**Goal**: Implement systematic documentation lifecycle
+
+**Timeline**: Week 6-7 (2025-11-18 ~ 2025-12-01)
+
+**Status**: โณ Planned
+
+### Tasks
+
+#### Directory Structure
+- [ ] Create `docs/temp/` template structure
+- [ ] Create `docs/patterns/` template structure
+- [ ] Create `docs/mistakes/` template structure
+- [ ] Add README.md to each directory explaining purpose
+- [ ] Create .gitignore for temporary files
+
+#### File Templates
+- [ ] Create `hypothesis-template.md` for Plan phase
+- [ ] Create `experiment-template.md` for Do phase
+- [ ] Create `lessons-template.md` for Check phase
+- [ ] Create `pattern-template.md` for successful patterns
+- [ ] Create `mistake-template.md` for error records
+
+#### Lifecycle Automation
+- [ ] Implement 7-day temporary file cleanup
+- [ ] Create docs/temp โ docs/patterns migration script
+- [ ] Create docs/temp โ docs/mistakes migration script
+- [ ] Automate "Last Verified" date updates
+- [ ] Implement duplicate pattern detection
+
+#### Knowledge Management
+- [ ] Implement pattern extraction logic
+- [ ] Implement CLAUDE.md auto-update mechanism
+- [ ] Create knowledge graph visualization
+- [ ] Implement pattern search functionality
+- [ ] Create mistake prevention checklist generator
+
+### Deliverables
+
+- [ ] **docs/temp/**, **docs/patterns/**, **docs/mistakes/** - Directory templates
+- [ ] **superclaude/Core/doc_lifecycle.py** - Lifecycle automation
+- [ ] **superclaude/Core/knowledge_manager.py** - Knowledge extraction
+- [ ] **scripts/migrate_docs.py** - Migration utilities
+- [ ] **tests/test_doc_lifecycle.py** - Lifecycle test suite
+
+### Success Criteria
+
+- [ ] Directory templates functional
+- [ ] Lifecycle automation working
+- [ ] Migration scripts reliable
+- [ ] Knowledge extraction accurate
+- [ ] CLAUDE.md auto-updates verified
+
+---
+
+## Phase 5: Auto-Activation System ๐ฌ
+
+**Goal**: PM Agent activates automatically at every session start
+
+**Timeline**: Week 8+ (2025-12-02 onwards)
+
+**Status**: ๐ฌ Research Needed
+
+### Research Phase
+
+- [ ] Research Claude Code initialization hooks
+- [ ] Investigate session start event handling
+- [ ] Study existing auto-activation patterns
+- [ ] Analyze Claude Code plugin system (if available)
+- [ ] Review Anthropic documentation on extensibility
+
+### Tasks
+
+#### Hook Implementation
+- [ ] Identify session start hook mechanism
+- [ ] Implement PM Agent auto-activation hook
+- [ ] Test activation timing and reliability
+- [ ] Handle edge cases (crash recovery, etc.)
+- [ ] Performance optimization (minimize startup delay)
+
+#### Context Restoration
+- [ ] Implement automatic context loading
+- [ ] Test memory restoration at startup
+- [ ] Verify user report generation
+- [ ] Handle missing or corrupted memory
+- [ ] Graceful fallback for new sessions
+
+#### Integration Testing
+- [ ] Test across multiple sessions
+- [ ] Test with different project contexts
+- [ ] Test memory persistence durability
+- [ ] Test error recovery mechanisms
+- [ ] Performance testing (startup time impact)
+
+### Deliverables
+
+- [ ] **superclaude/Core/auto_activation.py** - Auto-activation system
+- [ ] **docs/Developer-Guide/auto-activation.md** - Implementation guide
+- [ ] **tests/test_auto_activation.py** - Auto-activation tests
+- [ ] **Performance Report** - Startup time impact analysis
+
+### Success Criteria
+
+- [ ] PM Agent activates at every session start
+- [ ] Context restoration reliable (>99%)
+- [ ] User report generated consistently
+- [ ] Startup delay minimal (<500ms)
+- [ ] Error recovery robust
+
+---
+
+## ๐ Future Enhancements (Post-Phase 5)
+
+### Multi-Project Orchestration
+- [ ] Cross-project knowledge sharing
+- [ ] Unified pattern library
+- [ ] Multi-project context switching
+- [ ] Project-specific memory namespaces
+
+### AI-Driven Pattern Recognition
+- [ ] Machine learning for pattern extraction
+- [ ] Automatic best practice identification
+- [ ] Predictive mistake prevention
+- [ ] Smart knowledge graph generation
+
+### Enhanced Self-Evaluation
+- [ ] Advanced think operations
+- [ ] Quality scoring automation
+- [ ] Performance regression detection
+- [ ] Code quality trend analysis
+
+### Community Features
+- [ ] Pattern sharing marketplace
+- [ ] Community knowledge contributions
+- [ ] Collaborative PDCA cycles
+- [ ] Public pattern library
+
+---
+
+## ๐ Metrics & KPIs
+
+### Phase Completion Metrics
+
+| Metric | Target | Current | Status |
+|--------|--------|---------|--------|
+| Documentation Coverage | 100% | 40% | ๐ In Progress |
+| PM Agent Integration | 100% | 30% | ๐ In Progress |
+| Serena MCP Integration | 100% | 0% | โณ Pending |
+| Documentation Strategy | 100% | 0% | โณ Pending |
+| Auto-Activation | 100% | 0% | ๐ฌ Research |
+
+### Quality Metrics
+
+| Metric | Target | Current | Status |
+|--------|--------|---------|--------|
+| Test Coverage | >90% | 0% | โณ Pending |
+| Context Restoration Rate | 100% | N/A | โณ Pending |
+| Session Continuity | >95% | N/A | โณ Pending |
+| Documentation Freshness | <7 days | N/A | โณ Pending |
+| Mistake Prevention | <10% recurring | N/A | โณ Pending |
+
+---
+
+## ๐ Update Schedule
+
+- **Weekly**: Task progress updates
+- **Bi-weekly**: Phase milestone reviews
+- **Monthly**: Roadmap revision and priority adjustment
+- **Quarterly**: Long-term vision alignment
+
+---
+
+**Last Verified**: 2025-10-14
+**Next Review**: 2025-10-21 (1 week)
+**Version**: 4.1.5
diff --git a/docs/Development/TASKS.md b/docs/Development/TASKS.md
new file mode 100644
index 0000000..439a532
--- /dev/null
+++ b/docs/Development/TASKS.md
@@ -0,0 +1,151 @@
+# SuperClaude Development Tasks
+
+**Last Updated**: 2025-10-14
+**Current Sprint**: Phase 1 - Documentation Structure
+
+---
+
+## ๐ฅ High Priority (This Week: 2025-10-14 ~ 2025-10-20)
+
+### Phase 1: Documentation Structure
+- [x] Create docs/Development/ directory
+- [x] Write ARCHITECTURE.md
+- [x] Write ROADMAP.md
+- [ ] Write TASKS.md (this file)
+- [ ] Write PROJECT_STATUS.md
+- [ ] Write pm-agent-integration.md
+- [ ] Commit Phase 1 changes
+
+### PM Agent Mode
+- [x] Design Session Lifecycle
+- [x] Design PDCA Cycle
+- [x] Update Commands/pm.md
+- [x] Update Agents/pm-agent.md
+- [x] Create pm-agent-implementation-status.md
+- [ ] Commit PM Agent Mode changes
+
+---
+
+## ๐ Medium Priority (This Month: October 2025)
+
+### Phase 2: Core Implementation
+- [ ] Implement superclaude/Core/session_lifecycle.py
+- [ ] Implement superclaude/Core/pdca_engine.py
+- [ ] Implement superclaude/Core/memory_ops.py
+- [ ] Write unit tests for PM Agent core
+- [ ] Update User-Guide documentation
+
+### Testing & Validation
+- [ ] Create test suite for session_lifecycle
+- [ ] Create test suite for pdca_engine
+- [ ] Create test suite for memory_ops
+- [ ] Integration testing for PM Agent flow
+- [ ] Performance benchmarking
+
+---
+
+## ๐ก Low Priority (Future)
+
+### Phase 3: Serena MCP Integration
+- [ ] Configure Serena MCP server
+- [ ] Test Serena connection
+- [ ] Implement memory operations
+- [ ] Test cross-session persistence
+
+### Phase 4: Documentation Strategy
+- [ ] Create docs/temp/ template
+- [ ] Create docs/patterns/ template
+- [ ] Create docs/mistakes/ template
+- [ ] Implement 7-day cleanup automation
+
+### Phase 5: Auto-Activation
+- [ ] Research Claude Code init hooks
+- [ ] Implement auto-activation
+- [ ] Test session start behavior
+- [ ] Performance optimization
+
+---
+
+## ๐ Bugs & Issues
+
+### Known Issues
+- [ ] Serena MCP not configured (blocker for Phase 3)
+- [ ] Auto-activation hooks unknown (research needed for Phase 5)
+- [ ] Documentation directory structure missing (in progress)
+
+### Recent Fixes
+- [x] PM Agent changes salvaged from ~/.claude directory (2025-10-14)
+- [x] Git repository cleanup in ~/.claude (2025-10-14)
+
+---
+
+## โ
Completed Tasks
+
+### 2025-10-14
+- [x] Salvaged PM Agent mode changes from ~/.claude
+- [x] Cleaned up ~/.claude git repository
+- [x] Created pm-agent-implementation-status.md
+- [x] Created docs/Development/ directory
+- [x] Wrote ARCHITECTURE.md
+- [x] Wrote ROADMAP.md
+- [x] Wrote TASKS.md
+
+---
+
+## ๐ Sprint Metrics
+
+### Current Sprint (Week 1)
+- **Planned Tasks**: 8
+- **Completed**: 7
+- **In Progress**: 1
+- **Blocked**: 0
+- **Completion Rate**: 87.5%
+
+### Overall Progress (Phase 1)
+- **Total Tasks**: 6
+- **Completed**: 3
+- **Remaining**: 3
+- **On Schedule**: โ
Yes
+
+---
+
+## ๐ Task Management Process
+
+### Weekly Cycle
+1. **Monday**: Review last week, plan this week
+2. **Mid-week**: Progress check, adjust priorities
+3. **Friday**: Update task status, prepare next week
+
+### Task Categories
+- ๐ฅ **High Priority**: Must complete this week
+- ๐ **Medium Priority**: Complete this month
+- ๐ก **Low Priority**: Future enhancements
+- ๐ **Bugs**: Critical issues requiring immediate attention
+
+### Status Markers
+- โ
**Completed**: Task finished and verified
+- ๐ **In Progress**: Currently working on
+- โณ **Pending**: Waiting for dependencies
+- ๐ซ **Blocked**: Cannot proceed (document blocker)
+
+---
+
+## ๐ Task Template
+
+When adding new tasks, use this format:
+
+```markdown
+- [ ] Task description
+ - **Priority**: High/Medium/Low
+ - **Estimate**: 1-2 hours / 1-2 days / 1 week
+ - **Dependencies**: List dependent tasks
+ - **Blocker**: Any blocking issues
+ - **Assigned**: Person/Team
+ - **Due Date**: YYYY-MM-DD
+```
+
+---
+
+**Last Verified**: 2025-10-14
+**Next Update**: 2025-10-17 (Mid-week check)
+**Version**: 4.1.5
diff --git a/docs/Development/hypothesis-pm-autonomous-enhancement-2025-10-14.md b/docs/Development/hypothesis-pm-autonomous-enhancement-2025-10-14.md
new file mode 100644
index 0000000..2d27eb1
--- /dev/null
+++ b/docs/Development/hypothesis-pm-autonomous-enhancement-2025-10-14.md
@@ -0,0 +1,390 @@
+# PM Agent Autonomous Enhancement - ๆนๅๆๆก
+
+> **Date**: 2025-10-14
+> **Status**: ๆๆกไธญ๏ผใฆใผใถใผใฌใใฅใผๅพ
ใก๏ผ
+> **Goal**: ใฆใผใถใผใคใณใใใๆๅฐๅ + ็ขบไฟกใๆใฃใๅ
ๅใๆๆก
+
+---
+
+## ๐ฏ ็พ็ถใฎๅ้ก็น
+
+### ๆขๅญใฎ `superclaude/commands/pm.md`
+```yaml
+่ฏใ็น:
+ โ
PDCAใตใคใฏใซใๅฎ็พฉใใใฆใใ
+ โ
ใตใใจใผใธใงใณใ้ฃๆบใๆ็ขบ
+ โ
ใใญใฅใกใณใ่จ้ฒใฎไป็ตใฟใใใ
+
+ๆนๅใๅฟ
่ฆใช็น:
+ โ ใฆใผใถใผใคใณใใใไพๅญๅบฆใ้ซใ
+ โ ่ชฟๆปใใงใผใบใๅๅ็
+ โ ๆๆกใใใฉใใใพใใ๏ผใในใฟใคใซ
+ โ ็ขบไฟกใๆใฃใๆๆกใใชใ
+```
+
+---
+
+## ๐ก ๆนๅๆๆก
+
+### Phase 0: **่ชๅพ็่ชฟๆปใใงใผใบ**๏ผๆฐ่ฆ่ฟฝๅ ๏ผ
+
+#### ใฆใผใถใผใชใฏใจในใๅไฟกๆใฎ่ชๅๅฎ่ก
+```yaml
+Auto-Investigation (่จฑๅฏไธ่ฆใป่ชๅๅฎ่ก):
+ 1. Context Restoration:
+ - Read docs/Development/tasks/current-tasks.md
+ - list_memories() โ ๅๅใฎใปใใทใงใณ็ขบ่ช
+ - read_memory("project_context") โ ใใญใธใงใฏใ็่งฃ
+ - read_memory("past_mistakes") โ ้ๅปใฎๅคฑๆ็ขบ่ช
+
+ 2. Project Analysis:
+ - Read CLAUDE.md โ ใใญใธใงใฏใๅบๆใซใผใซ
+ - Glob **/*.md โ ใใญใฅใกใณใๆง้ ๆๆก
+ - mcp__serena__get_symbols_overview โ ใณใผใๆง้ ็่งฃ
+ - Grep "TODO\|FIXME\|XXX" โ ๆข็ฅใฎ่ชฒ้ก็ขบ่ช
+
+ 3. Current State Assessment:
+ - Bash "git status" โ ็พๅจใฎ็ถๆ
+ - Bash "git log -5 --oneline" โ ๆ่ฟใฎๅคๆด
+ - Read tests/ โ ใในใใซใใฌใใธ็ขบ่ช
+ - Security scan โ ใปใญใฅใชใใฃใชในใฏ็ขบ่ช
+
+ 4. Competitive Research (ๅฟ
่ฆๆ):
+ - tavily search โ ใในใใใฉใฏใใฃใน่ชฟๆป
+ - context7 โ ๅ
ฌๅผใใญใฅใกใณใๅ็
ง
+ - Deep Research โ ็ซถๅใตใผใในๅๆ
+
+ 5. Architecture Evaluation:
+ - ๆขๅญใขใผใญใใฏใใฃใฎๅผทใฟๅๆ
+ - ๆ่กในใฟใใฏใฎ็นๅพดๆๆก
+ - ๆกๅผตๅฏ่ฝๆงใฎ่ฉไพก
+```
+
+#### ๅบๅๅฝขๅผ
+```markdown
+๐ ่ชๅพ่ชฟๆปๅฎไบ
+
+็พ็ถๅๆ:
+ - ใใญใธใงใฏใ: [ๅๅ]๏ผ[ๆ่กในใฟใใฏ]๏ผ
+ - ้ฒๆ: [ๅๅใปใใทใงใณใฎ็ถใ or ๆฐ่ฆใฟในใฏ]
+ - ใณใผใใใผใน: [ใใกใคใซๆฐ]ใใในใใซใใฌใใธ [%]
+ - ๆข็ฅใฎ่ชฒ้ก: [TODO/FIXMEๆฐ]
+ - ๆ่ฟใฎๅคๆด: [git log่ฆ็ด]
+
+ใขใผใญใใฏใใฃใฎๅผทใฟ:
+ - [ๅผทใฟ1]: [ๅ
ทไฝ็ใช็็ฑ]
+ - [ๅผทใฟ2]: [ๅ
ทไฝ็ใช็็ฑ]
+
+ไธ่ถณใใฆใใ่ฆ็ด :
+ - [ไธ่ถณ1]: [ๅฝฑ้ฟ]
+ - [ไธ่ถณ2]: [ๅฝฑ้ฟ]
+```
+
+---
+
+### Phase 1: **็ขบไฟกใๆใฃใๆๆก**๏ผๅผทๅ๏ผ
+
+#### โ ๆนๅๅ๏ผๅๅ็๏ผ
+```
+User: "่ช่จผๆฉ่ฝไฝใฃใฆ"
+
+PM Agent: "่ช่จผๆฉ่ฝใๅฎ่ฃ
ใใพใใญใ
+ ใฉใใช่ช่จผๆนๅผใใใใงใใ๏ผ"
+
+โ ใฆใผใถใผใซไธธๆใ
+```
+
+#### โ
ๆนๅๅพ๏ผ่ฝๅ็ใป็ขบไฟกใใ๏ผ
+```
+User: "่ช่จผๆฉ่ฝไฝใฃใฆ"
+
+PM Agent:
+ ๐ ่ชๅพ่ชฟๆปๅฎไบ๏ผ3็ง๏ผ:
+ - ๆขๅญ: Supabase็ตฑๅๆธใฟ๏ผๅผทใฟ๏ผ
+ - ไธ่ถณ: ่ช่จผๆฉ่ฝใชใ
+ - ใในใ: ใซใใฌใใธ45%๏ผ็ฎๆจ80%๏ผ
+ - ็ซถๅ่ชฟๆป: Auth0ใClerkใSupabase Authๆฏ่ผๆธใฟ
+ - ใปใญใฅใชใใฃ: OWASPๆจๅฅจ3้
็ฎๆชๅฏพๅฟ
+
+ ๐ก ็ขบไฟกใๆใฃใๆๆก:
+
+ ใใฎใขใผใญใใฏใใฃใฏSupabase้ฃๆบใซๅผทใฟใใใใใใ
+ **Supabase Auth็ตฑๅ**ใๆจๅฅจใใพใใ
+
+ ๅ
ทไฝ็ใชๅฎ่ฃ
ๆน้:
+ 1. Supabase Auth็ตฑๅ๏ผJWT + ใชใใฌใใทใฅใใผใฏใณ๏ผ
+ 2. MFAๅฏพๅฟ๏ผTOTPๅฎ่ฃ
๏ผ
+ 3. ใปใญใฅใชใใฃใในใ่ฟฝๅ ๏ผใซใใฌใใธ85%็ฎๆจ๏ผ
+ 4. ๆขๅญAPIใจใฎใทใผใ ใฌใน็ตฑๅ
+
+ ้ธๆ็็ฑ:
+ โ
ๆขๅญใฎSupabaseๆฅ็ถๅๅฉ็จ๏ผๅฎ่ฃ
ใณในใๆๅฐ๏ผ
+ โ
ใจใณใฟใผใใฉใคใบใฐใฌใผใใฎใปใญใฅใชใใฃ
+ โ
็กๆๆ ใงๅๅใชๆฉ่ฝ๏ผใณในใๅน็โ๏ผ
+ โ
ๅฐๆฅใฎในใฑใผใฉใใชใใฃ็ขบไฟ
+
+ ไปฃๆฟๆกใจใฎๆฏ่ผ:
+ - Auth0: ๆ$25ใใๅฎ่ฃ
่ค้ๅบฆ้ซ
+ - Clerk: ๆ$25ใใReact็นๅ๏ผใใฎใใญใธใงใฏใใฏNext.js๏ผ
+ - Supabase Auth: ็กๆใๆขๅญ็ตฑๅๆธใฟ โ ๆจๅฅจ
+
+ ใใฎๆน้ใง้ฒใใฆใใใใใงใใ๏ผ
+```
+
+---
+
+### Phase 2: **่ชๅพๅฎ่ก**๏ผๆขๅญใๅผทๅ๏ผ
+
+#### ๆฟ่ชๅพใฎ่ชๅใใญใผ
+```yaml
+User: "OK"
+
+PM Agent๏ผๅฎๅ
จ่ชๅพๅฎ่ก๏ผ:
+ 1. Architecture Design:
+ - system-architect: Supabase Auth่จญ่จ
+ - security-engineer: ใปใญใฅใชใใฃใฌใใฅใผ
+
+ 2. Implementation:
+ - backend-architect: API็ตฑๅๅฎ่ฃ
+ - frontend-architect: UIๅฎ่ฃ
+ - Load magic: Login/Register components
+
+ 3. Testing:
+ - Write tests/auth/*.test.ts
+ - pytestๅฎ่ก โ ๅคฑๆๆคๅบ
+
+ 4. Self-Correction:
+ - context7 โ Supabaseๅ
ฌๅผใใญใฅใกใณใ็ขบ่ช
+ - ใจใฉใผๅๅ ็นๅฎ: "JWTใทใผใฏใฌใใๆช่จญๅฎ"
+ - ไฟฎๆญฃๅฎ่ฃ
+ - ๅใในใ โ ๅๆ ผ
+
+ 5. Documentation:
+ - Update docs/patterns/supabase-auth-integration.md
+ - Update CLAUDE.md๏ผ่ช่จผใใฟใผใณ่ฟฝๅ ๏ผ
+ - write_memory("success_pattern", ่ฉณ็ดฐ)
+
+ 6. Report:
+ โ
่ช่จผๆฉ่ฝๅฎ่ฃ
ๅฎไบ
+
+ ๅฎ่ฃ
ๅ
ๅฎน:
+ - Supabase Auth็ตฑๅ๏ผJWT + ใชใใฌใใทใฅ๏ผ
+ - MFAๅฏพๅฟ๏ผTOTP๏ผ
+ - ใในใใซใใฌใใธ: 45% โ 87%๏ผ็ฎๆจ้ๆ๏ผ
+ - ใปใญใฅใชใใฃ: OWASPๆบๆ ็ขบ่ชๆธใฟ
+
+ ๅญฆ็ฟ่จ้ฒ:
+ - ๆๅใใฟใผใณ: docs/patterns/supabase-auth-integration.md
+ - ้ญ้ใใใจใฉใผ: JWT่จญๅฎไธ่ถณ๏ผไฟฎๆญฃๆธใฟ๏ผ
+ - ๆฌกๅใฎๆนๅ: ็ฐๅขๅคๆฐใใงใใฏใชในใๆดๆฐ
+```
+
+---
+
+## ๐ง ๅฎ่ฃ
ๆน้
+
+### `superclaude/commands/pm.md` ใธใฎ่ฟฝๅ ใปใฏใทใงใณ
+
+#### 1. Autonomous Investigation Phase๏ผๆฐ่ฆ๏ผ
+```markdown
+## Phase 0: Autonomous Investigation (Auto-Execute)
+
+**Trigger**: Any user request received
+
+**Execution**: Automatic, no permission required
+
+### Investigation Steps:
+1. **Context Restoration**
+ - Read `docs/Development/tasks/current-tasks.md`
+ - Serena memory restoration
+ - Project context loading
+
+2. **Project Analysis**
+ - CLAUDE.md โ Project rules
+ - Code structure analysis
+ - Test coverage check
+ - Security scan
+ - Known issues detection (TODO/FIXME)
+
+3. **Competitive Research** (when relevant)
+ - Best practices research (Tavily)
+ - Official documentation (Context7)
+ - Alternative solutions analysis
+
+4. **Architecture Evaluation**
+ - Identify architectural strengths
+ - Detect technology stack characteristics
+ - Assess extensibility
+
+### Output Format:
+```
+๐ Autonomous Investigation Complete
+
+Current State:
+ - Project: [name] ([stack])
+ - Progress: [status]
+ - Codebase: [files count], Test Coverage: [%]
+ - Known Issues: [count]
+ - Recent Changes: [git log summary]
+
+Architectural Strengths:
+ - [strength 1]: [rationale]
+ - [strength 2]: [rationale]
+
+Missing Elements:
+ - [gap 1]: [impact]
+ - [gap 2]: [impact]
+```
+```
+
+#### 2. Confident Proposal Phase๏ผๅผทๅ๏ผ
+```markdown
+## Phase 1: Confident Proposal (Enhanced)
+
+**Principle**: Never ask "What do you want?" - Always propose with conviction
+
+### Proposal Format:
+```
+๐ก Confident Proposal:
+
+[Implementation approach] is recommended.
+
+Specific Implementation Plan:
+1. [Step 1 with rationale]
+2. [Step 2 with rationale]
+3. [Step 3 with rationale]
+
+Selection Rationale:
+โ
[Reason 1]: [Evidence]
+โ
[Reason 2]: [Evidence]
+โ
[Reason 3]: [Evidence]
+
+Alternatives Considered:
+- [Alt 1]: [Why not chosen]
+- [Alt 2]: [Why not chosen]
+- [Recommended]: [Why chosen] โ Recommended
+
+Proceed with this approach?
+```
+
+### Anti-Patterns (Never Do):
+โ "What authentication do you want?" (Passive)
+โ "How should we implement this?" (Uncertain)
+โ "There are several options..." (Indecisive)
+
+โ
"Supabase Auth is recommended because..." (Confident)
+โ
"Based on your architecture's Supabase integration..." (Evidence-based)
+```
+
+#### 3. Autonomous Execution Phase๏ผๆขๅญใๆ็คบๅ๏ผ
+```markdown
+## Phase 2: Autonomous Execution
+
+**Trigger**: User approval ("OK", "Go ahead", "Yes")
+
+**Execution**: Fully autonomous, systematic PDCA
+
+### Self-Correction Loop:
+```yaml
+Implementation:
+ - Execute with sub-agents
+ - Write comprehensive tests
+ - Run validation
+
+Error Detected:
+ โ Context7: Check official documentation
+ โ Identify root cause
+ โ Implement fix
+ โ Re-test
+ โ Repeat until passing
+
+Success:
+ โ Document pattern (docs/patterns/)
+ โ Update learnings (write_memory)
+ โ Report completion with evidence
+```
+
+### Quality Gates:
+- Tests must pass (no exceptions)
+- Coverage targets must be met
+- Security checks must pass
+- Documentation must be updated
+```
+
+---
+
+## ๐ ๆๅพ
ใใใๅนๆ
+
+### Before (็พ็ถ)
+```yaml
+User Input Required: ้ซ
+ - ่ช่จผๆนๅผใฎ้ธๆ
+ - ๅฎ่ฃ
ๆน้ใฎๆฑบๅฎ
+ - ใจใฉใผๅฏพๅฟใฎๆ็คบ
+ - ใในใๆน้ใฎๆฑบๅฎ
+
+Proposal Quality: ๅๅ็
+ - "ใฉใใใพใใ๏ผ"ในใฟใคใซ
+ - ้ธๆ่ขใฎ็พ
ๅใฎใฟ
+ - ใฆใผใถใผใๆฑบๅฎ
+
+Execution: ๅ่ชๅ
+ - ใจใฉใผๆใซใฆใผใถใผใซๅ ฑๅ
+ - ไฟฎๆญฃๆน้ใใฆใผใถใผใๆ็คบ
+```
+
+### After (ๆนๅๅพ)
+```yaml
+User Input Required: ๆๅฐ
+ - "่ช่จผๆฉ่ฝไฝใฃใฆ"ใฎใฟ
+ - ๆๆกใธใฎๆฟ่ช/ๆๅฆใฎใฟ
+
+Proposal Quality: ่ฝๅ็ใป็ขบไฟกใใ
+ - ่ชฟๆปๆธใฟใฎๆ นๆ ๆ็คบ
+ - ๆ็ขบใชๆจๅฅจๆก
+ - ไปฃๆฟๆกใจใฎๆฏ่ผ
+
+Execution: ๅฎๅ
จ่ชๅพ
+ - ใจใฉใผ่ชๅทฑไฟฎๆญฃ
+ - ๅ
ฌๅผใใญใฅใกใณใ่ชๅๅ็
ง
+ - ใในใๅๆ ผใพใง่ชๅๅฎ่ก
+ - ๅญฆ็ฟ่ชๅ่จ้ฒ
+```
+
+### ๅฎ้็็ฎๆจ
+- ใฆใผใถใผใคใณใใใๅๆธ: **80%ๅๆธ**
+- ๆๆกๅ่ณชๅไธ: **็ขบไฟกๅบฆ90%ไปฅไธ**
+- ่ชๅพๅฎ่กๆๅ็: **95%ไปฅไธ**
+
+---
+
+## ๐ ๅฎ่ฃ
ในใใใ
+
+### Step 1: pm.md ไฟฎๆญฃ
+- [ ] Phase 0: Autonomous Investigation ่ฟฝๅ
+- [ ] Phase 1: Confident Proposal ๅผทๅ
+- [ ] Phase 2: Autonomous Execution ๆ็คบๅ
+- [ ] Examples ใปใฏใทใงใณใซๅ
ทไฝไพ่ฟฝๅ
+
+### Step 2: ใในใไฝๆ
+- [ ] `tests/test_pm_autonomous.py`
+- [ ] ่ชๅพ่ชฟๆปใใญใผใฎใในใ
+- [ ] ็ขบไฟกๆๆกใใฉใผใใใใฎใในใ
+- [ ] ่ชๅทฑไฟฎๆญฃใซใผใใฎใในใ
+
+### Step 3: ๅไฝ็ขบ่ช
+- [ ] ้็บ็ใคใณในใใผใซ
+- [ ] ๅฎ้ใฎใฏใผใฏใใญใผใงๆค่จผ
+- [ ] ใใฃใผใใใใฏๅ้
+
+### Step 4: ๅญฆ็ฟ่จ้ฒ
+- [ ] `docs/patterns/pm-autonomous-workflow.md`
+- [ ] ๆๅใใฟใผใณใฎๆๆธๅ
+
+---
+
+## โ
ใฆใผใถใผๆฟ่ชๅพ
ใก
+
+**ใใฎๆน้ใงๅฎ่ฃ
ใ้ฒใใฆใใใใใงใใ๏ผ**
+
+ๆฟ่ชใใใ ใใใฐใใใใซ `superclaude/commands/pm.md` ใฎไฟฎๆญฃใ้ๅงใใพใใ
diff --git a/docs/Development/installation-flow-understanding.md b/docs/Development/installation-flow-understanding.md
new file mode 100644
index 0000000..1e7aee2
--- /dev/null
+++ b/docs/Development/installation-flow-understanding.md
@@ -0,0 +1,378 @@
+# SuperClaude Installation Flow - Complete Understanding
+
+> **ๅญฆ็ฟๅ
ๅฎน**: ใคใณในใใผใฉใผใใฉใใใฃใฆ `~/.claude/` ใซใใกใคใซใ้
็ฝฎใใใใฎๅฎๅ
จ็่งฃ
+
+---
+
+## ๐ ใคใณในใใผใซใใญใผๅ
จไฝๅ
+
+### ใฆใผใถใผๆไฝ
+```bash
+# Step 1: ใใใฑใผใธใคใณในใใผใซ
+pipx install SuperClaude
+# ใพใใฏ
+npm install -g @bifrost_inc/superclaude
+
+# Step 2: ใปใใใขใใๅฎ่ก
+SuperClaude install
+```
+
+### ๅ
้จๅฆ็ใฎๆตใ
+
+```yaml
+1. Entry Point:
+ File: superclaude/__main__.py โ main()
+
+2. CLI Parser:
+ File: superclaude/__main__.py โ create_parser()
+ Command: "install" ใตใใณใใณใ็ป้ฒ
+
+3. Component Manager:
+ File: setup/cli/install.py
+ Role: ใคใณในใใผใซใณใณใใผใใณใใฎ่ชฟๆด
+
+4. Commands Component:
+ File: setup/components/commands.py โ CommandsComponent
+ Role: ในใฉใใทใฅใณใใณใใฎใคใณในใใผใซ
+
+5. Source Files:
+ Location: superclaude/commands/*.md
+ Content: pm.md, implement.md, test.md, etc.
+
+6. Destination:
+ Location: ~/.claude/commands/sc/*.md
+ Result: ใฆใผใถใผ็ฐๅขใซ้
็ฝฎ
+```
+
+---
+
+## ๐ CommandsComponent ใฎ่ฉณ็ดฐ
+
+### ใฏใฉในๆง้
+```python
+class CommandsComponent(Component):
+ """
+ Role: ในใฉใใทใฅใณใใณใใฎใคใณในใใผใซใป็ฎก็
+ Parent: setup/core/base.py โ Component
+ Install Path: ~/.claude/commands/sc/
+ """
+```
+
+### ไธป่ฆใกใฝใใ
+
+#### 1. `__init__()`
+```python
+def __init__(self, install_dir: Optional[Path] = None):
+ super().__init__(install_dir, Path("commands/sc"))
+```
+**็่งฃ**:
+- `install_dir`: `~/.claude/` ๏ผใฆใผใถใผ็ฐๅข๏ผ
+- `Path("commands/sc")`: ใตใใใฃใฌใฏใใชๆๅฎ
+- ็ตๆ: `~/.claude/commands/sc/` ใซใคใณในใใผใซ
+
+#### 2. `_get_source_dir()`
+```python
+def _get_source_dir(self) -> Path:
+ # setup/components/commands.py ใฎไฝ็ฝฎใใ่จ็ฎ
+ project_root = Path(__file__).parent.parent.parent
+ # โ ~/github/SuperClaude_Framework/
+
+ return project_root / "superclaude" / "commands"
+ # โ ~/github/SuperClaude_Framework/superclaude/commands/
+```
+
+**็่งฃ**:
+```
+Source: ~/github/SuperClaude_Framework/superclaude/commands/*.md
+Target: ~/.claude/commands/sc/*.md
+
+ใคใพใ:
+superclaude/commands/pm.md
+ โ ใณใใผ
+~/.claude/commands/sc/pm.md
+```
+
+#### 3. `_install()` - ใคใณในใใผใซๅฎ่ก
+```python
+def _install(self, config: Dict[str, Any]) -> bool:
+ self.logger.info("Installing SuperClaude command definitions...")
+
+ # ๆขๅญใณใใณใใฎใใคใฐใฌใผใทใงใณ
+ self._migrate_existing_commands()
+
+ # ่ฆชใฏใฉในใฎใคใณในใใผใซๅฎ่ก
+ return super()._install(config)
+```
+
+**็่งฃ**:
+1. ใญใฐๅบๅ
+2. ๆงใใผใธใงใณใใใฎ็งป่กๅฆ็
+3. ๅฎ้ใฎใใกใคใซใณใใผ๏ผ่ฆชใฏใฉในใงๅฎ่ก๏ผ
+
+#### 4. `_migrate_existing_commands()` - ใใคใฐใฌใผใทใงใณ
+```python
+def _migrate_existing_commands(self) -> None:
+ """
+ ๆงLocation: ~/.claude/commands/*.md
+ ๆฐLocation: ~/.claude/commands/sc/*.md
+
+ V3 โ V4 ็งป่กๆใฎๅฆ็
+ """
+ old_commands_dir = self.install_dir / "commands"
+ new_commands_dir = self.install_dir / "commands" / "sc"
+
+ # ๆงๅ ดๆใใใใกใคใซๆคๅบ
+ # ๆฐๅ ดๆใธใณใใผ
+ # ๆงๅ ดๆใใๅ้ค
+```
+
+**็่งฃ**:
+- V3: `/analyze` โ V4: `/sc:analyze`
+- ๅๅ็ฉบ้่ก็ชใ้ฒใใใ `/sc:` ใใฌใใฃใใฏใน
+
+#### 5. `_post_install()` - ใกใฟใใผใฟๆดๆฐ
+```python
+def _post_install(self) -> bool:
+ # ใกใฟใใผใฟๆดๆฐ
+ metadata_mods = self.get_metadata_modifications()
+ self.settings_manager.update_metadata(metadata_mods)
+
+ # ใณใณใใผใใณใ็ป้ฒ
+ self.settings_manager.add_component_registration(
+ "commands",
+ {
+ "version": __version__,
+ "category": "commands",
+ "files_count": len(self.component_files),
+ },
+ )
+```
+
+**็่งฃ**:
+- `~/.claude/.superclaude.json` ๆดๆฐ
+- ใคใณในใใผใซๆธใฟใณใณใใผใใณใ่จ้ฒ
+- ใใผใธใงใณ็ฎก็
+
+---
+
+## ๐ ๅฎ้ใฎใใกใคใซใใใใณใฐ
+
+### Source๏ผใใฎใใญใธใงใฏใ๏ผ
+```
+~/github/SuperClaude_Framework/superclaude/commands/
+โโโ pm.md # PM Agentๅฎ็พฉ
+โโโ implement.md # Implement ใณใใณใ
+โโโ test.md # Test ใณใใณใ
+โโโ analyze.md # Analyze ใณใใณใ
+โโโ research.md # Research ใณใใณใ
+โโโ ...๏ผๅ
จ26ใณใใณใ๏ผ
+```
+
+### Destination๏ผใฆใผใถใผ็ฐๅข๏ผ
+```
+~/.claude/commands/sc/
+โโโ pm.md # โ /sc:pm ใงๅฎ่กๅฏ่ฝ
+โโโ implement.md # โ /sc:implement ใงๅฎ่กๅฏ่ฝ
+โโโ test.md # โ /sc:test ใงๅฎ่กๅฏ่ฝ
+โโโ analyze.md # โ /sc:analyze ใงๅฎ่กๅฏ่ฝ
+โโโ research.md # โ /sc:research ใงๅฎ่กๅฏ่ฝ
+โโโ ...๏ผๅ
จ26ใณใใณใ๏ผ
+```
+
+### Claude Codeๅไฝ
+```
+User: /sc:pm "Build authentication"
+
+Claude Code:
+ 1. ~/.claude/commands/sc/pm.md ่ชญใฟ่พผใฟ
+ 2. YAML frontmatter ่งฃๆ
+ 3. Markdownๆฌๆใๅฑ้
+ 4. PM Agent ใจใใฆๅฎ่ก
+```
+
+---
+
+## ๐ง ไปใฎใณใณใใผใใณใ
+
+### Modes Component
+```python
+File: setup/components/modes.py
+Source: superclaude/modes/*.md
+Target: ~/.claude/*.md
+
+Example:
+ superclaude/modes/MODE_Brainstorming.md
+ โ
+ ~/.claude/MODE_Brainstorming.md
+```
+
+### Agents Component
+```python
+File: setup/components/agents.py
+Source: superclaude/agents/*.md
+Target: ~/.claude/agents/*.md๏ผใพใใฏ็ตฑๅๅ
๏ผ
+```
+
+### Core Component
+```python
+File: setup/components/core.py
+Source: superclaude/core/CLAUDE.md
+Target: ~/.claude/CLAUDE.md
+
+ใใใใฐใญใผใใซ่จญๅฎ๏ผ
+```
+
+---
+
+## ๐ก ้็บๆใฎๆณจๆ็น
+
+### โ
ๆญฃใใๅคๆดๆนๆณ
+```bash
+# 1. ใฝใผในใใกใคใซใๅคๆด๏ผGit็ฎก็๏ผ
+cd ~/github/SuperClaude_Framework
+vim superclaude/commands/pm.md
+
+# 2. ใในใ่ฟฝๅ
+Write tests/test_pm_command.py
+
+# 3. ใในใๅฎ่ก
+pytest tests/test_pm_command.py -v
+
+# 4. ใณใใใ
+git add superclaude/commands/pm.md tests/
+git commit -m "feat: enhance PM command"
+
+# 5. ้็บ็ใคใณในใใผใซ
+pip install -e .
+# ใพใใฏ
+SuperClaude install --dev
+
+# 6. ๅไฝ็ขบ่ช
+claude
+/sc:pm "test"
+```
+
+### โ ้้ใฃใๅคๆดๆนๆณ
+```bash
+# ใใก๏ผGit็ฎก็ๅคใ็ดๆฅๅคๆด
+vim ~/.claude/commands/sc/pm.md
+
+# ๅคๆดใฏๆฌกๅใคใณในใใผใซๆใซไธๆธใใใใ
+SuperClaude install # โ ๅคๆดใๆถใใ๏ผ
+```
+
+---
+
+## ๐ฏ PM Modeๆนๅใฎๆญฃใใใใญใผ
+
+### Phase 1: ็่งฃ๏ผไปใใ๏ผ๏ผ
+```bash
+โ
setup/components/commands.py ็่งฃๅฎไบ
+โ
superclaude/commands/*.md ใฎๅญๅจ็ขบ่ชๅฎไบ
+โ
ใคใณในใใผใซใใญใผ็่งฃๅฎไบ
+```
+
+### Phase 2: ็พๅจใฎไปๆง็ขบ่ช
+```bash
+# ใฝใผใน็ขบ่ช๏ผGit็ฎก็๏ผ
+Read superclaude/commands/pm.md
+
+# ใคใณในใใผใซๅพ็ขบ่ช๏ผๅ่็จ๏ผ
+Read ~/.claude/commands/sc/pm.md
+
+# ใใชใใปใฉใใใใใไปๆงใซใชใฃใฆใใฎใใ
+```
+
+### Phase 3: ๆนๅๆกไฝๆ
+```bash
+# ใใฎใใญใธใงใฏใๅ
ใง๏ผGit็ฎก็๏ผ
+Write docs/Development/hypothesis-pm-enhancement-2025-10-14.md
+
+ๅ
ๅฎน:
+- ็พ็ถใฎๅ้ก๏ผใใญใฅใกใณใๅฏใใใใPMOๆฉ่ฝไธ่ถณ๏ผ
+- ๆนๅๆก๏ผ่ชๅพ็PDCAใ่ชๅทฑ่ฉไพก๏ผ
+- ๅฎ่ฃ
ๆน้
+- ๆๅพ
ใใใๅนๆ
+```
+
+### Phase 4: ๅฎ่ฃ
+```bash
+# ใฝใผในใใกใคใซไฟฎๆญฃ
+Edit superclaude/commands/pm.md
+
+ๅคๆดไพ:
+- PDCA่ชๅๅฎ่กใฎๅผทๅ
+- docs/ ใใฃใฌใฏใใชๆดป็จใฎๆ็คบ
+- ่ชๅทฑ่ฉไพกในใใใใฎ่ฟฝๅ
+- ใจใฉใผๆๅๅญฆ็ฟใใญใผใฎ่ฟฝๅ
+```
+
+### Phase 5: ใในใใปๆค่จผ
+```bash
+# ใในใ่ฟฝๅ
+Write tests/test_pm_enhanced.py
+
+# ใในใๅฎ่ก
+pytest tests/test_pm_enhanced.py -v
+
+# ้็บ็ใคใณในใใผใซ
+SuperClaude install --dev
+
+# ๅฎ้ใซไฝฟใฃใฆใฟใ
+claude
+/sc:pm "test enhanced workflow"
+```
+
+### Phase 6: ๅญฆ็ฟ่จ้ฒ
+```bash
+# ๆๅใใฟใผใณ่จ้ฒ
+Write docs/patterns/pm-autonomous-workflow.md
+
+# ๅคฑๆใใใใฐ่จ้ฒ
+Write docs/mistakes/mistake-2025-10-14.md
+```
+
+---
+
+## ๐ Component้ใฎไพๅญ้ขไฟ
+
+```yaml
+Commands Component:
+ depends_on: ["core"]
+
+Core Component:
+ provides:
+ - ~/.claude/CLAUDE.md๏ผใฐใญใผใใซ่จญๅฎ๏ผ
+ - ๅบๆฌใใฃใฌใฏใใชๆง้
+
+Modes Component:
+ depends_on: ["core"]
+ provides:
+ - ~/.claude/MODE_*.md
+
+Agents Component:
+ depends_on: ["core"]
+ provides:
+ - ใจใผใธใงใณใๅฎ็พฉ
+
+MCP Component:
+ depends_on: ["core"]
+ provides:
+ - MCPใตใผใใผ่จญๅฎ
+```
+
+---
+
+## ๐ ๆฌกใฎใขใฏใทใงใณ
+
+็่งฃๅฎไบ๏ผๆฌกใฏ๏ผ
+
+1. โ
`superclaude/commands/pm.md` ใฎ็พๅจใฎไปๆง็ขบ่ช
+2. โ
ๆนๅๆๆกใใญใฅใกใณใไฝๆ
+3. โ
ๅฎ่ฃ
ไฟฎๆญฃ๏ผPDCAๅผทๅใPMOๆฉ่ฝ่ฟฝๅ ๏ผ
+4. โ
ใในใ่ฟฝๅ ใปๅฎ่ก
+5. โ
ๅไฝ็ขบ่ช
+6. โ
ๅญฆ็ฟ่จ้ฒ
+
+ใใฎใใญใฅใกใณใ่ชไฝใ**ใคใณในใใผใซใใญใผใฎๅฎๅ
จ็่งฃ่จ้ฒ**ใจใใฆๆฉ่ฝใใใ
+ๆฌกๅใฎใปใใทใงใณใง่ชญใใฐใๅใ่ชฌๆใ็นฐใ่ฟใใชใใฆๆธใใ
diff --git a/docs/Development/pm-agent-ideal-workflow.md b/docs/Development/pm-agent-ideal-workflow.md
new file mode 100644
index 0000000..8d3e49b
--- /dev/null
+++ b/docs/Development/pm-agent-ideal-workflow.md
@@ -0,0 +1,341 @@
+# PM Agent - Ideal Autonomous Workflow
+
+> **็ฎ็**: ไฝ็พๅใๅใๆ็คบใ็นฐใ่ฟใใชใใใใฎ่ชๅพ็ใชใผใฑในใใฌใผใทใงใณใทในใใ
+
+## ๐ฏ ่งฃๆฑบใในใๅ้ก
+
+### ็พ็ถใฎ่ชฒ้ก
+- **็นฐใ่ฟใๆ็คบ**: ๅใใใจใไฝ็พๅใ่ชฌๆใใฆใใ
+- **ๅใใในใฎๅๅพฉ**: ไธๅบฆ้้ใใใใจใๅๅบฆ้้ใใ
+- **็ฅ่ญใฎๅชๅคฑ**: ใปใใทใงใณใ้ๅใใใจๅญฆ็ฟๅ
ๅฎนใๅคฑใใใ
+- **ใณใณใใญในใๅถ้**: ้ใใใใณใณใใญในใใงๅน็็ใซๅไฝใงใใฆใใชใ
+
+### ใใในใๅงฟ
+**่ชๅพ็ใง่ณขใPM Agent** - ใใญใฅใกใณใใใๅญฆใณใ่จ็ปใใๅฎ่กใใๆค่จผใใๅญฆ็ฟใ่จ้ฒใใใซใผใ
+
+---
+
+## ๐ ๅฎ็งใชใฏใผใฏใใญใผ๏ผ็ๆณๅฝข๏ผ
+
+### Phase 1: ๐ ็ถๆณๆๆก๏ผContext Restoration๏ผ
+
+```yaml
+1. ใใญใฅใกใณใ่ชญใฟ่พผใฟ:
+ ๅชๅ
้ ไฝ:
+ 1. ใฟในใฏ็ฎก็ใใญใฅใกใณใ โ ้ฒๆ็ขบ่ช
+ - docs/Development/tasks/current-tasks.md
+ - ๅๅใฉใใพใงใใฃใใ
+ - ๆฌกใซไฝใใในใใ
+
+ 2. ใขใผใญใใฏใใฃใใญใฅใกใณใ โ ไป็ตใฟ็่งฃ
+ - docs/Development/architecture-*.md
+ - ใใฎใใญใธใงใฏใใฎๆง้
+ - ใคใณในใใผใซใใญใผ
+ - ใณใณใใผใใณใ้ฃๆบ
+
+ 3. ็ฆๆญขไบ้
ใปใซใผใซ โ ๅถ็ด็ขบ่ช
+ - CLAUDE.md๏ผใฐใญใผใใซ๏ผ
+ - PROJECT/CLAUDE.md๏ผใใญใธใงใฏใๅบๆ๏ผ
+ - docs/Development/constraints.md
+
+ 4. ้ๅปใฎๅญฆใณ โ ๅใใในใ้ฒใ
+ - docs/mistakes/ ๏ผๅคฑๆ่จ้ฒ๏ผ
+ - docs/patterns/ ๏ผๆๅใใฟใผใณ๏ผ
+
+2. ใฆใผใถใผใชใฏใจในใ็่งฃ:
+ - ไฝใใใใใฎใ
+ - ใฉใใพใง้ฒใใงใใใฎใ
+ - ไฝใ่ชฒ้กใชใฎใ
+```
+
+### Phase 2: ๐ ่ชฟๆปใปๅๆ๏ผResearch & Analysis๏ผ
+
+```yaml
+1. ๆขๅญๅฎ่ฃ
ใฎ็่งฃ:
+ # ใฝใผในใณใผใๅด๏ผGit็ฎก็๏ผ
+ - setup/components/*.py โ ใคใณในใใผใซใญใธใใฏ
+ - superclaude/ โ ใฉใณใฟใคใ ใญใธใใฏ
+ - tests/ โ ใในใใใฟใผใณ
+
+ # ใคใณในใใผใซๅพ๏ผใฆใผใถใผ็ฐๅขใปGit็ฎก็ๅค๏ผ
+ - ~/.claude/commands/sc/ โ ๅฎ้ใฎ้
็ฝฎ็ขบ่ช
+ - ~/.claude/*.md โ ็พๅจใฎไปๆง็ขบ่ช
+
+ ็่งฃๅ
ๅฎน:
+ ใใชใใปใฉใใใใงใใๅฆ็ใใใฆใ
+ ใใใใใใกใคใซใ ~/.claude/ ใซไฝใใใใฎใญใ
+
+2. ใในใใใฉใฏใใฃใน่ชฟๆป:
+ # Deep Researchๆดป็จ
+ - ๅ
ฌๅผใชใใกใฌใณใน็ขบ่ช
+ - ไปใใญใธใงใฏใใฎๅฎ่ฃ
่ชฟๆป
+ - ๆๆฐใฎใในใใใฉใฏใใฃใน
+
+ ๆฐใฅใ:
+ - ใใใ็ก้งใ ใชใ
+ - ใใใๅคใใชใ
+ - ใใใใฏใใๅฎ่ฃ
ใ ใชใ
+ - ใใใฎๅ
ฑ้ๅใงใใใชใ
+
+3. ้่คใปๆนๅใใคใณใ็บ่ฆ:
+ - ใฉใคใใฉใชใฎๅ
ฑ้ๅๅฏ่ฝๆง
+ - ้่คๅฎ่ฃ
ใฎๆคๅบ
+ - ใณใผใๅ่ณชๅไธไฝๅฐ
+```
+
+### Phase 3: ๐ ่จ็ป็ซๆก๏ผPlanning๏ผ
+
+```yaml
+1. ๆนๅไปฎ่ชฌไฝๆ:
+ # ใใฎใใญใธใงใฏใๅ
ใง๏ผGit็ฎก็๏ผ
+ File: docs/Development/hypothesis-YYYY-MM-DD.md
+
+ ๅ
ๅฎน:
+ - ็พ็ถใฎๅ้ก็น
+ - ๆนๅๆก
+ - ๆๅพ
ใใใๅนๆ๏ผใใผใฏใณๅๆธใใใใฉใผใใณในๅไธ็ญ๏ผ
+ - ๅฎ่ฃ
ๆน้
+ - ๅฟ
่ฆใชใในใ
+
+2. ใฆใผใถใผใฌใใฅใผ:
+ ใใใใใใใฉใณใงใใใชใใจใใใใใจๆใฃใฆใใพใใ
+
+ ๆ็คบๅ
ๅฎน:
+ - ่ชฟๆป็ตๆใฎใตใใชใผ
+ - ๆนๅๆๆก๏ผ็็ฑไปใ๏ผ
+ - ๅฎ่ฃ
ในใใใ
+ - ๆๅพ
ใใใๆๆ
+
+ ใฆใผใถใผๆฟ่ชๅพ
ใก โ OKๅบใใๅฎ่ฃ
ใธ
+```
+
+### Phase 4: ๐ ๏ธ ๅฎ่ฃ
๏ผImplementation๏ผ
+
+```yaml
+1. ใฝใผในใณใผใไฟฎๆญฃ:
+ # Git็ฎก็ใใใฆใใใใฎใใญใธใงใฏใใงไฝๆฅญ
+ cd ~/github/SuperClaude_Framework
+
+ ไฟฎๆญฃๅฏพ่ฑก:
+ - setup/components/*.py โ ใคใณในใใผใซใญใธใใฏ
+ - superclaude/ โ ใฉใณใฟใคใ ๆฉ่ฝ
+ - setup/data/*.json โ ่จญๅฎใใผใฟ
+
+ # ใตใใจใผใธใงใณใๆดป็จ
+ - backend-architect: ใขใผใญใใฏใใฃๅฎ่ฃ
+ - refactoring-expert: ใณใผใๆนๅ
+ - quality-engineer: ใในใ่จญ่จ
+
+2. ๅฎ่ฃ
่จ้ฒ:
+ File: docs/Development/experiment-YYYY-MM-DD.md
+
+ ๅ
ๅฎน:
+ - ่ฉฆ่ก้ฏ่ชคใฎ่จ้ฒ
+ - ้ญ้ใใใจใฉใผ
+ - ่งฃๆฑบๆนๆณ
+ - ๆฐใฅใ
+```
+
+### Phase 5: โ
ๆค่จผ๏ผValidation๏ผ
+
+```yaml
+1. ใในใไฝๆใปๅฎ่ก:
+ # ใในใใๆธใ
+ Write tests/test_new_feature.py
+
+ # ใในใๅฎ่ก
+ pytest tests/test_new_feature.py -v
+
+ # ใฆใผใถใผ่ฆๆฑใๆบใใใฆใใใ็ขบ่ช
+ - ๆๅพ
้ใใฎๅไฝใ๏ผ
+ - ใจใใธใฑใผในใฏ๏ผ
+ - ใใใฉใผใใณในใฏ๏ผ
+
+2. ใจใฉใผๆใฎๅฏพๅฟ:
+ ใจใฉใผ็บ็
+ โ
+ ๅ
ฌๅผใชใใกใฌใณใน็ขบ่ช
+ ใใใฎใจใฉใผไฝใงใ ใใ๏ผใ
+ ใใใใฎๅฎ็พฉ้ใฃใฆใใใ ใ
+ โ
+ ไฟฎๆญฃ
+ โ
+ ๅใในใ
+ โ
+ ๅๆ ผใพใง็นฐใ่ฟใ
+
+3. ๅไฝ็ขบ่ช:
+ # ใคใณในใใผใซใใฆๅฎ้ใฎ็ฐๅขใงใในใ
+ SuperClaude install --dev
+
+ # ๅไฝ็ขบ่ช
+ claude # ่ตทๅใใฆๅฎ้ใซ่ฉฆใ
+```
+
+### Phase 6: ๐ ๅญฆ็ฟ่จ้ฒ๏ผLearning Documentation๏ผ
+
+```yaml
+1. ๆๅใใฟใผใณ่จ้ฒ:
+ File: docs/patterns/[pattern-name].md
+
+ ๅ
ๅฎน:
+ - ใฉใใชๅ้กใ่งฃๆฑบใใใ
+ - ใฉใๅฎ่ฃ
ใใใ
+ - ใชใใใฎใขใใญใผใใ
+ - ๅๅฉ็จๅฏ่ฝใชใใฟใผใณ
+
+2. ๅคฑๆใปใใน่จ้ฒ:
+ File: docs/mistakes/mistake-YYYY-MM-DD.md
+
+ ๅ
ๅฎน:
+ - ใฉใใชใในใใใใ
+ - ใชใ่ตทใใใ
+ - ้ฒๆญข็ญ
+ - ใใงใใฏใชในใ
+
+3. ใฟในใฏๆดๆฐ:
+ File: docs/Development/tasks/current-tasks.md
+
+ ๅ
ๅฎน:
+ - ๅฎไบใใใฟในใฏ
+ - ๆฌกใฎใฟในใฏ
+ - ้ฒๆ็ถๆณ
+ - ใใญใใซใผ
+
+4. ใฐใญใผใใซใใฟใผใณๆดๆฐ:
+ ๅฟ
่ฆใซๅฟใใฆ:
+ - CLAUDE.mdๆดๆฐ๏ผใฐใญใผใใซใซใผใซ๏ผ
+ - PROJECT/CLAUDE.mdๆดๆฐ๏ผใใญใธใงใฏใๅบๆ๏ผ
+```
+
+### Phase 7: ๐ ใปใใทใงใณไฟๅญ๏ผSession Persistence๏ผ
+
+```yaml
+1. Serenaใกใขใชใผไฟๅญ:
+ write_memory("session_summary", ๅฎไบๅ
ๅฎน)
+ write_memory("next_actions", ๆฌกใฎใขใฏใทใงใณ)
+ write_memory("learnings", ๅญฆใใ ใใจ)
+
+2. ใใญใฅใกใณใๆด็:
+ - docs/temp/ โ docs/patterns/ or docs/mistakes/
+ - ไธๆใใกใคใซๅ้ค
+ - ๆญฃๅผใใญใฅใกใณใๆดๆฐ
+```
+
+---
+
+## ๐ง ๆดป็จๅฏ่ฝใชใใผใซใปใชใฝใผใน
+
+### MCPใตใผใใผ๏ผใใซๆดป็จ๏ผ
+- **Sequential**: ่ค้ใชๅๆใปๆจ่ซ
+- **Context7**: ๅ
ฌๅผใใญใฅใกใณใๅ็
ง
+- **Tavily**: Deep Research๏ผใในใใใฉใฏใใฃใน่ชฟๆป๏ผ
+- **Serena**: ใปใใทใงใณๆฐธ็ถๅใใกใขใชใผ็ฎก็
+- **Playwright**: E2Eใในใใๅไฝ็ขบ่ช
+- **Morphllm**: ไธๆฌใณใผใๅคๆ
+- **Magic**: UI็ๆ๏ผๅฟ
่ฆๆ๏ผ
+- **Chrome DevTools**: ใใใฉใผใใณในๆธฌๅฎ
+
+### ใตใใจใผใธใงใณใ๏ผ้ฉๆ้ฉๆ๏ผ
+- **requirements-analyst**: ่ฆไปถๆด็
+- **system-architect**: ใขใผใญใใฏใใฃ่จญ่จ
+- **backend-architect**: ใใใฏใจใณใๅฎ่ฃ
+- **refactoring-expert**: ใณใผใๆนๅ
+- **security-engineer**: ใปใญใฅใชใใฃๆค่จผ
+- **quality-engineer**: ใในใ่จญ่จใปๅฎ่ก
+- **performance-engineer**: ใใใฉใผใใณในๆ้ฉๅ
+- **technical-writer**: ใใญใฅใกใณใๅท็ญ
+
+### ไปใใญใธใงใฏใ็ตฑๅ
+- **makefile-global**: Makefileๆจๆบๅใใฟใผใณ
+- **airis-mcp-gateway**: MCPใฒใผใใฆใงใค็ตฑๅ
+- ใใฎไปๆ็จใชใใฟใผใณใฏ็ฉๆฅต็ใซๅใ่พผใ
+
+---
+
+## ๐ฏ ้่ฆใชๅๅ
+
+### Git็ฎก็ใฎๅบๅฅ
+```yaml
+โ
Git็ฎก็ใใใฆใใ๏ผๅคๆด่ฟฝ่ทกๅฏ่ฝ๏ผ:
+ - ~/github/SuperClaude_Framework/
+ - ใใใงๅ
จใฆใฎๅคๆดใ่กใ
+ - ใณใใใๅฑฅๆญดใง่ฟฝ่ทก
+ - PRๆๅบๅฏ่ฝ
+
+โ Git็ฎก็ๅค๏ผๅคๆด่ฟฝ่ทกไธๅฏ๏ผ:
+ - ~/.claude/
+ - ่ชญใใ ใใ็่งฃใฎใฟ
+ - ใในใๆใฎใฟไธๆๅคๆด๏ผๅฟ
ใๆปใ๏ผ๏ผ
+```
+
+### ใในใๆใฎๆณจๆ
+```bash
+# ใในใๅ: ๅฟ
ใใใใฏใขใใ
+cp ~/.claude/commands/sc/pm.md ~/.claude/commands/sc/pm.md.backup
+
+# ใในใๅฎ่ก
+# ... ๆค่จผ ...
+
+# ใในใๅพ: ๅฟ
ใๅพฉๅ
๏ผ๏ผ
+mv ~/.claude/commands/sc/pm.md.backup ~/.claude/commands/sc/pm.md
+```
+
+### ใใญใฅใกใณใๆง้
+```
+docs/
+โโโ Development/ # ้็บ็จใใญใฅใกใณใ
+โ โโโ tasks/ # ใฟในใฏ็ฎก็
+โ โโโ architecture-*.md # ใขใผใญใใฏใใฃ
+โ โโโ constraints.md # ๅถ็ดใป็ฆๆญขไบ้
+โ โโโ hypothesis-*.md # ๆนๅไปฎ่ชฌ
+โ โโโ experiment-*.md # ๅฎ้จ่จ้ฒ
+โโโ patterns/ # ๆๅใใฟใผใณ๏ผๆธ
ๆธๅพ๏ผ
+โโโ mistakes/ # ๅคฑๆ่จ้ฒใจ้ฒๆญข็ญ
+โโโ (ๆขๅญใฎUser-Guide็ญ)
+```
+
+---
+
+## ๐ ๅฎ่ฃ
ๅชๅ
ๅบฆ
+
+### Phase 1๏ผๅฟ
้ ๏ผ
+1. ใใญใฅใกใณใๆง้ ๆดๅ
+2. ใฟในใฏ็ฎก็ใทในใใ
+3. ใปใใทใงใณๅพฉๅ
ใฏใผใฏใใญใผ
+
+### Phase 2๏ผ้่ฆ๏ผ
+4. ่ชๅทฑ่ฉไพกใปๆค่จผใซใผใ
+5. ๅญฆ็ฟ่จ้ฒ่ชๅๅ
+6. ใจใฉใผๆๅๅญฆ็ฟใใญใผ
+
+### Phase 3๏ผๅผทๅ๏ผ
+7. PMOๆฉ่ฝ๏ผ้่คๆคๅบใๅ
ฑ้ๅๆๆก๏ผ
+8. ใใใฉใผใใณในๆธฌๅฎใปๆนๅ
+9. ไปใใญใธใงใฏใ็ตฑๅ
+
+---
+
+## ๐ ๆๅๆๆจ
+
+### ๅฎ้็ๆๆจ
+- **็นฐใ่ฟใๆ็คบใฎๅๆธ**: ๅใๆ็คบ โ 50%ๅๆธ็ฎๆจ
+- **ใในๅ็บ็**: ๅใใใน โ 80%ๅๆธ็ฎๆจ
+- **ใปใใทใงใณๅพฉๅ
ๆ้**: <30็งใงๅๅใฎ็ถใใใ้ๅง
+
+### ๅฎๆง็ๆๆจ
+- ใฆใผใถใผใใๅๅใฎ็ถใใใใใจ่จใใ ใใงๅ้ใงใใ
+- ้ๅปใฎใในใ่ชๅ็ใซ้ฟใใใใ
+- ๅ
ฌๅผใใญใฅใกใณใๅ็
งใ่ชๅๅใใใฆใใ
+- ๅฎ่ฃ
โใในใโๆค่จผใ่ชๅพ็ใซๅใ
+
+---
+
+## ๐ก ๆฌกใฎใขใฏใทใงใณ
+
+ใใฎใใญใฅใกใณใไฝๆๅพ:
+1. ๆขๅญใฎใคใณในใใผใซใญใธใใฏ็่งฃ๏ผsetup/components/๏ผ
+2. ใฟในใฏ็ฎก็ใใญใฅใกใณใไฝๆ๏ผdocs/Development/tasks/๏ผ
+3. PM Agentๅฎ่ฃ
ไฟฎๆญฃ๏ผใใฎใฏใผใฏใใญใผใๅฎ้ใซๅฎ่ฃ
๏ผ
+
+ใใฎใใญใฅใกใณใ่ชไฝใ**PM Agentใฎๆฒๆณ**ใจใชใใ
diff --git a/docs/Development/pm-agent-integration.md b/docs/Development/pm-agent-integration.md
new file mode 100644
index 0000000..2656a72
--- /dev/null
+++ b/docs/Development/pm-agent-integration.md
@@ -0,0 +1,477 @@
+# PM Agent Mode Integration Guide
+
+**Last Updated**: 2025-10-14
+**Target Version**: 4.2.0
+**Status**: Implementation Guide
+
+---
+
+## ๐ Overview
+
+This guide provides step-by-step procedures for integrating PM Agent mode as SuperClaude's always-active meta-layer with session lifecycle management, PDCA self-evaluation, and systematic knowledge management.
+
+---
+
+## ๐ฏ Integration Goals
+
+1. **Session Lifecycle**: Auto-activation at session start with context restoration
+2. **PDCA Engine**: Automated Plan-Do-Check-Act cycle execution
+3. **Memory Operations**: Serena MCP integration for session persistence
+4. **Documentation Strategy**: Systematic knowledge evolution
+
+---
+
+## ๐ Architecture Integration
+
+### PM Agent Position
+
+```
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ PM Agent Mode (Meta-Layer) โ
+โ โข Always Active โ
+โ โข Session Management โ
+โ โข PDCA Self-Evaluation โ
+โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ โ
+ [Specialist Agents Layer]
+ โ
+ [Commands & Modes Layer]
+ โ
+ [MCP Tool Layer]
+```
+
+See: [ARCHITECTURE.md](./ARCHITECTURE.md) for full system architecture
+
+---
+
+## ๐ง Phase 2: Core Implementation
+
+### File Structure
+
+```
+superclaude/
+โโโ Commands/
+โ โโโ pm.md # โ
Already updated
+โโโ Agents/
+โ โโโ pm-agent.md # โ
Already updated
+โโโ Core/
+ โโโ __init__.py # Module initialization
+ โโโ session_lifecycle.py # ๐ Session management
+ โโโ pdca_engine.py # ๐ PDCA automation
+ โโโ memory_ops.py # ๐ Memory operations
+```
+
+### Implementation Order
+
+1. `memory_ops.py` - Serena MCP wrapper (foundation)
+2. `session_lifecycle.py` - Session management (depends on memory_ops)
+3. `pdca_engine.py` - PDCA automation (depends on memory_ops)
+
+---
+
+## 1๏ธโฃ memory_ops.py Implementation
+
+### Purpose
+Wrapper for Serena MCP memory operations with error handling and fallback.
+
+### Key Functions
+
+```python
+# superclaude/Core/memory_ops.py
+
+class MemoryOperations:
+ """Serena MCP memory operations wrapper"""
+
+ def list_memories() -> List[str]:
+ """List all available memories"""
+
+ def read_memory(key: str) -> Optional[Dict]:
+ """Read memory by key"""
+
+ def write_memory(key: str, value: Dict) -> bool:
+ """Write memory with key"""
+
+ def delete_memory(key: str) -> bool:
+ """Delete memory by key"""
+```
+
+### Integration Points
+- Connect to Serena MCP server
+- Handle connection errors gracefully
+- Provide fallback for offline mode
+- Validate memory structure
+
+### Testing
+```bash
+pytest tests/test_memory_ops.py -v
+```
+
+---
+
+## 2๏ธโฃ session_lifecycle.py Implementation
+
+### Purpose
+Auto-activation at session start, context restoration, user report generation.
+
+### Key Functions
+
+```python
+# superclaude/Core/session_lifecycle.py
+
+class SessionLifecycle:
+ """Session lifecycle management"""
+
+ def on_session_start():
+ """Hook for session start (auto-activation)"""
+ # 1. list_memories()
+ # 2. read_memory("pm_context")
+ # 3. read_memory("last_session")
+ # 4. read_memory("next_actions")
+ # 5. generate_user_report()
+
+ def generate_user_report() -> str:
+ """Generate user report (ๅๅ/้ฒๆ/ไปๅ/่ชฒ้ก)"""
+
+ def on_session_end():
+ """Hook for session end (checkpoint save)"""
+ # 1. write_memory("last_session", summary)
+ # 2. write_memory("next_actions", todos)
+ # 3. write_memory("pm_context", complete_state)
+```
+
+### User Report Format
+```
+ๅๅ: [last session summary]
+้ฒๆ: [current progress status]
+ไปๅ: [planned next actions]
+่ชฒ้ก: [blockers or issues]
+```
+
+### Integration Points
+- Hook into Claude Code session start
+- Read memories using memory_ops
+- Generate human-readable report
+- Handle missing or corrupted memory
+
+### Testing
+```bash
+pytest tests/test_session_lifecycle.py -v
+```
+
+---
+
+## 3๏ธโฃ pdca_engine.py Implementation
+
+### Purpose
+Automate PDCA cycle execution with documentation generation.
+
+### Key Functions
+
+```python
+# superclaude/Core/pdca_engine.py
+
+class PDCAEngine:
+ """PDCA cycle automation"""
+
+ def plan_phase(goal: str):
+ """Generate hypothesis (ไปฎ่ชฌ)"""
+ # 1. write_memory("plan", goal)
+ # 2. Create docs/temp/hypothesis-YYYY-MM-DD.md
+
+ def do_phase():
+ """Track experimentation (ๅฎ้จ)"""
+ # 1. TodoWrite tracking
+ # 2. write_memory("checkpoint", progress) every 30min
+ # 3. Update docs/temp/experiment-YYYY-MM-DD.md
+
+ def check_phase():
+ """Self-evaluation (่ฉไพก)"""
+ # 1. think_about_task_adherence()
+ # 2. think_about_whether_you_are_done()
+ # 3. Create docs/temp/lessons-YYYY-MM-DD.md
+
+ def act_phase():
+ """Knowledge extraction (ๆนๅ)"""
+ # 1. Success โ docs/patterns/[pattern-name].md
+ # 2. Failure โ docs/mistakes/mistake-YYYY-MM-DD.md
+ # 3. Update CLAUDE.md if global pattern
+```
+
+### Documentation Templates
+
+**hypothesis-template.md**:
+```markdown
+# Hypothesis: [Goal Description]
+
+Date: YYYY-MM-DD
+Status: Planning
+
+## Goal
+What are we trying to accomplish?
+
+## Approach
+How will we implement this?
+
+## Success Criteria
+How do we know when we're done?
+
+## Potential Risks
+What could go wrong?
+```
+
+**experiment-template.md**:
+```markdown
+# Experiment Log: [Implementation Name]
+
+Date: YYYY-MM-DD
+Status: In Progress
+
+## Implementation Steps
+- [ ] Step 1
+- [ ] Step 2
+
+## Errors Encountered
+- Error 1: Description, solution
+
+## Solutions Applied
+- Solution 1: Description, result
+
+## Checkpoint Saves
+- 10:00: [progress snapshot]
+- 10:30: [progress snapshot]
+```
+
+### Integration Points
+- Create docs/ directory templates
+- Integrate with TodoWrite
+- Call Serena MCP think operations
+- Generate documentation files
+
+### Testing
+```bash
+pytest tests/test_pdca_engine.py -v
+```
+
+---
+
+## ๐ Phase 3: Serena MCP Integration
+
+### Prerequisites
+```bash
+# Install Serena MCP server
+# See: docs/troubleshooting/serena-installation.md
+```
+
+### Configuration
+```json
+// ~/.claude/.claude.json
+{
+ "mcpServers": {
+ "serena": {
+ "command": "uv",
+ "args": ["run", "serena-mcp"]
+ }
+ }
+}
+```
+
+### Memory Structure
+```json
+{
+ "pm_context": {
+ "project": "SuperClaude_Framework",
+ "current_phase": "Phase 2",
+ "architecture": "Context-Oriented Configuration",
+ "patterns": ["PDCA Cycle", "Session Lifecycle"]
+ },
+ "last_session": {
+ "date": "2025-10-14",
+ "accomplished": ["Phase 1 complete"],
+ "issues": ["Serena MCP not configured"],
+ "learned": ["Session Lifecycle pattern"]
+ },
+ "next_actions": [
+ "Implement session_lifecycle.py",
+ "Configure Serena MCP",
+ "Test memory operations"
+ ]
+}
+```
+
+### Testing Serena Connection
+```bash
+# Test memory operations
+python -m SuperClaude.Core.memory_ops --test
+```
+
+---
+
+## ๐ Phase 4: Documentation Strategy
+
+### Directory Structure
+```
+docs/
+โโโ temp/ # Temporary (7-day lifecycle)
+โ โโโ hypothesis-YYYY-MM-DD.md
+โ โโโ experiment-YYYY-MM-DD.md
+โ โโโ lessons-YYYY-MM-DD.md
+โโโ patterns/ # Formal patterns (ๆฐธไน
ไฟๅญ)
+โ โโโ [pattern-name].md
+โโโ mistakes/ # Mistake records (ๆฐธไน
ไฟๅญ)
+ โโโ mistake-YYYY-MM-DD.md
+```
+
+### Lifecycle Automation
+```bash
+# Create cleanup script
+scripts/cleanup_temp_docs.sh
+
+# Run daily via cron
+0 0 * * * /path/to/scripts/cleanup_temp_docs.sh
+```
+
+### Migration Scripts
+```bash
+# Migrate successful experiments to patterns
+python scripts/migrate_to_patterns.py
+
+# Migrate failures to mistakes
+python scripts/migrate_to_mistakes.py
+```
+
+---
+
+## ๐ Phase 5: Auto-Activation (Research Needed)
+
+### Research Questions
+1. How does Claude Code handle initialization?
+2. Are there plugin hooks available?
+3. Can we intercept session start events?
+
+### Implementation Plan (TBD)
+Once research complete, implement auto-activation hooks:
+
+```python
+# superclaude/Core/auto_activation.py (future)
+
+def on_claude_code_start():
+ """Auto-activate PM Agent at session start"""
+ session_lifecycle.on_session_start()
+```
+
+---
+
+## โ
Implementation Checklist
+
+### Phase 2: Core Implementation
+- [ ] Implement `memory_ops.py`
+- [ ] Write unit tests for memory_ops
+- [ ] Implement `session_lifecycle.py`
+- [ ] Write unit tests for session_lifecycle
+- [ ] Implement `pdca_engine.py`
+- [ ] Write unit tests for pdca_engine
+- [ ] Integration testing
+
+### Phase 3: Serena MCP
+- [ ] Install Serena MCP server
+- [ ] Configure `.claude.json`
+- [ ] Test memory operations
+- [ ] Test think operations
+- [ ] Test cross-session persistence
+
+### Phase 4: Documentation Strategy
+- [ ] Create `docs/temp/` template
+- [ ] Create `docs/patterns/` template
+- [ ] Create `docs/mistakes/` template
+- [ ] Implement lifecycle automation
+- [ ] Create migration scripts
+
+### Phase 5: Auto-Activation
+- [ ] Research Claude Code hooks
+- [ ] Design auto-activation system
+- [ ] Implement auto-activation
+- [ ] Test session start behavior
+
+---
+
+## ๐งช Testing Strategy
+
+### Unit Tests
+```bash
+tests/
+โโโ test_memory_ops.py # Memory operations
+โโโ test_session_lifecycle.py # Session management
+โโโ test_pdca_engine.py # PDCA automation
+```
+
+### Integration Tests
+```bash
+tests/integration/
+โโโ test_pm_agent_flow.py # End-to-end PM Agent
+โโโ test_serena_integration.py # Serena MCP integration
+โโโ test_cross_session.py # Session persistence
+```
+
+### Manual Testing
+1. Start new session โ Verify context restoration
+2. Work on task โ Verify checkpoint saves
+3. End session โ Verify state preservation
+4. Restart โ Verify seamless resumption
+
+---
+
+## ๐ Success Criteria
+
+### Functional
+- [ ] PM Agent activates at session start
+- [ ] Context restores from memory
+- [ ] User report generates correctly
+- [ ] PDCA cycle executes automatically
+- [ ] Documentation strategy works
+
+### Performance
+- [ ] Session start delay <500ms
+- [ ] Memory operations <100ms
+- [ ] Context restoration reliable (>99%)
+
+### Quality
+- [ ] Test coverage >90%
+- [ ] No regression in existing features
+- [ ] Documentation complete
+
+---
+
+## ๐ง Troubleshooting
+
+### Common Issues
+
+**"Serena MCP not connecting"**
+- Check server installation
+- Verify `.claude.json` configuration
+- Test connection: `claude mcp list`
+
+**"Memory operations failing"**
+- Check network connection
+- Verify Serena server running
+- Check error logs
+
+**"Context not restoring"**
+- Verify memory structure
+- Check `pm_context` exists
+- Test with fresh memory
+
+---
+
+## ๐ References
+
+- [ARCHITECTURE.md](./ARCHITECTURE.md) - System architecture
+- [ROADMAP.md](./ROADMAP.md) - Development roadmap
+- [pm-agent-implementation-status.md](../pm-agent-implementation-status.md) - Status tracking
+- [Commands/pm.md](../../superclaude/Commands/pm.md) - PM Agent command
+- [Agents/pm-agent.md](../../superclaude/Agents/pm-agent.md) - PM Agent persona
+
+---
+
+**Last Verified**: 2025-10-14
+**Next Review**: 2025-10-21 (1 week)
+**Version**: 4.1.5
diff --git a/docs/Development/project-structure-understanding.md b/docs/Development/project-structure-understanding.md
new file mode 100644
index 0000000..9f82f66
--- /dev/null
+++ b/docs/Development/project-structure-understanding.md
@@ -0,0 +1,368 @@
+# SuperClaude Framework - Project Structure Understanding
+
+> **Critical Understanding**: ใใฎใใญใธใงใฏใใจใคใณในใใผใซๅพใฎ็ฐๅขใฎ้ขไฟ
+
+---
+
+## ๐๏ธ 2ใคใฎไธ็ใฎๅบๅฅ
+
+### 1. ใใฎใใญใธใงใฏใ๏ผGit็ฎก็ใป้็บ็ฐๅข๏ผ
+
+**Location**: `~/github/SuperClaude_Framework/`
+
+**Role**: ใฝใผในใณใผใใป้็บใปใในใ
+
+```
+SuperClaude_Framework/
+โโโ setup/ # ใคใณในใใผใฉใผใญใธใใฏ
+โ โโโ components/ # ใณใณใใผใใณใๅฎ็พฉ๏ผไฝใใคใณในใใผใซใใใ๏ผ
+โ โโโ data/ # ่จญๅฎใใผใฟ๏ผJSON/YAML๏ผ
+โ โโโ cli/ # CLIใคใณใฟใผใใงใผใน
+โ โโโ utils/ # ใฆใผใใฃใชใใฃ้ขๆฐ
+โ โโโ services/ # ใตใผใในใญใธใใฏ
+โ
+โโโ superclaude/ # ใฉใณใฟใคใ ใญใธใใฏ๏ผๅฎ่กๆใฎๅไฝ๏ผ
+โ โโโ core/ # ใณใขๆฉ่ฝ
+โ โโโ modes/ # ่กๅใขใผใ
+โ โโโ agents/ # ใจใผใธใงใณใๅฎ็พฉ
+โ โโโ mcp/ # MCPใตใผใใผ็ตฑๅ
+โ โโโ commands/ # ใณใใณใๅฎ่ฃ
+โ
+โโโ tests/ # ใในใใณใผใ
+โโโ docs/ # ้็บ่
ๅใใใญใฅใกใณใ
+โโโ pyproject.toml # Python่จญๅฎ
+โโโ package.json # npm่จญๅฎ
+```
+
+**Operations**:
+- โ
ใฝใผในใณใผใๅคๆด
+- โ
Git ใณใใใใปPR
+- โ
ใในใๅฎ่ก
+- โ
ใใญใฅใกใณใไฝๆ
+- โ
ใใผใธใงใณ็ฎก็
+
+---
+
+### 2. ใคใณในใใผใซๅพ๏ผใฆใผใถใผ็ฐๅขใปGit็ฎก็ๅค๏ผ
+
+**Location**: `~/.claude/`
+
+**Role**: ๅฎ้ใซๅไฝใใ่จญๅฎใปใณใใณใ๏ผใฆใผใถใผ็ฐๅข๏ผ
+
+```
+~/.claude/
+โโโ commands/
+โ โโโ sc/ # ในใฉใใทใฅใณใใณใ๏ผใคใณในใใผใซๅพ๏ผ
+โ โโโ pm.md
+โ โโโ implement.md
+โ โโโ test.md
+โ โโโ ... (26 commands)
+โ
+โโโ CLAUDE.md # ใฐใญใผใใซ่จญๅฎ๏ผใคใณในใใผใซๅพ๏ผ
+โโโ *.md # ใขใผใๅฎ็พฉ๏ผใคใณในใใผใซๅพ๏ผ
+โ โโโ MODE_Brainstorming.md
+โ โโโ MODE_Orchestration.md
+โ โโโ ...
+โ
+โโโ .claude.json # Claude Code่จญๅฎ
+```
+
+**Operations**:
+- โ
**่ชญใใ ใ**๏ผ็่งฃใป็ขบ่ช็จ๏ผ
+- โ
ๅไฝ็ขบ่ช
+- โ ๏ธ ใในใๆใฎใฟไธๆๅคๆด๏ผ**ๅฟ
ใๅ
ใซๆปใ๏ผ**๏ผ
+- โ ๆฐธ็ถ็ใชๅคๆด็ฆๆญข๏ผGit่ฟฝ่ทกไธๅฏ๏ผ
+
+---
+
+## ๐ ใคใณในใใผใซใใญใผ
+
+### ใฆใผใถใผๆไฝ
+```bash
+# 1. ใคใณในใใผใซ
+pipx install SuperClaude
+# ใพใใฏ
+npm install -g @bifrost_inc/superclaude
+
+# 2. ใปใใใขใใๅฎ่ก
+SuperClaude install
+```
+
+### ๅ
้จๅฆ็๏ผsetup/ใๅฎ่ก๏ผ
+```python
+# setup/components/*.py ใๅฎ่กใใใ
+
+1. ~/.claude/ ใใฃใฌใฏใใชไฝๆ
+2. commands/sc/ ใซในใฉใใทใฅใณใใณใ้
็ฝฎ
+3. CLAUDE.md ใจๅ็จฎ *.md ้
็ฝฎ
+4. .claude.json ๆดๆฐ
+5. MCPใตใผใใผ่จญๅฎ
+```
+
+### ็ตๆ
+- **ใใฎใใญใธใงใฏใใฎใใกใคใซ** โ **~/.claude/ ใซใณใใผ**
+- ใฆใผใถใผใClaude่ตทๅ โ `~/.claude/` ใฎ่จญๅฎใ่ชญใฟ่พผใพใใ
+- `/sc:pm` ๅฎ่ก โ `~/.claude/commands/sc/pm.md` ใๅฑ้ใใใ
+
+---
+
+## ๐ ้็บใฏใผใฏใใญใผ
+
+### โ ้้ใฃใๆนๆณ
+```bash
+# Git็ฎก็ๅคใ็ดๆฅๅคๆด
+vim ~/.claude/commands/sc/pm.md # โ ใใก๏ผๅฑฅๆญด่ฟฝใใชใ
+
+# ๅคๆดใในใ
+claude # ๅไฝ็ขบ่ช
+
+# ๅคๆดใ ~/.claude/ ใซๆฎใ
+# โ ๅ
ใซๆปใใฎๅฟใใ
+# โ ่จญๅฎใใใกใใใกใใซใชใ
+# โ Gitใง่ฟฝ่ทกใงใใชใ
+```
+
+### โ
ๆญฃใใๆนๆณ
+
+#### Step 1: ๆขๅญๅฎ่ฃ
ใ็่งฃ
+```bash
+cd ~/github/SuperClaude_Framework
+
+# ใคใณในใใผใซใญใธใใฏ็ขบ่ช
+Read setup/components/commands.py # ใณใใณใใฎใคใณในใใผใซๆนๆณ
+Read setup/components/modes.py # ใขใผใใฎใคใณในใใผใซๆนๆณ
+Read setup/data/commands.json # ใณใใณใๅฎ็พฉใใผใฟ
+
+# ใคใณในใใผใซๅพใฎ็ถๆ
็ขบ่ช๏ผ็่งฃใฎใใ๏ผ
+ls ~/.claude/commands/sc/
+cat ~/.claude/commands/sc/pm.md # ็พๅจใฎไปๆง็ขบ่ช
+
+# ใใชใใปใฉใsetup/components/commands.py ใงใใๅฆ็ใใใฆใ
+# ~/.claude/commands/sc/ ใซ้
็ฝฎใใใใฎใญใ
+```
+
+#### Step 2: ๆนๅๆกใใใญใฅใกใณใๅ
+```bash
+cd ~/github/SuperClaude_Framework
+
+# Git็ฎก็ใใใฆใใใใฎใใญใธใงใฏใๅ
ใง
+Write docs/Development/hypothesis-pm-improvement-YYYY-MM-DD.md
+
+# ๅ
ๅฎนไพ:
+# - ็พ็ถใฎๅ้ก
+# - ๆนๅๆก
+# - ๅฎ่ฃ
ๆน้
+# - ๆๅพ
ใใใๅนๆ
+```
+
+#### Step 3: ใในใใๅฟ
่ฆใชๅ ดๅ
+```bash
+# ใใใฏใขใใไฝๆ๏ผๅฟ
้ ๏ผ๏ผ
+cp ~/.claude/commands/sc/pm.md ~/.claude/commands/sc/pm.md.backup
+
+# ๅฎ้จ็ๅคๆด
+vim ~/.claude/commands/sc/pm.md
+
+# Claude่ตทๅใใฆๆค่จผ
+claude
+# ... ๅไฝ็ขบ่ช ...
+
+# ใในใๅฎไบๅพใๅฟ
ใๅพฉๅ
๏ผ๏ผ
+mv ~/.claude/commands/sc/pm.md.backup ~/.claude/commands/sc/pm.md
+```
+
+#### Step 4: ๆฌๅฎ่ฃ
+```bash
+cd ~/github/SuperClaude_Framework
+
+# ใฝใผในใณใผใๅดใงๅคๆด
+Edit setup/components/commands.py # ใคใณในใใผใซใญใธใใฏไฟฎๆญฃ
+Edit setup/data/commands/pm.md # ใณใใณใไปๆงไฟฎๆญฃ
+
+# ใในใ่ฟฝๅ
+Write tests/test_pm_command.py
+
+# ใในใๅฎ่ก
+pytest tests/test_pm_command.py -v
+
+# ใณใใใ๏ผGitๅฑฅๆญดใซๆฎใ๏ผ
+git add setup/ tests/
+git commit -m "feat: enhance PM command with autonomous workflow"
+```
+
+#### Step 5: ๅไฝ็ขบ่ช
+```bash
+# ้็บ็ใคใณในใใผใซ
+cd ~/github/SuperClaude_Framework
+pip install -e .
+
+# ใพใใฏ
+SuperClaude install --dev
+
+# ๅฎ้ใฎ็ฐๅขใงใในใ
+claude
+/sc:pm "test request"
+```
+
+---
+
+## ๐ฏ ้่ฆใชใซใผใซ
+
+### Rule 1: Git็ฎก็ใฎๅข็ใๅฎใ
+- **ๅคๆด**: ใใฎใใญใธใงใฏใๅ
ใฎใฟ
+- **็ขบ่ช**: `~/.claude/` ใฏ่ชญใใ ใ
+- **ใในใ**: ใใใฏใขใใ โ ๅคๆด โ ๅพฉๅ
+
+### Rule 2: ใในใๆใฏๅฟ
ใๅพฉๅ
+```bash
+# ใในใๅ
+cp original backup
+
+# ใในใ
+# ... ๅฎ้จ ...
+
+# ใในใๅพ๏ผๅฟ
้ ๏ผ๏ผ
+mv backup original
+```
+
+### Rule 3: ใใญใฅใกใณใ้งๅ้็บ
+1. ็่งฃ โ docs/Development/ ใซ่จ้ฒ
+2. ไปฎ่ชฌ โ docs/Development/hypothesis-*.md
+3. ๅฎ้จ โ docs/Development/experiment-*.md
+4. ๆๅ โ docs/patterns/
+5. ๅคฑๆ โ docs/mistakes/
+
+---
+
+## ๐ ็่งฃใในใใใกใคใซ
+
+### ใคใณในใใผใฉใผๅด๏ผsetup/๏ผ
+```python
+# ๅชๅ
ๅบฆ: ้ซ
+setup/components/commands.py # ใณใใณใใคใณในใใผใซ
+setup/components/modes.py # ใขใผใใคใณในใใผใซ
+setup/components/agents.py # ใจใผใธใงใณใๅฎ็พฉ
+setup/data/commands/*.md # ใณใใณใไปๆง๏ผใฝใผใน๏ผ
+setup/data/modes/*.md # ใขใผใไปๆง๏ผใฝใผใน๏ผ
+
+# ใใใใ ~/.claude/ ใซ้
็ฝฎใใใ
+```
+
+### ใฉใณใฟใคใ ๅด๏ผsuperclaude/๏ผ
+```python
+# ๅชๅ
ๅบฆ: ไธญ
+superclaude/__main__.py # CLIใจใณใใชใผใใคใณใ
+superclaude/core/ # ใณใขๆฉ่ฝๅฎ่ฃ
+superclaude/agents/ # ใจใผใธใงใณใใญใธใใฏ
+```
+
+### ใคใณในใใผใซๅพ๏ผ~/.claude/๏ผ
+```markdown
+# ๅชๅ
ๅบฆ: ็่งฃใฎใใ๏ผๅคๆดไธๅฏ๏ผ
+~/.claude/commands/sc/pm.md # ๅฎ้ใซๅใPMไปๆง
+~/.claude/MODE_*.md # ๅฎ้ใซๅใใขใผใไปๆง
+~/.claude/CLAUDE.md # ๅฎ้ใซ่ชญใฟ่พผใพใใใฐใญใผใใซ่จญๅฎ
+```
+
+---
+
+## ๐ ใใใใฐๆนๆณ
+
+### ใคใณในใใผใซ็ขบ่ช
+```bash
+# ใคใณในใใผใซๆธใฟใณใณใใผใใณใ็ขบ่ช
+SuperClaude install --list-components
+
+# ใคใณในใใผใซๅ
็ขบ่ช
+ls -la ~/.claude/commands/sc/
+ls -la ~/.claude/*.md
+```
+
+### ๅไฝ็ขบ่ช
+```bash
+# Claude่ตทๅ
+claude
+
+# ใณใใณใๅฎ่ก
+/sc:pm "test"
+
+# ใญใฐ็ขบ่ช๏ผๅฟ
่ฆใซๅฟใใฆ๏ผ
+tail -f ~/.claude/logs/*.log
+```
+
+### ใใฉใใซใทใฅใผใใฃใณใฐ
+```bash
+# ่จญๅฎใๅฃใใๅ ดๅ
+SuperClaude install --force # ๅใคใณในใใผใซ
+
+# ้็บ็ใซๅใๆฟใ
+cd ~/github/SuperClaude_Framework
+pip install -e .
+
+# ๆฌ็ช็ใซๆปใ
+pip uninstall superclaude
+pipx install SuperClaude
+```
+
+---
+
+## ๐ก ใใใใ้้ใ
+
+### ้้ใ1: Git็ฎก็ๅคใๅคๆด
+```bash
+# โ WRONG
+vim ~/.claude/commands/sc/pm.md
+git add ~/.claude/ # โ ใงใใชใ๏ผGit็ฎก็ๅค
+```
+
+### ้้ใ2: ใใใฏใขใใใชใใในใ
+```bash
+# โ WRONG
+vim ~/.claude/commands/sc/pm.md
+# ใในใ...
+# ๅ
ใซๆปใใฎๅฟใใ โ ่จญๅฎใใกใใใกใ
+```
+
+### ้้ใ3: ใฝใผใน็ขบ่ชใใใซๅคๆด
+```bash
+# โ WRONG
+ใPMใขใผใ็ดใใใใ
+โ ใใใชใ ~/.claude/ ๅคๆด
+โ ใฝใผในใณใผใ็่งฃใใฆใชใ
+โ ๅใคใณในใใผใซใงไธๆธใใใใ
+```
+
+### ๆญฃ่งฃ
+```bash
+# โ
CORRECT
+1. setup/components/ ใงใญใธใใฏ็่งฃ
+2. docs/Development/ ใซๆนๅๆก่จ้ฒ
+3. setup/ ๅดใงๅคๆดใปใในใ
+4. Git ใณใใใ
+5. SuperClaude install --dev ใงๅไฝ็ขบ่ช
+```
+
+---
+
+## ๐ ๆฌกใฎในใใใ
+
+ใใฎใใญใฅใกใณใ็่งฃๅพ:
+
+1. **setup/components/ ่ชญ่งฃ**
+ - ใคใณในใใผใซใญใธใใฏใฎ็่งฃ
+ - ใฉใใซไฝใ้
็ฝฎใใใใ
+
+2. **ๆขๅญไปๆงใฎๆๆก**
+ - `~/.claude/commands/sc/pm.md` ็ขบ่ช๏ผ่ชญใใ ใ๏ผ
+ - ็พๅจใฎๅไฝ็่งฃ
+
+3. **ๆนๅๆๆกไฝๆ**
+ - `docs/Development/hypothesis-*.md` ไฝๆ
+ - ใฆใผใถใผใฌใใฅใผ
+
+4. **ๅฎ่ฃ
ใปใในใ**
+ - `setup/` ๅดใงๅคๆด
+ - `tests/` ใงใในใ่ฟฝๅ
+ - Git็ฎก็ไธใง้็บ
+
+ใใใง**ไฝ็พๅใๅใ่ชฌๆใใใชใใฆๆธใ**ใใใซใชใใ
diff --git a/docs/Development/tasks/current-tasks.md b/docs/Development/tasks/current-tasks.md
new file mode 100644
index 0000000..c38c4c7
--- /dev/null
+++ b/docs/Development/tasks/current-tasks.md
@@ -0,0 +1,163 @@
+# Current Tasks - SuperClaude Framework
+
+> **Last Updated**: 2025-10-14
+> **Session**: PM Agent Enhancement & PDCA Integration
+
+---
+
+## ๐ฏ Main Objective
+
+**PM Agent ใๅฎ็งใช่ชๅพ็ใชใผใฑในใใฌใผใฟใผใซ้ฒๅใใใ**
+
+- ็นฐใ่ฟใๆ็คบใไธ่ฆใซใใ
+- ๅใใในใ็นฐใ่ฟใใชใ
+- ใปใใทใงใณ้ใงๅญฆ็ฟๅ
ๅฎนใไฟๆ
+- ่ชๅพ็ใซPDCAใตใคใฏใซใๅใ
+
+---
+
+## โ
Completed Tasks
+
+### Phase 1: ใใญใฅใกใณใๅบ็คๆดๅ
+- [x] **PM Agent็ๆณใฏใผใฏใใญใผใใใญใฅใกใณใๅ**
+ - File: `docs/Development/pm-agent-ideal-workflow.md`
+ - Content: ๅฎ็งใชใฏใผใฏใใญใผ๏ผ7ใใงใผใบ๏ผ
+ - Purpose: ๆฌกๅใปใใทใงใณใงๅใ่ชฌๆใ็นฐใ่ฟใใชใ
+
+- [x] **ใใญใธใงใฏใๆง้ ็่งฃใใใญใฅใกใณใๅ**
+ - File: `docs/Development/project-structure-understanding.md`
+ - Content: Git็ฎก็ใจใคใณในใใผใซๅพ็ฐๅขใฎๅบๅฅ
+ - Purpose: ไฝ็พๅใ่ชฌๆใใๅ
ๅฎนใๅค้จๅ
+
+- [x] **ใคใณในใใผใซใใญใผ็่งฃใใใญใฅใกใณใๅ**
+ - File: `docs/Development/installation-flow-understanding.md`
+ - Content: CommandsComponentๅไฝใฎๅฎๅ
จ็่งฃ
+ - Source: `superclaude/commands/*.md` โ `~/.claude/commands/sc/*.md`
+
+- [x] **ใใฃใฌใฏใใชๆง้ ไฝๆ**
+ - `docs/Development/tasks/` - ใฟในใฏ็ฎก็
+ - `docs/patterns/` - ๆๅใใฟใผใณ่จ้ฒ
+ - `docs/mistakes/` - ๅคฑๆ่จ้ฒใจ้ฒๆญข็ญ
+
+---
+
+## ๐ In Progress
+
+### Phase 2: ็พ็ถๅๆใจๆนๅๆๆก
+
+- [ ] **superclaude/commands/pm.md ็พๅจใฎไปๆง็ขบ่ช**
+ - Status: Pending
+ - Action: ใฝใผในใใกใคใซใ่ชญใใง็พๅจใฎๅฎ่ฃ
ใ็่งฃ
+ - File: `superclaude/commands/pm.md`
+
+- [ ] **~/.claude/commands/sc/pm.md ๅไฝ็ขบ่ช**
+ - Status: Pending
+ - Action: ใคใณในใใผใซๅพใฎๅฎ้ใฎไปๆง็ขบ่ช๏ผ่ชญใใ ใ๏ผ
+ - File: `~/.claude/commands/sc/pm.md`
+
+- [ ] **ๆนๅๆๆกใใญใฅใกใณใไฝๆ**
+ - Status: Pending
+ - Action: ไปฎ่ชฌใใญใฅใกใณใไฝๆ
+ - File: `docs/Development/hypothesis-pm-enhancement-2025-10-14.md`
+ - Content:
+ - ็พ็ถใฎๅ้ก็น๏ผใใญใฅใกใณใๅฏใใPMOๆฉ่ฝไธ่ถณ๏ผ
+ - ๆนๅๆก๏ผ่ชๅพ็PDCAใ่ชๅทฑ่ฉไพก๏ผ
+ - ๅฎ่ฃ
ๆน้
+ - ๆๅพ
ใใใๅนๆ
+
+---
+
+## ๐ Pending Tasks
+
+### Phase 3: ๅฎ่ฃ
ไฟฎๆญฃ
+
+- [ ] **superclaude/commands/pm.md ไฟฎๆญฃ**
+ - Content:
+ - PDCA่ชๅๅฎ่กใฎๅผทๅ
+ - docs/ใใฃใฌใฏใใชๆดป็จใฎๆ็คบ
+ - ่ชๅทฑ่ฉไพกในใใใใฎ่ฟฝๅ
+ - ใจใฉใผๆๅๅญฆ็ฟใใญใผใฎ่ฟฝๅ
+ - PMOๆฉ่ฝ๏ผ้่คๆคๅบใๅ
ฑ้ๅๆๆก๏ผ
+
+- [ ] **MODE_Task_Management.md ไฟฎๆญฃ**
+ - Serenaใกใขใชใผ โ docs/็ตฑๅ
+ - ใฟในใฏ็ฎก็ใใญใฅใกใณใ้ฃๆบ
+
+### Phase 4: ใในใใปๆค่จผ
+
+- [ ] **ใในใ่ฟฝๅ **
+ - File: `tests/test_pm_enhanced.py`
+ - Coverage: PDCAๅฎ่กใ่ชๅทฑ่ฉไพกใๅญฆ็ฟ่จ้ฒ
+
+- [ ] **ๅไฝ็ขบ่ช**
+ - ้็บ็ใคใณในใใผใซ: `SuperClaude install --dev`
+ - ๅฎ้ใฎใฏใผใฏใใญใผๅฎ่ก
+ - Before/Afterๆฏ่ผ
+
+### Phase 5: ๅญฆ็ฟ่จ้ฒ
+
+- [ ] **ๆๅใใฟใผใณ่จ้ฒ**
+ - File: `docs/patterns/pm-autonomous-workflow.md`
+ - Content: ่ชๅพ็PDCAใใฟใผใณใฎ่ฉณ็ดฐ
+
+- [ ] **ๅคฑๆ่จ้ฒ๏ผๅฟ
่ฆๆ๏ผ**
+ - File: `docs/mistakes/mistake-2025-10-14.md`
+ - Content: ้ญ้ใใใจใฉใผใจ้ฒๆญข็ญ
+
+---
+
+## ๐ฏ Success Criteria
+
+### ๅฎ้็ๆๆจ
+- [ ] ็นฐใ่ฟใๆ็คบ 50%ๅๆธ
+- [ ] ๅใใในๅ็บ็ 80%ๅๆธ
+- [ ] ใปใใทใงใณๅพฉๅ
ๆ้ <30็ง
+
+### ๅฎๆง็ๆๆจ
+- [ ] ใๅๅใฎ็ถใใใใใ ใใงๅ้ๅฏ่ฝ
+- [ ] ้ๅปใฎใในใ่ชๅ็ใซๅ้ฟ
+- [ ] ๅ
ฌๅผใใญใฅใกใณใๅ็
งใ่ชๅๅ
+- [ ] ๅฎ่ฃ
โใในใโๆค่จผใ่ชๅพ็ใซๅใ
+
+---
+
+## ๐ Notes
+
+### ้่ฆใชๅญฆใณ
+- **Git็ฎก็ใฎๅบๅฅใๆ้่ฆ**
+ - ใใฎใใญใธใงใฏใ๏ผGit็ฎก็๏ผใงๅคๆด
+ - `~/.claude/`๏ผGit็ฎก็ๅค๏ผใฏ่ชญใใ ใ
+ - ใในใๆใฎใใใฏใขใใใปๅพฉๅ
ๅฟ
้
+
+- **ใใญใฅใกใณใ้งๅ้็บ**
+ - ็่งฃ โ docs/Development/ ใซ่จ้ฒ
+ - ไปฎ่ชฌ โ hypothesis-*.md
+ - ๅฎ้จ โ experiment-*.md
+ - ๆๅ โ docs/patterns/
+ - ๅคฑๆ โ docs/mistakes/
+
+- **ใคใณในใใผใซใใญใผ**
+ - Source: `superclaude/commands/*.md`
+ - Installer: `setup/components/commands.py`
+ - Target: `~/.claude/commands/sc/*.md`
+
+### ใใญใใซใผ
+- ใชใ๏ผ็พๆ็น๏ผ
+
+### ๆฌกๅใปใใทใงใณ็จใฎใกใข
+1. ใใฎใใกใคใซ๏ผcurrent-tasks.md๏ผใๆๅใซ่ชญใ
+2. Completedใปใฏใทใงใณใง้ฒๆ็ขบ่ช
+3. In Progressใใๅ้
+4. ๆฐใใๅญฆใณใ้ฉๅใชใใญใฅใกใณใใซ่จ้ฒ
+
+---
+
+## ๐ Related Documentation
+
+- [PM Agent็ๆณใฏใผใฏใใญใผ](../pm-agent-ideal-workflow.md)
+- [ใใญใธใงใฏใๆง้ ็่งฃ](../project-structure-understanding.md)
+- [ใคใณในใใผใซใใญใผ็่งฃ](../installation-flow-understanding.md)
+
+---
+
+**ๆฌกใฎในใใใ**: `superclaude/commands/pm.md` ใ่ชญใใง็พๅจใฎไปๆงใ็ขบ่ชใใ
diff --git a/Docs/Getting-Started/installation.md b/docs/Getting-Started/installation.md
similarity index 100%
rename from Docs/Getting-Started/installation.md
rename to docs/Getting-Started/installation.md
diff --git a/Docs/Getting-Started/quick-start.md b/docs/Getting-Started/quick-start.md
similarity index 100%
rename from Docs/Getting-Started/quick-start.md
rename to docs/Getting-Started/quick-start.md
diff --git a/Docs/README.md b/docs/README.md
similarity index 100%
rename from Docs/README.md
rename to docs/README.md
diff --git a/Docs/Reference/README.md b/docs/Reference/README.md
similarity index 100%
rename from Docs/Reference/README.md
rename to docs/Reference/README.md
diff --git a/Docs/Reference/advanced-patterns.md b/docs/Reference/advanced-patterns.md
similarity index 100%
rename from Docs/Reference/advanced-patterns.md
rename to docs/Reference/advanced-patterns.md
diff --git a/Docs/Reference/advanced-workflows.md b/docs/Reference/advanced-workflows.md
similarity index 100%
rename from Docs/Reference/advanced-workflows.md
rename to docs/Reference/advanced-workflows.md
diff --git a/Docs/Reference/basic-examples.md b/docs/Reference/basic-examples.md
similarity index 100%
rename from Docs/Reference/basic-examples.md
rename to docs/Reference/basic-examples.md
diff --git a/docs/Reference/claude-code-history-management.md b/docs/Reference/claude-code-history-management.md
new file mode 100644
index 0000000..de25e16
--- /dev/null
+++ b/docs/Reference/claude-code-history-management.md
@@ -0,0 +1,556 @@
+# Claude Code Conversation History Management Research
+
+**Research Date**: 2025-10-09
+**Purpose**: Understand .jsonl file structure, performance impact, and establish rotation policy
+
+---
+
+## 1. Official Documentation & Purpose
+
+### .jsonl File Structure
+**Location**: `~/.claude/projects/{project-directory}/`
+
+**Data Structure** (from analysis of actual files):
+```json
+{
+ "type": "summary|file-history-snapshot|user|assistant|system|tool_use|tool_result|message",
+ "timestamp": "ISO-8601 timestamp",
+ "cwd": "/absolute/path/to/working/directory",
+ "sessionId": "uuid",
+ "gitBranch": "branch-name",
+ "content": "message content or command",
+ "messageId": "uuid for message tracking"
+}
+```
+
+**Key Message Types** (from 2.6MB conversation analysis):
+- `message` (228): Container for conversation messages
+- `assistant` (228): Claude's responses
+- `user` (182): User inputs
+- `tool_use` (137): Tool invocations
+- `tool_result` (137): Tool execution results
+- `text` (74): Text content blocks
+- `file-history-snapshot` (39): File state tracking
+- `thinking` (31): Claude's reasoning process
+- `system` (12): System-level messages
+
+### File History Snapshot Purpose
+```json
+{
+ "type": "file-history-snapshot",
+ "messageId": "uuid",
+ "snapshot": {
+ "messageId": "uuid",
+ "trackedFileBackups": {},
+ "timestamp": "ISO-8601"
+ },
+ "isSnapshotUpdate": false
+}
+```
+
+**Purpose** (inferred from structure):
+- Tracks file states at specific conversation points
+- Enables undo/redo functionality for file changes
+- Provides rollback capability for edits
+- **Note**: No official documentation found on this feature
+
+### Conversation Loading Behavior
+**Official Best Practices** ([source](https://www.anthropic.com/engineering/claude-code-best-practices)):
+- "All conversations are automatically saved locally with their full message history"
+- "When resuming, the entire message history is restored to maintain context"
+- "Tool usage and results from previous conversations preserved"
+
+**Resume Commands**:
+- `--continue`: Automatically continue most recent conversation
+- `/resume`: Show list of recent sessions and choose one
+- Session ID specification: Resume specific conversation
+
+---
+
+## 2. Performance Impact
+
+### Known Issues from GitHub
+
+#### Issue #5024: History Accumulation Causing Performance Issues
+**Status**: Open (Major Issue)
+**URL**: https://github.com/anthropics/claude-code/issues/5024
+
+**Reported Problems**:
+- File sizes growing to "hundreds of MB or more"
+- Slower application startup times
+- System performance degradation
+- No automatic cleanup mechanism
+- One user reported file size of 968KB+ continuously growing
+
+**Current Workaround**:
+- Manual editing of `.claude.json` (risky - can break configurations)
+- `claude history clear` (removes ALL history across ALL projects)
+
+#### Issue #7985: Severe Memory Leak
+**Status**: Critical
+**URL**: https://github.com/anthropics/claude-code/issues/7985
+
+**Reported Problems**:
+- Context accumulation causing massive memory usage
+- Memory leaks with objects not garbage collected
+- One user reported ~570GB of virtual memory usage
+- Long-running sessions become unusable
+
+#### Issue #8839: Conversation Compaction Failure
+**Status**: Regression (after undo/redo feature)
+**URL**: https://github.com/anthropics/claude-code/issues/8839
+
+**Impact**:
+- Claude Code can no longer automatically compact long conversations
+- "Too long" errors after conversation history navigation feature added
+- Conversations become unmanageable without manual intervention
+
+#### Issue #8755: /clear Command Not Working
+**Status**: Bug
+**URL**: https://github.com/anthropics/claude-code/issues/8755
+
+**Impact**:
+- `/clear` command stopped functioning for some users
+- "Clear Conversations" menu option non-functional
+- Users cannot reset context window as recommended
+
+### Actual Performance Data (Your Environment)
+
+**Current State** (as of 2025-10-09):
+- **Total agiletec project**: 33MB (57 conversation files)
+- **Largest file**: 2.6MB (462 lines)
+- **Average file**: ~580KB
+- **Files >1MB**: 3 files
+- **Total across all projects**: ~62MB
+
+**Age Distribution**:
+- Files older than 30 days: 0
+- Files older than 7 days: 4
+- Most files: <7 days old
+
+**Comparison to Other Projects**:
+```
+33M agiletec (57 files) - Most active
+14M SSD-2TB project
+6.3M tokium
+2.6M bunseki
+```
+
+---
+
+## 3. Official Retention Policies
+
+### Standard Retention (Consumer)
+**Source**: [Anthropic Privacy Center](https://privacy.claude.com/en/articles/10023548-how-long-do-you-store-my-data)
+
+- **Prompts/Responses**: Up to 30 days in back-end logs
+- **Deleted chats**: Immediately removed from UI, purged within 30 days
+- **API logs**: Reducing to 7 days starting September 15, 2025 (from 30 days)
+
+### Enterprise Controls
+**Source**: [Custom Data Retention Controls](https://privacy.anthropic.com/en/articles/10440198-custom-data-retention-controls-for-claude-enterprise)
+
+- **Minimum retention**: 30 days
+- **Retention start**: Last observed activity (last message or project update)
+- **Custom periods**: Available for organizations
+
+### Local Storage (No Official Policy)
+**Finding**: No official documentation found regarding:
+- Recommended local .jsonl file retention periods
+- Automatic cleanup of old conversations
+- Performance thresholds for file sizes
+- Safe deletion procedures
+
+**Current Tools**:
+- `claude history clear`: Removes ALL history (all projects, destructive)
+- No selective cleanup tools available
+- No archive functionality
+
+---
+
+## 4. Best Practices (Official & Community)
+
+### Official Recommendations
+
+#### Context Management
+**Source**: [Claude Code Best Practices](https://www.anthropic.com/engineering/claude-code-best-practices)
+
+**Key Guidelines**:
+1. **Use `/clear` frequently**: "Reset context window between tasks"
+2. **Scope conversations**: "One project or feature per conversation"
+3. **Clear before switching**: "/clear before fixing bugs to prevent context pollution"
+4. **Don't rely on long context**: "Claude's context window can fill with irrelevant conversation"
+
+**Quote**: "During long sessions, Claude's context window can fill with irrelevant conversation, file contents, and commands which can reduce performance, so use the /clear command frequently between tasks to reset the context window."
+
+#### CLAUDE.md Strategy
+- **Persistent context**: Use CLAUDE.md files for stable instructions
+- **Auto-loaded**: "Claude automatically pulls into context when starting"
+- **Hierarchy**: Global (`~/.claude/CLAUDE.md`) โ Workspace โ Project
+- **Refinement**: "Take time to experiment and determine what produces best results"
+
+#### When to Restart vs /clear
+**Source**: [Community Best Practices](https://claudelog.com/faqs/does-claude-code-store-my-data/)
+
+**Use `/clear` when**:
+- Starting new task/feature
+- Switching between features
+- Context becomes polluted
+- Before bug fixing
+
+**Restart session when**:
+- Switching projects
+- Updating CLAUDE.md files
+- Experiencing session issues
+- Memory usage high
+
+### Community Strategies
+
+#### Conversation Organization
+**Pattern**: "Scope a chat to one project or feature"
+- Start conversation for specific goal
+- Use `/clear` when goal complete
+- Don't mix unrelated tasks in same conversation
+
+#### Context Optimization
+**Pattern**: "Avoid extensive, unrefined context"
+- Iterate on CLAUDE.md effectiveness
+- Remove ineffective instructions
+- Test and refine periodically
+
+#### Incognito Mode for Sensitive Work
+**Pattern**: "Ghost icon for temporary conversations"
+- Not saved to chat history
+- No contribution to context memory
+- Useful for experimental or sensitive work
+
+---
+
+## 5. Recommended Rotation Policy
+
+### Immediate Actions (No Risk)
+
+#### 1. Delete Very Old Conversations (>30 days)
+```bash
+# Backup first
+mkdir -p ~/.claude/projects-archive/$(date +%Y-%m)
+
+# Find and archive
+find ~/.claude/projects/ -name "*.jsonl" -mtime +30 -type f \
+ -exec mv {} ~/.claude/projects-archive/$(date +%Y-%m)/ \;
+```
+
+**Rationale**:
+- Aligns with Anthropic's 30-day back-end retention
+- Minimal functionality loss (context rarely useful after 30 days)
+- Significant space savings
+
+#### 2. Archive Project-Specific Old Conversations (>14 days)
+```bash
+# Per-project archive
+mkdir -p ~/.claude/projects-archive/agiletec/$(date +%Y-%m)
+
+find ~/.claude/projects/-Users-kazuki-github-agiletec -name "*.jsonl" -mtime +14 -type f \
+ -exec mv {} ~/.claude/projects-archive/agiletec/$(date +%Y-%m)/ \;
+```
+
+**Rationale**:
+- 14 days provides buffer for resumed work
+- Most development tasks complete within 2 weeks
+- Easy to restore if needed
+
+### Periodic Maintenance (Weekly)
+
+#### 3. Identify Large Files for Manual Review
+```bash
+# Find files >1MB
+find ~/.claude/projects/ -name "*.jsonl" -type f -size +1M -exec ls -lh {} \;
+
+# Review and archive if not actively used
+```
+
+**Criteria for Archival**:
+- File >1MB and not modified in 7 days
+- Completed feature/project conversations
+- Debugging sessions that are resolved
+
+### Aggressive Cleanup (Monthly)
+
+#### 4. Archive All Inactive Conversations (>7 days)
+```bash
+# Monthly archive
+mkdir -p ~/.claude/projects-archive/$(date +%Y-%m)
+
+find ~/.claude/projects/ -name "*.jsonl" -mtime +7 -type f \
+ -exec mv {} ~/.claude/projects-archive/$(date +%Y-%m)/ \;
+```
+
+**When to Use**:
+- Project directory >50MB
+- Startup performance degraded
+- Running low on disk space
+
+### Emergency Cleanup (Performance Issues)
+
+#### 5. Nuclear Option - Keep Only Recent Week
+```bash
+# BACKUP EVERYTHING FIRST
+tar -czf ~/claude-history-backup-$(date +%Y%m%d).tar.gz ~/.claude/projects/
+
+# Keep only last 7 days
+find ~/.claude/projects/ -name "*.jsonl" -mtime +7 -type f -delete
+```
+
+**When to Use**:
+- Claude Code startup >10 seconds
+- Memory usage abnormally high
+- Experiencing Issue #7985 symptoms
+
+---
+
+## 6. Proposed Automated Solution
+
+### Shell Script: `claude-history-rotate.sh`
+```bash
+#!/usr/bin/env bash
+# Claude Code Conversation History Rotation
+# Usage: ./claude-history-rotate.sh [--dry-run] [--days N]
+
+set -euo pipefail
+
+DAYS=${DAYS:-30}
+DRY_RUN=false
+ARCHIVE_BASE=~/.claude/projects-archive
+
+# Parse arguments
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --dry-run) DRY_RUN=true; shift ;;
+ --days) DAYS="$2"; shift 2 ;;
+ *) echo "Unknown option: $1"; exit 1 ;;
+ esac
+done
+
+# Create archive directory
+ARCHIVE_DIR="$ARCHIVE_BASE/$(date +%Y-%m)"
+mkdir -p "$ARCHIVE_DIR"
+
+# Find old conversations
+OLD_FILES=$(find ~/.claude/projects/ -name "*.jsonl" -mtime "+$DAYS" -type f)
+
+if [[ -z "$OLD_FILES" ]]; then
+ echo "No files older than $DAYS days found."
+ exit 0
+fi
+
+# Count and size
+FILE_COUNT=$(echo "$OLD_FILES" | wc -l | tr -d ' ')
+TOTAL_SIZE=$(echo "$OLD_FILES" | xargs du -ch | tail -1 | awk '{print $1}')
+
+echo "Found $FILE_COUNT files older than $DAYS days ($TOTAL_SIZE total)"
+
+if [[ "$DRY_RUN" == "true" ]]; then
+ echo "DRY RUN - Would archive:"
+ echo "$OLD_FILES"
+ exit 0
+fi
+
+# Archive files
+echo "$OLD_FILES" | while read -r file; do
+ mv "$file" "$ARCHIVE_DIR/"
+ echo "Archived: $(basename "$file")"
+done
+
+echo "โ Archived $FILE_COUNT files to $ARCHIVE_DIR"
+```
+
+### Cron Job Setup (Optional)
+```bash
+# Add to crontab (monthly cleanup)
+# 0 3 1 * * /Users/kazuki/.local/bin/claude-history-rotate.sh --days 30
+
+# Or use launchd on macOS
+cat > ~/Library/LaunchAgents/com.user.claude-history-rotate.plist <<'EOF'
+
+
+
+
+ Label
+ com.user.claude-history-rotate
+ ProgramArguments
+
+ /Users/kazuki/.local/bin/claude-history-rotate.sh
+ --days
+ 30
+
+ StartCalendarInterval
+
+ Day
+ 1
+ Hour
+ 3
+
+
+
+EOF
+
+launchctl load ~/Library/LaunchAgents/com.user.claude-history-rotate.plist
+```
+
+---
+
+## 7. Monitoring & Alerts
+
+### Disk Usage Check Script
+```bash
+#!/usr/bin/env bash
+# claude-history-check.sh
+
+THRESHOLD_MB=100
+PROJECTS_DIR=~/.claude/projects
+
+TOTAL_SIZE_MB=$(du -sm "$PROJECTS_DIR" | awk '{print $1}')
+
+echo "Claude Code conversation history: ${TOTAL_SIZE_MB}MB"
+
+if [[ $TOTAL_SIZE_MB -gt $THRESHOLD_MB ]]; then
+ echo "โ ๏ธ WARNING: History size exceeds ${THRESHOLD_MB}MB threshold"
+ echo "Consider running: claude-history-rotate.sh --days 30"
+
+ # Find largest projects
+ echo ""
+ echo "Largest projects:"
+ du -sm "$PROJECTS_DIR"/*/ | sort -rn | head -5
+fi
+```
+
+### Performance Indicators to Watch
+1. **Startup time**: >5 seconds = investigate
+2. **File sizes**: >2MB per conversation = review
+3. **Total size**: >100MB across all projects = cleanup
+4. **Memory usage**: >2GB during session = Issue #7985
+5. **Conversation length**: >500 message pairs = use `/clear`
+
+---
+
+## 8. Key Takeaways & Recommendations
+
+### Critical Findings
+
+โ
**Safe to Delete**:
+- Conversations >30 days old (aligns with Anthropic retention)
+- Completed feature/project conversations
+- Large files (>1MB) not accessed in 14+ days
+
+โ ๏ธ **Caution Required**:
+- Active project conversations (<7 days)
+- Files referenced in recent work
+- Conversations with unfinished tasks
+
+โ **Known Issues**:
+- No official cleanup tools (Issue #5024)
+- Memory leaks in long sessions (Issue #7985)
+- `/clear` command bugs (Issue #8755)
+- Conversation compaction broken (Issue #8839)
+
+### Recommended Policy for Your Environment
+
+**Daily Practice**:
+- Use `/clear` between major tasks
+- Scope conversations to single features
+- Restart session if >2 hours continuous work
+
+**Weekly Review** (Sunday):
+```bash
+# Check current state
+du -sh ~/.claude/projects/*/
+
+# Archive old conversations (>14 days)
+claude-history-rotate.sh --days 14 --dry-run # Preview
+claude-history-rotate.sh --days 14 # Execute
+```
+
+**Monthly Cleanup** (1st of month):
+```bash
+# Aggressive cleanup (>30 days)
+claude-history-rotate.sh --days 30
+
+# Review large files
+find ~/.claude/projects/ -name "*.jsonl" -size +1M -mtime +7
+```
+
+**Performance Threshold Actions**:
+- Total size >50MB: Archive 30-day-old conversations
+- Total size >100MB: Archive 14-day-old conversations
+- Total size >200MB: Emergency cleanup (7-day retention)
+- Startup >10s: Investigate memory leaks, consider Issue #7985
+
+### Future-Proofing
+
+**Watch for Official Solutions**:
+- `claude history prune` command (requested in #5024)
+- Automatic history rotation feature
+- Configurable retention settings
+- Separate configuration from history storage
+
+**Community Tools**:
+- [cclogviewer](https://github.com/hesreallyhim/awesome-claude-code): View .jsonl files
+- Consider contributing to #5024 discussion
+- Monitor anthropics/claude-code releases
+
+---
+
+## 9. References
+
+### Official Documentation
+- [Claude Code Best Practices](https://www.anthropic.com/engineering/claude-code-best-practices)
+- [How Long Do You Store My Data?](https://privacy.claude.com/en/articles/10023548-how-long-do-you-store-my-data)
+- [Custom Data Retention Controls](https://privacy.anthropic.com/en/articles/10440198-custom-data-retention-controls-for-claude-enterprise)
+
+### GitHub Issues
+- [#5024: History accumulation causes performance issues](https://github.com/anthropics/claude-code/issues/5024)
+- [#7985: Severe memory leak](https://github.com/anthropics/claude-code/issues/7985)
+- [#8839: Conversation compaction failure](https://github.com/anthropics/claude-code/issues/8839)
+- [#8755: /clear command not working](https://github.com/anthropics/claude-code/issues/8755)
+
+### Community Resources
+- [Awesome Claude Code](https://github.com/hesreallyhim/awesome-claude-code)
+- [Claude Code Context Guide](https://www.arsturn.com/blog/beyond-prompting-a-guide-to-managing-context-in-claude-code)
+- [ClaudeLog Documentation](https://claudelog.com/)
+
+---
+
+## Appendix: Current Environment Statistics
+
+**Generated**: 2025-10-09 04:24 JST
+
+### Project Size Breakdown
+```
+33M -Users-kazuki-github-agiletec (57 files)
+14M -Volumes-SSD-2TB (project count: N/A)
+6.3M -Users-kazuki-github-tokium
+2.6M -Users-kazuki-github-bunseki
+1.9M -Users-kazuki
+1.9M -Users-kazuki-github-superclaude
+---
+Total: ~62MB across all projects
+```
+
+### agiletec Project Details
+- **Total conversations**: 57
+- **Largest file**: 2.6MB (d4852655-b760-4311-8f67-26f593f2403f.jsonl)
+- **Files >1MB**: 3 files
+- **Avg file size**: ~580KB
+- **Files >7 days**: 4 files
+- **Files >30 days**: 0 files
+
+### Immediate Recommendation
+**Status**: โ
Healthy (no immediate action required)
+
+**Reasoning**:
+- Total size (33MB) well below concern threshold (100MB)
+- No files >30 days old
+- Only 4 files >7 days old
+- Largest file (2.6MB) within acceptable range
+
+**Next Review**: 2025-10-16 (weekly check)
diff --git a/Docs/Reference/common-issues.md b/docs/Reference/common-issues.md
similarity index 100%
rename from Docs/Reference/common-issues.md
rename to docs/Reference/common-issues.md
diff --git a/Docs/Reference/diagnostic-reference.md b/docs/Reference/diagnostic-reference.md
similarity index 100%
rename from Docs/Reference/diagnostic-reference.md
rename to docs/Reference/diagnostic-reference.md
diff --git a/Docs/Reference/examples-cookbook.md b/docs/Reference/examples-cookbook.md
similarity index 100%
rename from Docs/Reference/examples-cookbook.md
rename to docs/Reference/examples-cookbook.md
diff --git a/Docs/Reference/integration-patterns.md b/docs/Reference/integration-patterns.md
similarity index 100%
rename from Docs/Reference/integration-patterns.md
rename to docs/Reference/integration-patterns.md
diff --git a/Docs/Reference/mcp-server-guide.md b/docs/Reference/mcp-server-guide.md
similarity index 100%
rename from Docs/Reference/mcp-server-guide.md
rename to docs/Reference/mcp-server-guide.md
diff --git a/Docs/Reference/troubleshooting.md b/docs/Reference/troubleshooting.md
similarity index 100%
rename from Docs/Reference/troubleshooting.md
rename to docs/Reference/troubleshooting.md
diff --git a/Docs/Templates/__init__.py b/docs/Templates/__init__.py
similarity index 100%
rename from Docs/Templates/__init__.py
rename to docs/Templates/__init__.py
diff --git a/Docs/User-Guide-jp/agents.md b/docs/User-Guide-jp/agents.md
similarity index 92%
rename from Docs/User-Guide-jp/agents.md
rename to docs/User-Guide-jp/agents.md
index 8a10080..7b75e26 100644
--- a/Docs/User-Guide-jp/agents.md
+++ b/docs/User-Guide-jp/agents.md
@@ -1,12 +1,12 @@
# SuperClaude ใจใผใธใงใณใใฌใคใ ๐ค
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#superclaude-agents-guide-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#superclaude-agents-guide-)
SuperClaude ใฏใClaude Code ใๅฐ้็ฅ่ญใๅพใใใใซๅผใณๅบใใใจใใงใใ 14 ใฎใใกใคใณ ในใใทใฃใชในใ ใจใผใธใงใณใใๆไพใใพใใ
## ๐งช ใจใผใธใงใณใใฎใขใฏใใฃใใผใทใงใณใฎใในใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#-testing-agent-activation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#-testing-agent-activation)
ใใฎใฌใคใใไฝฟ็จใใๅใซใใจใผใธใงใณใใฎ้ธๆใๆฉ่ฝใใใใจใ็ขบ่ชใใฆใใ ใใใ
@@ -37,23 +37,23 @@ SuperClaude ใฏใClaude Code ใๅฐ้็ฅ่ญใๅพใใใใซๅผใณๅบใใ
## ใณใขใณใณใปใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#core-concepts)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#core-concepts)
### SuperClaude ใจใผใธใงใณใใจใฏไฝใงใใ?
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#what-are-superclaude-agents)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#what-are-superclaude-agents)
-**ใจใผใธใงใณใใฏ**ใClaude Codeใฎ่กๅใๅคๆดใใใณใณใใญในใๆ็คบใจใใฆๅฎ่ฃ
ใใใใๅฐ้ๅ้ใฎAIใใกใคใณใจใญในใใผใใงใใๅใจใผใธใงใณใใฏใใใกใคใณๅบๆใฎๅฐ้็ฅ่ญใ่กๅใใฟใผใณใๅ้ก่งฃๆฑบใขใใญใผใใๅซใใใใฃใฌใฏใใช`.md`ๅ
ใซ็ถฟๅฏใซไฝๆใใใใใกใคใซใงใ`SuperClaude/Agents/`ใ
+**ใจใผใธใงใณใใฏ**ใClaude Codeใฎ่กๅใๅคๆดใใใณใณใใญในใๆ็คบใจใใฆๅฎ่ฃ
ใใใใๅฐ้ๅ้ใฎAIใใกใคใณใจใญในใใผใใงใใๅใจใผใธใงใณใใฏใใใกใคใณๅบๆใฎๅฐ้็ฅ่ญใ่กๅใใฟใผใณใๅ้ก่งฃๆฑบใขใใญใผใใๅซใใใใฃใฌใฏใใช`.md`ๅ
ใซ็ถฟๅฏใซไฝๆใใใใใกใคใซใงใ`superclaude/Agents/`ใ
**้่ฆ**: ใจใผใธใงใณใใฏๅฅๅใฎ AI ใขใใซใใฝใใใฆใงใขใงใฏใชใใClaude Code ใ่ชญใฟๅใฃใฆ็นๆฎใชๅไฝใๆก็จใใใณใณใใญในใๆงๆใงใใ
### ใจใผใธใงใณใใฎ2ใคใฎไฝฟ็จๆนๆณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#two-ways-to-use-agents)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#two-ways-to-use-agents)
#### 1. @agent- ใใฌใใฃใใฏในใไฝฟ็จใใๆๅๅผใณๅบใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#1-manual-invocation-with-agent--prefix)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#1-manual-invocation-with-agent--prefix)
```shell
# Directly invoke a specific agent
@@ -64,7 +64,7 @@ SuperClaude ใฏใClaude Code ใๅฐ้็ฅ่ญใๅพใใใใซๅผใณๅบใใ
#### 2. ่ชๅใขใฏใใฃใใผใทใงใณ๏ผ่กๅใซใผใใฃใณใฐ๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#2-auto-activation-behavioral-routing)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#2-auto-activation-behavioral-routing)
ใ่ชๅใขใฏใใฃใใผใทใงใณใใจใฏใClaude Codeใใชใฏใจในใๅ
ใฎใญใผใฏใผใใจใใฟใผใณใซๅบใฅใใฆ้ฉๅใชใณใณใใญในใใงๅไฝๆ็คบใ่ชญใฟๅใใใจใณใฒใผใธใใใใจใๆๅณใใพใใSuperClaudeใฏใClaudeใๆ้ฉใชในใใทใฃใชในใใซใซใผใใฃใณใฐใใใใใฎๅไฝใฌใคใใฉใคใณใๆไพใใพใใ
@@ -83,7 +83,7 @@ SuperClaude ใฏใClaude Code ใๅฐ้็ฅ่ญใๅพใใใใซๅผใณๅบใใ
### ใจใผใธใงใณใ้ธๆใซใผใซ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#agent-selection-rules)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#agent-selection-rules)
**ๅชๅ
้ ไฝใฎ้ๅฑค:**
@@ -115,11 +115,11 @@ Task Analysis โ
## ใฏใคใใฏในใฟใผใใฎไพ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#quick-start-examples)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#quick-start-examples)
### ๆๅใจใผใธใงใณใๅผใณๅบใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#manual-agent-invocation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#manual-agent-invocation)
```shell
# Explicitly call specific agents with @agent- prefix
@@ -131,7 +131,7 @@ Task Analysis โ
### ่ชๅใจใผใธใงใณใ่ชฟๆด
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#automatic-agent-coordination)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#automatic-agent-coordination)
```shell
# Commands that trigger auto-activation
@@ -150,7 +150,7 @@ Task Analysis โ
### ๆๅใจ่ชๅใฎใขใใญใผใใ็ตใฟๅใใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#combining-manual-and-auto-approaches)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#combining-manual-and-auto-approaches)
```shell
# Start with command (auto-activation)
@@ -165,15 +165,15 @@ Task Analysis โ
## SuperClaude ใจใผใธใงใณใใใผใ ๐ฅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#the-superclaude-agent-team-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#the-superclaude-agent-team-)
### ใขใผใญใใฏใใฃใจใทในใใ ่จญ่จใจใผใธใงใณใ ๐๏ธ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#architecture--system-design-agents-%EF%B8%8F)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#architecture--system-design-agents-%EF%B8%8F)
### ใทในใใ ใขใผใญใใฏใ ๐ข
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#system-architect-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#system-architect-)
**ๅฐ้ๅ้**๏ผในใฑใผใฉใใชใใฃใจใตใผใในใขใผใญใใฏใใฃใซ้็นใ็ฝฎใใๅคง่ฆๆจกๅๆฃใทในใใ ่จญ่จ
@@ -199,7 +199,7 @@ Task Analysis โ
### ๆๅๅบๆบ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#success-criteria)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#success-criteria)
- [ ] ๅฟ็ญใซ่กจใใใทในใใ ใฌใใซใฎๆ่
- [ ] ใตใผใในใฎๅข็ใจ็ตฑๅใใฟใผใณใซใคใใฆ่จๅใใ
@@ -216,7 +216,7 @@ Task Analysis โ
### ใใใฏใจใณใใขใผใญใใฏใ โ๏ธ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#backend-architect-%EF%B8%8F)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#backend-architect-%EF%B8%8F)
**ๅฐ้ๅ้**: APIใฎไฟก้ ผๆงใจใใผใฟใฎๆดๅๆงใ้่ฆใใๅ
็ขใชใตใผใใผใตใคใใทในใใ ่จญ่จ
@@ -246,7 +246,7 @@ Task Analysis โ
### ใใญใณใใจใณใใขใผใญใใฏใ ๐จ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#frontend-architect-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#frontend-architect-)
**ๅฐ้ๅ้**: ใขใฏใปใทใใชใใฃใจใฆใผใถใผใจใฏในใใชใจใณในใ้่ฆใใๆๆฐใฎ Web ใขใใชใฑใผใทใงใณ ใขใผใญใใฏใใฃ
@@ -276,7 +276,7 @@ Task Analysis โ
### DevOps ใขใผใญใใฏใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#devops-architect-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#devops-architect-)
**ๅฐ้ๅ้**: ไฟก้ ผๆงใฎ้ซใใฝใใใฆใงใข้
ไฟกใฎใใใฎใคใณใใฉในใใฉใฏใใฃ่ชๅๅใจๅฑ้ใใคใใฉใคใณ่จญ่จ
@@ -304,11 +304,11 @@ Task Analysis โ
### ๅ่ณชใปๅๆใจใผใธใงใณใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#quality--analysis-agents-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#quality--analysis-agents-)
### ใปใญใฅใชใใฃใจใณใธใใข ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#security-engineer-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#security-engineer-)
**ๅฐ้ๅ้**: ่
ๅจใขใใชใณใฐใจ่ๅผฑๆง้ฒๆญขใซ้็นใ็ฝฎใใใขใใชใฑใผใทใงใณ ใปใญใฅใชใใฃ ใขใผใญใใฏใใฃ
@@ -338,7 +338,7 @@ Task Analysis โ
### ใใใฉใผใใณในใจใณใธใใข โก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#performance-engineer-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#performance-engineer-)
**ๅฐ้ๅ้**๏ผในใฑใผใฉใใชใใฃใจใชใฝใผในๅน็ใ้่ฆใใใทในใใ ใใใฉใผใใณในใฎๆ้ฉๅ
@@ -368,7 +368,7 @@ Task Analysis โ
### ๆ นๆฌๅๅ ๅๆ่
๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#root-cause-analyst-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#root-cause-analyst-)
**ๅฐ้ๅ้**๏ผ่จผๆ ใซๅบใฅใๅๆใจไปฎ่ชฌๆคๅฎใ็จใใไฝ็ณป็ใชๅ้ก่ชฟๆป
@@ -398,7 +398,7 @@ Task Analysis โ
### ๅ่ณชใจใณใธใใข โ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#quality-engineer-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#quality-engineer-)
**ๅฐ้ๅ้**:่ชๅๅใจใซใใฌใใธใซ้็นใ็ฝฎใใๅ
ๆฌ็ใชใในใๆฆ็ฅใจๅ่ณชไฟ่จผ
@@ -428,7 +428,7 @@ Task Analysis โ
### ใชใใกใฏใฟใชใณใฐใฎๅฐ้ๅฎถ ๐ง
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#refactoring-expert-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#refactoring-expert-)
**ๅฐ้ๅ้**๏ผไฝ็ณป็ใชใชใใกใฏใฟใชใณใฐใจๆ่ก็่ฒ ๅต็ฎก็ใซใใใณใผใๅ่ณชใฎๆนๅ
@@ -456,11 +456,11 @@ Task Analysis โ
### ๅฐ้้็บใจใผใธใงใณใ ๐ฏ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#specialized-development-agents-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#specialized-development-agents-)
### Python ใจใญในใใผใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#python-expert-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#python-expert-)
**ๅฐ้ๅ้**: ๆๆฐใฎใใฌใผใ ใฏใผใฏใจใใใฉใผใใณในใ้่ฆใใใๆฌ็ช็ฐๅขๅฏพๅฟใฎ Python ้็บ
@@ -490,7 +490,7 @@ Task Analysis โ
### ่ฆไปถใขใใชในใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#requirements-analyst-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#requirements-analyst-)
**ๅฐ้ๅ้**๏ผไฝ็ณป็ใชในใใผใฏใใซใใผๅๆใซใใ่ฆไปถ็บ่ฆใจไปๆง็ญๅฎ
@@ -518,11 +518,11 @@ Task Analysis โ
### ใณใใฅใใฑใผใทใงใณใจๅญฆ็ฟใจใผใธใงใณใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#communication--learning-agents-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#communication--learning-agents-)
### ใใฏใใซใซใฉใคใฟใผ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#technical-writer-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#technical-writer-)
**ๅฐ้ๅ้**: ่ฆ่ด่
ๅๆใจๆ็ขบใใ้่ฆใใๆ่กๆๆธไฝๆใจใณใใฅใใฑใผใทใงใณ
@@ -552,7 +552,7 @@ Task Analysis โ
### ๅญฆ็ฟใฌใคใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#learning-guide-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#learning-guide-)
**ๅฐ้ๅ้**๏ผในใญใซ้็บใจใกใณใฟใผใทใใใซ้็นใ็ฝฎใใๆ่ฒใณใณใใณใใฎ่จญ่จใจๆผธ้ฒ็ๅญฆ็ฟ
@@ -582,11 +582,11 @@ Task Analysis โ
## ใจใผใธใงใณใใฎ่ชฟๆดใจ็ตฑๅ ๐ค
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#agent-coordination--integration-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#agent-coordination--integration-)
### ่ชฟๆดใใฟใผใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#coordination-patterns)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#coordination-patterns)
**ใขใผใญใใฏใใฃใใผใ **:
@@ -608,7 +608,7 @@ Task Analysis โ
### MCP ใตใผใใผ็ตฑๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#mcp-server-integration)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#mcp-server-integration)
**MCP ใตใผใใผใซใใๆกๅผตๆฉ่ฝ**:
@@ -621,20 +621,20 @@ Task Analysis โ
### ใจใผใธใงใณใใฎใขใฏใใฃใใผใทใงใณใฎใใฉใใซใทใฅใผใใฃใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#troubleshooting-agent-activation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#troubleshooting-agent-activation)
## ใใฉใใซใทใฅใผใใฃใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#troubleshooting)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#troubleshooting)
ใใฉใใซใทใฅใผใใฃใณใฐใฎใใซใใซใคใใฆใฏใไปฅไธใๅ็
งใใฆใใ ใใใ
-- [ใใใใๅ้ก](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/common-issues.md)- ใใใใๅ้กใซๅฏพใใใฏใคใใฏไฟฎๆญฃ
-- [ใใฉใใซใทใฅใผใใฃใณใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/troubleshooting.md)- ๅ
ๆฌ็ใชๅ้ก่งฃๆฑบ
+- [ใใใใๅ้ก](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/common-issues.md)- ใใใใๅ้กใซๅฏพใใใฏใคใใฏไฟฎๆญฃ
+- [ใใฉใใซใทใฅใผใใฃใณใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/troubleshooting.md)- ๅ
ๆฌ็ใชๅ้ก่งฃๆฑบ
### ใใใใๅ้ก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#common-issues)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#common-issues)
- **ใจใผใธใงใณใใฎใขใฏใใฃใใผใทใงใณใชใ**: ใใกใคใณใญใผใฏใผใใใปใญใฅใชใใฃใใใใใใฉใผใใณในใใใใใญใณใใจใณใใใไฝฟ็จใใพใ
- **้้ใฃใใจใผใธใงใณใใ้ธๆใใใพใใ**: ใจใผใธใงใณใใฎใใญใฅใกใณใใงใใชใฌใผใญใผใฏใผใใ็ขบ่ชใใฆใใ ใใ
@@ -644,7 +644,7 @@ Task Analysis โ
### ๅณๆไฟฎๆญฃ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#immediate-fixes)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#immediate-fixes)
- **ใจใผใธใงใณใใฎๅผทๅถใขใฏใใฃใใผใทใงใณ**: ใชใฏใจในใใงๆ็คบ็ใชใใกใคใณใญใผใฏใผใใไฝฟ็จใใ
- **ใจใผใธใงใณใใฎ้ธๆใใชใปใใ**: ใจใผใธใงใณใใฎ็ถๆ
ใใชใปใใใใใซใฏใClaude Code ใปใใทใงใณใๅ่ตทๅใใพใใ
@@ -653,7 +653,7 @@ Task Analysis โ
### ใจใผใธใงใณใๅบๆใฎใใฉใใซใทใฅใผใใฃใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#agent-specific-troubleshooting)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#agent-specific-troubleshooting)
**ใปใญใฅใชใใฃใจใผใธใงใณใใชใ:**
@@ -697,7 +697,7 @@ Task Analysis โ
### ใตใใผใใฌใใซ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#support-levels)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#support-levels)
**ใฏใคใใฏใใฃใใฏใน:**
@@ -707,13 +707,13 @@ Task Analysis โ
**่ฉณ็ดฐใชใใซใ:**
-- ใจใผใธใงใณใใฎใคใณในใใผใซใซ้ขใใๅ้กใซใคใใฆใฏใ[ไธ่ฌ็ใชๅ้กใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/common-issues.md)ใๅ็
งใใฆใใ ใใใ
+- ใจใผใธใงใณใใฎใคใณในใใผใซใซ้ขใใๅ้กใซใคใใฆใฏใ[ไธ่ฌ็ใชๅ้กใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/common-issues.md)ใๅ็
งใใฆใใ ใใใ
- ๅฏพ่ฑกใจใผใธใงใณใใฎใใชใฌใผใญใผใฏใผใใ็ขบ่ชใใ
**ๅฐ้ๅฎถใซใใใตใใผใ:**
- ไฝฟ็จ`SuperClaude install --diagnose`
-- ๅ่ชฟๅๆใซใคใใฆใฏ[่จบๆญใชใใกใฌใณในใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/diagnostic-reference.md)ใๅ็
งใใฆใใ ใใ
+- ๅ่ชฟๅๆใซใคใใฆใฏ[่จบๆญใชใใกใฌใณในใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/diagnostic-reference.md)ใๅ็
งใใฆใใ ใใ
**ใณใใฅใใใฃใตใใผใ:**
@@ -722,7 +722,7 @@ Task Analysis โ
### ๆๅใฎๆค่จผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#success-validation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#success-validation)
ใจใผใธใงใณใใฎไฟฎๆญฃใ้ฉ็จใใๅพใๆฌกใฎใใใซใในใใใพใใ
@@ -734,7 +734,7 @@ Task Analysis โ
## ใฏใคใใฏใใฉใใซใทใฅใผใใฃใณใฐ๏ผใฌใฌใทใผ๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#quick-troubleshooting-legacy)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#quick-troubleshooting-legacy)
- **ใจใผใธใงใณใใๆๅนๅใใใฆใใชใๅ ดๅ**โ ใใกใคใณใญใผใฏใผใใใปใญใฅใชใใฃใใใใใใฉใผใใณในใใใใใญใณใใจใณใใใไฝฟ็จใใพใ
- **ใจใผใธใงใณใใ้้ใฃใฆใใ**โ ใจใผใธใงใณใใฎใใญใฅใกใณใใงใใชใฌใผใญใผใฏใผใใ็ขบ่ชใใฆใใ ใใ
@@ -762,11 +762,11 @@ Task Analysis โ
## ใฏใคใใฏใชใใกใฌใณใน ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#quick-reference-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#quick-reference-)
### ใจใผใธใงใณใใใชใฌใผๆค็ดข
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#agent-trigger-lookup)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#agent-trigger-lookup)
|ใใชใฌใผใฟใคใ|ใญใผใฏใผใ/ใใฟใผใณ|ๆดปๆงๅใจใผใธใงใณใ|
|---|---|---|
@@ -786,7 +786,7 @@ Task Analysis โ
### ใณใใณใใจใผใธใงใณใใใใใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#command-agent-mapping)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#command-agent-mapping)
|ๆ็คบ|ไธปใช่ฌๅค|ใตใใผใใจใผใธใงใณใ|
|---|---|---|
@@ -801,7 +801,7 @@ Task Analysis โ
### ๅนๆ็ใช่ฌๅคใฎ็ตใฟๅใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#effective-agent-combinations)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#effective-agent-combinations)
**้็บใฏใผใฏใใญใผ**:
@@ -822,11 +822,11 @@ Task Analysis โ
## ใในใใใฉใฏใใฃใน๐ก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#best-practices-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#best-practices-)
### ใฏใใใซ๏ผใทใณใใซใชใขใใญใผใ๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#getting-started-simple-approach)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#getting-started-simple-approach)
**่ช็ถ่จ่ชใใกใผในใ:**
@@ -837,7 +837,7 @@ Task Analysis โ
### ใจใผใธใงใณใใฎ้ธๆใฎๆ้ฉๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#optimizing-agent-selection)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#optimizing-agent-selection)
**ๅนๆ็ใชใญใผใฏใผใใฎไฝฟ็จๆณ:**
@@ -859,7 +859,7 @@ Task Analysis โ
### ไธ่ฌ็ใชไฝฟ็จใใฟใผใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#common-usage-patterns)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#common-usage-patterns)
**้็บใฏใผใฏใใญใผ:**
@@ -895,7 +895,7 @@ Task Analysis โ
### ้ซๅบฆใชใจใผใธใงใณใ่ชฟๆด
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#advanced-agent-coordination)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#advanced-agent-coordination)
**ใใซใใใกใคใณใใญใธใงใฏใ:**
@@ -923,7 +923,7 @@ Task Analysis โ
### ๅ่ณช้่ฆใฎ้็บ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#quality-driven-development)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#quality-driven-development)
**ใปใญใฅใชใใฃ็ฌฌไธใฎใขใใญใผใ:**ย ้็บใชใฏใจในใใซใฏๅธธใซใปใญใฅใชใใฃใซ้ขใใ่ๆ
ฎไบ้
ใๅซใใใใกใคใณในใใทใฃใชในใใจใจใใซใปใญใฅใชใใฃใจใณใธใใขใ่ชๅ็ใซ้ขไธใใใพใใ
@@ -937,11 +937,11 @@ Task Analysis โ
## ใจใผใธใงใณใใคใณใใชใธใงใณในใ็่งฃใใ๐ง
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#understanding-agent-intelligence-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#understanding-agent-intelligence-)
### ใจใผใธใงใณใใๅนๆ็ใซใใ่ฆ็ด
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#what-makes-agents-effective)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#what-makes-agents-effective)
**ใใกใคใณๅฐ้็ฅ่ญ**: ๅใจใผใธใงใณใใฏใใใใใใฎใใกใคใณใซ็นๆใฎๅฐ้็ใช็ฅ่ญใใฟใผใณใ่กๅใขใใญใผใใๅ้ก่งฃๆฑบๆนๆณ่ซใๅใใฆใใพใใ
@@ -953,7 +953,7 @@ Task Analysis โ
### ใจใผใธใงใณใ vs. ๅพๆฅใฎAI
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#agent-vs-traditional-ai)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#agent-vs-traditional-ai)
**ๅพๆฅใฎใขใใญใผใ**: ๅไธใฎAIใใใใพใใพใชใฌใใซใฎๅฐ้็ฅ่ญใๆใคใในใฆใฎใใกใคใณใๅฆ็ใใพใใย **ใจใผใธใงใณใใขใใญใผใ**: ๅฐ้ใฎใจใญในใใผใใใๆทฑใใใกใคใณ็ฅ่ญใจ้ไธญ็ใชๅ้ก่งฃๆฑบใงๅๅใใพใใ
@@ -966,7 +966,7 @@ Task Analysis โ
### ใทในใใ ใไฟก้ ผใใใใฟใผใณใ็่งฃใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#trust-the-system-understand-the-patterns)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#trust-the-system-understand-the-patterns)
**ๆๅพ
ใใใใจ**:
@@ -986,36 +986,36 @@ Task Analysis โ
## ้ข้ฃใชใฝใผใน ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#related-resources-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#related-resources-)
### ๅฟ
้ ใใญใฅใกใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#essential-documentation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#essential-documentation)
-- **[ใณใใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md)**- ๆ้ฉใชใจใผใธใงใณใ่ชฟๆดใใใชใฌใผใใSuperClaudeใณใใณใใใในใฟใผใใ
-- **[MCP ใตใผใใผ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md)**- ๅฐ็จใใผใซใฎ็ตฑๅใซใใใจใผใธใงใณใๆฉ่ฝใฎๅผทๅ
-- **[ใปใใทใงใณ็ฎก็](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md)**- ๆฐธ็ถ็ใชใจใผใธใงใณใใณใณใใญในใใซใใ้ทๆใฏใผใฏใใญใผ
+- **[ใณใใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md)**- ๆ้ฉใชใจใผใธใงใณใ่ชฟๆดใใใชใฌใผใใSuperClaudeใณใใณใใใในใฟใผใใ
+- **[MCP ใตใผใใผ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md)**- ๅฐ็จใใผใซใฎ็ตฑๅใซใใใจใผใธใงใณใๆฉ่ฝใฎๅผทๅ
+- **[ใปใใทใงใณ็ฎก็](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md)**- ๆฐธ็ถ็ใชใจใผใธใงใณใใณใณใใญในใใซใใ้ทๆใฏใผใฏใใญใผ
### ้ซๅบฆใชไฝฟ็จๆณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#advanced-usage)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#advanced-usage)
-- **[่กๅใขใผใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md)**- ใจใผใธใงใณใใฎ่ชฟๆดใๅผทๅใใใใใฎใณใณใใญในใๆ้ฉๅ
-- **[ใฏใใใซ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Getting-Started/quick-start.md)**- ใจใผใธใงใณใใฎๆ้ฉๅใฎใใใฎๅฐ้ๅฎถใฎใใฏใใใฏ
-- **[ไพใฎใฏใใฏใใใฏ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/examples-cookbook.md)**- ็พๅฎไธ็ใฎใจใผใธใงใณใใฎ่ชฟๆดใใฟใผใณ
+- **[่กๅใขใผใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md)**- ใจใผใธใงใณใใฎ่ชฟๆดใๅผทๅใใใใใฎใณใณใใญในใๆ้ฉๅ
+- **[ใฏใใใซ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Getting-Started/quick-start.md)**- ใจใผใธใงใณใใฎๆ้ฉๅใฎใใใฎๅฐ้ๅฎถใฎใใฏใใใฏ
+- **[ไพใฎใฏใใฏใใใฏ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/examples-cookbook.md)**- ็พๅฎไธ็ใฎใจใผใธใงใณใใฎ่ชฟๆดใใฟใผใณ
### ้็บใชใฝใผใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#development-resources)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#development-resources)
-- **[ๆ่กใขใผใญใใฏใใฃ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Developer-Guide/technical-architecture.md)**- SuperClaude ใฎใจใผใธใงใณใ ใทในใใ ่จญ่จใ็่งฃใใ
-- **[่ฒข็ฎ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Developer-Guide/contributing-code.md)**- ใจใผใธใงใณใใฎๆฉ่ฝใจ่ชฟๆดใใฟใผใณใฎๆกๅผต
+- **[ๆ่กใขใผใญใใฏใใฃ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Developer-Guide/technical-architecture.md)**- SuperClaude ใฎใจใผใธใงใณใ ใทในใใ ่จญ่จใ็่งฃใใ
+- **[่ฒข็ฎ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Developer-Guide/contributing-code.md)**- ใจใผใธใงใณใใฎๆฉ่ฝใจ่ชฟๆดใใฟใผใณใฎๆกๅผต
---
## ใจใผใธใงใณใใจใใฆใฎ้ใฎใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md#your-agent-journey-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md#your-agent-journey-)
**็ฌฌ1้ฑ๏ผ่ช็ถใชไฝฟ็จๆณ**ย ่ช็ถใช่จ่ชใซใใ่ชฌๆใใๅงใใพใใใใใฉใฎใจใผใธใงใณใใใใใใฆใชใใขใฏใใฃใใซใชใใฎใใซๆณจ็ฎใใพใใใใใใญใปในใ่ใใใใใซใใญใผใฏใผใใฎใใฟใผใณใซๅฏพใใ็ดๆใ้คใใพใใ
diff --git a/Docs/User-Guide-jp/commands.md b/docs/User-Guide-jp/commands.md
similarity index 85%
rename from Docs/User-Guide-jp/commands.md
rename to docs/User-Guide-jp/commands.md
index 20edd0f..05d2b7f 100644
--- a/Docs/User-Guide-jp/commands.md
+++ b/docs/User-Guide-jp/commands.md
@@ -1,12 +1,12 @@
# SuperClaude ใณใใณใใฌใคใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#superclaude-commands-guide)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#superclaude-commands-guide)
`/sc:*`SuperClaude ใฏใใฏใผใฏใใญใผ็จใณใใณใใจ`@agent-*`ในใใทใฃใชในใ็จใณใใณใใฎ 21 ๅใฎ Claude Code ใณใใณใใๆไพใใพใใ
## ใณใใณใใฎ็จฎ้ก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#command-types)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#command-types)
|ใฟใคใ|ไฝฟ็จๅ ดๆ|ๅฝขๅผ|ไพ|
|---|---|---|---|
@@ -16,7 +16,7 @@
## ใฏใคใใฏใในใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#quick-test)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#quick-test)
```shell
# Terminal: Verify installation
@@ -32,11 +32,11 @@ python3 -m SuperClaude --version
## ๐ฏ SuperClaude ใณใใณใใฎ็่งฃ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#-understanding-superclaude-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#-understanding-superclaude-commands)
## SuperClaudeใฎไป็ตใฟ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#how-superclaude-works)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#how-superclaude-works)
SuperClaude ใฏใClaude Code ใ็นๆฎใชๅไฝใๅฎ่กใใใใใซ่ชญใฟ่พผใๅไฝใณใณใใญในใใใกใคใซใๆไพใใพใใ ใจๅ
ฅๅใใใจ`/sc:implement`ใClaude Code ใฏ`implement.md`ใณใณใใญในใใใกใคใซใ่ชญใฟ่พผใฟใใใฎๅไฝๆ็คบใซๅพใใพใใ
@@ -44,7 +44,7 @@ SuperClaude ใฏใClaude Code ใ็นๆฎใชๅไฝใๅฎ่กใใใใใซ่ชญใฟ
### ใณใใณใใฎ็จฎ้ก:
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#command-types-1)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#command-types-1)
- **ในใฉใใทใฅใณใใณใ**๏ผ`/sc:*`๏ผ๏ผใฏใผใฏใใญใผใใฟใผใณใจๅไฝโโใขใผใใใใชใฌใผใใ
- **ใจใผใธใงใณใใฎๅผใณๅบใ**๏ผ`@agent-*`๏ผ๏ผ็นๅฎใฎใใกใคใณในใใทใฃใชในใใๆๅใง่ตทๅใใ
@@ -52,10 +52,10 @@ SuperClaude ใฏใClaude Code ใ็นๆฎใชๅไฝใๅฎ่กใใใใใซ่ชญใฟ
### ใณใณใใญในใใกใซใใบใ :
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#the-context-mechanism)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#the-context-mechanism)
1. **ใฆใผใถใผๅ
ฅๅ**: ๅ
ฅๅใใ`/sc:implement "auth system"`
-2. **ใณใณใใญในใ่ชญใฟ่พผใฟ**: ใฏใญใผใใณใผใ่ชญใฟๅใ`~/.claude/SuperClaude/Commands/implement.md`
+2. **ใณใณใใญในใ่ชญใฟ่พผใฟ**: ใฏใญใผใใณใผใ่ชญใฟๅใ`~/.claude/superclaude/Commands/implement.md`
3. **่กๅใฎๆก็จ**๏ผใฏใญใผใใฏใใกใคใณใฎๅฐ้็ฅ่ญใใใผใซใฎ้ธๆใๆค่จผใใฟใผใณใ้ฉ็จใใพใ
4. **ๅผทๅใใใๅบๅ**: ใปใญใฅใชใใฃไธใฎ่ๆ
ฎไบ้
ใจใในใใใฉใฏใใฃในใๅใใๆง้ ๅใใใๅฎ่ฃ
@@ -63,7 +63,7 @@ SuperClaude ใฏใClaude Code ใ็นๆฎใชๅไฝใๅฎ่กใใใใใซ่ชญใฟ
### ใคใณในใใผใซใณใใณใใจไฝฟ็จใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#installation-vs-usage-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#installation-vs-usage-commands)
**๐ฅ๏ธ ใฟใผใใใซใณใใณใ**๏ผๅฎ้ใฎ CLI ใฝใใใฆใงใข๏ผ๏ผ
@@ -83,11 +83,11 @@ SuperClaude ใฏใClaude Code ใ็นๆฎใชๅไฝใๅฎ่กใใใใใซ่ชญใฟ
## ๐งช ใปใใใขใใใฎใในใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#-testing-your-setup)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#-testing-your-setup)
### ๐ฅ๏ธ ใฟใผใใใซๆค่จผ๏ผใฟใผใใใซ/CMDใงๅฎ่ก๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#%EF%B8%8F-terminal-verification-run-in-terminalcmd)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#%EF%B8%8F-terminal-verification-run-in-terminalcmd)
```shell
# Verify SuperClaude is working (primary method)
@@ -104,7 +104,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ๐ฌ ใฏใญใผใใณใผใใในใ๏ผใฏใญใผใใณใผใใใฃใใใซๅ
ฅๅ๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#-claude-code-testing-type-in-claude-code-chat)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#-claude-code-testing-type-in-claude-code-chat)
```
# Test basic /sc: command
@@ -116,11 +116,11 @@ python3 -m SuperClaude install --list-components | grep mcp
# Example behavior: List of available commands
```
-**ใในใใๅคฑๆใใๅ ดๅ**:[ใคใณในใใผใซใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Getting-Started/installation.md)ใพใใฏ[ใใฉใใซใทใฅใผใใฃใณใฐใ็ขบ่ชใใฆใใ ใใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#troubleshooting)
+**ใในใใๅคฑๆใใๅ ดๅ**:[ใคใณในใใผใซใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Getting-Started/installation.md)ใพใใฏ[ใใฉใใซใทใฅใผใใฃใณใฐใ็ขบ่ชใใฆใใ ใใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#troubleshooting)
### ๐ ใณใใณใใฏใคใใฏใชใใกใฌใณใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#-command-quick-reference)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#-command-quick-reference)
|ใณใใณใใฟใคใ|่ตฐใๅ ดๆ|ๅฝขๅผ|็ฎ็|ไพ|
|---|---|---|---|---|
@@ -134,25 +134,25 @@ python3 -m SuperClaude install --list-components | grep mcp
## ็ฎๆฌก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#table-of-contents)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#table-of-contents)
-- [ๅฟ
้ ใณใใณใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#essential-commands)- ใใใใๅงใใพใใใ๏ผ8ใคใฎใณใขใณใใณใ๏ผ
-- [ไธ่ฌ็ใชใฏใผใฏใใญใผ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#common-workflows)- ๆฉ่ฝใใใณใใณใใฎ็ตใฟๅใใ
-- [ๅฎๅ
จใชใณใใณใใชใใกใฌใณใน](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#full-command-reference)- ใซใใดใชๅฅใซๆด็ใใใๅ
จ21ๅใฎใณใใณใ
-- [ใใฉใใซใทใฅใผใใฃใณใฐ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#troubleshooting)- ใใใใๅ้กใจ่งฃๆฑบ็ญ
-- [ใณใใณใใคใณใใใฏใน](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#command-index)- ใซใใดใชๅฅใซใณใใณใใๆค็ดข
+- [ๅฟ
้ ใณใใณใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#essential-commands)- ใใใใๅงใใพใใใ๏ผ8ใคใฎใณใขใณใใณใ๏ผ
+- [ไธ่ฌ็ใชใฏใผใฏใใญใผ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#common-workflows)- ๆฉ่ฝใใใณใใณใใฎ็ตใฟๅใใ
+- [ๅฎๅ
จใชใณใใณใใชใใกใฌใณใน](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#full-command-reference)- ใซใใดใชๅฅใซๆด็ใใใๅ
จ21ๅใฎใณใใณใ
+- [ใใฉใใซใทใฅใผใใฃใณใฐ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#troubleshooting)- ใใใใๅ้กใจ่งฃๆฑบ็ญ
+- [ใณใใณใใคใณใใใฏใน](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#command-index)- ใซใใดใชๅฅใซใณใใณใใๆค็ดข
---
## ๅฟ
้ ใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#essential-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#essential-commands)
**ๅณๆใฎ็็ฃๆงๅไธใฎใใใฎใณใขใฏใผใฏใใญใผ ใณใใณใ:**
### `/sc:brainstorm`- ใใญใธใงใฏใ็บ่ฆ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#scbrainstorm---project-discovery)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#scbrainstorm---project-discovery)
**็ฎ็**: ๅฏพ่ฉฑๅใฎ่ฆไปถๆคๅบใจใใญใธใงใฏใ่จ็ป
**ๆงๆ**:`/sc:brainstorm "your idea"`ย `[--strategy systematic|creative]`
@@ -165,7 +165,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### `/sc:implement`- ๆฉ่ฝ้็บ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#scimplement---feature-development)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#scimplement---feature-development)
**็ฎ็**: ใคใณใใชใธใงใณใใชในใใทใฃใชในใใซใผใใฃใณใฐใซใใใใซในใฟใใฏๆฉ่ฝใฎๅฎ่ฃ
**ๆงๆ**:`/sc:implement "feature description"`ย `[--type frontend|backend|fullstack] [--focus security|performance]`
@@ -179,7 +179,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### `/sc:analyze`- ใณใผใ่ฉไพก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#scanalyze---code-assessment)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#scanalyze---code-assessment)
**็ฎ็**: ๅ่ณชใใปใญใฅใชใใฃใใใใฉใผใใณในใซใใใๅ
ๆฌ็ใชใณใผใๅๆ
**ๆงๆ**:`/sc:analyze [path]`ย `[--focus quality|security|performance|architecture]`
@@ -192,7 +192,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### `/sc:troubleshoot`- ๅ้ก่จบๆญ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#sctroubleshoot---problem-diagnosis)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#sctroubleshoot---problem-diagnosis)
**็ฎ็**: ๆ นๆฌๅๅ ๅๆใซใใไฝ็ณป็ใชๅ้ก่จบๆญ
**ๆงๆ**:`/sc:troubleshoot "issue description"`ย `[--type build|runtime|performance]`
@@ -205,7 +205,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### `/sc:test`- ๅ่ณชไฟ่จผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#sctest---quality-assurance)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#sctest---quality-assurance)
**็ฎ็**: ใซใใฌใใธๅๆใซใใๅ
ๆฌ็ใชใในใ
**ๆงๆ**:`/sc:test`ย `[--type unit|integration|e2e] [--coverage] [--fix]`
@@ -218,7 +218,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### `/sc:improve`- ใณใผใๅผทๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#scimprove---code-enhancement)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#scimprove---code-enhancement)
**็ฎ็**: ไฝ็ณป็ใชใณใผใใฎๆนๅใจๆ้ฉๅใ้ฉ็จใใ
**ๆงๆ**:`/sc:improve [path]`ย `[--type performance|quality|security] [--preview]`
@@ -231,7 +231,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### `/sc:document`- ใใญใฅใกใณใ็ๆ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#scdocument---documentation-generation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#scdocument---documentation-generation)
**็ฎ็**: ใณใผใใจAPIใฎๅ
ๆฌ็ใชใใญใฅใกใณใใ็ๆใใ
**ๆงๆ**:`/sc:document [path]`ย `[--type api|user-guide|technical] [--format markdown|html]`
@@ -244,7 +244,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### `/sc:workflow`- ๅฎ่ฃ
่จ็ป
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#scworkflow---implementation-planning)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#scworkflow---implementation-planning)
**็ฎ็**: ่ฆไปถใใๆง้ ๅใใใๅฎ่ฃ
่จ็ปใ็ๆใใ
**ๆงๆ**:`/sc:workflow "feature description"`ย `[--strategy agile|waterfall] [--format markdown]`
@@ -259,13 +259,13 @@ python3 -m SuperClaude install --list-components | grep mcp
## ไธ่ฌ็ใชใฏใผใฏใใญใผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#common-workflows)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#common-workflows)
**ๅฎ่จผๆธใฟใฎใณใใณใใฎ็ตใฟๅใใ:**
### ๆฐใใใใญใธใงใฏใใฎใปใใใขใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#new-project-setup)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#new-project-setup)
```shell
/sc:brainstorm "project concept" # Define requirements
@@ -275,7 +275,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ๆฉ่ฝ้็บ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#feature-development)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#feature-development)
```shell
/sc:implement "feature name" # Build the feature
@@ -285,7 +285,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ใณใผใๅ่ณชใฎๆนๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#code-quality-improvement)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#code-quality-improvement)
```shell
/sc:analyze --focus quality # Assess current state
@@ -295,7 +295,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ใใฐ่ชฟๆป
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#bug-investigation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#bug-investigation)
```shell
/sc:troubleshoot "issue description" # Diagnose the problem
@@ -305,11 +305,11 @@ python3 -m SuperClaude install --list-components | grep mcp
## ๅฎๅ
จใชใณใใณใใชใใกใฌใณใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#full-command-reference)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#full-command-reference)
### ้็บใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#development-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#development-commands)
|ๆ็คบ|็ฎ็|ๆ้ฉใช็จ้|
|---|---|---|
@@ -320,7 +320,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ๅๆใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#analysis-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#analysis-commands)
|ๆ็คบ|็ฎ็|ๆ้ฉใช็จ้|
|---|---|---|
@@ -330,7 +330,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ๅ่ณชใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#quality-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#quality-commands)
|ๆ็คบ|็ฎ็|ๆ้ฉใช็จ้|
|---|---|---|
@@ -341,7 +341,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ใใญใธใงใฏใ็ฎก็
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#project-management)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#project-management)
|ๆ็คบ|็ฎ็|ๆ้ฉใช็จ้|
|---|---|---|
@@ -351,7 +351,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ใฆใผใใฃใชใใฃใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#utility-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#utility-commands)
|ๆ็คบ|็ฎ็|ๆ้ฉใช็จ้|
|---|---|---|
@@ -360,7 +360,7 @@ python3 -m SuperClaude install --list-components | grep mcp
### ใปใใทใงใณใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#session-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#session-commands)
|ๆ็คบ|็ฎ็|ๆ้ฉใช็จ้|
|---|---|---|
@@ -373,7 +373,7 @@ python3 -m SuperClaude install --list-components | grep mcp
## ใณใใณใใคใณใใใฏใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#command-index)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#command-index)
**ๆฉ่ฝๅฅ:**
@@ -392,7 +392,7 @@ python3 -m SuperClaude install --list-components | grep mcp
## ใใฉใใซใทใฅใผใใฃใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#troubleshooting)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#troubleshooting)
**ใณใใณใใฎๅ้ก:**
@@ -404,12 +404,12 @@ python3 -m SuperClaude install --list-components | grep mcp
- ใปใใทใงใณใใชใปใใ:`/sc:load`ๅๅๆๅใใ
- ในใใผใฟในใ็ขบ่ช:`SuperClaude install --list-components`
-- ใใซใ:[ใใฉใใซใทใฅใผใใฃใณใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/troubleshooting.md)
+- ใใซใ:[ใใฉใใซใทใฅใผใใฃใณใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/troubleshooting.md)
## ๆฌกใฎในใใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#next-steps)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#next-steps)
-- [ใใฉใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md)- ใณใใณใใฎๅไฝใๅถๅพกใใ
-- [ใจใผใธใงใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md)- ในใใทใฃใชในใใฎใขใฏใใฃใใผใทใงใณ
-- [ไพใฎใฏใใฏใใใฏ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/examples-cookbook.md)- ๅฎ้ใฎไฝฟ็จใใฟใผใณ
\ No newline at end of file
+- [ใใฉใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md)- ใณใใณใใฎๅไฝใๅถๅพกใใ
+- [ใจใผใธใงใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md)- ในใใทใฃใชในใใฎใขใฏใใฃใใผใทใงใณ
+- [ไพใฎใฏใใฏใใใฏ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/examples-cookbook.md)- ๅฎ้ใฎไฝฟ็จใใฟใผใณ
\ No newline at end of file
diff --git a/Docs/User-Guide-jp/flags.md b/docs/User-Guide-jp/flags.md
similarity index 85%
rename from Docs/User-Guide-jp/flags.md
rename to docs/User-Guide-jp/flags.md
index 50e2c80..2233aec 100644
--- a/Docs/User-Guide-jp/flags.md
+++ b/docs/User-Guide-jp/flags.md
@@ -1,16 +1,16 @@
# SuperClaude ใใฉใฐใฌใคใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#superclaude-flags-guide-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#superclaude-flags-guide-)
**ใปใจใใฉใฎใใฉใฐใฏ่ชๅ็ใซใขใฏใใฃใใซใชใใพใ**ใClaude Code ใฏใใชใฏใจในใๅ
ใฎใญใผใฏใผใใจใใฟใผใณใซๅบใฅใใฆ้ฉๅใชใณใณใใญในใใๅฎ่กใใใใใฎๅไฝๆ็คบใ่ชญใฟๅใใพใใ
## ๅฟ
้ ใฎ่ชๅใขใฏใใฃใใผใทใงใณใใฉใฐ๏ผใฆใผในใฑใผในใฎ90%๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#essential-auto-activation-flags-90-of-use-cases)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#essential-auto-activation-flags-90-of-use-cases)
### ใณใขๅๆใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#core-analysis-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#core-analysis-flags)
|ใใฉใฐ|่ตทๅๆ|ไฝใใใใฎใ|
|---|---|---|
@@ -20,7 +20,7 @@
### MCP ใตใผใใผใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#mcp-server-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#mcp-server-flags)
|ใใฉใฐ|ใตใผใ|็ฎ็|่ชๅใใชใฌใผ|
|---|---|---|---|
@@ -33,7 +33,7 @@
### ๅไฝใขใผใใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#behavioral-mode-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#behavioral-mode-flags)
|ใใฉใฐ|่ตทๅๆ|ไฝใใใใฎใ|
|---|---|---|
@@ -45,7 +45,7 @@
### ๅฎ่กๅถๅพกใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#execution-control-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#execution-control-flags)
|ใใฉใฐ|่ตทๅๆ|ไฝใใใใฎใ|
|---|---|---|
@@ -56,11 +56,11 @@
## ใณใใณใๅบๆใฎใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#command-specific-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#command-specific-flags)
### ๅๆใณใใณใใใฉใฐ๏ผ`/sc:analyze`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#analysis-command-flags-scanalyze)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#analysis-command-flags-scanalyze)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -70,7 +70,7 @@
### ใใซใใณใใณใใใฉใฐ๏ผ`/sc:build`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#build-command-flags-scbuild)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#build-command-flags-scbuild)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -81,7 +81,7 @@
### ่จญ่จใณใใณใใใฉใฐ๏ผ`/sc:design`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#design-command-flags-scdesign)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#design-command-flags-scdesign)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -90,7 +90,7 @@
### ใณใใณใใใฉใฐใฎ่ชฌๆ๏ผ`/sc:explain`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#explain-command-flags-scexplain)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#explain-command-flags-scexplain)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -100,7 +100,7 @@
### ใณใใณใใใฉใฐใฎๆนๅ๏ผ`/sc:improve`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#improve-command-flags-scimprove)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#improve-command-flags-scimprove)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -111,7 +111,7 @@
### ใฟในใฏใณใใณใใใฉใฐ๏ผ`/sc:task`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#task-command-flags-sctask)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#task-command-flags-sctask)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -121,7 +121,7 @@
### ใฏใผใฏใใญใผใณใใณใใใฉใฐ๏ผ`/sc:workflow`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#workflow-command-flags-scworkflow)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#workflow-command-flags-scworkflow)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -131,7 +131,7 @@
### ใณใใณใใใฉใฐใฎใใฉใใซใทใฅใผใใฃใณใฐ (ย `/sc:troubleshoot`)
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#troubleshoot-command-flags-sctroubleshoot)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#troubleshoot-command-flags-sctroubleshoot)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -141,7 +141,7 @@
### ใฏใชใผใณใขใใใณใใณใใใฉใฐ๏ผ`/sc:cleanup`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#cleanup-command-flags-sccleanup)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#cleanup-command-flags-sccleanup)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -152,7 +152,7 @@
### ใณใใณใใใฉใฐใฎๆจๅฎ๏ผ`/sc:estimate`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#estimate-command-flags-scestimate)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#estimate-command-flags-scestimate)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -162,7 +162,7 @@
### ใคใณใใใฏในใณใใณใใใฉใฐ๏ผ`/sc:index`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#index-command-flags-scindex)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#index-command-flags-scindex)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -171,7 +171,7 @@
### ใณใใณใใใฉใฐใๅๆ ใใ (ย `/sc:reflect`)
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#reflect-command-flags-screflect)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#reflect-command-flags-screflect)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -181,7 +181,7 @@
### ในใใผใณใณใใณใใใฉใฐ๏ผ`/sc:spawn`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#spawn-command-flags-scspawn)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#spawn-command-flags-scspawn)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -190,7 +190,7 @@
### Gitใณใใณใใใฉใฐ๏ผ`/sc:git`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#git-command-flags-scgit)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#git-command-flags-scgit)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -199,7 +199,7 @@
### ้ธๆใใผใซใณใใณใใใฉใฐ (ย `/sc:select-tool`)
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#select-tool-command-flags-scselect-tool)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#select-tool-command-flags-scselect-tool)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -208,7 +208,7 @@
### ใในใใณใใณใใใฉใฐ๏ผ`/sc:test`๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#test-command-flags-sctest)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#test-command-flags-sctest)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -218,11 +218,11 @@
## ้ซๅบฆใชๅถๅพกใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#advanced-control-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#advanced-control-flags)
### ็ฏๅฒใจ็ฆ็น
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#scope-and-focus)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#scope-and-focus)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -231,7 +231,7 @@
### ๅฎ่กๅถๅพก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#execution-control)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#execution-control)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -242,7 +242,7 @@
### ใทในใใ ใใฉใฐ๏ผSuperClaude ใคใณในใใผใซ๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#system-flags-superclaude-installation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#system-flags-superclaude-installation)
|ใใฉใฐ|็ฎ็|ไพกๅค่ฆณ|
|---|---|---|
@@ -258,11 +258,11 @@
## ไธ่ฌ็ใชไฝฟ็จใใฟใผใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#common-usage-patterns)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#common-usage-patterns)
### ใใญใณใใจใณใ้็บ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#frontend-development)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#frontend-development)
```shell
/sc:implement "responsive dashboard" --magic --c7
@@ -273,7 +273,7 @@
### ใใใฏใจใณใ้็บ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#backend-development)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#backend-development)
```shell
/sc:analyze api/ --focus performance --seq --think
@@ -284,7 +284,7 @@
### ๅคง่ฆๆจกใใญใธใงใฏใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#large-projects)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#large-projects)
```shell
/sc:analyze . --ultrathink --all-mcp --safe-mode
@@ -295,7 +295,7 @@
### ๅ่ณชใจใกใณใใใณใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#quality--maintenance)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#quality--maintenance)
```shell
/sc:improve src/ --type quality --safe --interactive
@@ -306,11 +306,11 @@
## ใใฉใฐใคใณใฟใฉใฏใทใงใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#flag-interactions)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#flag-interactions)
### ไบๆๆงใฎใใ็ตใฟๅใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#compatible-combinations)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#compatible-combinations)
- `--think`+ย `--c7`: ใใญใฅใกใณใไปใๅๆ
- `--magic`+ย `--play`: ใในใไปใใฎUI็ๆ
@@ -320,7 +320,7 @@
### ็ซถๅใใใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#conflicting-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#conflicting-flags)
- `--all-mcp`ๅๅฅใฎMCPใใฉใฐใจๆฏ่ผ๏ผใฉใกใใไธๆนใไฝฟ็จ๏ผ
- `--no-mcp`ไปปๆใฎMCPใใฉใฐใจๆฏ่ผ๏ผ--no-mcpใๅชๅ
๏ผ
@@ -329,7 +329,7 @@
### ้ขไฟใฎ่ชๅๆๅนๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#auto-enabling-relationships)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#auto-enabling-relationships)
- `--safe-mode`่ชๅ็`--uc`ใซๆๅนใซใชใใ`--validate`
- `--ultrathink`ใในใฆใฎMCPใตใผใใผใ่ชๅ็ใซๆๅนใซใใ
@@ -338,11 +338,11 @@
## ใใฉใใซใทใฅใผใใฃใณใฐใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#troubleshooting-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#troubleshooting-flags)
### ใใใใๅ้ก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#common-issues)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#common-issues)
- **ใใผใซใๅคใใใ**:`--no-mcp`ใใคใใฃใใใผใซใฎใฟใงใในใใใ
- **ๆไฝใ้
ใใใพใ**:`--uc`ๅบๅใๅง็ธฎใใใใใซ่ฟฝๅ ใใพใ
@@ -351,7 +351,7 @@
### ใใใใฐใใฉใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#debug-flags)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#debug-flags)
```shell
/sc:analyze . --verbose # Shows decision logic and flag activation
@@ -361,7 +361,7 @@
### ใฏใคใใฏใใฃใใฏใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#quick-fixes)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#quick-fixes)
```shell
/sc:analyze . --help # Shows available flags for command
@@ -371,7 +371,7 @@
## ใใฉใฐใฎๅชๅ
ใซใผใซ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#flag-priority-rules)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#flag-priority-rules)
1. **ๅฎๅ
จ็ฌฌไธ**:ย `--safe-mode`>ย `--validate`> ๆ้ฉๅใใฉใฐ
2. **ๆ็คบ็ใชใชใผใใผใฉใคใ**: ใฆใผใถใผใใฉใฐ > ่ชๅๆคๅบ
@@ -381,8 +381,8 @@
## ้ข้ฃใชใฝใผใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md#related-resources)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md#related-resources)
-- [ใณใใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md)- ใใใใฎใใฉใฐใไฝฟ็จใใใณใใณใ
-- [MCP ใตใผใใผใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md)- MCP ใใฉใฐใฎใขใฏใใฃใๅใซใคใใฆ
-- [ใปใใทใงใณ็ฎก็](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md)- ๆฐธ็ถใปใใทใงใณใงใฎใใฉใฐใฎไฝฟ็จ
\ No newline at end of file
+- [ใณใใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md)- ใใใใฎใใฉใฐใไฝฟ็จใใใณใใณใ
+- [MCP ใตใผใใผใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md)- MCP ใใฉใฐใฎใขใฏใใฃใๅใซใคใใฆ
+- [ใปใใทใงใณ็ฎก็](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md)- ๆฐธ็ถใปใใทใงใณใงใฎใใฉใฐใฎไฝฟ็จ
\ No newline at end of file
diff --git a/Docs/User-Guide-jp/mcp-servers.md b/docs/User-Guide-jp/mcp-servers.md
similarity index 88%
rename from Docs/User-Guide-jp/mcp-servers.md
rename to docs/User-Guide-jp/mcp-servers.md
index 8259a8c..284a05f 100644
--- a/Docs/User-Guide-jp/mcp-servers.md
+++ b/docs/User-Guide-jp/mcp-servers.md
@@ -1,16 +1,16 @@
# SuperClaude MCP ใตใผใใผใฌใคใ ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#superclaude-mcp-servers-guide-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#superclaude-mcp-servers-guide-)
## ๆฆ่ฆ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#overview)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#overview)
MCP๏ผใขใใซใณใณใใญในใใใญใใณใซ๏ผใตใผใใผใฏใๅฐ็จใใผใซใ้ใใฆClaude Codeใฎๆฉ่ฝใๆกๅผตใใพใใSuperClaudeใฏ6ใคใฎMCPใตใผใใผใ็ตฑๅใใใฟในใฏใซๅฟใใฆใตใผใใผใใใค่ตทๅใใใใClaudeใซๆ็คบใใพใใ
### ๐ ็พๅฎใใงใใฏ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#-reality-check)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#-reality-check)
- **MCPใตใผใใผใจใฏ**: ่ฟฝๅ ใใผใซใๆไพใใๅค้จNode.jsใใญใปใน
- **ๅซใพใใฆใใชใใใฎ**๏ผSuperClaude ๆฉ่ฝใ็ตใฟ่พผใพใใฆใใ
@@ -28,9 +28,9 @@ MCP๏ผใขใใซใณใณใใญในใใใญใใณใซ๏ผใตใผใใผใฏใๅฐ็จใ
## ใฏใคใใฏในใฟใผใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#quick-start)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#quick-start)
-**ใปใใใขใใใฎ็ขบ่ช**๏ผMCPใตใผใใผใฏ่ชๅ็ใซ่ตทๅใใพใใใคใณในใใผใซใจใใฉใใซใทใฅใผใใฃใณใฐใซใคใใฆใฏใ[ใใคใณในใใผใซใฌใคใใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Getting-Started/installation.md)ใจ[ใใใฉใใซใทใฅใผใใฃใณใฐใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/troubleshooting.md)ใๅ็
งใใฆใใ ใใใ
+**ใปใใใขใใใฎ็ขบ่ช**๏ผMCPใตใผใใผใฏ่ชๅ็ใซ่ตทๅใใพใใใคใณในใใผใซใจใใฉใใซใทใฅใผใใฃใณใฐใซใคใใฆใฏใ[ใใคใณในใใผใซใฌใคใใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Getting-Started/installation.md)ใจ[ใใใฉใใซใทใฅใผใใฃใณใฐใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/troubleshooting.md)ใๅ็
งใใฆใใ ใใใ
**่ชๅใขใฏใใฃใใผใทใงใณใญใธใใฏ:**
@@ -45,11 +45,11 @@ MCP๏ผใขใใซใณใณใใญในใใใญใใณใซ๏ผใตใผใใผใฏใๅฐ็จใ
## ใตใผใใผใฎ่ฉณ็ดฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#server-details)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#server-details)
### ใณใณใใญในใ7 ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#context7-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#context7-)
**็ฎ็**: ๅ
ฌๅผใฉใคใใฉใชใใญใฅใกใณใใธใฎใขใฏใปในย **ใใชใฌใผ**: ใคใณใใผใในใใผใใกใณใใใใฌใผใ ใฏใผใฏใญใผใฏใผใใใใญใฅใกใณใใชใฏใจในใย **่ฆไปถ**: Node.js 16+ใAPIใญใผใชใ
@@ -64,7 +64,7 @@ MCP๏ผใขใใซใณใณใใญในใใใญใใณใซ๏ผใตใผใใผใฏใๅฐ็จใ
### ้ฃ็ถๆ่ ๐ง
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#sequential-thinking-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#sequential-thinking-)
**็ฎ็**: ๆง้ ๅใใใๅคๆฎต้ใฎๆจ่ซใจไฝ็ณป็ใชๅๆย **ใใชใฌใผ**: ่ค้ใชใใใใฐใ`--think`ใใฉใฐใใขใผใญใใฏใใฃๅๆย **่ฆไปถ**: Node.js 16+ใAPIใญใผใชใ
@@ -79,7 +79,7 @@ MCP๏ผใขใใซใณใณใใญในใใใญใใณใซ๏ผใตใผใใผใฏใๅฐ็จใ
### ้ญๆณโจ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#magic-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#magic-)
**็ฎ็**: 21st.dev ใใฟใผใณใใใฎใขใใณ UI ใณใณใใผใใณใ็ๆย **ใใชใฌใผ**: UI ใชใฏใจในใใ`/ui`ใณใใณใใใณใณใใผใใณใ้็บย **่ฆไปถ**: Node.js 16+ใTWENTYFIRST_API_KEY()
@@ -94,7 +94,7 @@ export TWENTYFIRST_API_KEY="your_key_here"
### ๅไฝๅฎถ๐ญ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#playwright-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#playwright-)
**็ฎ็**: ๅฎ้ใฎใใฉใฆใถ่ชๅๅใจE2Eใในใย **ใใชใฌใผ**: ใใฉใฆใถใในใใE2Eใทใใชใชใ่ฆ่ฆ็ๆค่จผย **่ฆไปถ**: Node.js 16ไปฅไธใAPIใญใผใชใ
@@ -109,7 +109,7 @@ export TWENTYFIRST_API_KEY="your_key_here"
### morphllm-fast-apply ๐
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#morphllm-fast-apply-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#morphllm-fast-apply-)
**็ฎ็**: ๅน็็ใชใใฟใผใณใใผในใฎใณใผใๅคๆย **ใใชใฌใผ**: ่คๆฐใใกใคใซใฎ็ทจ้ใใชใใกใฏใฟใชใณใฐใใใฌใผใ ใฏใผใฏใฎ็งป่กย **่ฆไปถ**: Node.js 16+ใMORPH_API_KEY
@@ -124,7 +124,7 @@ export MORPH_API_KEY="your_key_here"
### ใปใฌใ๐งญ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#serena-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#serena-)
**็ฎ็**: ใใญใธใงใฏใใกใขใชใไฝฟ็จใใใปใใณใใฃใใฏใณใผใ็่งฃย **ใใชใฌใผ**: ใทใณใใซๆไฝใๅคง่ฆๆจกใณใผใใใผในใใปใใทใงใณ็ฎก็ย **่ฆไปถ**: Python 3.9+ใUV ใใใฑใผใธใใใผใธใฃใผใAPI ใญใผใชใ
@@ -139,7 +139,7 @@ export MORPH_API_KEY="your_key_here"
## ๆงๆ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#configuration)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#configuration)
**MCP ๆงๆใใกใคใซ (ย `~/.claude.json`):**
@@ -178,7 +178,7 @@ export MORPH_API_KEY="your_key_here"
## ไฝฟ็จใใฟใผใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#usage-patterns)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#usage-patterns)
**ใตใผใใผๅถๅพก:**
@@ -207,7 +207,7 @@ export MORPH_API_KEY="your_key_here"
## ใใฉใใซใทใฅใผใใฃใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#troubleshooting)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#troubleshooting)
**ใใใใๅ้ก:**
@@ -255,7 +255,7 @@ echo 'export MORPH_API_KEY="your_key"' >> ~/.bashrc
## ใตใผใใผใฎ็ตใฟๅใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#server-combinations)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#server-combinations)
**APIใญใผใชใ๏ผ็กๆ๏ผ**ย :
@@ -278,7 +278,7 @@ echo 'export MORPH_API_KEY="your_key"' >> ~/.bashrc
## ็ตฑๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#integration)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#integration)
**SuperClaude ใณใใณใใไฝฟ็จใใๅ ดๅ:**
@@ -300,20 +300,20 @@ echo 'export MORPH_API_KEY="your_key"' >> ~/.bashrc
## ้ข้ฃใชใฝใผใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md#related-resources)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md#related-resources)
**ๅฟ
่ชญ:**
-- [ใณใใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md)- MCPใตใผใใผใใขใฏใใฃใๅใใใณใใณใ
-- [ใฏใคใใฏในใฟใผใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Getting-Started/quick-start.md)- MCP ใปใใใขใใใฌใคใ
+- [ใณใใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md)- MCPใตใผใใผใใขใฏใใฃใๅใใใณใใณใ
+- [ใฏใคใใฏในใฟใผใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Getting-Started/quick-start.md)- MCP ใปใใใขใใใฌใคใ
**้ซๅบฆใชไฝฟ็จๆณ:**
-- [่กๅใขใผใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md)- ใขใผใ-MCP่ชฟๆด
-- [ใจใผใธใงใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md)- ใจใผใธใงใณใใจMCPใฎ็ตฑๅ
-- [ใปใใทใงใณ็ฎก็](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md)- Serena ใฏใผใฏใใญใผ
+- [่กๅใขใผใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md)- ใขใผใ-MCP่ชฟๆด
+- [ใจใผใธใงใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md)- ใจใผใธใงใณใใจMCPใฎ็ตฑๅ
+- [ใปใใทใงใณ็ฎก็](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md)- Serena ใฏใผใฏใใญใผ
**ๆ่กใชใใกใฌใณใน:**
-- [ไพใฎใฏใใฏใใใฏ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/examples-cookbook.md)- MCP ใฏใผใฏใใญใผใใฟใผใณ
-- [ๆ่กใขใผใญใใฏใใฃ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Developer-Guide/technical-architecture.md)- ็ตฑๅใฎ่ฉณ็ดฐ
\ No newline at end of file
+- [ไพใฎใฏใใฏใใใฏ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/examples-cookbook.md)- MCP ใฏใผใฏใใญใผใใฟใผใณ
+- [ๆ่กใขใผใญใใฏใใฃ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Developer-Guide/technical-architecture.md)- ็ตฑๅใฎ่ฉณ็ดฐ
\ No newline at end of file
diff --git a/Docs/User-Guide-jp/modes.md b/docs/User-Guide-jp/modes.md
similarity index 91%
rename from Docs/User-Guide-jp/modes.md
rename to docs/User-Guide-jp/modes.md
index 4e48c9a..6811ef1 100644
--- a/Docs/User-Guide-jp/modes.md
+++ b/docs/User-Guide-jp/modes.md
@@ -1,16 +1,16 @@
# SuperClaude ่กๅใขใผใใฌใคใ ๐ง
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#superclaude-behavioral-modes-guide-)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#superclaude-behavioral-modes-guide-)
## โ
ใฏใคใใฏๆค่จผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#-quick-verification)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#-quick-verification)
-ใณใใณใใไฝฟ็จใใฆใขใผใใใในใใใพใ`/sc:`ใใขใผใใฏใฟในใฏใฎ่ค้ใใซๅบใฅใใฆ่ชๅ็ใซใขใฏใใฃใใซใชใใพใใใณใใณใใฎๅฎๅ
จใชใชใใกใฌใณในใซใคใใฆใฏใ[ใณใใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md)ใใ่ฆงใใ ใใใ
+ใณใใณใใไฝฟ็จใใฆใขใผใใใในใใใพใ`/sc:`ใใขใผใใฏใฟในใฏใฎ่ค้ใใซๅบใฅใใฆ่ชๅ็ใซใขใฏใใฃใใซใชใใพใใใณใใณใใฎๅฎๅ
จใชใชใใกใฌใณในใซใคใใฆใฏใ[ใณใใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md)ใใ่ฆงใใ ใใใ
## ใฏใคใใฏใชใใกใฌใณในใใผใใซ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#quick-reference-table)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#quick-reference-table)
|ใขใผใ|็ฎ็|่ชๅใใชใฌใผ|้่ฆใช่กๅ|ๆ้ฉใช็จ้|
|---|---|---|---|---|
@@ -24,7 +24,7 @@
## ใฏใใใซ๏ผ2ๅใฎๆฆ่ฆ๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#getting-started-2-minute-overview)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#getting-started-2-minute-overview)
**ใขใผใใฏๅไฝๆ็คบใ้ใใฆใขใฏใใฃใๅใใใพใ**- Claude Code ใฏใณใณใใญในใ ใใกใคใซใ่ชญใฟๅใใใฟในใฏใฎใใฟใผใณใจ่ค้ใใซๅบใฅใใฆใฉใฎใขใผใๅไฝใๆก็จใใใใๆฑบๅฎใใพใใ
@@ -47,11 +47,11 @@
## ใขใผใใฎ่ฉณ็ดฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#mode-details)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#mode-details)
### ๐ง ใใฌใคใณในใใผใใณใฐใขใผใ - ใคใณใฟใฉใฏใใฃใใช็บ่ฆ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#-brainstorming-mode---interactive-discovery)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#-brainstorming-mode---interactive-discovery)
**็ฎ็**: ๅ
ฑๅไฝๆฅญใซใใ็บ่ฆใ้ใใฆใๆผ ็ถใจใใใขใคใใขใๆง้ ๅใใใ่ฆไปถใซๅคๆใใพใใ
@@ -85,7 +85,7 @@ Brainstorming Approach:
#### ๆๅๅบๆบ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#success-criteria)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#success-criteria)
- [ ] ใใใซ่งฃๆฑบ็ญใๆ็คบใใใฎใงใฏใชใใ่ณชๅใงๅฟ็ญใใ
- [ ] ่ณชๅใฏใฆใผใถใผใฎใใผใบใๆ่ก็ๅถ็ดใใใธใใน็ฎๆจใๆขใใพใ
@@ -106,7 +106,7 @@ Brainstorming Approach:
### ๐ ๅ
็ใขใผใ - ใกใฟ่ช็ฅๅๆ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#-introspection-mode---meta-cognitive-analysis)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#-introspection-mode---meta-cognitive-analysis)
**็ฎ็**: ๅญฆ็ฟใฎๆ้ฉๅใจ้ๆใชๆๆๆฑบๅฎใฎใใใฎๆจ่ซใใญใปในใๅ
ฌ้ใใพใใ
@@ -149,7 +149,7 @@ Introspective Approach:
### ๐ ใฟในใฏ็ฎก็ใขใผใ - ่ค้ใช่ชฟๆด
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#-task-management-mode---complex-coordination)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#-task-management-mode---complex-coordination)
**็ฎ็**: ่คๆฐในใใใใฎๆไฝใฎใใใฎใปใใทใงใณๆฐธ็ถๆงใๅใใ้ๅฑค็ใชใฟในใฏๆงๆใ
@@ -193,7 +193,7 @@ Task Management Approach:
### ๐ฏ ใชใผใฑในใใฌใผใทใงใณใขใผใ - ใคใณใใชใธใงใณใใชใใผใซ้ธๆ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#-orchestration-mode---intelligent-tool-selection)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#-orchestration-mode---intelligent-tool-selection)
**็ฎ็**: ใคใณใใชใธใงใณใใชใใผใซใซใผใใฃใณใฐใจไธฆๅ่ชฟๆดใ้ใใฆใฟในใฏใฎๅฎ่กใๆ้ฉๅใใพใใ
@@ -235,7 +235,7 @@ Orchestration Approach:
### โก ใใผใฏใณๅน็ใขใผใ - ๅง็ธฎ้ไฟก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#-token-efficiency-mode---compressed-communication)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#-token-efficiency-mode---compressed-communication)
**็ฎ็**: ๆ
ๅ ฑใฎๅ่ณชใ็ถญๆใใชใใใใทใณใใซ ใทในใใ ใ้ใใฆๆจๅฎ 30 ๏ฝ 50% ใฎใใผใฏใณๅๆธใๅฎ็พใใพใใ
@@ -276,7 +276,7 @@ Token Efficient Approach:
### ๐จ ๆจๆบใขใผใ - ใใฉใณในใฎใจใใใใใฉใซใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#-standard-mode---balanced-default)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#-standard-mode---balanced-default)
**็ฎ็**: ็ฐกๅใช้็บใฟในใฏใซๅฏพใใฆๆ็ขบใงใใญใใงใใทใงใใซใชใณใใฅใใฑใผใทใงใณใๆไพใใพใใ
@@ -319,11 +319,11 @@ Standard Approach: Consistent, professional baseline for all tasks
## ้ซๅบฆใชไฝฟ็จๆณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#advanced-usage)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#advanced-usage)
### ใขใผใใฎ็ตใฟๅใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#mode-combinations)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#mode-combinations)
**ใใซใใขใผใใฏใผใฏใใญใผ:**
@@ -341,7 +341,7 @@ Standard Approach: Consistent, professional baseline for all tasks
### ๆๅใขใผใๅถๅพก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#manual-mode-control)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#manual-mode-control)
**็นๅฎใฎๅไฝใๅผทๅถใใ:**
@@ -366,7 +366,7 @@ Standard Approach: Consistent, professional baseline for all tasks
### ใขใผใใฎๅข็ใจๅชๅ
้ ไฝ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#mode-boundaries-and-priority)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#mode-boundaries-and-priority)
**ใขใผใใใขใฏใใฃใใซใชใใจ:**
@@ -387,11 +387,11 @@ Standard Approach: Consistent, professional baseline for all tasks
## ๅฎไธ็ใฎไพ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#real-world-examples)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#real-world-examples)
### ๅฎๅ
จใชใฏใผใฏใใญใผใฎไพ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#complete-workflow-examples)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#complete-workflow-examples)
**ๆฐ่ฆใใญใธใงใฏใ้็บ:**
@@ -430,7 +430,7 @@ Standard Approach: Consistent, professional baseline for all tasks
### ใขใผใใฎ็ตใฟๅใใใใฟใผใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#mode-combination-patterns)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#mode-combination-patterns)
**้ๅธธใซ่ค้ใชใทใใชใช:**
@@ -447,11 +447,11 @@ Standard Approach: Consistent, professional baseline for all tasks
## ใฏใคใใฏใชใใกใฌใณใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#quick-reference)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#quick-reference)
### ใขใผใ่ตทๅใใฟใผใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#mode-activation-patterns)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#mode-activation-patterns)
|ใใชใฌใผใฟใคใ|ๅ
ฅๅไพ|ใขใผใใๆๅน|ไธป่ฆใชๅไฝ|
|---|---|---|---|
@@ -464,7 +464,7 @@ Standard Approach: Consistent, professional baseline for all tasks
### ๆๅใชใผใใผใฉใคใใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#manual-override-commands)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#manual-override-commands)
```shell
# Force specific mode behaviors
@@ -483,26 +483,26 @@ Standard Approach: Consistent, professional baseline for all tasks
## ใใฉใใซใทใฅใผใใฃใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#troubleshooting)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#troubleshooting)
ใใฉใใซใทใฅใผใใฃใณใฐใฎใใซใใซใคใใฆใฏใไปฅไธใๅ็
งใใฆใใ ใใใ
-- [ใใใใๅ้ก](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/common-issues.md)- ใใใใๅ้กใซๅฏพใใใฏใคใใฏไฟฎๆญฃ
-- [ใใฉใใซใทใฅใผใใฃใณใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/troubleshooting.md)- ๅ
ๆฌ็ใชๅ้ก่งฃๆฑบ
+- [ใใใใๅ้ก](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/common-issues.md)- ใใใใๅ้กใซๅฏพใใใฏใคใใฏไฟฎๆญฃ
+- [ใใฉใใซใทใฅใผใใฃใณใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/troubleshooting.md)- ๅ
ๆฌ็ใชๅ้ก่งฃๆฑบ
### ใใใใๅ้ก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#common-issues)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#common-issues)
- **ใขใผใใใขใฏใใฃใๅใใใฆใใพใใ**: ๆๅใใฉใฐใไฝฟ็จใใฆใใ ใใ:ย `--brainstorm`ใใ`--introspect``--uc`
- **้้ใฃใใขใผใใใขใฏใใฃใใงใ**: ใชใฏใจในใๅ
ใฎ่ค้ใชใใชใฌใผใจใญใผใฏใผใใ็ขบ่ชใใฆใใ ใใ
- **ไบๆใใชใใขใผใๅใๆฟใ**๏ผใฟในใฏใฎ้ฒ่กใซๅบใฅใ้ๅธธใฎๅไฝ
- **ๅฎ่กใธใฎๅฝฑ้ฟ**: ใขใผใใฏใใผใซใฎไฝฟ็จใๆ้ฉๅใใใใฎใงใใใๅฎ่กใซใฏๅฝฑ้ฟใใชใใฏใใงใใ
-- **ใขใผใใฎ็ซถๅ**:[ใใฉใฐใฌใคใใงใใฉใฐใฎๅชๅ
้ ไฝใซใผใซใ็ขบ่ชใใฆใใ ใใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md)
+- **ใขใผใใฎ็ซถๅ**:[ใใฉใฐใฌใคใใงใใฉใฐใฎๅชๅ
้ ไฝใซใผใซใ็ขบ่ชใใฆใใ ใใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md)
### ๅณๆไฟฎๆญฃ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#immediate-fixes)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#immediate-fixes)
- **็นๅฎใฎใขใผใใๅผทๅถ**:`--brainstorm`ใพใใฏใฎใใใชๆ็คบ็ใชใใฉใฐใไฝฟ็จใใ`--task-manage`
- **ใชใปใใใขใผใใฎๅไฝ**: ใขใผใ็ถๆ
ใใชใปใใใใใซใฏใClaude Code ใปใใทใงใณใๅ่ตทๅใใพใใ
@@ -511,7 +511,7 @@ Standard Approach: Consistent, professional baseline for all tasks
### ใขใผใๅบๆใฎใใฉใใซใทใฅใผใใฃใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#mode-specific-troubleshooting)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#mode-specific-troubleshooting)
**ใใฌใคใณในใใผใใณใฐใขใผใใฎๅ้ก:**
@@ -564,7 +564,7 @@ Standard Approach: Consistent, professional baseline for all tasks
### ใจใฉใผใณใผใใชใใกใฌใณใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#error-code-reference)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#error-code-reference)
|ใขใผใใจใฉใผ|ๆๅณ|ใฏใคใใฏใใฃใใฏใน|
|---|---|---|
@@ -579,7 +579,7 @@ Standard Approach: Consistent, professional baseline for all tasks
### ใใญใฐใฌใใทใใตใใผใใฌใใซ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#progressive-support-levels)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#progressive-support-levels)
**ใฌใใซ 1: ใฏใคใใฏใใฃใใฏใน (< 2 ๅ)**
@@ -596,7 +596,7 @@ Standard Approach: Consistent, professional baseline for all tasks
# Review request complexity and triggers
```
-- ใขใผใใฎใคใณในใใผใซใซ้ขใใๅ้กใซใคใใฆใฏใ[ไธ่ฌ็ใชๅ้กใฌใคใใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/common-issues.md)ๅ็
งใใฆใใ ใใใ
+- ใขใผใใฎใคใณในใใผใซใซ้ขใใๅ้กใซใคใใฆใฏใ[ไธ่ฌ็ใชๅ้กใฌใคใใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/common-issues.md)ๅ็
งใใฆใใ ใใใ
**ใฌใใซ3: ๅฐ้ๅฎถใซใใใตใใผใ๏ผ30ๅไปฅไธ๏ผ**
@@ -607,7 +607,7 @@ SuperClaude install --diagnose
# Review behavioral triggers and thresholds
```
-- ่กๅใขใผใๅๆใซใคใใฆใฏ[่จบๆญใชใใกใฌใณในใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/diagnostic-reference.md)ใๅ็
งใใฆใใ ใใ
+- ่กๅใขใผใๅๆใซใคใใฆใฏ[่จบๆญใชใใกใฌใณในใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/diagnostic-reference.md)ใๅ็
งใใฆใใ ใใ
**ใฌใใซ4: ใณใใฅใใใฃใตใใผใ**
@@ -617,7 +617,7 @@ SuperClaude install --diagnose
### ๆๅใฎๆค่จผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#success-validation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#success-validation)
ใขใผใไฟฎๆญฃใ้ฉ็จใใๅพใๆฌกใฎใใใซใในใใใพใใ
@@ -629,17 +629,17 @@ SuperClaude install --diagnose
## ใฏใคใใฏใใฉใใซใทใฅใผใใฃใณใฐ๏ผใฌใฌใทใผ๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#quick-troubleshooting-legacy)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#quick-troubleshooting-legacy)
- **ใขใผใใใขใฏใใฃใๅใใใชใ**โๆๅใใฉใฐใไฝฟ็จ:ย `--brainstorm`ใใ`--introspect``--uc`
- **้้ใฃใใขใผใใใขใฏใใฃใใงใ**โ ใชใฏใจในใๅ
ใฎ่ค้ใชใใชใฌใผใจใญใผใฏใผใใ็ขบ่ชใใฆใใ ใใ
- **ไบๆใใฌใขใผใๅใๆฟใ**โ ใฟในใฏใฎ้ฒ่กใซๅบใฅใ้ๅธธใฎๅไฝ
- **ๅฎ่กใธใฎๅฝฑ้ฟ**โ ใขใผใใฏใใผใซใฎไฝฟ็จใๆ้ฉๅใใใใฎใงใใใๅฎ่กใซใฏๅฝฑ้ฟใใชใใฏใใงใ
-- **ใขใผใใฎ็ซถๅโ**[ใใฉใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md)ใงใใฉใฐใฎๅชๅ
้ ไฝใซใผใซใ็ขบ่ชใใฆใใ ใใ[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md)
+- **ใขใผใใฎ็ซถๅโ**[ใใฉใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md)ใงใใฉใฐใฎๅชๅ
้ ไฝใซใผใซใ็ขบ่ชใใฆใใ ใใ[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md)
## ใใใใ่ณชๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#frequently-asked-questions)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#frequently-asked-questions)
**Q: ใฉใฎใขใผใใใขใฏใใฃใใซใชใฃใฆใใใใฏใฉใใใใฐใใใใพใใ?**ย A: ้ไฟกใใฟใผใณใงๆฌกใฎใคใณใธใฑใผใฟใผใ็ขบ่ชใใฆใใ ใใใ
@@ -674,7 +674,7 @@ SuperClaude install --diagnose
## ใพใจใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#summary)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#summary)
SuperClaude ใฎ 5 ใคใฎ่กๅใขใผใใฏใใฆใผใถใผใฎใใผใบใซ่ชๅ็ใซ้ฉๅใใ**ใคใณใใชใธใงใณใใช้ฉๅฟใทในใใ ใไฝๆใใพใใ**
@@ -691,36 +691,36 @@ SuperClaude ใฎ 5 ใคใฎ่กๅใขใผใใฏใใฆใผใถใผใฎใใผใบใซ่ชๅ
## ้ข้ฃใฌใคใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/modes.md#related-guides)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/modes.md#related-guides)
**ๅญฆ็ฟใฎ้ฒๆ:**
**๐ฑ ใจใใปใณใทใฃใซ๏ผ็ฌฌ1้ฑ๏ผ**
-- [ใฏใคใใฏในใฟใผใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Getting-Started/quick-start.md)- ใขใผใใฎๆๅนๅไพ
-- [ใณใใณใใชใใกใฌใณใน](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md)- ใณใใณใใฏ่ชๅ็ใซใขใผใใใขใฏใใฃใๅใใพใ
-- [ใคใณในใใผใซใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Getting-Started/installation.md)- ๅไฝใขใผใใฎ่จญๅฎ
+- [ใฏใคใใฏในใฟใผใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Getting-Started/quick-start.md)- ใขใผใใฎๆๅนๅไพ
+- [ใณใใณใใชใใกใฌใณใน](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md)- ใณใใณใใฏ่ชๅ็ใซใขใผใใใขใฏใใฃใๅใใพใ
+- [ใคใณในใใผใซใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Getting-Started/installation.md)- ๅไฝใขใผใใฎ่จญๅฎ
**๐ฟไธญ็ด๏ผ็ฌฌ2๏ฝ3้ฑ๏ผ**
-- [ใจใผใธใงใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/agents.md)- ใขใผใใจในใใทใฃใชในใใฎ้ฃๆบๆนๆณ
-- [ใใฉใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/flags.md)- ๆๅใขใผใใฎๅถๅพกใจๆ้ฉๅ
-- [ไพๆ้](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/examples-cookbook.md)- ใขใผใใใฟใผใณใฎๅฎ่ทต
+- [ใจใผใธใงใณใใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/agents.md)- ใขใผใใจในใใทใฃใชในใใฎ้ฃๆบๆนๆณ
+- [ใใฉใฐใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/flags.md)- ๆๅใขใผใใฎๅถๅพกใจๆ้ฉๅ
+- [ไพๆ้](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/examples-cookbook.md)- ใขใผใใใฟใผใณใฎๅฎ่ทต
**๐ฒ ไธ็ด๏ผ2ใถๆ็ฎไปฅ้๏ผ**
-- [MCP ใตใผใใผ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md)- ๆกๅผตๆฉ่ฝใๅใใใขใผใ็ตฑๅ
-- [ใปใใทใงใณ็ฎก็](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md)- ใฟในใฏ็ฎก็ใขใผใใฎใฏใผใฏใใญใผ
-- [ใฏใใใซ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Getting-Started/quick-start.md)- ใขใผใใฎไฝฟ็จใใฟใผใณ
+- [MCP ใตใผใใผ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md)- ๆกๅผตๆฉ่ฝใๅใใใขใผใ็ตฑๅ
+- [ใปใใทใงใณ็ฎก็](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md)- ใฟในใฏ็ฎก็ใขใผใใฎใฏใผใฏใใญใผ
+- [ใฏใใใซ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Getting-Started/quick-start.md)- ใขใผใใฎไฝฟ็จใใฟใผใณ
**๐ง ใจใญในใใผใ**
-- [ๆ่กใขใผใญใใฏใใฃ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Developer-Guide/technical-architecture.md)- ใขใผใๅฎ่ฃ
ใฎ่ฉณ็ดฐ
-- [ใณใผใใฎ่ฒข็ฎ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Developer-Guide/contributing-code.md)- ใขใผใใฎๆฉ่ฝใๆกๅผตใใ
+- [ๆ่กใขใผใญใใฏใใฃ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Developer-Guide/technical-architecture.md)- ใขใผใๅฎ่ฃ
ใฎ่ฉณ็ดฐ
+- [ใณใผใใฎ่ฒข็ฎ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Developer-Guide/contributing-code.md)- ใขใผใใฎๆฉ่ฝใๆกๅผตใใ
**ใขใผใๅบๆใฎใฌใคใ:**
-- **ใใฌใคใณในใใผใใณใฐ**๏ผ[่ฆไปถ็บ่ฆใใฟใผใณ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/Reference/examples-cookbook.md#requirements)
-- **ใฟในใฏ็ฎก็**๏ผ[ใปใใทใงใณ็ฎก็ใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md)
-- **ใชใผใฑในใใฌใผใทใงใณ**:ย [MCP ใตใผใใผ ใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/mcp-servers.md)
-- **ใใผใฏใณๅน็**๏ผ[ใณใใณใใฎๅบ็ค](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/commands.md#token-efficiency)
\ No newline at end of file
+- **ใใฌใคใณในใใผใใณใฐ**๏ผ[่ฆไปถ็บ่ฆใใฟใผใณ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/Reference/examples-cookbook.md#requirements)
+- **ใฟในใฏ็ฎก็**๏ผ[ใปใใทใงใณ็ฎก็ใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md)
+- **ใชใผใฑในใใฌใผใทใงใณ**:ย [MCP ใตใผใใผ ใฌใคใ](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/mcp-servers.md)
+- **ใใผใฏใณๅน็**๏ผ[ใณใใณใใฎๅบ็ค](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/commands.md#token-efficiency)
\ No newline at end of file
diff --git a/Docs/User-Guide-jp/session-management.md b/docs/User-Guide-jp/session-management.md
similarity index 88%
rename from Docs/User-Guide-jp/session-management.md
rename to docs/User-Guide-jp/session-management.md
index 3ecd744..e9c9fe6 100644
--- a/Docs/User-Guide-jp/session-management.md
+++ b/docs/User-Guide-jp/session-management.md
@@ -1,16 +1,16 @@
# ใปใใทใงใณ็ฎก็ใฌใคใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#session-management-guide)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#session-management-guide)
SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ็ฎก็ใๆไพใใClaude Code ใฎไผ่ฉฑๅ
จไฝใซใใใ็ใฎใณใณใใญในใไฟๅญใจ้ทๆ็ใชใใญใธใงใฏใ็ถ็ถๆงใๅฎ็พใใพใใ
## ๆฐธ็ถใกใขใชใไฝฟ็จใใใณใขใปใใทใงใณใณใใณใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#core-session-commands-with-persistent-memory)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#core-session-commands-with-persistent-memory)
### `/sc:load`- ๆฐธ็ถใกใขใชใซใใใณใณใใญในใใฎ่ชญใฟ่พผใฟ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#scload---context-loading-with-persistent-memory)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#scload---context-loading-with-persistent-memory)
**็ฎ็**: ไปฅๅใฎใปใใทใงใณใใใฎใใญใธใงใฏใใณใณใใญในใใจๆฐธ็ถใกใขใชใไฝฟ็จใใฆใปใใทใงใณใๅๆๅใใพใใMCP
**็ตฑๅ**: Serena MCP ใใใชใฌใผใใฆใไฟๅญใใใใใญใธใงใฏใใกใขใชใ่ชญใฟๅใใพใใ
@@ -38,7 +38,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### `/sc:save`- ใกใขใชใธใฎใปใใทใงใณใฎๆฐธ็ถๆง
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#scsave---session-persistence-to-memory)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#scsave---session-persistence-to-memory)
**็ฎ็**: ็พๅจใฎใปใใทใงใณ็ถๆ
ใจๆฑบๅฎใๆฐธ็ถใกใขใช
**MCP ใซไฟๅญใใพใใ็ตฑๅ**: Serena MCP ใใใชใฌใผใใฆใกใขใช ใใกใคใซใซๆธใ่พผใฟใพใใ
@@ -66,7 +66,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### `/sc:reflect`- ใกใขใชใณใณใใญในใใซใใ้ฒๆ็ถๆณใฎ่ฉไพก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#screflect---progress-assessment-with-memory-context)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#screflect---progress-assessment-with-memory-context)
**็ฎ็**: ไฟๅญใใใใกใขใชใซๅฏพใใฆ็พๅจใฎ้ฒ่ก็ถๆณใๅๆใใใปใใทใงใณใฎๅฎๅ
จๆงใๆค่จผใใ
**MCP ็ตฑๅ**: Serena MCP ใไฝฟ็จใใฆใไฟๅญใใใใกใขใชใจ็พๅจใฎ็ถๆ
ใๆฏ่ผใใ
@@ -94,11 +94,11 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
## ๆฐธ็ถใกใขใชใขใผใญใใฏใใฃ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#persistent-memory-architecture)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#persistent-memory-architecture)
### Serena MCP ใ็ใฎๆฐธ็ถๆงใๅฎ็พใใๆนๆณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#how-serena-mcp-enables-true-persistence)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#how-serena-mcp-enables-true-persistence)
**ใกใขใชในใใฌใผใธ**:
@@ -123,11 +123,11 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
## ๆฐธ็ถๆงใๅใใใปใใทใงใณใฉใคใใตใคใฏใซใใฟใผใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#session-lifecycle-patterns-with-persistence)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#session-lifecycle-patterns-with-persistence)
### ๆฐใใใใญใธใงใฏใใฎๅๆๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#new-project-initialization)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#new-project-initialization)
```shell
# 1. Start fresh project
@@ -145,7 +145,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ๆขๅญใฎไฝๆฅญใฎๅ้๏ผใฏใญในไผ่ฉฑ๏ผ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#resuming-existing-work-cross-conversation)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#resuming-existing-work-cross-conversation)
```shell
# 1. Load previous context from persistent memory
@@ -163,7 +163,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ้ทๆใใญใธใงใฏใ็ฎก็
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#long-term-project-management)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#long-term-project-management)
```shell
# Weekly checkpoint pattern with persistence
@@ -180,11 +180,11 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
## ใฏใญในไผ่ฉฑใฎ็ถ็ถๆง
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#cross-conversation-continuity)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#cross-conversation-continuity)
### ็ฒใๅผทใๆฐใใไผ่ฉฑใๅงใใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#starting-new-conversations-with-persistence)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#starting-new-conversations-with-persistence)
ๆฐใใ Claude Code ไผ่ฉฑใ้ๅงใใใจใๆฐธ็ถใกใขใช ใทในใใ ใซใใฃใฆๆฌกใฎใใจใๅฏ่ฝใซใชใใพใใ
@@ -208,7 +208,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ใกใขใชๆ้ฉๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#memory-optimization)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#memory-optimization)
**ๆๅนใชใกใขใชไฝฟ็จ้**:
@@ -233,11 +233,11 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
## ๆฐธ็ถใปใใทใงใณใฎใในใใใฉใฏใใฃใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#best-practices-for-persistent-sessions)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#best-practices-for-persistent-sessions)
### ใปใใทใงใณ้ๅงใใญใใณใซ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#session-start-protocol)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#session-start-protocol)
1. `/sc:load`ๆขๅญใฎใใญใธใงใฏใใฎๅ ดๅใฏๅธธใซ
2. `/sc:reflect`่จๆถใใ็พๅจใฎ็ถๆ
ใ็่งฃใใใใใซไฝฟ็จใใ
@@ -246,7 +246,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ใปใใทใงใณ็ตไบใใญใใณใซ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#session-end-protocol)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#session-end-protocol)
1. `/sc:reflect`ไฟๅญใใใ็ฎๆจใซๅฏพใใๅฎๅ
จๆงใ่ฉไพกใใใใใซไฝฟ็จใใพใ
2. ้่ฆใชๆฑบๅฎใ`/sc:save`ๅฐๆฅใฎใปใใทใงใณใฎใใใซไฟๅญใใ
@@ -255,7 +255,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ่จๆถๅ่ณชใฎ็ถญๆ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#memory-quality-maintenance)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#memory-quality-maintenance)
- ็ฐกๅใซๆใๅบใใใใใซใๅใใใใใ่ชฌๆ็ใชใกใขใชๅใไฝฟ็จใใ
- ๆฑบๅฎไบ้
ใจไปฃๆฟใขใใญใผใใซ้ขใใ่ๆฏๆ
ๅ ฑใๅซใใ
@@ -264,11 +264,11 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
## ไปใฎSuperClaudeๆฉ่ฝใจใฎ็ตฑๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#integration-with-other-superclaude-features)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#integration-with-other-superclaude-features)
### MCP ใตใผใใผ่ชฟๆด
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#mcp-server-coordination)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#mcp-server-coordination)
- **Serena MCP**ย : ๆฐธ็ถใกใขใชใคใณใใฉในใใฉใฏใใฃใๆไพใใพใ
- **ใทใผใฑใณใทใฃใซMCP**ย : ไฟๅญใใใใกใขใชใไฝฟ็จใใฆ่ค้ใชๅๆใๅผทๅใใพใ
@@ -277,7 +277,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ใจใผใธใงใณใใจใกใขใชใฎ้ฃๆบ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#agent-collaboration-with-memory)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#agent-collaboration-with-memory)
- ใจใผใธใงใณใใฏๅผทๅใใใใณใณใใญในใใฎใใใซๆฐธ็ถ็ใชใกใขใชใซใขใฏใปในใใพใ
- ไปฅๅใฎๅฐ้ๅฎถใฎๆฑบๅฎใฏไฟๅญใใใๅ็
งใใใพใ
@@ -286,7 +286,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ๆฐธ็ถๆงใๅใใใณใใณใ็ตฑๅ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#command-integration-with-persistence)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#command-integration-with-persistence)
- ใในใฆใฎ`/sc:`ใณใใณใใฏๆฐธ็ถ็ใชใณใณใใญในใใๅ็
งใใใใฎใณใณใใญในใใซๅบใฅใใฆๆง็ฏใงใใพใใ
- ไปฅๅใฎใณใใณใๅบๅใจๆฑบๅฎใฏใปใใทใงใณ้ใงๅฉ็จๅฏ่ฝ
@@ -295,11 +295,11 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
## ๆฐธ็ถใปใใทใงใณใฎใใฉใใซใทใฅใผใใฃใณใฐ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#troubleshooting-persistent-sessions)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#troubleshooting-persistent-sessions)
### ใใใใๅ้ก
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#common-issues)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#common-issues)
**ใกใขใชใ่ชญใฟ่พผใพใใพใใ**:
@@ -324,7 +324,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ใฏใคใใฏใใฃใใฏใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#quick-fixes)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#quick-fixes)
**ใปใใทใงใณ็ถๆ
ใใชใปใใ**:
@@ -349,11 +349,11 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
## ้ซๅบฆใชๆฐธ็ถใปใใทใงใณใใฟใผใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#advanced-persistent-session-patterns)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#advanced-persistent-session-patterns)
### ่คๆฐใใงใผใบใฎใใญใธใงใฏใ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#multi-phase-projects)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#multi-phase-projects)
- ๆด็ใฎใใใซใใงใผใบๅบๆใฎใกใขใชๅฝๅใไฝฟ็จใใ
- ใใงใผใบๅ
จไฝใงใขใผใญใใฏใใฃไธใฎๆฑบๅฎใฎ็ถ็ถๆงใ็ถญๆใใ
@@ -362,7 +362,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ใใผใ ใณใฉใใฌใผใทใงใณ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#team-collaboration)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#team-collaboration)
- ๅ
ฑๆใกใขใชใฎ่ฆๅใจๅฝๅ่ฆๅ
- ใใผใ ใฎใณใณใใญในใใซใใใๆๆๆฑบๅฎๆ นๆ ใฎไฟๅญ
@@ -371,7 +371,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ้ทๆใกใณใใใณใน
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#long-term-maintenance)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#long-term-maintenance)
- ๅฎไบใใใใญใธใงใฏใใฎใกใขใชใขใผใซใคใๆฆ็ฅ
- ่็ฉใใใ่จๆถใซใใใใฟใผใณใฉใคใใฉใชใฎ้็บ
@@ -380,11 +380,11 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
## ๆฐธ็ถใปใใทใงใณ็ฎก็ใฎไธปใชๅฉ็น
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#key-benefits-of-persistent-session-management)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#key-benefits-of-persistent-session-management)
### ใใญใธใงใฏใใฎ็ถ็ถๆง
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#project-continuity)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#project-continuity)
- ่คๆฐใฎไผ่ฉฑใซใใใใทใผใ ใฌในใชไฝๆฅญ็ถ็ถ
- Claude Codeใปใใทใงใณ้ใงใณใณใใญในใใๅคฑใใใใใจใฏใใใพใใ
@@ -393,7 +393,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ็็ฃๆงใฎๅไธ
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#enhanced-productivity)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#enhanced-productivity)
- ใใญใธใงใฏใใฎใณใณใใญในใใๅๅบฆ่ชฌๆใใๅฟ
่ฆๆงใๆธๅฐ
- ่ตทๅๆ้ใ้ใใไฝๆฅญใ็ถ็ถใงใใ
@@ -402,7 +402,7 @@ SuperClaude ใฏใSerena MCP ใตใผใใผใ้ใใฆๆฐธ็ถ็ใชใปใใทใงใณ
### ๅ่ณชใฎไธ่ฒซๆง
-[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/Docs/User-Guide/session-management.md#quality-consistency)
+[](https://github.com/khayashi4337/SuperClaude_Framework/blob/master/docs/User-Guide/session-management.md#quality-consistency)
- ใปใใทใงใณ้ใงไธ่ฒซใใใขใผใญใใฏใใฃใใฟใผใณ
- ใณใผใๅ่ณชใฎๆฑบๅฎใจๆจๆบใฎไฟๆ
diff --git a/Docs/User-Guide-kr/agents.md b/docs/User-Guide-kr/agents.md
similarity index 99%
rename from Docs/User-Guide-kr/agents.md
rename to docs/User-Guide-kr/agents.md
index 5faca4d..5186093 100644
--- a/Docs/User-Guide-kr/agents.md
+++ b/docs/User-Guide-kr/agents.md
@@ -35,7 +35,7 @@ SuperClaude๋ Claude Code๊ฐ ์ ๋ฌธ ์ง์์ ์ํด ํธ์ถํ ์ ์๋ 15๊ฐ
### SuperClaude ์์ด์ ํธ๋?
-**์์ด์ ํธ**๋ Claude Code์ ๋์์ ์์ ํ๋ ์ปจํ
์คํธ ์ง์๋ฌธ์ผ๋ก ๊ตฌํ๋ ์ ๋ฌธ AI ๋๋ฉ์ธ ์ ๋ฌธ๊ฐ์
๋๋ค. ๊ฐ ์์ด์ ํธ๋ `SuperClaude/Agents/` ๋๋ ํ ๋ฆฌ์ ์๋ ์ ์คํ๊ฒ ์์ฑ๋ `.md` ํ์ผ๋ก, ๋๋ฉ์ธ๋ณ ์ ๋ฌธ ์ง์, ํ๋ ํจํด, ๋ฌธ์ ํด๊ฒฐ ์ ๊ทผ ๋ฐฉ์์ ํฌํจํฉ๋๋ค.
+**์์ด์ ํธ**๋ Claude Code์ ๋์์ ์์ ํ๋ ์ปจํ
์คํธ ์ง์๋ฌธ์ผ๋ก ๊ตฌํ๋ ์ ๋ฌธ AI ๋๋ฉ์ธ ์ ๋ฌธ๊ฐ์
๋๋ค. ๊ฐ ์์ด์ ํธ๋ `superclaude/Agents/` ๋๋ ํ ๋ฆฌ์ ์๋ ์ ์คํ๊ฒ ์์ฑ๋ `.md` ํ์ผ๋ก, ๋๋ฉ์ธ๋ณ ์ ๋ฌธ ์ง์, ํ๋ ํจํด, ๋ฌธ์ ํด๊ฒฐ ์ ๊ทผ ๋ฐฉ์์ ํฌํจํฉ๋๋ค.
**์ค์**: ์์ด์ ํธ๋ ๋ณ๋์ AI ๋ชจ๋ธ์ด๋ ์ํํธ์จ์ด๊ฐ ์๋๋๋ค - Claude Code๊ฐ ์ฝ์ด ์ ๋ฌธํ๋ ํ๋์ ์ฑํํ๋ ์ปจํ
์คํธ ๊ตฌ์ฑ์
๋๋ค.
diff --git a/Docs/User-Guide-kr/commands.md b/docs/User-Guide-kr/commands.md
similarity index 99%
rename from Docs/User-Guide-kr/commands.md
rename to docs/User-Guide-kr/commands.md
index 2eba97f..c383a5c 100644
--- a/Docs/User-Guide-kr/commands.md
+++ b/docs/User-Guide-kr/commands.md
@@ -38,7 +38,7 @@ SuperClaude๋ Claude Code๊ฐ ์ฝ์ด ์ ๋ฌธํ๋ ๋์์ ์ฑํํ๋ ํ๋
### ์ปจํ
์คํธ ๋ฉ์ปค๋์ฆ:
1. **์ฌ์ฉ์ ์
๋ ฅ**: `/sc:implement "์ธ์ฆ ์์คํ
"` ์
๋ ฅ
-2. **์ปจํ
์คํธ ๋ก๋ฉ**: Claude Code๊ฐ `~/.claude/SuperClaude/Commands/implement.md` ์ฝ์
+2. **์ปจํ
์คํธ ๋ก๋ฉ**: Claude Code๊ฐ `~/.claude/superclaude/Commands/implement.md` ์ฝ์
3. **๋์ ์ฑํ**: Claude๊ฐ ๋๋ฉ์ธ ์ ๋ฌธ ์ง์, ๋๊ตฌ ์ ํ, ๊ฒ์ฆ ํจํด ์ ์ฉ
4. **ํฅ์๋ ์ถ๋ ฅ**: ๋ณด์ ๊ณ ๋ ค์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ฐ์ถ ๊ตฌ์กฐํ๋ ๊ตฌํ
diff --git a/Docs/User-Guide-kr/flags.md b/docs/User-Guide-kr/flags.md
similarity index 100%
rename from Docs/User-Guide-kr/flags.md
rename to docs/User-Guide-kr/flags.md
diff --git a/Docs/User-Guide-kr/mcp-servers.md b/docs/User-Guide-kr/mcp-servers.md
similarity index 100%
rename from Docs/User-Guide-kr/mcp-servers.md
rename to docs/User-Guide-kr/mcp-servers.md
diff --git a/Docs/User-Guide-kr/modes.md b/docs/User-Guide-kr/modes.md
similarity index 100%
rename from Docs/User-Guide-kr/modes.md
rename to docs/User-Guide-kr/modes.md
diff --git a/Docs/User-Guide-kr/session-management.md b/docs/User-Guide-kr/session-management.md
similarity index 100%
rename from Docs/User-Guide-kr/session-management.md
rename to docs/User-Guide-kr/session-management.md
diff --git a/Docs/User-Guide-zh/agents.md b/docs/User-Guide-zh/agents.md
similarity index 99%
rename from Docs/User-Guide-zh/agents.md
rename to docs/User-Guide-zh/agents.md
index 90a9029..cdaa908 100644
--- a/Docs/User-Guide-zh/agents.md
+++ b/docs/User-Guide-zh/agents.md
@@ -35,7 +35,7 @@ SuperClaude ๆไพไบ 14 ไธช้ขๅไธไธๆบ่ฝไฝ๏ผClaude Code ๅฏไปฅ่ฐ็จๅฎ
## ๆ ธๅฟๆฆๅฟต
### ไปไนๆฏ SuperClaude ๆบ่ฝไฝ๏ผ
-**ๆบ่ฝไฝ**ๆฏไธไธ็ AI ้ขๅไธๅฎถ๏ผไปฅไธไธๆๆไปค็ๅฝขๅผๅฎ็ฐ๏ผ็จไบไฟฎๆน Claude Code ็่กไธบใๆฏไธชๆบ่ฝไฝ้ฝๆฏ `SuperClaude/Agents/` ็ฎๅฝไธญ็ฒพๅฟๅถไฝ็ `.md` ๆไปถ๏ผๅ
ๅซ้ขๅ็นๅฎ็ไธไธ็ฅ่ฏใ่กไธบๆจกๅผๅ้ฎ้ข่งฃๅณๆนๆณใ
+**ๆบ่ฝไฝ**ๆฏไธไธ็ AI ้ขๅไธๅฎถ๏ผไปฅไธไธๆๆไปค็ๅฝขๅผๅฎ็ฐ๏ผ็จไบไฟฎๆน Claude Code ็่กไธบใๆฏไธชๆบ่ฝไฝ้ฝๆฏ `superclaude/Agents/` ็ฎๅฝไธญ็ฒพๅฟๅถไฝ็ `.md` ๆไปถ๏ผๅ
ๅซ้ขๅ็นๅฎ็ไธไธ็ฅ่ฏใ่กไธบๆจกๅผๅ้ฎ้ข่งฃๅณๆนๆณใ
**้่ฆๆ็คบ**๏ผๆบ่ฝไฝไธๆฏ็ฌ็ซ็ AI ๆจกๅๆ่ฝฏไปถ - ๅฎไปฌๆฏ Claude Code ่ฏปๅ็ไธไธๆ้
็ฝฎ๏ผ็จไบ้็จไธ้จ็่กไธบใ
diff --git a/Docs/User-Guide-zh/commands.md b/docs/User-Guide-zh/commands.md
similarity index 99%
rename from Docs/User-Guide-zh/commands.md
rename to docs/User-Guide-zh/commands.md
index 8461f57..b45261b 100644
--- a/Docs/User-Guide-zh/commands.md
+++ b/docs/User-Guide-zh/commands.md
@@ -38,7 +38,7 @@ SuperClaude ๆไพ่กไธบไธไธๆๆไปถ๏ผClaude Code ้่ฟ่ฏปๅ่ฟไบๆไปถ
### ไธไธๆๆบๅถ๏ผ
1. **็จๆท่พๅ
ฅ**๏ผๆจ่พๅ
ฅ `/sc:implement "auth system"`
-2. **ไธไธๆๅ ่ฝฝ**๏ผClaude Code ่ฏปๅ `~/.claude/SuperClaude/Commands/implement.md`
+2. **ไธไธๆๅ ่ฝฝ**๏ผClaude Code ่ฏปๅ `~/.claude/superclaude/Commands/implement.md`
3. **่กไธบ้็จ**๏ผClaude ่ฟ็จไธไธ็ฅ่ฏ่ฟ่กๅทฅๅ
ท้ๆฉๅ้ช่ฏ
4. **ๅขๅผบ่พๅบ**๏ผๅธฆๆๅฎๅ
จ่่ๅๆไฝณๅฎ่ทต็็ปๆๅๅฎ็ฐ
diff --git a/Docs/User-Guide-zh/flags.md b/docs/User-Guide-zh/flags.md
similarity index 100%
rename from Docs/User-Guide-zh/flags.md
rename to docs/User-Guide-zh/flags.md
diff --git a/Docs/User-Guide-zh/mcp-servers.md b/docs/User-Guide-zh/mcp-servers.md
similarity index 100%
rename from Docs/User-Guide-zh/mcp-servers.md
rename to docs/User-Guide-zh/mcp-servers.md
diff --git a/Docs/User-Guide-zh/modes.md b/docs/User-Guide-zh/modes.md
similarity index 100%
rename from Docs/User-Guide-zh/modes.md
rename to docs/User-Guide-zh/modes.md
diff --git a/Docs/User-Guide-zh/session-management.md b/docs/User-Guide-zh/session-management.md
similarity index 100%
rename from Docs/User-Guide-zh/session-management.md
rename to docs/User-Guide-zh/session-management.md
diff --git a/Docs/User-Guide/agents.md b/docs/User-Guide/agents.md
similarity index 99%
rename from Docs/User-Guide/agents.md
rename to docs/User-Guide/agents.md
index cb7d792..ae2d3cc 100644
--- a/Docs/User-Guide/agents.md
+++ b/docs/User-Guide/agents.md
@@ -35,7 +35,7 @@ Before using this guide, verify agent selection works:
## Core Concepts
### What are SuperClaude Agents?
-**Agents** are specialized AI domain experts implemented as context instructions that modify Claude Code's behavior. Each agent is a carefully crafted `.md` file in the `SuperClaude/Agents/` directory containing domain-specific expertise, behavioral patterns, and problem-solving approaches.
+**Agents** are specialized AI domain experts implemented as context instructions that modify Claude Code's behavior. Each agent is a carefully crafted `.md` file in the `superclaude/Agents/` directory containing domain-specific expertise, behavioral patterns, and problem-solving approaches.
**Important**: Agents are NOT separate AI models or software - they are context configurations that Claude Code reads to adopt specialized behaviors.
diff --git a/Docs/User-Guide/commands.md b/docs/User-Guide/commands.md
similarity index 99%
rename from Docs/User-Guide/commands.md
rename to docs/User-Guide/commands.md
index 24f8fe8..c30cb25 100644
--- a/Docs/User-Guide/commands.md
+++ b/docs/User-Guide/commands.md
@@ -38,7 +38,7 @@ SuperClaude provides behavioral context files that Claude Code reads to adopt sp
### The Context Mechanism:
1. **User Input**: You type `/sc:implement "auth system"`
-2. **Context Loading**: Claude Code reads `~/.claude/SuperClaude/Commands/implement.md`
+2. **Context Loading**: Claude Code reads `~/.claude/superclaude/Commands/implement.md`
3. **Behavior Adoption**: Claude applies domain expertise, tool selection, and validation patterns
4. **Enhanced Output**: Structured implementation with security considerations and best practices
diff --git a/Docs/User-Guide/flags.md b/docs/User-Guide/flags.md
similarity index 100%
rename from Docs/User-Guide/flags.md
rename to docs/User-Guide/flags.md
diff --git a/Docs/User-Guide/mcp-servers.md b/docs/User-Guide/mcp-servers.md
similarity index 100%
rename from Docs/User-Guide/mcp-servers.md
rename to docs/User-Guide/mcp-servers.md
diff --git a/Docs/User-Guide/modes.md b/docs/User-Guide/modes.md
similarity index 100%
rename from Docs/User-Guide/modes.md
rename to docs/User-Guide/modes.md
diff --git a/Docs/User-Guide/session-management.md b/docs/User-Guide/session-management.md
similarity index 100%
rename from Docs/User-Guide/session-management.md
rename to docs/User-Guide/session-management.md
diff --git a/docs/pm-agent-implementation-status.md b/docs/pm-agent-implementation-status.md
new file mode 100644
index 0000000..d7fb8d9
--- /dev/null
+++ b/docs/pm-agent-implementation-status.md
@@ -0,0 +1,332 @@
+# PM Agent Implementation Status
+
+**Last Updated**: 2025-10-14
+**Version**: 1.0.0
+
+## ๐ Overview
+
+PM Agent has been redesigned as an **Always-Active Foundation Layer** that provides continuous context preservation, PDCA self-evaluation, and systematic knowledge management across sessions.
+
+---
+
+## โ
Implemented Features
+
+### 1. Session Lifecycle (Serena MCP Memory Integration)
+
+**Status**: โ
Documented (Implementation Pending)
+
+#### Session Start Protocol
+- **Auto-Activation**: PM Agent restores context at every session start
+- **Memory Operations**:
+ - `list_memories()` โ Check existing state
+ - `read_memory("pm_context")` โ Overall project context
+ - `read_memory("last_session")` โ Previous session summary
+ - `read_memory("next_actions")` โ Planned next steps
+- **User Report**: Automatic status report (ๅๅ/้ฒๆ/ไปๅ/่ชฒ้ก)
+
+**Implementation Details**: superclaude/Commands/pm.md:34-97
+
+#### During Work (PDCA Cycle)
+- **Plan Phase**: Hypothesis generation with `docs/temp/hypothesis-*.md`
+- **Do Phase**: Experimentation with `docs/temp/experiment-*.md`
+- **Check Phase**: Self-evaluation with `docs/temp/lessons-*.md`
+- **Act Phase**: Success โ `docs/patterns/` | Failure โ `docs/mistakes/`
+
+**Implementation Details**: superclaude/Commands/pm.md:56-80, superclaude/Agents/pm-agent.md:48-98
+
+#### Session End Protocol
+- **Final Checkpoint**: `think_about_whether_you_are_done()`
+- **State Preservation**: `write_memory("pm_context", complete_state)`
+- **Documentation Cleanup**: Temporary โ Formal/Mistakes
+
+**Implementation Details**: superclaude/Commands/pm.md:82-97, superclaude/Agents/pm-agent.md:100-135
+
+---
+
+### 2. PDCA Self-Evaluation Pattern
+
+**Status**: โ
Documented (Implementation Pending)
+
+#### Plan (ไปฎ่ชฌ็ๆ)
+- Goal definition and success criteria
+- Hypothesis formulation
+- Risk identification
+
+#### Do (ๅฎ้จๅฎ่ก)
+- TodoWrite task tracking
+- 30-minute checkpoint saves
+- Trial-and-error recording
+
+#### Check (่ชๅทฑ่ฉไพก)
+- `think_about_task_adherence()` โ Pattern compliance
+- `think_about_collected_information()` โ Context sufficiency
+- `think_about_whether_you_are_done()` โ Completion verification
+
+#### Act (ๆนๅๅฎ่ก)
+- Success โ Extract pattern โ docs/patterns/
+- Failure โ Root cause analysis โ docs/mistakes/
+- Update CLAUDE.md if global pattern
+
+**Implementation Details**: superclaude/Agents/pm-agent.md:137-175
+
+---
+
+### 3. Documentation Strategy (Trial-and-Error to Knowledge)
+
+**Status**: โ
Documented (Implementation Pending)
+
+#### Temporary Documentation (`docs/temp/`)
+- **Purpose**: Trial-and-error experimentation
+- **Files**:
+ - `hypothesis-YYYY-MM-DD.md` โ Initial plan
+ - `experiment-YYYY-MM-DD.md` โ Implementation log
+ - `lessons-YYYY-MM-DD.md` โ Reflections
+- **Lifecycle**: 7 days โ Move to formal or delete
+
+#### Formal Documentation (`docs/patterns/`)
+- **Purpose**: Successful patterns ready for reuse
+- **Trigger**: Verified implementation success
+- **Content**: Clean approach + concrete examples + "Last Verified" date
+
+#### Mistake Documentation (`docs/mistakes/`)
+- **Purpose**: Error records with prevention strategies
+- **Structure**:
+ - What Happened (็พ่ฑก)
+ - Root Cause (ๆ นๆฌๅๅ )
+ - Why Missed (ใชใ่ฆ้ใใใ)
+ - Fix Applied (ไฟฎๆญฃๅ
ๅฎน)
+ - Prevention Checklist (้ฒๆญข็ญ)
+ - Lesson Learned (ๆ่จ)
+
+**Implementation Details**: superclaude/Agents/pm-agent.md:177-235
+
+---
+
+### 4. Memory Operations Reference
+
+**Status**: โ
Documented (Implementation Pending)
+
+#### Memory Types
+- **Session Start**: `pm_context`, `last_session`, `next_actions`
+- **During Work**: `plan`, `checkpoint`, `decision`
+- **Self-Evaluation**: `think_about_*` operations
+- **Session End**: `last_session`, `next_actions`, `pm_context`
+
+**Implementation Details**: superclaude/Agents/pm-agent.md:237-267
+
+---
+
+## ๐ง Pending Implementation
+
+### 1. Serena MCP Memory Operations
+
+**Required Actions**:
+- [ ] Implement `list_memories()` integration
+- [ ] Implement `read_memory(key)` integration
+- [ ] Implement `write_memory(key, value)` integration
+- [ ] Test memory persistence across sessions
+
+**Blockers**: Requires Serena MCP server configuration
+
+---
+
+### 2. PDCA Think Operations
+
+**Required Actions**:
+- [ ] Implement `think_about_task_adherence()` hook
+- [ ] Implement `think_about_collected_information()` hook
+- [ ] Implement `think_about_whether_you_are_done()` hook
+- [ ] Integrate with TodoWrite completion tracking
+
+**Blockers**: Requires Serena MCP server configuration
+
+---
+
+### 3. Documentation Directory Structure
+
+**Required Actions**:
+- [ ] Create `docs/temp/` directory template
+- [ ] Create `docs/patterns/` directory template
+- [ ] Create `docs/mistakes/` directory template
+- [ ] Implement automatic file lifecycle management (7-day cleanup)
+
+**Blockers**: None (can be implemented immediately)
+
+---
+
+### 4. Auto-Activation at Session Start
+
+**Required Actions**:
+- [ ] Implement PM Agent auto-activation hook
+- [ ] Integrate with Claude Code session lifecycle
+- [ ] Test context restoration across sessions
+- [ ] Verify "ๅๅ/้ฒๆ/ไปๅ/่ชฒ้ก" report generation
+
+**Blockers**: Requires understanding of Claude Code initialization hooks
+
+---
+
+## ๐ Implementation Roadmap
+
+### Phase 1: Documentation Structure (Immediate)
+**Timeline**: 1-2 days
+**Complexity**: Low
+
+1. Create `docs/temp/`, `docs/patterns/`, `docs/mistakes/` directories
+2. Add README.md to each directory explaining purpose
+3. Create template files for hypothesis/experiment/lessons
+
+### Phase 2: Serena MCP Integration (High Priority)
+**Timeline**: 1 week
+**Complexity**: Medium
+
+1. Configure Serena MCP server
+2. Implement memory operations (read/write/list)
+3. Test memory persistence
+4. Integrate with PM Agent workflow
+
+### Phase 3: PDCA Think Operations (High Priority)
+**Timeline**: 1 week
+**Complexity**: Medium
+
+1. Implement think_about_* hooks
+2. Integrate with TodoWrite
+3. Test self-evaluation flow
+4. Document best practices
+
+### Phase 4: Auto-Activation (Critical)
+**Timeline**: 2 weeks
+**Complexity**: High
+
+1. Research Claude Code initialization hooks
+2. Implement PM Agent auto-activation
+3. Test session start protocol
+4. Verify context restoration
+
+### Phase 5: Documentation Lifecycle (Medium Priority)
+**Timeline**: 3-5 days
+**Complexity**: Low
+
+1. Implement 7-day temporary file cleanup
+2. Create docs/temp โ docs/patterns migration script
+3. Create docs/temp โ docs/mistakes migration script
+4. Automate "Last Verified" date updates
+
+---
+
+## ๐ Testing Strategy
+
+### Unit Tests
+- [ ] Memory operations (read/write/list)
+- [ ] Think operations (task_adherence/collected_information/done)
+- [ ] File lifecycle management (7-day cleanup)
+
+### Integration Tests
+- [ ] Session start โ context restoration โ user report
+- [ ] PDCA cycle โ temporary docs โ formal docs
+- [ ] Mistake detection โ root cause analysis โ prevention checklist
+
+### E2E Tests
+- [ ] Full session lifecycle (start โ work โ end)
+- [ ] Cross-session context preservation
+- [ ] Knowledge accumulation over time
+
+---
+
+## ๐ Documentation Updates Needed
+
+### SuperClaude Framework
+- [x] `superclaude/Commands/pm.md` - Updated with session lifecycle
+- [x] `superclaude/Agents/pm-agent.md` - Updated with PDCA and memory operations
+- [ ] `docs/ARCHITECTURE.md` - Add PM Agent architecture section
+- [ ] `docs/GETTING_STARTED.md` - Add PM Agent usage examples
+
+### Global CLAUDE.md (Future)
+- [ ] Add PM Agent PDCA cycle to global rules
+- [ ] Document session lifecycle best practices
+- [ ] Add memory operations reference
+
+---
+
+## ๐ Known Issues
+
+### Issue 1: Serena MCP Not Configured
+**Status**: Blocker
+**Impact**: High (prevents memory operations)
+**Resolution**: Configure Serena MCP server in project
+
+### Issue 2: Auto-Activation Hook Unknown
+**Status**: Research Needed
+**Impact**: High (prevents session start automation)
+**Resolution**: Research Claude Code initialization hooks
+
+### Issue 3: Documentation Directory Structure Missing
+**Status**: Can Implement Immediately
+**Impact**: Medium (prevents PDCA documentation flow)
+**Resolution**: Create directory structure (Phase 1)
+
+---
+
+## ๐ Success Metrics
+
+### Quantitative
+- **Context Restoration Rate**: 100% (sessions resume without re-explanation)
+- **Documentation Coverage**: >80% (implementations documented)
+- **Mistake Prevention**: <10% (recurring mistakes)
+- **Session Continuity**: >90% (successful checkpoint restorations)
+
+### Qualitative
+- Users never re-explain project context
+- Knowledge accumulates systematically
+- Mistakes documented with prevention checklists
+- Documentation stays fresh (Last Verified dates)
+
+---
+
+## ๐ฏ Next Steps
+
+1. **Immediate**: Create documentation directory structure (Phase 1)
+2. **High Priority**: Configure Serena MCP server (Phase 2)
+3. **High Priority**: Implement PDCA think operations (Phase 3)
+4. **Critical**: Research and implement auto-activation (Phase 4)
+5. **Medium Priority**: Implement documentation lifecycle automation (Phase 5)
+
+---
+
+## ๐ References
+
+- **PM Agent Command**: `superclaude/Commands/pm.md`
+- **PM Agent Persona**: `superclaude/Agents/pm-agent.md`
+- **Salvaged Changes**: `tmp/salvaged-pm-agent/`
+- **Original Patches**: `tmp/salvaged-pm-agent/*.patch`
+
+---
+
+## ๐ Commit Information
+
+**Branch**: master
+**Salvaged From**: `/Users/kazuki/.claude` (mistaken development location)
+**Integration Date**: 2025-10-14
+**Status**: Documentation complete, implementation pending
+
+**Git Operations**:
+```bash
+# Salvaged valuable changes to tmp/
+cp ~/.claude/Commands/pm.md tmp/salvaged-pm-agent/pm.md
+cp ~/.claude/agents/pm-agent.md tmp/salvaged-pm-agent/pm-agent.md
+git diff ~/.claude/CLAUDE.md > tmp/salvaged-pm-agent/CLAUDE.md.patch
+git diff ~/.claude/RULES.md > tmp/salvaged-pm-agent/RULES.md.patch
+
+# Cleaned up .claude directory
+cd ~/.claude && git reset --hard HEAD
+cd ~/.claude && rm -rf .git
+
+# Applied changes to SuperClaude_Framework
+cp tmp/salvaged-pm-agent/pm.md superclaude/Commands/pm.md
+cp tmp/salvaged-pm-agent/pm-agent.md superclaude/Agents/pm-agent.md
+```
+
+---
+
+**Last Verified**: 2025-10-14
+**Next Review**: 2025-10-21 (1 week)
diff --git a/Docs/troubleshooting/serena-installation.md b/docs/troubleshooting/serena-installation.md
similarity index 100%
rename from Docs/troubleshooting/serena-installation.md
rename to docs/troubleshooting/serena-installation.md
diff --git a/pr_documentation.md b/pr_documentation.md
new file mode 100644
index 0000000..565d2b5
--- /dev/null
+++ b/pr_documentation.md
@@ -0,0 +1,191 @@
+# Pull Request: Redesign PM Agent as Self-Improvement Meta-Layer
+
+## Summary
+
+Redesigned PM Agent from task orchestration system to self-improvement workflow executor (meta-layer agent). PM Agent now complements existing auto-activation by systematically documenting implementations, analyzing mistakes, and maintaining knowledge base quality.
+
+## Motivation
+
+**Problem**: Initial PM Agent design competed with existing auto-activation system for task routing, creating confusion about responsibilities and adding unnecessary complexity.
+
+**Solution**: Redefined PM Agent as a meta-layer that operates AFTER specialist agents complete tasks, focusing on:
+- Post-implementation documentation
+- Immediate mistake analysis and prevention
+- Monthly documentation maintenance
+- Pattern extraction and knowledge synthesis
+
+**Value Proposition**: Transforms SuperClaude into a continuously learning system that accumulates knowledge, prevents recurring mistakes, and maintains fresh documentation without manual intervention.
+
+## Changes
+
+### 1. PM Agent Agent File (`superclaude/Agents/pm-agent.md`)
+**Status**: Complete rewrite
+
+**Before**:
+- Category: orchestration
+- Triggers: All user interactions (default mode)
+- Role: Task router and sub-agent coordinator
+- Competed with existing auto-activation
+
+**After**:
+- Category: meta
+- Triggers: Post-implementation, mistake detection, monthly maintenance
+- Role: Self-improvement workflow executor
+- Complements existing auto-activation
+
+**Key Additions**:
+- Behavioral Mindset: "Think like a continuous learning system"
+- Focus Areas: Implementation Documentation, Mistake Analysis, Pattern Recognition, Knowledge Maintenance, Self-Improvement Loop
+- Self-Improvement Workflow Integration: BEFORE/DURING/AFTER/MISTAKE RECOVERY/MAINTENANCE phases
+- Quality Standards: Latest, Minimal, Clear, Practical documentation criteria
+- Performance Metrics: Documentation coverage, mistake prevention effectiveness, knowledge maintenance health
+
+**Workflow Examples**:
+1. Post-Implementation Documentation: Backend architect implements JWT โ PM Agent documents pattern
+2. Immediate Mistake Analysis: Kong Gateway bypass detected โ PM Agent stops, analyzes, documents prevention
+3. Monthly Documentation Maintenance: PM Agent prunes outdated docs, merges duplicates, updates versions
+
+### 2. Framework Rules (`superclaude/Core/RULES.md`)
+**Status**: Agent Orchestration section updated (lines 17-44)
+
+**Changes**:
+- Split orchestration into two clear layers:
+ - **Task Execution Layer**: Existing auto-activation (unchanged)
+ - **Self-Improvement Layer**: PM Agent meta-layer (new)
+- Added orchestration flow diagram showing task execution โ documentation cycle
+- Clarified examples: โ
Right patterns and โ Wrong anti-patterns
+- Emphasized PM Agent activates AFTER task completion, not before/during
+
+**Purpose**: Eliminate confusion between task routing (auto-activation) and learning (PM Agent)
+
+### 3. README.md
+**Status**: PM Agent description updated (line 208)
+
+**Before**: "PM Agent orchestrates all interactions seamlessly"
+
+**After**: "PM Agent ensures continuous learning through systematic documentation"
+
+**Impact**: Accurate representation of PM Agent's meta-layer role in main documentation
+
+### 4. Agents Guide (`docs/User-Guide/agents.md`)
+**Status**: PM Agent section completely rewritten (lines 140-208)
+
+**Changes**:
+- Section title: "Orchestration Agent" โ "Meta-Layer Agent"
+- Expertise: Project orchestration โ Self-improvement workflow executor
+- Auto-Activation: Default mode for all interactions โ Post-implementation, mistake detection, monthly maintenance
+- Capabilities: Workflow orchestration โ Implementation documentation, mistake analysis, pattern recognition, knowledge maintenance
+- Examples: Vague feature requests โ Post-implementation documentation, immediate mistake analysis, monthly maintenance
+- Integration: Orchestrates entire ecosystem โ Documents specialist agents' work
+
+**Purpose**: User-facing documentation accurately reflects PM Agent's actual behavior
+
+## Two-Layer Orchestration System
+
+```
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ Task Execution Layer (Existing Auto-Activation) โ
+โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
+โ User Request โ Context Analysis โ Specialist Selection โ
+โ backend-architect | frontend-architect | security, etc. โ
+โ โ
+โ โ Implementation Complete โ โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+โ Self-Improvement Layer (PM Agent Meta-Layer) โ
+โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
+โ PM Agent Auto-Triggers โ Documentation โ Learning โ
+โ Pattern Recording | Mistake Analysis | Maintenance โ
+โ โ
+โ โ Knowledge Base Updated โ โ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+```
+
+**Flow**:
+1. User: "Add JWT authentication"
+2. Task Execution Layer: Auto-activation โ security-engineer + backend-architect โ Implementation
+3. Self-Improvement Layer: PM Agent auto-triggers โ Documents JWT pattern in docs/authentication.md โ Records security decisions โ Updates CLAUDE.md
+
+## Testing
+
+**Validation Method**: Verified integration with existing self-improvement workflow
+
+**Test Case**: agiletec project
+- โ
Reviewed `/Users/kazuki/github/agiletec/docs/self-improvement-workflow.md`
+- โ
Confirmed PM Agent design aligns with BEFORE/DURING/AFTER/MISTAKE RECOVERY phases
+- โ
Verified PM Agent complements (not competes with) existing workflow
+- โ
Confirmed agiletec workflow defines WHAT, PM Agent defines WHO executes it
+
+**Integration Check**:
+- โ
PM Agent operates as meta-layer above specialist agents
+- โ
Existing auto-activation handles task routing (unchanged)
+- โ
PM Agent handles post-implementation documentation (new capability)
+- โ
No conflicts with existing agent activation patterns
+
+## Breaking Changes
+
+**None**. This is a design clarification and documentation update:
+
+- โ
Existing auto-activation continues to work identically
+- โ
Specialist agents (backend-architect, frontend-architect, etc.) unchanged
+- โ
User workflows remain the same
+- โ
Manual `@agent-[name]` override still works
+- โ
Commands (`/sc:implement`, `/sc:build`, etc.) unchanged
+
+**New Capability**: PM Agent now automatically documents implementations and maintains knowledge base without user intervention.
+
+## Impact on User Experience
+
+**Before**:
+- User requests task โ Specialist agents implement โ User manually documents (if at all)
+- Mistakes repeated due to lack of systematic documentation
+- Documentation becomes outdated over time
+
+**After**:
+- User requests task โ Specialist agents implement โ PM Agent auto-documents patterns
+- Mistakes automatically analyzed with prevention checklists created
+- Documentation systematically maintained through monthly reviews
+
+**Result**: Zero additional user effort, continuous improvement built into framework
+
+## Verification Checklist
+
+- [x] PM Agent agent file completely rewritten with meta-layer design
+- [x] RULES.md Agent Orchestration section updated with two-layer system
+- [x] README.md PM Agent description updated
+- [x] agents.md PM Agent section completely rewritten
+- [x] Integration validated with agiletec project self-improvement workflow
+- [x] All files properly formatted and consistent
+- [x] No breaking changes to existing functionality
+- [x] Documentation accurately reflects implementation
+
+## Future Enhancements
+
+**Potential Additions** (not included in this PR):
+1. `/sc:pm status` - Show documentation coverage and maintenance health
+2. `/sc:pm review` - Manual trigger for documentation review
+3. Performance metrics dashboard - Track mistake prevention effectiveness
+4. Integration with CI/CD - Auto-generate documentation on PR merge
+
+**These are OPTIONAL** and should be separate PRs based on user feedback.
+
+## Related Issues
+
+Addresses internal design discussion about PM Agent role clarity and integration with existing auto-activation system.
+
+## Reviewer Notes
+
+**Key Points to Review**:
+1. **pm-agent.md**: Complete rewrite - verify behavioral mindset, focus areas, and workflow examples make sense
+2. **RULES.md**: Two-layer orchestration system - verify clear distinction between task execution and self-improvement
+3. **agents.md**: User-facing documentation - verify accurate representation of PM Agent behavior
+4. **Integration**: Verify PM Agent complements (not competes with) existing auto-activation
+
+**Expected Outcome**: PM Agent transforms SuperClaude into a continuously learning system through systematic documentation, mistake analysis, and knowledge maintenance.
+
+---
+
+**PR Type**: Enhancement (Design Clarification)
+**Complexity**: Medium (Documentation-focused, no code changes)
+**Risk**: Low (No breaking changes, purely additive capability)
diff --git a/pyproject.toml b/pyproject.toml
index 40c734a..3f9f7db 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
-name = "SuperClaude"
+name = "superclaude"
version = "4.1.5"
authors = [
{name = "NomenAK", email = "anton.knoery@gmail.com"},
@@ -43,8 +43,8 @@ GitHub = "https://github.com/SuperClaude-Org/SuperClaude_Framework"
"NomenAK" = "https://github.com/NomenAK"
[project.scripts]
-SuperClaude = "SuperClaude.__main__:main"
-superclaude = "SuperClaude.__main__:main"
+SuperClaude = "superclaude.__main__:main"
+superclaude = "superclaude.__main__:main"
[project.optional-dependencies]
dev = [
@@ -64,12 +64,12 @@ include-package-data = true
[tool.setuptools.packages.find]
where = ["."]
-include = ["SuperClaude*", "setup*"]
+include = ["superclaude*", "setup*"]
exclude = ["tests*", "*.tests*", "*.tests", ".git*", ".venv*", "*.egg-info*"]
[tool.setuptools.package-data]
"setup" = ["data/*.json", "data/*.yaml", "data/*.yml", "components/*.py", "**/*.py"]
-"SuperClaude" = ["*.md", "*.txt", "**/*.md", "**/*.txt", "**/*.json", "**/*.yaml", "**/*.yml"]
+"superclaude" = ["*.md", "*.txt", "**/*.md", "**/*.txt", "**/*.json", "**/*.yaml", "**/*.yml"]
[tool.black]
line-length = 88
@@ -115,7 +115,7 @@ markers = [
]
[tool.coverage.run]
-source = ["SuperClaude", "setup"]
+source = ["superclaude", "setup"]
omit = [
"*/tests/*",
"*/test_*",
diff --git a/scripts/README.md b/scripts/README.md
index 44eb7c1..1e4f188 100644
--- a/scripts/README.md
+++ b/scripts/README.md
@@ -107,8 +107,8 @@ Set these in your GitHub repository settings โ Secrets and variables โ Actio
Before publishing, ensure version consistency across:
- `pyproject.toml`
-- `SuperClaude/__init__.py`
-- `SuperClaude/__main__.py`
+- `superclaude/__init__.py`
+- `superclaude/__main__.py`
- `setup/__init__.py`
The build script validates version consistency automatically.
diff --git a/scripts/build_and_upload.py b/scripts/build_and_upload.py
index ce87869..aa8812c 100755
--- a/scripts/build_and_upload.py
+++ b/scripts/build_and_upload.py
@@ -17,16 +17,13 @@ PROJECT_ROOT = Path(__file__).parent.parent
DIST_DIR = PROJECT_ROOT / "dist"
BUILD_DIR = PROJECT_ROOT / "build"
+
def run_command(cmd: List[str], description: str) -> Tuple[bool, str]:
"""Run a command and return success status and output"""
print(f"๐ {description}...")
try:
result = subprocess.run(
- cmd,
- capture_output=True,
- text=True,
- cwd=PROJECT_ROOT,
- check=True
+ cmd, capture_output=True, text=True, cwd=PROJECT_ROOT, check=True
)
print(f"โ
{description} completed successfully")
return True, result.stdout
@@ -39,10 +36,11 @@ def run_command(cmd: List[str], description: str) -> Tuple[bool, str]:
print(f"โ {description} failed with exception: {e}")
return False, str(e)
+
def clean_build_artifacts():
"""Clean previous build artifacts"""
- artifacts = [DIST_DIR, BUILD_DIR, PROJECT_ROOT / "SuperClaude.egg-info"]
-
+ artifacts = [DIST_DIR, BUILD_DIR, PROJECT_ROOT / "superclaude.egg-info"]
+
for artifact in artifacts:
if artifact.exists():
print(f"๐งน Removing {artifact}")
@@ -51,179 +49,214 @@ def clean_build_artifacts():
else:
artifact.unlink()
+
def install_build_tools() -> bool:
"""Install required build tools"""
tools = ["build", "twine"]
-
+
for tool in tools:
success, _ = run_command(
[sys.executable, "-m", "pip", "install", "--upgrade", tool],
- f"Installing {tool}"
+ f"Installing {tool}",
)
if not success:
return False
-
+
return True
+
def validate_project_structure() -> bool:
"""Validate project structure before building"""
required_files = [
"pyproject.toml",
- "README.md",
+ "README.md",
"LICENSE",
- "SuperClaude/__init__.py",
- "SuperClaude/__main__.py",
- "setup/__init__.py"
+ "superclaude/__init__.py",
+ "superclaude/__main__.py",
+ "setup/__init__.py",
]
-
+
print("๐ Validating project structure...")
-
+
for file_path in required_files:
full_path = PROJECT_ROOT / file_path
if not full_path.exists():
print(f"โ Missing required file: {file_path}")
return False
-
+
# Check if version is consistent
try:
- from SuperClaude import __version__
+ from superclaude import __version__
+
print(f"๐ฆ Package version: {__version__}")
except ImportError as e:
print(f"โ Could not import version from SuperClaude: {e}")
return False
-
+
print("โ
Project structure validation passed")
return True
+
def build_package() -> bool:
"""Build the package"""
return run_command(
- [sys.executable, "-m", "build"],
- "Building package distributions"
+ [sys.executable, "-m", "build"], "Building package distributions"
)[0]
+
def validate_distribution() -> bool:
"""Validate the built distribution"""
if not DIST_DIR.exists():
print("โ Distribution directory does not exist")
return False
-
+
dist_files = list(DIST_DIR.glob("*"))
if not dist_files:
print("โ No distribution files found")
return False
-
+
print(f"๐ฆ Found distribution files:")
for file in dist_files:
print(f" - {file.name}")
-
+
# Check with twine
return run_command(
[sys.executable, "-m", "twine", "check"] + [str(f) for f in dist_files],
- "Validating distributions with twine"
+ "Validating distributions with twine",
)[0]
+
def upload_to_testpypi() -> bool:
"""Upload to TestPyPI for testing"""
dist_files = list(DIST_DIR.glob("*"))
return run_command(
- [sys.executable, "-m", "twine", "upload", "--repository", "testpypi"] + [str(f) for f in dist_files],
- "Uploading to TestPyPI"
+ [sys.executable, "-m", "twine", "upload", "--repository", "testpypi"]
+ + [str(f) for f in dist_files],
+ "Uploading to TestPyPI",
)[0]
+
def upload_to_pypi() -> bool:
"""Upload to production PyPI"""
dist_files = list(DIST_DIR.glob("*"))
-
+
# Check if we have API token in environment
- if os.getenv('PYPI_API_TOKEN'):
+ if os.getenv("PYPI_API_TOKEN"):
cmd = [
- sys.executable, "-m", "twine", "upload",
- "--username", "__token__",
- "--password", os.getenv('PYPI_API_TOKEN')
+ sys.executable,
+ "-m",
+ "twine",
+ "upload",
+ "--username",
+ "__token__",
+ "--password",
+ os.getenv("PYPI_API_TOKEN"),
] + [str(f) for f in dist_files]
else:
# Fall back to .pypirc configuration
cmd = [sys.executable, "-m", "twine", "upload"] + [str(f) for f in dist_files]
-
+
return run_command(cmd, "Uploading to PyPI")[0]
+
def test_installation_from_testpypi() -> bool:
"""Test installation from TestPyPI"""
print("๐งช Testing installation from TestPyPI...")
print(" Note: This will install in a separate process")
-
- success, output = run_command([
- sys.executable, "-m", "pip", "install",
- "--index-url", "https://test.pypi.org/simple/",
- "--extra-index-url", "https://pypi.org/simple/",
- "SuperClaude", "--force-reinstall", "--no-deps"
- ], "Installing from TestPyPI")
-
+
+ success, output = run_command(
+ [
+ sys.executable,
+ "-m",
+ "pip",
+ "install",
+ "--index-url",
+ "https://test.pypi.org/simple/",
+ "--extra-index-url",
+ "https://pypi.org/simple/",
+ "SuperClaude",
+ "--force-reinstall",
+ "--no-deps",
+ ],
+ "Installing from TestPyPI",
+ )
+
if success:
print("โ
Test installation successful")
# Try to import the package
try:
- import SuperClaude
- print(f"โ
Package import successful, version: {SuperClaude.__version__}")
+ import superclaude
+
+ print(f"โ
Package import successful, version: {superclaude.__version__}")
return True
except ImportError as e:
print(f"โ Package import failed: {e}")
return False
-
+
return False
+
def main():
"""Main execution function"""
parser = argparse.ArgumentParser(description="Build and upload SuperClaude to PyPI")
- parser.add_argument("--testpypi", action="store_true", help="Upload to TestPyPI instead of PyPI")
- parser.add_argument("--test-install", action="store_true", help="Test installation from TestPyPI")
- parser.add_argument("--skip-build", action="store_true", help="Skip build step (use existing dist)")
- parser.add_argument("--skip-validation", action="store_true", help="Skip validation steps")
- parser.add_argument("--clean", action="store_true", help="Only clean build artifacts")
-
+ parser.add_argument(
+ "--testpypi", action="store_true", help="Upload to TestPyPI instead of PyPI"
+ )
+ parser.add_argument(
+ "--test-install", action="store_true", help="Test installation from TestPyPI"
+ )
+ parser.add_argument(
+ "--skip-build", action="store_true", help="Skip build step (use existing dist)"
+ )
+ parser.add_argument(
+ "--skip-validation", action="store_true", help="Skip validation steps"
+ )
+ parser.add_argument(
+ "--clean", action="store_true", help="Only clean build artifacts"
+ )
+
args = parser.parse_args()
-
+
# Change to project root
os.chdir(PROJECT_ROOT)
-
+
if args.clean:
clean_build_artifacts()
return
-
+
print("๐ SuperClaude PyPI Build and Upload Script")
print(f"๐ Working directory: {PROJECT_ROOT}")
-
+
# Step 1: Clean previous builds
clean_build_artifacts()
-
+
# Step 2: Install build tools
if not install_build_tools():
print("โ Failed to install build tools")
sys.exit(1)
-
+
# Step 3: Validate project structure
if not args.skip_validation and not validate_project_structure():
print("โ Project structure validation failed")
sys.exit(1)
-
+
# Step 4: Build package
if not args.skip_build:
if not build_package():
print("โ Package build failed")
sys.exit(1)
-
+
# Step 5: Validate distribution
if not args.skip_validation and not validate_distribution():
print("โ Distribution validation failed")
sys.exit(1)
-
+
# Step 6: Upload
if args.testpypi:
if not upload_to_testpypi():
print("โ Upload to TestPyPI failed")
sys.exit(1)
-
+
# Test installation if requested
if args.test_install:
if not test_installation_from_testpypi():
@@ -231,16 +264,19 @@ def main():
sys.exit(1)
else:
# Confirm production upload
- response = input("๐จ Upload to production PyPI? This cannot be undone! (yes/no): ")
+ response = input(
+ "๐จ Upload to production PyPI? This cannot be undone! (yes/no): "
+ )
if response.lower() != "yes":
print("โ Upload cancelled")
sys.exit(1)
-
+
if not upload_to_pypi():
print("โ Upload to PyPI failed")
sys.exit(1)
-
+
print("โ
All operations completed successfully!")
+
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff --git a/scripts/validate_pypi_ready.py b/scripts/validate_pypi_ready.py
index ab64e65..b87c48b 100755
--- a/scripts/validate_pypi_ready.py
+++ b/scripts/validate_pypi_ready.py
@@ -12,6 +12,7 @@ from typing import List, Tuple
# Project root
PROJECT_ROOT = Path(__file__).parent.parent
+
def check_file_exists(file_path: Path, description: str) -> bool:
"""Check if a required file exists"""
if file_path.exists():
@@ -21,42 +22,45 @@ def check_file_exists(file_path: Path, description: str) -> bool:
print(f"โ Missing {description}: {file_path}")
return False
+
def check_version_consistency() -> bool:
"""Check if versions are consistent across files"""
print("\n๐ Checking version consistency...")
-
+
versions = {}
-
+
# Check pyproject.toml
try:
pyproject_path = PROJECT_ROOT / "pyproject.toml"
- with open(pyproject_path, 'r') as f:
+ with open(pyproject_path, "r") as f:
pyproject = toml.load(f)
- versions['pyproject.toml'] = pyproject['project']['version']
+ versions["pyproject.toml"] = pyproject["project"]["version"]
print(f"๐ pyproject.toml version: {versions['pyproject.toml']}")
except Exception as e:
print(f"โ Error reading pyproject.toml: {e}")
return False
-
- # Check SuperClaude/__init__.py
+
+ # Check superclaude/__init__.py
try:
sys.path.insert(0, str(PROJECT_ROOT))
- from SuperClaude import __version__
- versions['SuperClaude/__init__.py'] = __version__
- print(f"๐ฆ Package version: {versions['SuperClaude/__init__.py']}")
+ from superclaude import __version__
+
+ versions["superclaude/__init__.py"] = __version__
+ print(f"๐ฆ Package version: {versions['superclaude/__init__.py']}")
except Exception as e:
print(f"โ Error importing SuperClaude version: {e}")
return False
-
+
# Check setup/__init__.py
try:
from setup import __version__ as setup_version
- versions['setup/__init__.py'] = setup_version
+
+ versions["setup/__init__.py"] = setup_version
print(f"๐ง Setup version: {versions['setup/__init__.py']}")
except Exception as e:
print(f"โ Error importing setup version: {e}")
return False
-
+
# Check consistency
all_versions = list(versions.values())
if len(set(all_versions)) == 1:
@@ -66,33 +70,35 @@ def check_version_consistency() -> bool:
print(f"โ Version mismatch: {versions}")
return False
+
def check_package_structure() -> bool:
"""Check if package structure is correct"""
print("\n๐๏ธ Checking package structure...")
-
+
required_structure = [
- ("SuperClaude/__init__.py", "Main package __init__.py"),
- ("SuperClaude/__main__.py", "Main entry point"),
- ("SuperClaude/Core/__init__.py", "Core module __init__.py"),
- ("SuperClaude/Commands/__init__.py", "Commands module __init__.py"),
- ("SuperClaude/Agents/__init__.py", "Agents module __init__.py"),
- ("SuperClaude/Modes/__init__.py", "Modes module __init__.py"),
- ("SuperClaude/MCP/__init__.py", "MCP module __init__.py"),
+ ("superclaude/__init__.py", "Main package __init__.py"),
+ ("superclaude/__main__.py", "Main entry point"),
+ ("superclaude/Core/__init__.py", "Core module __init__.py"),
+ ("superclaude/Commands/__init__.py", "Commands module __init__.py"),
+ ("superclaude/Agents/__init__.py", "Agents module __init__.py"),
+ ("superclaude/Modes/__init__.py", "Modes module __init__.py"),
+ ("superclaude/MCP/__init__.py", "MCP module __init__.py"),
("setup/__init__.py", "Setup package __init__.py"),
]
-
+
all_good = True
for file_path, description in required_structure:
full_path = PROJECT_ROOT / file_path
if not check_file_exists(full_path, description):
all_good = False
-
+
return all_good
+
def check_required_files() -> bool:
"""Check if all required files are present"""
print("\n๐ Checking required files...")
-
+
required_files = [
("pyproject.toml", "Package configuration"),
("README.md", "Project README"),
@@ -100,77 +106,81 @@ def check_required_files() -> bool:
("MANIFEST.in", "Package manifest"),
("setup.py", "Setup script"),
]
-
+
all_good = True
for file_path, description in required_files:
full_path = PROJECT_ROOT / file_path
if not check_file_exists(full_path, description):
all_good = False
-
+
return all_good
+
def check_pyproject_config() -> bool:
"""Check pyproject.toml configuration"""
print("\nโ๏ธ Checking pyproject.toml configuration...")
-
+
try:
pyproject_path = PROJECT_ROOT / "pyproject.toml"
- with open(pyproject_path, 'r') as f:
+ with open(pyproject_path, "r") as f:
pyproject = toml.load(f)
-
- project = pyproject.get('project', {})
-
+
+ project = pyproject.get("project", {})
+
# Required fields
- required_fields = ['name', 'version', 'description', 'authors']
+ required_fields = ["name", "version", "description", "authors"]
for field in required_fields:
if field in project:
print(f"โ
{field}: {project[field]}")
else:
print(f"โ Missing required field: {field}")
return False
-
+
# Check entry points
- scripts = project.get('scripts', {})
- if 'SuperClaude' in scripts:
- print(f"โ
CLI entry point: {scripts['SuperClaude']}")
+ scripts = project.get("scripts", {})
+ if "superclaude" in scripts:
+ print(f"โ
CLI entry point: {scripts['superclaude']}")
else:
print("โ Missing CLI entry point")
return False
-
+
# Check classifiers
- classifiers = project.get('classifiers', [])
+ classifiers = project.get("classifiers", [])
if len(classifiers) > 0:
print(f"โ
{len(classifiers)} PyPI classifiers defined")
else:
print("โ ๏ธ No PyPI classifiers defined")
-
+
return True
-
+
except Exception as e:
print(f"โ Error reading pyproject.toml: {e}")
return False
+
def check_import_test() -> bool:
"""Test if the package can be imported"""
print("\n๐งช Testing package import...")
-
+
try:
sys.path.insert(0, str(PROJECT_ROOT))
- import SuperClaude
+ import superclaude
+
print(f"โ
SuperClaude import successful")
- print(f"๐ฆ Version: {SuperClaude.__version__}")
- print(f"๐ค Author: {SuperClaude.__author__}")
+ print(f"๐ฆ Version: {superclaude.__version__}")
+ print(f"๐ค Author: {superclaude.__author__}")
return True
except Exception as e:
print(f"โ Import failed: {e}")
return False
+
def main():
"""Main validation function"""
print("๐ SuperClaude PyPI Readiness Validation")
print(f"๐ Project root: {PROJECT_ROOT}")
print("=" * 50)
-
+
checks = [
("Required Files", check_required_files),
("Package Structure", check_package_structure),
@@ -178,9 +188,9 @@ def main():
("PyProject Configuration", check_pyproject_config),
("Import Test", check_import_test),
]
-
+
results = []
-
+
for name, check_func in checks:
try:
result = check_func()
@@ -188,23 +198,23 @@ def main():
except Exception as e:
print(f"โ {name} check failed with exception: {e}")
results.append((name, False))
-
+
# Summary
print("\n" + "=" * 50)
print("๐ VALIDATION SUMMARY")
print("=" * 50)
-
+
passed = 0
total = len(results)
-
+
for name, result in results:
status = "โ
PASS" if result else "โ FAIL"
print(f"{status} {name}")
if result:
passed += 1
-
+
print(f"\n๐ Overall: {passed}/{total} checks passed")
-
+
if passed == total:
print("๐ Project is ready for PyPI publication!")
print("\nNext steps:")
@@ -215,6 +225,7 @@ def main():
print("โ Project needs fixes before PyPI publication")
return False
+
if __name__ == "__main__":
success = main()
- sys.exit(0 if success else 1)
\ No newline at end of file
+ sys.exit(0 if success else 1)
diff --git a/setup/__init__.py b/setup/__init__.py
index a4055a5..504226b 100644
--- a/setup/__init__.py
+++ b/setup/__init__.py
@@ -21,4 +21,4 @@ DATA_DIR = SETUP_DIR / "data"
from .utils.paths import get_home_directory
# Installation target
-DEFAULT_INSTALL_DIR = get_home_directory() / ".claude"
\ No newline at end of file
+DEFAULT_INSTALL_DIR = get_home_directory() / ".claude"
diff --git a/setup/cli/__init__.py b/setup/cli/__init__.py
index df9a352..4fdd868 100644
--- a/setup/cli/__init__.py
+++ b/setup/cli/__init__.py
@@ -7,5 +7,5 @@ from .base import OperationBase
from .commands import *
__all__ = [
- 'OperationBase',
-]
\ No newline at end of file
+ "OperationBase",
+]
diff --git a/setup/cli/base.py b/setup/cli/base.py
index df5b3bb..cc4ae47 100644
--- a/setup/cli/base.py
+++ b/setup/cli/base.py
@@ -19,61 +19,65 @@ def get_command_info():
"install": {
"name": "install",
"description": "Install SuperClaude framework components",
- "module": "setup.cli.commands.install"
+ "module": "setup.cli.commands.install",
},
"update": {
- "name": "update",
+ "name": "update",
"description": "Update existing SuperClaude installation",
- "module": "setup.cli.commands.update"
+ "module": "setup.cli.commands.update",
},
"uninstall": {
"name": "uninstall",
- "description": "Remove SuperClaude framework installation",
- "module": "setup.cli.commands.uninstall"
+ "description": "Remove SuperClaude framework installation",
+ "module": "setup.cli.commands.uninstall",
},
"backup": {
"name": "backup",
"description": "Backup and restore SuperClaude installations",
- "module": "setup.cli.commands.backup"
- }
+ "module": "setup.cli.commands.backup",
+ },
}
class OperationBase:
"""Base class for all operations providing common functionality"""
-
+
def __init__(self, operation_name: str):
self.operation_name = operation_name
self.logger = None
-
+
def setup_operation_logging(self, args):
"""Setup operation-specific logging"""
from ..utils.logger import get_logger
+
self.logger = get_logger()
self.logger.info(f"Starting {self.operation_name} operation")
-
+
def validate_global_args(self, args):
"""Validate global arguments common to all operations"""
errors = []
-
+
# Validate install directory
- if hasattr(args, 'install_dir') and args.install_dir:
+ if hasattr(args, "install_dir") and args.install_dir:
from ..utils.security import SecurityValidator
- is_safe, validation_errors = SecurityValidator.validate_installation_target(args.install_dir)
+
+ is_safe, validation_errors = SecurityValidator.validate_installation_target(
+ args.install_dir
+ )
if not is_safe:
errors.extend(validation_errors)
-
+
# Check for conflicting flags
- if hasattr(args, 'verbose') and hasattr(args, 'quiet'):
+ if hasattr(args, "verbose") and hasattr(args, "quiet"):
if args.verbose and args.quiet:
errors.append("Cannot specify both --verbose and --quiet")
-
+
return len(errors) == 0, errors
-
+
def handle_operation_error(self, operation: str, error: Exception):
"""Standard error handling for operations"""
if self.logger:
self.logger.exception(f"Error in {operation} operation: {error}")
else:
print(f"Error in {operation} operation: {error}")
- return 1
\ No newline at end of file
+ return 1
diff --git a/setup/cli/commands/__init__.py b/setup/cli/commands/__init__.py
index 1d9ee6d..c55c25a 100644
--- a/setup/cli/commands/__init__.py
+++ b/setup/cli/commands/__init__.py
@@ -10,9 +10,9 @@ from .update import UpdateOperation
from .backup import BackupOperation
__all__ = [
- 'OperationBase',
- 'InstallOperation',
- 'UninstallOperation',
- 'UpdateOperation',
- 'BackupOperation'
-]
\ No newline at end of file
+ "OperationBase",
+ "InstallOperation",
+ "UninstallOperation",
+ "UpdateOperation",
+ "BackupOperation",
+]
diff --git a/setup/cli/commands/backup.py b/setup/cli/commands/backup.py
index fbca3d6..f5fbe50 100644
--- a/setup/cli/commands/backup.py
+++ b/setup/cli/commands/backup.py
@@ -9,14 +9,22 @@ import tarfile
import json
from pathlib import Path
from ...utils.paths import get_home_directory
-from datetime import datetime
+from datetime import datetime, timedelta
from typing import List, Optional, Dict, Any, Tuple
import argparse
from ...services.settings import SettingsService
from ...utils.ui import (
- display_header, display_info, display_success, display_error,
- display_warning, Menu, confirm, ProgressBar, Colors, format_size
+ display_header,
+ display_info,
+ display_success,
+ display_error,
+ display_warning,
+ Menu,
+ confirm,
+ ProgressBar,
+ Colors,
+ format_size,
)
from ...utils.logger import get_logger
from ... import DEFAULT_INSTALL_DIR
@@ -25,7 +33,7 @@ from . import OperationBase
class BackupOperation(OperationBase):
"""Backup operation implementation"""
-
+
def __init__(self):
super().__init__("backup")
@@ -33,7 +41,7 @@ class BackupOperation(OperationBase):
def register_parser(subparsers, global_parser=None) -> argparse.ArgumentParser:
"""Register backup CLI arguments"""
parents = [global_parser] if global_parser else []
-
+
parser = subparsers.add_parser(
"backup",
help="Backup and restore SuperClaude installations",
@@ -48,84 +56,70 @@ Examples:
SuperClaude backup --cleanup --force # Clean up old backups (forced)
""",
formatter_class=argparse.RawDescriptionHelpFormatter,
- parents=parents
+ parents=parents,
)
-
+
# Backup operations (mutually exclusive)
operation_group = parser.add_mutually_exclusive_group(required=True)
-
+
operation_group.add_argument(
- "--create",
- action="store_true",
- help="Create a new backup"
+ "--create", action="store_true", help="Create a new backup"
)
-
+
operation_group.add_argument(
- "--list",
- action="store_true",
- help="List available backups"
+ "--list", action="store_true", help="List available backups"
)
-
+
operation_group.add_argument(
"--restore",
nargs="?",
const="interactive",
- help="Restore from backup (optionally specify backup file)"
+ help="Restore from backup (optionally specify backup file)",
)
-
+
operation_group.add_argument(
- "--info",
- type=str,
- help="Show information about a specific backup file"
+ "--info", type=str, help="Show information about a specific backup file"
)
-
+
operation_group.add_argument(
- "--cleanup",
- action="store_true",
- help="Clean up old backup files"
+ "--cleanup", action="store_true", help="Clean up old backup files"
)
-
+
# Backup options
parser.add_argument(
"--backup-dir",
type=Path,
- help="Backup directory (default: /backups)"
+ help="Backup directory (default: /backups)",
)
-
- parser.add_argument(
- "--name",
- type=str,
- help="Custom backup name (for --create)"
- )
-
+
+ parser.add_argument("--name", type=str, help="Custom backup name (for --create)")
+
parser.add_argument(
"--compress",
choices=["none", "gzip", "bzip2"],
default="gzip",
- help="Compression method (default: gzip)"
+ help="Compression method (default: gzip)",
)
-
+
# Restore options
parser.add_argument(
"--overwrite",
action="store_true",
- help="Overwrite existing files during restore"
+ help="Overwrite existing files during restore",
)
-
+
# Cleanup options
parser.add_argument(
"--keep",
type=int,
default=5,
- help="Number of backups to keep during cleanup (default: 5)"
+ help="Number of backups to keep during cleanup (default: 5)",
)
-
+
parser.add_argument(
- "--older-than",
- type=int,
- help="Remove backups older than N days"
+ "--older-than", type=int, help="Remove backups older than N days"
)
-
+
return parser
@@ -141,7 +135,10 @@ def check_installation_exists(install_dir: Path) -> bool:
"""Check if SuperClaude installation (v2 included) exists"""
settings_manager = SettingsService(install_dir)
- return settings_manager.check_installation_exists() or settings_manager.check_v2_installation_exists()
+ return (
+ settings_manager.check_installation_exists()
+ or settings_manager.check_v2_installation_exists()
+ )
def get_backup_info(backup_path: Path) -> Dict[str, Any]:
@@ -151,18 +148,18 @@ def get_backup_info(backup_path: Path) -> Dict[str, Any]:
"exists": backup_path.exists(),
"size": 0,
"created": None,
- "metadata": {}
+ "metadata": {},
}
-
+
if not backup_path.exists():
return info
-
+
try:
# Get file stats
stats = backup_path.stat()
info["size"] = stats.st_size
info["created"] = datetime.fromtimestamp(stats.st_mtime)
-
+
# Try to read metadata from backup
if backup_path.suffix == ".gz":
mode = "r:gz"
@@ -170,7 +167,7 @@ def get_backup_info(backup_path: Path) -> Dict[str, Any]:
mode = "r:bz2"
else:
mode = "r"
-
+
with tarfile.open(backup_path, mode) as tar:
# Look for metadata file
try:
@@ -180,32 +177,32 @@ def get_backup_info(backup_path: Path) -> Dict[str, Any]:
info["metadata"] = json.loads(metadata_file.read().decode())
except KeyError:
pass # No metadata file
-
+
# Get list of files in backup
info["files"] = len(tar.getnames())
-
+
except Exception as e:
info["error"] = str(e)
-
+
return info
def list_backups(backup_dir: Path) -> List[Dict[str, Any]]:
"""List all available backups"""
backups = []
-
+
if not backup_dir.exists():
return backups
-
+
# Find all backup files
for backup_file in backup_dir.glob("*.tar*"):
if backup_file.is_file():
info = get_backup_info(backup_file)
backups.append(info)
-
+
# Sort by creation date (newest first)
backups.sort(key=lambda x: x.get("created", datetime.min), reverse=True)
-
+
return backups
@@ -213,43 +210,49 @@ def display_backup_list(backups: List[Dict[str, Any]]) -> None:
"""Display list of available backups"""
print(f"\n{Colors.CYAN}{Colors.BRIGHT}Available Backups{Colors.RESET}")
print("=" * 70)
-
+
if not backups:
print(f"{Colors.YELLOW}No backups found{Colors.RESET}")
return
-
+
print(f"{'Name':<30} {'Size':<10} {'Created':<20} {'Files':<8}")
print("-" * 70)
-
+
for backup in backups:
name = backup["path"].name
size = format_size(backup["size"]) if backup["size"] > 0 else "unknown"
- created = backup["created"].strftime("%Y-%m-%d %H:%M") if backup["created"] else "unknown"
+ created = (
+ backup["created"].strftime("%Y-%m-%d %H:%M")
+ if backup["created"]
+ else "unknown"
+ )
files = str(backup.get("files", "unknown"))
-
+
print(f"{name:<30} {size:<10} {created:<20} {files:<8}")
-
+
print()
def create_backup_metadata(install_dir: Path) -> Dict[str, Any]:
"""Create metadata for the backup"""
+ from setup import __version__
+
metadata = {
"backup_version": __version__,
"created": datetime.now().isoformat(),
"install_dir": str(install_dir),
"components": {},
- "framework_version": "unknown"
+ "framework_version": "unknown",
}
-
+
try:
# Get installed components from metadata
settings_manager = SettingsService(install_dir)
framework_config = settings_manager.get_metadata_setting("framework")
-
+
if framework_config:
metadata["framework_version"] = framework_config.get("version", "unknown")
-
+
if "components" in framework_config:
for component_name in framework_config["components"]:
version = settings_manager.get_component_version(component_name)
@@ -257,31 +260,31 @@ def create_backup_metadata(install_dir: Path) -> Dict[str, Any]:
metadata["components"][component_name] = version
except Exception:
pass # Continue without metadata
-
+
return metadata
def create_backup(args: argparse.Namespace) -> bool:
"""Create a new backup"""
logger = get_logger()
-
+
try:
# Check if installation exists
if not check_installation_exists(args.install_dir):
logger.error(f"No SuperClaude installation found in {args.install_dir}")
return False
-
+
# Setup backup directory
backup_dir = get_backup_directory(args)
backup_dir.mkdir(parents=True, exist_ok=True)
-
+
# Generate backup filename
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
if args.name:
backup_name = f"{args.name}_{timestamp}"
else:
backup_name = f"superclaude_backup_{timestamp}"
-
+
# Determine compression
if args.compress == "gzip":
backup_file = backup_dir / f"{backup_name}.tar.gz"
@@ -292,24 +295,27 @@ def create_backup(args: argparse.Namespace) -> bool:
else:
backup_file = backup_dir / f"{backup_name}.tar"
mode = "w"
-
+
logger.info(f"Creating backup: {backup_file}")
-
+
# Create metadata
metadata = create_backup_metadata(args.install_dir)
-
+
# Create backup
start_time = time.time()
-
+
with tarfile.open(backup_file, mode) as tar:
# Add metadata file
import tempfile
- with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as temp_file:
+
+ with tempfile.NamedTemporaryFile(
+ mode="w", suffix=".json", delete=False
+ ) as temp_file:
json.dump(metadata, temp_file, indent=2)
temp_file.flush()
tar.add(temp_file.name, arcname="backup_metadata.json")
Path(temp_file.name).unlink() # Clean up temp file
-
+
# Add installation directory contents (excluding backups and local dirs)
files_added = 0
for item in args.install_dir.rglob("*"):
@@ -317,30 +323,30 @@ def create_backup(args: argparse.Namespace) -> bool:
try:
# Create relative path for archive
rel_path = item.relative_to(args.install_dir)
-
+
# Skip files in excluded directories
if rel_path.parts and rel_path.parts[0] in ["backups", "local"]:
continue
-
+
tar.add(item, arcname=str(rel_path))
files_added += 1
-
+
if files_added % 10 == 0:
logger.debug(f"Added {files_added} files to backup")
-
+
except Exception as e:
logger.warning(f"Could not add {item} to backup: {e}")
-
+
duration = time.time() - start_time
file_size = backup_file.stat().st_size
-
+
logger.success(f"Backup created successfully in {duration:.1f} seconds")
logger.info(f"Backup file: {backup_file}")
logger.info(f"Files archived: {files_added}")
logger.info(f"Backup size: {format_size(file_size)}")
-
+
return True
-
+
except Exception as e:
logger.exception(f"Failed to create backup: {e}")
return False
@@ -349,20 +355,20 @@ def create_backup(args: argparse.Namespace) -> bool:
def restore_backup(backup_path: Path, args: argparse.Namespace) -> bool:
"""Restore from a backup file"""
logger = get_logger()
-
+
try:
if not backup_path.exists():
logger.error(f"Backup file not found: {backup_path}")
return False
-
+
# Check backup file
info = get_backup_info(backup_path)
if "error" in info:
logger.error(f"Invalid backup file: {info['error']}")
return False
-
+
logger.info(f"Restoring from backup: {backup_path}")
-
+
# Determine compression
if backup_path.suffix == ".gz":
mode = "r:gz"
@@ -370,47 +376,47 @@ def restore_backup(backup_path: Path, args: argparse.Namespace) -> bool:
mode = "r:bz2"
else:
mode = "r"
-
+
# Create backup of current installation if it exists
if check_installation_exists(args.install_dir) and not args.dry_run:
logger.info("Creating backup of current installation before restore")
# This would call create_backup internally
-
+
# Extract backup
start_time = time.time()
files_restored = 0
-
+
with tarfile.open(backup_path, mode) as tar:
# Extract all files except metadata
for member in tar.getmembers():
if member.name == "backup_metadata.json":
continue
-
+
try:
target_path = args.install_dir / member.name
-
+
# Check if file exists and overwrite flag
if target_path.exists() and not args.overwrite:
logger.warning(f"Skipping existing file: {target_path}")
continue
-
+
# Extract file
tar.extract(member, args.install_dir)
files_restored += 1
-
+
if files_restored % 10 == 0:
logger.debug(f"Restored {files_restored} files")
-
+
except Exception as e:
logger.warning(f"Could not restore {member.name}: {e}")
-
+
duration = time.time() - start_time
-
+
logger.success(f"Restore completed successfully in {duration:.1f} seconds")
logger.info(f"Files restored: {files_restored}")
-
+
return True
-
+
except Exception as e:
logger.exception(f"Failed to restore backup: {e}")
return False
@@ -421,69 +427,73 @@ def interactive_restore_selection(backups: List[Dict[str, Any]]) -> Optional[Pat
if not backups:
print(f"{Colors.YELLOW}No backups available for restore{Colors.RESET}")
return None
-
+
print(f"\n{Colors.CYAN}Select Backup to Restore:{Colors.RESET}")
-
+
# Create menu options
backup_options = []
for backup in backups:
name = backup["path"].name
size = format_size(backup["size"]) if backup["size"] > 0 else "unknown"
- created = backup["created"].strftime("%Y-%m-%d %H:%M") if backup["created"] else "unknown"
+ created = (
+ backup["created"].strftime("%Y-%m-%d %H:%M")
+ if backup["created"]
+ else "unknown"
+ )
backup_options.append(f"{name} ({size}, {created})")
-
+
menu = Menu("Select backup:", backup_options)
choice = menu.display()
-
+
if choice == -1 or choice >= len(backups):
return None
-
+
return backups[choice]["path"]
def cleanup_old_backups(backup_dir: Path, args: argparse.Namespace) -> bool:
"""Clean up old backup files"""
logger = get_logger()
-
+
try:
backups = list_backups(backup_dir)
if not backups:
logger.info("No backups found to clean up")
return True
-
+
to_remove = []
-
+
# Remove by age
if args.older_than:
cutoff_date = datetime.now() - timedelta(days=args.older_than)
for backup in backups:
if backup["created"] and backup["created"] < cutoff_date:
to_remove.append(backup)
-
+
# Keep only N most recent
if args.keep and len(backups) > args.keep:
# Sort by date and take oldest ones to remove
backups.sort(key=lambda x: x.get("created", datetime.min), reverse=True)
- to_remove.extend(backups[args.keep:])
-
+ to_remove.extend(backups[args.keep :])
+
# Remove duplicates
to_remove = list({backup["path"]: backup for backup in to_remove}.values())
-
+
if not to_remove:
logger.info("No backups need to be cleaned up")
return True
-
+
logger.info(f"Cleaning up {len(to_remove)} old backups")
-
+
for backup in to_remove:
try:
backup["path"].unlink()
logger.info(f"Removed backup: {backup['path'].name}")
except Exception as e:
logger.warning(f"Could not remove {backup['path'].name}: {e}")
-
+
return True
-
+
except Exception as e:
logger.exception(f"Failed to cleanup backups: {e}")
return False
@@ -503,7 +513,7 @@ def run(args: argparse.Namespace) -> int:
print(f" Expected prefix: {expected_home}")
print(f" Provided path: {actual_dir}")
sys.exit(1)
-
+
try:
# Validate global arguments
success, errors = operation.validate_global_args(args)
@@ -511,26 +521,27 @@ def run(args: argparse.Namespace) -> int:
for error in errors:
logger.error(error)
return 1
-
+
# Display header
if not args.quiet:
from setup.cli.base import __version__
+
display_header(
f"SuperClaude Backup v{__version__}",
- "Backup and restore SuperClaude installations"
+ "Backup and restore SuperClaude installations",
)
-
+
backup_dir = get_backup_directory(args)
-
+
# Handle different backup operations
if args.create:
success = create_backup(args)
-
+
elif args.list:
backups = list_backups(backup_dir)
display_backup_list(backups)
success = True
-
+
elif args.restore:
if args.restore == "interactive":
# Interactive restore
@@ -544,14 +555,14 @@ def run(args: argparse.Namespace) -> int:
backup_path = Path(args.restore)
if not backup_path.is_absolute():
backup_path = backup_dir / backup_path
-
+
success = restore_backup(backup_path, args)
-
+
elif args.info:
backup_path = Path(args.info)
if not backup_path.is_absolute():
backup_path = backup_dir / backup_path
-
+
info = get_backup_info(backup_path)
if info["exists"]:
print(f"\n{Colors.CYAN}Backup Information:{Colors.RESET}")
@@ -559,10 +570,12 @@ def run(args: argparse.Namespace) -> int:
print(f"Size: {format_size(info['size'])}")
print(f"Created: {info['created']}")
print(f"Files: {info.get('files', 'unknown')}")
-
+
if info["metadata"]:
metadata = info["metadata"]
- print(f"Framework Version: {metadata.get('framework_version', 'unknown')}")
+ print(
+ f"Framework Version: {metadata.get('framework_version', 'unknown')}"
+ )
if metadata.get("components"):
print("Components:")
for comp, ver in metadata["components"].items():
@@ -571,14 +584,14 @@ def run(args: argparse.Namespace) -> int:
logger.error(f"Backup file not found: {backup_path}")
success = False
success = True
-
+
elif args.cleanup:
success = cleanup_old_backups(backup_dir, args)
-
+
else:
logger.error("No backup operation specified")
success = False
-
+
if success:
if not args.quiet and args.create:
display_success("Backup operation completed successfully!")
@@ -588,7 +601,7 @@ def run(args: argparse.Namespace) -> int:
else:
display_error("Backup operation failed. Check logs for details.")
return 1
-
+
except KeyboardInterrupt:
print(f"\n{Colors.YELLOW}Backup operation cancelled by user{Colors.RESET}")
return 130
diff --git a/setup/cli/commands/install.py b/setup/cli/commands/install.py
index ed6e0a8..8a32ec4 100644
--- a/setup/cli/commands/install.py
+++ b/setup/cli/commands/install.py
@@ -15,8 +15,17 @@ from ...core.registry import ComponentRegistry
from ...services.config import ConfigService
from ...core.validator import Validator
from ...utils.ui import (
- display_header, display_info, display_success, display_error,
- display_warning, Menu, confirm, ProgressBar, Colors, format_size, prompt_api_key
+ display_header,
+ display_info,
+ display_success,
+ display_error,
+ display_warning,
+ Menu,
+ confirm,
+ ProgressBar,
+ Colors,
+ format_size,
+ prompt_api_key,
)
from ...utils.environment import setup_environment_variables
from ...utils.logger import get_logger
@@ -26,7 +35,7 @@ from . import OperationBase
class InstallOperation(OperationBase):
"""Installation operation implementation"""
-
+
def __init__(self):
super().__init__("install")
@@ -34,7 +43,7 @@ class InstallOperation(OperationBase):
def register_parser(subparsers, global_parser=None) -> argparse.ArgumentParser:
"""Register installation CLI arguments"""
parents = [global_parser] if global_parser else []
-
+
parser = subparsers.add_parser(
"install",
help="Install SuperClaude framework components",
@@ -47,54 +56,51 @@ Examples:
SuperClaude install --verbose --force # Verbose with force mode
""",
formatter_class=argparse.RawDescriptionHelpFormatter,
- parents=parents
+ parents=parents,
)
-
+
# Installation mode options
-
+
parser.add_argument(
- "--components",
- type=str,
- nargs="+",
- help="Specific components to install"
+ "--components", type=str, nargs="+", help="Specific components to install"
)
-
+
# Installation options
- parser.add_argument(
- "--no-backup",
- action="store_true",
- help="Skip backup creation"
- )
-
+ parser.add_argument("--no-backup", action="store_true", help="Skip backup creation")
+
parser.add_argument(
"--list-components",
action="store_true",
- help="List available components and exit"
+ help="List available components and exit",
)
-
+
parser.add_argument(
"--diagnose",
action="store_true",
- help="Run system diagnostics and show installation help"
+ help="Run system diagnostics and show installation help",
)
-
+
return parser
-def validate_system_requirements(validator: Validator, component_names: List[str]) -> bool:
+def validate_system_requirements(
+ validator: Validator, component_names: List[str]
+) -> bool:
"""Validate system requirements"""
logger = get_logger()
-
+
logger.info("Validating system requirements...")
-
+
try:
# Load requirements configuration
config_manager = ConfigService(DATA_DIR)
requirements = config_manager.get_requirements_for_components(component_names)
-
+
# Validate requirements
- success, errors = validator.validate_component_requirements(component_names, requirements)
-
+ success, errors = validator.validate_component_requirements(
+ component_names, requirements
+ )
+
if success:
logger.success("All system requirements met")
return True
@@ -102,67 +108,79 @@ def validate_system_requirements(validator: Validator, component_names: List[str
logger.error("System requirements not met:")
for error in errors:
logger.error(f" - {error}")
-
+
# Provide additional guidance
print(f"\n{Colors.CYAN}๐ก Installation Help:{Colors.RESET}")
- print(" Run 'SuperClaude install --diagnose' for detailed system diagnostics")
+ print(
+ " Run 'superclaude install --diagnose' for detailed system diagnostics"
+ )
print(" and step-by-step installation instructions.")
-
+
return False
-
+
except Exception as e:
logger.error(f"Could not validate system requirements: {e}")
return False
-def get_components_to_install(args: argparse.Namespace, registry: ComponentRegistry, config_manager: ConfigService) -> Optional[List[str]]:
+def get_components_to_install(
+ args: argparse.Namespace, registry: ComponentRegistry, config_manager: ConfigService
+) -> Optional[List[str]]:
"""Determine which components to install"""
logger = get_logger()
-
+
# Explicit components specified
if args.components:
- if 'all' in args.components:
+ if "all" in args.components:
components = ["core", "commands", "agents", "modes", "mcp", "mcp_docs"]
else:
components = args.components
# If mcp or mcp_docs is specified non-interactively, we should still ask which servers to install.
- if 'mcp' in components or 'mcp_docs' in components:
+ if "mcp" in components or "mcp_docs" in components:
selected_servers = select_mcp_servers(registry)
- if not hasattr(config_manager, '_installation_context'):
+ if not hasattr(config_manager, "_installation_context"):
config_manager._installation_context = {}
- config_manager._installation_context["selected_mcp_servers"] = selected_servers
+ config_manager._installation_context["selected_mcp_servers"] = (
+ selected_servers
+ )
# If the user selected some servers, ensure both mcp and mcp_docs are included
if selected_servers:
- if 'mcp' not in components:
- components.append('mcp')
- logger.debug(f"Auto-added 'mcp' component for selected servers: {selected_servers}")
- if 'mcp_docs' not in components:
- components.append('mcp_docs')
- logger.debug(f"Auto-added 'mcp_docs' component for selected servers: {selected_servers}")
+ if "mcp" not in components:
+ components.append("mcp")
+ logger.debug(
+ f"Auto-added 'mcp' component for selected servers: {selected_servers}"
+ )
+ if "mcp_docs" not in components:
+ components.append("mcp_docs")
+ logger.debug(
+ f"Auto-added 'mcp_docs' component for selected servers: {selected_servers}"
+ )
logger.info(f"Final components to install: {components}")
# If mcp_docs was explicitly requested but no servers selected, allow auto-detection
- elif not selected_servers and 'mcp_docs' in components:
+ elif not selected_servers and "mcp_docs" in components:
logger.info("mcp_docs component will auto-detect existing MCP servers")
logger.info("Documentation will be installed for any detected servers")
return components
-
+
# Interactive two-stage selection
return interactive_component_selection(registry, config_manager)
-def collect_api_keys_for_servers(selected_servers: List[str], mcp_instance) -> Dict[str, str]:
+def collect_api_keys_for_servers(
+ selected_servers: List[str], mcp_instance
+) -> Dict[str, str]:
"""
Collect API keys for servers that require them
-
+
Args:
selected_servers: List of selected server keys
mcp_instance: MCP component instance
-
+
Returns:
Dictionary of environment variable names to API key values
"""
@@ -170,132 +188,164 @@ def collect_api_keys_for_servers(selected_servers: List[str], mcp_instance) -> D
servers_needing_keys = [
(server_key, mcp_instance.mcp_servers[server_key])
for server_key in selected_servers
- if server_key in mcp_instance.mcp_servers and
- mcp_instance.mcp_servers[server_key].get("requires_api_key", False)
+ if server_key in mcp_instance.mcp_servers
+ and mcp_instance.mcp_servers[server_key].get("requires_api_key", False)
]
-
+
if not servers_needing_keys:
return {}
-
+
# Display API key configuration header
print(f"\n{Colors.CYAN}{Colors.BRIGHT}=== API Key Configuration ==={Colors.RESET}")
- print(f"{Colors.YELLOW}The following servers require API keys for full functionality:{Colors.RESET}\n")
-
+ print(
+ f"{Colors.YELLOW}The following servers require API keys for full functionality:{Colors.RESET}\n"
+ )
+
collected_keys = {}
for server_key, server_info in servers_needing_keys:
api_key_env = server_info.get("api_key_env")
service_name = server_info["name"]
-
+
if api_key_env:
key = prompt_api_key(service_name, api_key_env)
if key:
collected_keys[api_key_env] = key
-
+
return collected_keys
def select_mcp_servers(registry: ComponentRegistry) -> List[str]:
"""Stage 1: MCP Server Selection with API Key Collection"""
logger = get_logger()
-
+
try:
# Get MCP component to access server list
- mcp_instance = registry.get_component_instance("mcp", get_home_directory() / ".claude")
- if not mcp_instance or not hasattr(mcp_instance, 'mcp_servers'):
+ mcp_instance = registry.get_component_instance(
+ "mcp", get_home_directory() / ".claude"
+ )
+ if not mcp_instance or not hasattr(mcp_instance, "mcp_servers"):
logger.error("Could not access MCP server information")
return []
-
+
# Create MCP server menu
mcp_servers = mcp_instance.mcp_servers
server_options = []
-
+
for server_key, server_info in mcp_servers.items():
description = server_info["description"]
- api_key_note = " (requires API key)" if server_info.get("requires_api_key", False) else ""
+ api_key_note = (
+ " (requires API key)"
+ if server_info.get("requires_api_key", False)
+ else ""
+ )
server_options.append(f"{server_key} - {description}{api_key_note}")
-
+
print(f"\n{Colors.CYAN}{Colors.BRIGHT}{'='*51}{Colors.RESET}")
- print(f"{Colors.CYAN}{Colors.BRIGHT}Stage 1: MCP Server Selection (Optional){Colors.RESET}")
+ print(
+ f"{Colors.CYAN}{Colors.BRIGHT}Stage 1: MCP Server Selection (Optional){Colors.RESET}"
+ )
print(f"{Colors.CYAN}{Colors.BRIGHT}{'='*51}{Colors.RESET}")
- print(f"\n{Colors.BLUE}MCP servers extend Claude Code with specialized capabilities.{Colors.RESET}")
- print(f"{Colors.BLUE}Select servers to configure (you can always add more later):{Colors.RESET}")
-
+ print(
+ f"\n{Colors.BLUE}MCP servers extend Claude Code with specialized capabilities.{Colors.RESET}"
+ )
+ print(
+ f"{Colors.BLUE}Select servers to configure (you can always add more later):{Colors.RESET}"
+ )
+
# Add option to skip MCP
server_options.append("Skip MCP Server installation")
-
- menu = Menu("Select MCP servers to configure:", server_options, multi_select=True)
+
+ menu = Menu(
+ "Select MCP servers to configure:", server_options, multi_select=True
+ )
selections = menu.display()
-
+
if not selections:
logger.info("No MCP servers selected")
return []
-
+
# Filter out the "skip" option and return server keys
server_keys = list(mcp_servers.keys())
selected_servers = []
-
+
for i in selections:
if i < len(server_keys): # Not the "skip" option
selected_servers.append(server_keys[i])
-
+
if selected_servers:
logger.info(f"Selected MCP servers: {', '.join(selected_servers)}")
-
+
# NEW: Collect API keys for selected servers
- collected_keys = collect_api_keys_for_servers(selected_servers, mcp_instance)
-
+ collected_keys = collect_api_keys_for_servers(
+ selected_servers, mcp_instance
+ )
+
# Set up environment variables
if collected_keys:
setup_environment_variables(collected_keys)
-
+
# Store keys for MCP component to use during installation
mcp_instance.collected_api_keys = collected_keys
else:
logger.info("No MCP servers selected")
-
+
return selected_servers
-
+
except Exception as e:
logger.error(f"Error in MCP server selection: {e}")
return []
-def select_framework_components(registry: ComponentRegistry, config_manager: ConfigService, selected_mcp_servers: List[str]) -> List[str]:
+def select_framework_components(
+ registry: ComponentRegistry,
+ config_manager: ConfigService,
+ selected_mcp_servers: List[str],
+) -> List[str]:
"""Stage 2: Framework Component Selection"""
logger = get_logger()
-
+
try:
# Framework components (excluding MCP-related ones)
framework_components = ["core", "modes", "commands", "agents"]
-
+
# Create component menu
component_options = []
component_info = {}
-
+
for component_name in framework_components:
metadata = registry.get_component_metadata(component_name)
if metadata:
description = metadata.get("description", "No description")
component_options.append(f"{component_name} - {description}")
component_info[component_name] = metadata
-
+
# Add MCP documentation option
if selected_mcp_servers:
mcp_docs_desc = f"MCP documentation for {', '.join(selected_mcp_servers)} (auto-selected)"
component_options.append(f"mcp_docs - {mcp_docs_desc}")
auto_selected_mcp_docs = True
else:
- component_options.append("mcp_docs - MCP server documentation (none selected)")
+ component_options.append(
+ "mcp_docs - MCP server documentation (none selected)"
+ )
auto_selected_mcp_docs = False
-
+
print(f"\n{Colors.CYAN}{Colors.BRIGHT}{'='*51}{Colors.RESET}")
- print(f"{Colors.CYAN}{Colors.BRIGHT}Stage 2: Framework Component Selection{Colors.RESET}")
+ print(
+ f"{Colors.CYAN}{Colors.BRIGHT}Stage 2: Framework Component Selection{Colors.RESET}"
+ )
print(f"{Colors.CYAN}{Colors.BRIGHT}{'='*51}{Colors.RESET}")
- print(f"\n{Colors.BLUE}Select SuperClaude framework components to install:{Colors.RESET}")
-
- menu = Menu("Select components (Core is recommended):", component_options, multi_select=True)
+ print(
+ f"\n{Colors.BLUE}Select SuperClaude framework components to install:{Colors.RESET}"
+ )
+
+ menu = Menu(
+ "Select components (Core is recommended):",
+ component_options,
+ multi_select=True,
+ )
selections = menu.display()
-
+
if not selections:
# Default to core if nothing selected
logger.info("No components selected, defaulting to core")
@@ -303,11 +353,11 @@ def select_framework_components(registry: ComponentRegistry, config_manager: Con
else:
selected_components = []
all_components = framework_components + ["mcp_docs"]
-
+
for i in selections:
if i < len(all_components):
selected_components.append(all_components[i])
-
+
# Auto-select MCP docs if not explicitly deselected and we have MCP servers
if auto_selected_mcp_docs and "mcp_docs" not in selected_components:
# Check if user explicitly deselected it
@@ -316,82 +366,96 @@ def select_framework_components(registry: ComponentRegistry, config_manager: Con
# User didn't select it, but we auto-select it
selected_components.append("mcp_docs")
logger.info("Auto-selected MCP documentation for configured servers")
-
+
# Always include MCP component if servers were selected
if selected_mcp_servers and "mcp" not in selected_components:
selected_components.append("mcp")
-
+
logger.info(f"Selected framework components: {', '.join(selected_components)}")
return selected_components
-
+
except Exception as e:
logger.error(f"Error in framework component selection: {e}")
return ["core"] # Fallback to core
-def interactive_component_selection(registry: ComponentRegistry, config_manager: ConfigService) -> Optional[List[str]]:
+def interactive_component_selection(
+ registry: ComponentRegistry, config_manager: ConfigService
+) -> Optional[List[str]]:
"""Two-stage interactive component selection"""
logger = get_logger()
-
+
try:
print(f"\n{Colors.CYAN}SuperClaude Interactive Installation{Colors.RESET}")
- print(f"{Colors.BLUE}Select components to install using the two-stage process:{Colors.RESET}")
-
+ print(
+ f"{Colors.BLUE}Select components to install using the two-stage process:{Colors.RESET}"
+ )
+
# Stage 1: MCP Server Selection
selected_mcp_servers = select_mcp_servers(registry)
-
+
# Stage 2: Framework Component Selection
- selected_components = select_framework_components(registry, config_manager, selected_mcp_servers)
-
+ selected_components = select_framework_components(
+ registry, config_manager, selected_mcp_servers
+ )
+
# Store selected MCP servers for components to use
- if not hasattr(config_manager, '_installation_context'):
+ if not hasattr(config_manager, "_installation_context"):
config_manager._installation_context = {}
- config_manager._installation_context["selected_mcp_servers"] = selected_mcp_servers
-
+ config_manager._installation_context["selected_mcp_servers"] = (
+ selected_mcp_servers
+ )
+
return selected_components
-
+
except Exception as e:
logger.error(f"Error in component selection: {e}")
return None
-def display_installation_plan(components: List[str], registry: ComponentRegistry, install_dir: Path) -> None:
+def display_installation_plan(
+ components: List[str], registry: ComponentRegistry, install_dir: Path
+) -> None:
"""Display installation plan"""
logger = get_logger()
-
+
print(f"\n{Colors.CYAN}{Colors.BRIGHT}Installation Plan{Colors.RESET}")
print("=" * 50)
-
+
# Resolve dependencies
try:
ordered_components = registry.resolve_dependencies(components)
-
+
print(f"{Colors.BLUE}Installation Directory:{Colors.RESET} {install_dir}")
print(f"{Colors.BLUE}Components to install:{Colors.RESET}")
-
+
total_size = 0
for i, component_name in enumerate(ordered_components, 1):
metadata = registry.get_component_metadata(component_name)
if metadata:
description = metadata.get("description", "No description")
print(f" {i}. {component_name} - {description}")
-
+
# Get size estimate if component supports it
try:
- instance = registry.get_component_instance(component_name, install_dir)
- if instance and hasattr(instance, 'get_size_estimate'):
+ instance = registry.get_component_instance(
+ component_name, install_dir
+ )
+ if instance and hasattr(instance, "get_size_estimate"):
size = instance.get_size_estimate()
total_size += size
except Exception:
pass
else:
print(f" {i}. {component_name} - Unknown component")
-
+
if total_size > 0:
- print(f"\n{Colors.BLUE}Estimated size:{Colors.RESET} {format_size(total_size)}")
-
+ print(
+ f"\n{Colors.BLUE}Estimated size:{Colors.RESET} {format_size(total_size)}"
+ )
+
print()
-
+
except Exception as e:
logger.error(f"Could not resolve dependencies: {e}")
raise
@@ -400,101 +464,113 @@ def display_installation_plan(components: List[str], registry: ComponentRegistry
def run_system_diagnostics(validator: Validator) -> None:
"""Run comprehensive system diagnostics"""
logger = get_logger()
-
+
print(f"\n{Colors.CYAN}{Colors.BRIGHT}SuperClaude System Diagnostics{Colors.RESET}")
print("=" * 50)
-
+
# Run diagnostics
diagnostics = validator.diagnose_system()
-
+
# Display platform info
print(f"{Colors.BLUE}Platform:{Colors.RESET} {diagnostics['platform']}")
-
+
# Display check results
print(f"\n{Colors.BLUE}System Checks:{Colors.RESET}")
all_passed = True
-
- for check_name, check_info in diagnostics['checks'].items():
- status = check_info['status']
- message = check_info['message']
-
- if status == 'pass':
+
+ for check_name, check_info in diagnostics["checks"].items():
+ status = check_info["status"]
+ message = check_info["message"]
+
+ if status == "pass":
print(f" โ
{check_name}: {message}")
else:
print(f" โ {check_name}: {message}")
all_passed = False
-
+
# Display issues and recommendations
- if diagnostics['issues']:
+ if diagnostics["issues"]:
print(f"\n{Colors.YELLOW}Issues Found:{Colors.RESET}")
- for issue in diagnostics['issues']:
+ for issue in diagnostics["issues"]:
print(f" โ ๏ธ {issue}")
-
+
print(f"\n{Colors.CYAN}Recommendations:{Colors.RESET}")
- for recommendation in diagnostics['recommendations']:
+ for recommendation in diagnostics["recommendations"]:
print(recommendation)
-
+
# Summary
if all_passed:
- print(f"\n{Colors.GREEN}โ
All system checks passed! Your system is ready for SuperClaude.{Colors.RESET}")
+ print(
+ f"\n{Colors.GREEN}โ
All system checks passed! Your system is ready for superclaude.{Colors.RESET}"
+ )
else:
- print(f"\n{Colors.YELLOW}โ ๏ธ Some issues found. Please address the recommendations above.{Colors.RESET}")
-
+ print(
+ f"\n{Colors.YELLOW}โ ๏ธ Some issues found. Please address the recommendations above.{Colors.RESET}"
+ )
+
print(f"\n{Colors.BLUE}Next steps:{Colors.RESET}")
if all_passed:
- print(" 1. Run 'SuperClaude install' to proceed with installation")
- print(" 2. Choose your preferred installation mode (quick, minimal, or custom)")
+ print(" 1. Run 'superclaude install' to proceed with installation")
+ print(
+ " 2. Choose your preferred installation mode (quick, minimal, or custom)"
+ )
else:
print(" 1. Install missing dependencies using the commands above")
print(" 2. Restart your terminal after installing tools")
- print(" 3. Run 'SuperClaude install --diagnose' again to verify")
+ print(" 3. Run 'superclaude install --diagnose' again to verify")
-def perform_installation(components: List[str], args: argparse.Namespace, config_manager: ConfigService = None) -> bool:
+def perform_installation(
+ components: List[str],
+ args: argparse.Namespace,
+ config_manager: ConfigService = None,
+) -> bool:
"""Perform the actual installation"""
logger = get_logger()
start_time = time.time()
-
+
try:
# Create installer
installer = Installer(args.install_dir, dry_run=args.dry_run)
-
+
# Create component registry
registry = ComponentRegistry(PROJECT_ROOT / "setup" / "components")
registry.discover_components()
-
+
# Create component instances
- component_instances = registry.create_component_instances(components, args.install_dir)
-
+ component_instances = registry.create_component_instances(
+ components, args.install_dir
+ )
+
if not component_instances:
logger.error("No valid component instances created")
return False
-
+
# Register components with installer
installer.register_components(list(component_instances.values()))
-
+
# The 'components' list is already resolved, so we can use it directly.
ordered_components = components
-
+
# Setup progress tracking
progress = ProgressBar(
- total=len(ordered_components),
- prefix="Installing: ",
- suffix=""
+ total=len(ordered_components), prefix="Installing: ", suffix=""
)
-
+
# Install components
logger.info(f"Installing {len(ordered_components)} components...")
-
+
config = {
"force": args.force,
"backup": not args.no_backup,
"dry_run": args.dry_run,
- "selected_mcp_servers": getattr(config_manager, '_installation_context', {}).get("selected_mcp_servers", [])
+ "selected_mcp_servers": getattr(
+ config_manager, "_installation_context", {}
+ ).get("selected_mcp_servers", []),
}
-
+
success = installer.install_components(ordered_components, config)
-
+
# Update progress
for i, component_name in enumerate(ordered_components):
if component_name in installer.installed_components:
@@ -502,32 +578,36 @@ def perform_installation(components: List[str], args: argparse.Namespace, config
else:
progress.update(i + 1, f"Failed {component_name}")
time.sleep(0.1) # Brief pause for visual effect
-
+
progress.finish("Installation complete")
-
+
# Show results
duration = time.time() - start_time
-
+
if success:
- logger.success(f"Installation completed successfully in {duration:.1f} seconds")
-
+ logger.success(
+ f"Installation completed successfully in {duration:.1f} seconds"
+ )
+
# Show summary
summary = installer.get_installation_summary()
- if summary['installed']:
+ if summary["installed"]:
logger.info(f"Installed components: {', '.join(summary['installed'])}")
-
- if summary['backup_path']:
+
+ if summary["backup_path"]:
logger.info(f"Backup created: {summary['backup_path']}")
-
+
else:
- logger.error(f"Installation completed with errors in {duration:.1f} seconds")
-
+ logger.error(
+ f"Installation completed with errors in {duration:.1f} seconds"
+ )
+
summary = installer.get_installation_summary()
- if summary['failed']:
+ if summary["failed"]:
logger.error(f"Failed components: {', '.join(summary['failed'])}")
-
+
return success
-
+
except Exception as e:
logger.exception(f"Unexpected error during installation: {e}")
return False
@@ -547,18 +627,18 @@ def run(args: argparse.Namespace) -> int:
try:
# Verify the resolved path is still within user home
install_dir_resolved.relative_to(expected_home)
-
+
# Additional check: if there's a symlink in the path, verify it doesn't escape user home
if install_dir_original != install_dir_resolved:
# Path contains symlinks - verify each component stays within user home
current_path = expected_home
parts = install_dir_original.parts
home_parts = expected_home.parts
-
+
# Skip home directory parts
- if len(parts) >= len(home_parts) and parts[:len(home_parts)] == home_parts:
- relative_parts = parts[len(home_parts):]
-
+ if len(parts) >= len(home_parts) and parts[: len(home_parts)] == home_parts:
+ relative_parts = parts[len(home_parts) :]
+
for part in relative_parts:
current_path = current_path / part
if current_path.is_symlink():
@@ -575,7 +655,7 @@ def run(args: argparse.Namespace) -> int:
print(f"\n[x] Security validation failed: {e}")
print(f" Please use a standard directory path within your user profile.")
sys.exit(1)
-
+
try:
# Validate global arguments
success, errors = operation.validate_global_args(args)
@@ -583,20 +663,21 @@ def run(args: argparse.Namespace) -> int:
for error in errors:
logger.error(error)
return 1
-
+
# Display header
if not args.quiet:
from setup.cli.base import __version__
+
display_header(
f"SuperClaude Installation v{__version__}",
- "Installing SuperClaude framework components"
+ "Installing SuperClaude framework components",
)
-
+
# Handle special modes
if args.list_components:
registry = ComponentRegistry(PROJECT_ROOT / "setup" / "components")
registry.discover_components()
-
+
components = registry.list_components()
if components:
print(f"\n{Colors.CYAN}Available Components:{Colors.RESET}")
@@ -611,22 +692,22 @@ def run(args: argparse.Namespace) -> int:
else:
print("No components found")
return 0
-
+
# Handle diagnostic mode
if args.diagnose:
validator = Validator()
run_system_diagnostics(validator)
return 0
-
+
# Create component registry and load configuration
logger.info("Initializing installation system...")
-
+
registry = ComponentRegistry(PROJECT_ROOT / "setup" / "components")
registry.discover_components()
-
+
config_manager = ConfigService(DATA_DIR)
validator = Validator()
-
+
# Validate configuration
config_errors = config_manager.validate_config_files()
if config_errors:
@@ -634,9 +715,11 @@ def run(args: argparse.Namespace) -> int:
for error in config_errors:
logger.error(f" - {error}")
return 1
-
+
# Get components to install
- components_to_install = get_components_to_install(args, registry, config_manager)
+ components_to_install = get_components_to_install(
+ args, registry, config_manager
+ )
if not components_to_install:
logger.error("No components selected for installation")
return 1
@@ -647,50 +730,58 @@ def run(args: argparse.Namespace) -> int:
except ValueError as e:
logger.error(f"Dependency resolution error: {e}")
return 1
-
+
# Validate system requirements for all components
if not validate_system_requirements(validator, resolved_components):
if not args.force:
logger.error("System requirements not met. Use --force to override.")
return 1
else:
- logger.warning("System requirements not met, but continuing due to --force flag")
-
+ logger.warning(
+ "System requirements not met, but continuing due to --force flag"
+ )
+
# Check for existing installation
if args.install_dir.exists() and not args.force:
if not args.dry_run:
- logger.warning(f"Installation directory already exists: {args.install_dir}")
- if not args.yes and not confirm("Continue and update existing installation?", default=False):
+ logger.warning(
+ f"Installation directory already exists: {args.install_dir}"
+ )
+ if not args.yes and not confirm(
+ "Continue and update existing installation?", default=False
+ ):
logger.info("Installation cancelled by user")
return 0
-
+
# Display installation plan
if not args.quiet:
display_installation_plan(resolved_components, registry, args.install_dir)
-
+
if not args.dry_run:
- if not args.yes and not confirm("Proceed with installation?", default=True):
+ if not args.yes and not confirm(
+ "Proceed with installation?", default=True
+ ):
logger.info("Installation cancelled by user")
return 0
-
+
# Perform installation
success = perform_installation(resolved_components, args, config_manager)
-
+
if success:
if not args.quiet:
display_success("SuperClaude installation completed successfully!")
-
+
if not args.dry_run:
print(f"\n{Colors.CYAN}Next steps:{Colors.RESET}")
print(f"1. Restart your Claude Code session")
print(f"2. Framework files are now available in {args.install_dir}")
print(f"3. Use SuperClaude commands and features in Claude Code")
-
+
return 0
else:
display_error("Installation failed. Check logs for details.")
return 1
-
+
except KeyboardInterrupt:
print(f"\n{Colors.YELLOW}Installation cancelled by user{Colors.RESET}")
return 130
diff --git a/setup/cli/commands/uninstall.py b/setup/cli/commands/uninstall.py
index 84d760a..fa7d18f 100644
--- a/setup/cli/commands/uninstall.py
+++ b/setup/cli/commands/uninstall.py
@@ -14,10 +14,20 @@ from ...core.registry import ComponentRegistry
from ...services.settings import SettingsService
from ...services.files import FileService
from ...utils.ui import (
- display_header, display_info, display_success, display_error,
- display_warning, Menu, confirm, ProgressBar, Colors
+ display_header,
+ display_info,
+ display_success,
+ display_error,
+ display_warning,
+ Menu,
+ confirm,
+ ProgressBar,
+ Colors,
+)
+from ...utils.environment import (
+ get_superclaude_environment_variables,
+ cleanup_environment_variables,
)
-from ...utils.environment import get_superclaude_environment_variables, cleanup_environment_variables
from ...utils.logger import get_logger
from ... import DEFAULT_INSTALL_DIR, PROJECT_ROOT
from . import OperationBase
@@ -26,57 +36,75 @@ from . import OperationBase
def verify_superclaude_file(file_path: Path, component: str) -> bool:
"""
Verify this is a SuperClaude file before removal
-
+
Args:
file_path: Path to the file to verify
component: Component name this file belongs to
-
+
Returns:
True if safe to remove, False if uncertain (preserve by default)
"""
try:
# Known SuperClaude file patterns by component
superclaude_patterns = {
- 'core': [
- 'CLAUDE.md', 'FLAGS.md', 'PRINCIPLES.md', 'RULES.md',
- 'ORCHESTRATOR.md', 'SESSION_LIFECYCLE.md'
+ "core": [
+ "CLAUDE.md",
+ "FLAGS.md",
+ "PRINCIPLES.md",
+ "RULES.md",
+ "ORCHESTRATOR.md",
+ "SESSION_LIFECYCLE.md",
],
- 'commands': [
+ "commands": [
# Commands are only in sc/ subdirectory
],
- 'agents': [
- 'backend-engineer.md', 'brainstorm-PRD.md', 'code-educator.md',
- 'code-refactorer.md', 'devops-engineer.md', 'frontend-specialist.md',
- 'performance-optimizer.md', 'python-ultimate-expert.md', 'qa-specialist.md',
- 'root-cause-analyzer.md', 'security-auditor.md', 'system-architect.md',
- 'technical-writer.md'
+ "agents": [
+ "backend-engineer.md",
+ "brainstorm-PRD.md",
+ "code-educator.md",
+ "code-refactorer.md",
+ "devops-engineer.md",
+ "frontend-specialist.md",
+ "performance-optimizer.md",
+ "python-ultimate-expert.md",
+ "qa-specialist.md",
+ "root-cause-analyzer.md",
+ "security-auditor.md",
+ "system-architect.md",
+ "technical-writer.md",
],
- 'modes': [
- 'MODE_Brainstorming.md', 'MODE_Introspection.md',
- 'MODE_Task_Management.md', 'MODE_Token_Efficiency.md'
+ "modes": [
+ "MODE_Brainstorming.md",
+ "MODE_Introspection.md",
+ "MODE_Task_Management.md",
+ "MODE_Token_Efficiency.md",
+ ],
+ "mcp_docs": [
+ "MCP_Context7.md",
+ "MCP_Sequential.md",
+ "MCP_Magic.md",
+ "MCP_Playwright.md",
+ "MCP_Morphllm.md",
+ "MCP_Serena.md",
],
- 'mcp_docs': [
- 'MCP_Context7.md', 'MCP_Sequential.md', 'MCP_Magic.md',
- 'MCP_Playwright.md', 'MCP_Morphllm.md', 'MCP_Serena.md'
- ]
}
-
+
# For commands component, verify it's in the sc/ subdirectory
- if component == 'commands':
- return 'commands/sc/' in str(file_path)
-
+ if component == "commands":
+ return "commands/sc/" in str(file_path)
+
# For other components, check against known file lists
if component in superclaude_patterns:
filename = file_path.name
return filename in superclaude_patterns[component]
-
+
# For MCP component, it doesn't remove files but modifies .claude.json
- if component == 'mcp':
+ if component == "mcp":
return True # MCP component has its own safety logic
-
+
# Default to preserve if uncertain
return False
-
+
except Exception:
# If any error occurs in verification, preserve the file
return False
@@ -85,23 +113,23 @@ def verify_superclaude_file(file_path: Path, component: str) -> bool:
def verify_directory_safety(directory: Path, component: str) -> bool:
"""
Verify it's safe to remove a directory
-
+
Args:
directory: Directory path to verify
component: Component name
-
+
Returns:
True if safe to remove (only if empty or only contains SuperClaude files)
"""
try:
if not directory.exists():
return True
-
+
# Check if directory is empty
contents = list(directory.iterdir())
if not contents:
return True
-
+
# Check if all contents are SuperClaude files for this component
for item in contents:
if item.is_file():
@@ -110,9 +138,9 @@ def verify_directory_safety(directory: Path, component: str) -> bool:
elif item.is_dir():
# Don't remove directories that contain non-SuperClaude subdirectories
return False
-
+
return True
-
+
except Exception:
# If any error occurs, preserve the directory
return False
@@ -120,7 +148,7 @@ def verify_directory_safety(directory: Path, component: str) -> bool:
class UninstallOperation(OperationBase):
"""Uninstall operation implementation"""
-
+
def __init__(self):
super().__init__("uninstall")
@@ -128,7 +156,7 @@ class UninstallOperation(OperationBase):
def register_parser(subparsers, global_parser=None) -> argparse.ArgumentParser:
"""Register uninstall CLI arguments"""
parents = [global_parser] if global_parser else []
-
+
parser = subparsers.add_parser(
"uninstall",
help="Remove SuperClaude framework installation",
@@ -141,64 +169,58 @@ Examples:
SuperClaude uninstall --keep-backups # Keep backup files
""",
formatter_class=argparse.RawDescriptionHelpFormatter,
- parents=parents
+ parents=parents,
)
-
+
# Uninstall mode options
parser.add_argument(
- "--components",
- type=str,
- nargs="+",
- help="Specific components to uninstall"
+ "--components", type=str, nargs="+", help="Specific components to uninstall"
)
-
+
parser.add_argument(
"--complete",
action="store_true",
- help="Complete uninstall (remove all files and directories)"
+ help="Complete uninstall (remove all files and directories)",
)
-
+
# Data preservation options
parser.add_argument(
- "--keep-backups",
- action="store_true",
- help="Keep backup files during uninstall"
+ "--keep-backups", action="store_true", help="Keep backup files during uninstall"
)
-
+
parser.add_argument(
- "--keep-logs",
- action="store_true",
- help="Keep log files during uninstall"
+ "--keep-logs", action="store_true", help="Keep log files during uninstall"
)
-
+
parser.add_argument(
"--keep-settings",
action="store_true",
- help="Keep user settings during uninstall"
+ help="Keep user settings during uninstall",
)
-
+
# Safety options
parser.add_argument(
"--no-confirm",
action="store_true",
- help="Skip confirmation prompts (use with caution)"
+ help="Skip confirmation prompts (use with caution)",
)
-
+
# Environment cleanup options
parser.add_argument(
"--cleanup-env",
action="store_true",
- help="Remove SuperClaude environment variables"
+ help="Remove SuperClaude environment variables",
)
-
+
parser.add_argument(
"--no-restore-script",
action="store_true",
- help="Skip creating environment variable restore script"
+ help="Skip creating environment variable restore script",
)
-
+
return parser
+
def get_installed_components(install_dir: Path) -> Dict[str, Dict[str, Any]]:
"""Get currently installed components and their versions"""
try:
@@ -216,15 +238,15 @@ def get_installation_info(install_dir: Path) -> Dict[str, Any]:
"components": {},
"directories": [],
"files": [],
- "total_size": 0
+ "total_size": 0,
}
-
+
if not install_dir.exists():
return info
-
+
info["exists"] = True
info["components"] = get_installed_components(install_dir)
-
+
# Scan installation directory
try:
for item in install_dir.rglob("*"):
@@ -235,27 +257,33 @@ def get_installation_info(install_dir: Path) -> Dict[str, Any]:
info["directories"].append(item)
except Exception:
pass
-
+
return info
def display_environment_info() -> Dict[str, str]:
"""Display SuperClaude environment variables and return them"""
env_vars = get_superclaude_environment_variables()
-
+
if env_vars:
print(f"\n{Colors.CYAN}{Colors.BRIGHT}Environment Variables{Colors.RESET}")
print("=" * 50)
- print(f"{Colors.BLUE}SuperClaude API key environment variables found:{Colors.RESET}")
+ print(
+ f"{Colors.BLUE}SuperClaude API key environment variables found:{Colors.RESET}"
+ )
for env_var, value in env_vars.items():
# Show only first few and last few characters for security
masked_value = f"{value[:4]}...{value[-4:]}" if len(value) > 8 else "***"
print(f" {env_var}: {masked_value}")
-
- print(f"\n{Colors.YELLOW}Note: These environment variables will remain unless you use --cleanup-env{Colors.RESET}")
+
+ print(
+ f"\n{Colors.YELLOW}Note: These environment variables will remain unless you use --cleanup-env{Colors.RESET}"
+ )
else:
- print(f"\n{Colors.GREEN}No SuperClaude environment variables found{Colors.RESET}")
-
+ print(
+ f"\n{Colors.GREEN}No SuperClaude environment variables found{Colors.RESET}"
+ )
+
return env_vars
@@ -263,73 +291,82 @@ def display_uninstall_info(info: Dict[str, Any]) -> None:
"""Display installation information before uninstall"""
print(f"\n{Colors.CYAN}{Colors.BRIGHT}Current Installation{Colors.RESET}")
print("=" * 50)
-
+
if not info["exists"]:
print(f"{Colors.YELLOW}No SuperClaude installation found{Colors.RESET}")
return
-
+
print(f"{Colors.BLUE}Installation Directory:{Colors.RESET} {info['install_dir']}")
-
+
if info["components"]:
print(f"{Colors.BLUE}Installed Components:{Colors.RESET}")
for component, version in info["components"].items():
print(f" {component}: v{version}")
-
+
print(f"{Colors.BLUE}Files:{Colors.RESET} {len(info['files'])}")
print(f"{Colors.BLUE}Directories:{Colors.RESET} {len(info['directories'])}")
-
+
if info["total_size"] > 0:
from ...utils.ui import format_size
- print(f"{Colors.BLUE}Total Size:{Colors.RESET} {format_size(info['total_size'])}")
-
+
+ print(
+ f"{Colors.BLUE}Total Size:{Colors.RESET} {format_size(info['total_size'])}"
+ )
+
print()
-def get_components_to_uninstall(args: argparse.Namespace, installed_components: Dict[str, str]) -> Optional[List[str]]:
+def get_components_to_uninstall(
+ args: argparse.Namespace, installed_components: Dict[str, str]
+) -> Optional[List[str]]:
"""Determine which components to uninstall"""
logger = get_logger()
-
+
# Complete uninstall
if args.complete:
return list(installed_components.keys())
-
+
# Explicit components specified
if args.components:
# Validate that specified components are installed
- invalid_components = [c for c in args.components if c not in installed_components]
+ invalid_components = [
+ c for c in args.components if c not in installed_components
+ ]
if invalid_components:
logger.error(f"Components not installed: {invalid_components}")
return None
return args.components
-
+
# Interactive selection
return interactive_uninstall_selection(installed_components)
-def interactive_component_selection(installed_components: Dict[str, str], env_vars: Dict[str, str]) -> Optional[tuple]:
+def interactive_component_selection(
+ installed_components: Dict[str, str], env_vars: Dict[str, str]
+) -> Optional[tuple]:
"""
Enhanced interactive selection with granular component options
-
+
Returns:
Tuple of (components_to_remove, cleanup_options) or None if cancelled
"""
if not installed_components:
return []
-
+
print(f"\n{Colors.CYAN}{Colors.BRIGHT}SuperClaude Uninstall Options{Colors.RESET}")
print("=" * 60)
-
+
# Main uninstall type selection
main_options = [
"Complete Uninstall (remove all SuperClaude components)",
"Custom Uninstall (choose specific components)",
- "Cancel Uninstall"
+ "Cancel Uninstall",
]
-
+
print(f"\n{Colors.BLUE}Choose uninstall type:{Colors.RESET}")
main_menu = Menu("Select option:", main_options)
main_choice = main_menu.display()
-
+
if main_choice == -1 or main_choice == 2: # Cancelled
return None
elif main_choice == 0: # Complete uninstall
@@ -338,86 +375,98 @@ def interactive_component_selection(installed_components: Dict[str, str], env_va
return list(installed_components.keys()), cleanup_options
elif main_choice == 1: # Custom uninstall
return _custom_component_selection(installed_components, env_vars)
-
+
return None
def _ask_complete_uninstall_options(env_vars: Dict[str, str]) -> Dict[str, bool]:
"""Ask for complete uninstall options"""
cleanup_options = {
- 'remove_mcp_configs': True,
- 'cleanup_env_vars': False,
- 'create_restore_script': True
+ "remove_mcp_configs": True,
+ "cleanup_env_vars": False,
+ "create_restore_script": True,
}
-
+
print(f"\n{Colors.YELLOW}{Colors.BRIGHT}Complete Uninstall Options{Colors.RESET}")
print("This will remove ALL SuperClaude components.")
-
+
if env_vars:
print(f"\n{Colors.BLUE}Environment variables found:{Colors.RESET}")
for env_var, value in env_vars.items():
masked_value = f"{value[:4]}...{value[-4:]}" if len(value) > 8 else "***"
print(f" {env_var}: {masked_value}")
-
- cleanup_env = confirm("Also remove API key environment variables?", default=False)
- cleanup_options['cleanup_env_vars'] = cleanup_env
-
+
+ cleanup_env = confirm(
+ "Also remove API key environment variables?", default=False
+ )
+ cleanup_options["cleanup_env_vars"] = cleanup_env
+
if cleanup_env:
- create_script = confirm("Create restore script for environment variables?", default=True)
- cleanup_options['create_restore_script'] = create_script
-
+ create_script = confirm(
+ "Create restore script for environment variables?", default=True
+ )
+ cleanup_options["create_restore_script"] = create_script
+
return cleanup_options
-def _custom_component_selection(installed_components: Dict[str, str], env_vars: Dict[str, str]) -> Optional[tuple]:
+def _custom_component_selection(
+ installed_components: Dict[str, str], env_vars: Dict[str, str]
+) -> Optional[tuple]:
"""Handle custom component selection with granular options"""
- print(f"\n{Colors.CYAN}{Colors.BRIGHT}Custom Uninstall - Choose Components{Colors.RESET}")
+ print(
+ f"\n{Colors.CYAN}{Colors.BRIGHT}Custom Uninstall - Choose Components{Colors.RESET}"
+ )
print("Select which SuperClaude components to remove:")
-
+
# Build component options with descriptions
component_options = []
component_keys = []
-
+
component_descriptions = {
- 'core': 'Core Framework Files (CLAUDE.md, FLAGS.md, PRINCIPLES.md, etc.)',
- 'commands': 'SuperClaude Commands (commands/sc/*.md)',
- 'agents': 'Specialized Agents (agents/*.md)',
- 'mcp': 'MCP Server Configurations',
- 'mcp_docs': 'MCP Documentation',
- 'modes': 'SuperClaude Modes'
+ "core": "Core Framework Files (CLAUDE.md, FLAGS.md, PRINCIPLES.md, etc.)",
+ "commands": "superclaude Commands (commands/sc/*.md)",
+ "agents": "Specialized Agents (agents/*.md)",
+ "mcp": "MCP Server Configurations",
+ "mcp_docs": "MCP Documentation",
+ "modes": "superclaude Modes",
}
-
+
for component, version in installed_components.items():
description = component_descriptions.get(component, f"{component} component")
component_options.append(f"{description}")
component_keys.append(component)
-
+
print(f"\n{Colors.BLUE}Select components to remove:{Colors.RESET}")
component_menu = Menu("Components:", component_options, multi_select=True)
selections = component_menu.display()
-
+
if not selections:
return None
-
+
selected_components = [component_keys[i] for i in selections]
-
+
# If MCP component is selected, ask about related cleanup options
cleanup_options = {
- 'remove_mcp_configs': 'mcp' in selected_components,
- 'cleanup_env_vars': False,
- 'create_restore_script': True
+ "remove_mcp_configs": "mcp" in selected_components,
+ "cleanup_env_vars": False,
+ "create_restore_script": True,
}
-
- if 'mcp' in selected_components:
+
+ if "mcp" in selected_components:
cleanup_options.update(_ask_mcp_cleanup_options(env_vars))
elif env_vars:
# Even if MCP not selected, ask about env vars if they exist
- cleanup_env = confirm(f"Remove {len(env_vars)} API key environment variables?", default=False)
- cleanup_options['cleanup_env_vars'] = cleanup_env
+ cleanup_env = confirm(
+ f"Remove {len(env_vars)} API key environment variables?", default=False
+ )
+ cleanup_options["cleanup_env_vars"] = cleanup_env
if cleanup_env:
- create_script = confirm("Create restore script for environment variables?", default=True)
- cleanup_options['create_restore_script'] = create_script
-
+ create_script = confirm(
+ "Create restore script for environment variables?", default=True
+ )
+ cleanup_options["create_restore_script"] = create_script
+
return selected_components, cleanup_options
@@ -425,43 +474,53 @@ def _ask_mcp_cleanup_options(env_vars: Dict[str, str]) -> Dict[str, bool]:
"""Ask for MCP-related cleanup options"""
print(f"\n{Colors.YELLOW}{Colors.BRIGHT}MCP Cleanup Options{Colors.RESET}")
print("Since you're removing the MCP component:")
-
+
cleanup_options = {}
-
+
# Ask about MCP server configurations
- remove_configs = confirm("Remove MCP server configurations from .claude.json?", default=True)
- cleanup_options['remove_mcp_configs'] = remove_configs
-
+ remove_configs = confirm(
+ "Remove MCP server configurations from .claude.json?", default=True
+ )
+ cleanup_options["remove_mcp_configs"] = remove_configs
+
# Ask about API key environment variables
if env_vars:
- print(f"\n{Colors.BLUE}Related API key environment variables found:{Colors.RESET}")
+ print(
+ f"\n{Colors.BLUE}Related API key environment variables found:{Colors.RESET}"
+ )
for env_var, value in env_vars.items():
masked_value = f"{value[:4]}...{value[-4:]}" if len(value) > 8 else "***"
print(f" {env_var}: {masked_value}")
-
- cleanup_env = confirm(f"Remove {len(env_vars)} API key environment variables?", default=False)
- cleanup_options['cleanup_env_vars'] = cleanup_env
-
+
+ cleanup_env = confirm(
+ f"Remove {len(env_vars)} API key environment variables?", default=False
+ )
+ cleanup_options["cleanup_env_vars"] = cleanup_env
+
if cleanup_env:
- create_script = confirm("Create restore script for environment variables?", default=True)
- cleanup_options['create_restore_script'] = create_script
+ create_script = confirm(
+ "Create restore script for environment variables?", default=True
+ )
+ cleanup_options["create_restore_script"] = create_script
else:
- cleanup_options['create_restore_script'] = True
+ cleanup_options["create_restore_script"] = True
else:
- cleanup_options['cleanup_env_vars'] = False
- cleanup_options['create_restore_script'] = True
-
+ cleanup_options["cleanup_env_vars"] = False
+ cleanup_options["create_restore_script"] = True
+
return cleanup_options
-def interactive_uninstall_selection(installed_components: Dict[str, str]) -> Optional[List[str]]:
+def interactive_uninstall_selection(
+ installed_components: Dict[str, str],
+) -> Optional[List[str]]:
"""Legacy function - redirects to enhanced selection"""
env_vars = get_superclaude_environment_variables()
result = interactive_component_selection(installed_components, env_vars)
-
+
if result is None:
return None
-
+
# For backwards compatibility, return only component list
components, cleanup_options = result
return components
@@ -471,103 +530,124 @@ def display_preservation_info() -> None:
"""Show what will NOT be removed (user's custom files)"""
print(f"\n{Colors.GREEN}{Colors.BRIGHT}Files that will be preserved:{Colors.RESET}")
print(f"{Colors.GREEN}+ User's custom commands (not in commands/sc/){Colors.RESET}")
- print(f"{Colors.GREEN}+ User's custom agents (not SuperClaude agents){Colors.RESET}")
+ print(
+ f"{Colors.GREEN}+ User's custom agents (not SuperClaude agents){Colors.RESET}"
+ )
print(f"{Colors.GREEN}+ User's custom .claude.json configurations{Colors.RESET}")
print(f"{Colors.GREEN}+ User's custom files in shared directories{Colors.RESET}")
- print(f"{Colors.GREEN}+ Claude Code settings and other tools' configurations{Colors.RESET}")
+ print(
+ f"{Colors.GREEN}+ Claude Code settings and other tools' configurations{Colors.RESET}"
+ )
def display_component_details(component: str, info: Dict[str, Any]) -> Dict[str, Any]:
"""Get detailed information about what will be removed for a component"""
- details = {
- 'files': [],
- 'directories': [],
- 'size': 0,
- 'description': ''
- }
-
- install_dir = info['install_dir']
-
+ details = {"files": [], "directories": [], "size": 0, "description": ""}
+
+ install_dir = info["install_dir"]
+
component_paths = {
- 'core': {
- 'files': ['CLAUDE.md', 'FLAGS.md', 'PRINCIPLES.md', 'RULES.md', 'ORCHESTRATOR.md', 'SESSION_LIFECYCLE.md'],
- 'description': 'Core framework files in ~/.claude/'
+ "core": {
+ "files": [
+ "CLAUDE.md",
+ "FLAGS.md",
+ "PRINCIPLES.md",
+ "RULES.md",
+ "ORCHESTRATOR.md",
+ "SESSION_LIFECYCLE.md",
+ ],
+ "description": "Core framework files in ~/.claude/",
},
- 'commands': {
- 'files': 'commands/sc/*.md',
- 'description': 'SuperClaude commands in ~/.claude/commands/sc/'
+ "commands": {
+ "files": "commands/sc/*.md",
+ "description": "superclaude commands in ~/.claude/commands/sc/",
},
- 'agents': {
- 'files': 'agents/*.md',
- 'description': 'Specialized AI agents in ~/.claude/agents/'
+ "agents": {
+ "files": "agents/*.md",
+ "description": "Specialized AI agents in ~/.claude/agents/",
},
- 'mcp': {
- 'files': 'MCP server configurations in .claude.json',
- 'description': 'MCP server configurations'
+ "mcp": {
+ "files": "MCP server configurations in .claude.json",
+ "description": "MCP server configurations",
},
- 'mcp_docs': {
- 'files': 'MCP/*.md',
- 'description': 'MCP documentation files'
- },
- 'modes': {
- 'files': 'MODE_*.md',
- 'description': 'SuperClaude operational modes'
- }
+ "mcp_docs": {"files": "MCP/*.md", "description": "MCP documentation files"},
+ "modes": {"files": "MODE_*.md", "description": "superclaude operational modes"},
}
-
+
if component in component_paths:
- details['description'] = component_paths[component]['description']
-
+ details["description"] = component_paths[component]["description"]
+
# Get actual file count from metadata if available
component_metadata = info["components"].get(component, {})
if isinstance(component_metadata, dict):
- if 'files_count' in component_metadata:
- details['file_count'] = component_metadata['files_count']
- elif 'agents_count' in component_metadata:
- details['file_count'] = component_metadata['agents_count']
- elif 'servers_configured' in component_metadata:
- details['file_count'] = component_metadata['servers_configured']
-
+ if "files_count" in component_metadata:
+ details["file_count"] = component_metadata["files_count"]
+ elif "agents_count" in component_metadata:
+ details["file_count"] = component_metadata["agents_count"]
+ elif "servers_configured" in component_metadata:
+ details["file_count"] = component_metadata["servers_configured"]
+
return details
-def display_uninstall_plan(components: List[str], args: argparse.Namespace, info: Dict[str, Any], env_vars: Dict[str, str]) -> None:
+def display_uninstall_plan(
+ components: List[str],
+ args: argparse.Namespace,
+ info: Dict[str, Any],
+ env_vars: Dict[str, str],
+) -> None:
"""Display detailed uninstall plan"""
print(f"\n{Colors.CYAN}{Colors.BRIGHT}Uninstall Plan{Colors.RESET}")
print("=" * 60)
-
+
print(f"{Colors.BLUE}Installation Directory:{Colors.RESET} {info['install_dir']}")
-
+
if components:
print(f"\n{Colors.BLUE}Components to remove:{Colors.RESET}")
total_files = 0
-
+
for i, component_name in enumerate(components, 1):
details = display_component_details(component_name, info)
version = info["components"].get(component_name, "unknown")
-
+
if isinstance(version, dict):
- version_str = version.get('version', 'unknown')
- file_count = details.get('file_count', version.get('files_count', version.get('agents_count', version.get('servers_configured', '?'))))
+ version_str = version.get("version", "unknown")
+ file_count = details.get(
+ "file_count",
+ version.get(
+ "files_count",
+ version.get(
+ "agents_count", version.get("servers_configured", "?")
+ ),
+ ),
+ )
else:
version_str = str(version)
- file_count = details.get('file_count', '?')
-
+ file_count = details.get("file_count", "?")
+
print(f" {i}. {component_name} (v{version_str}) - {file_count} files")
print(f" {details['description']}")
-
+
if isinstance(file_count, int):
total_files += file_count
-
- print(f"\n{Colors.YELLOW}Total estimated files to remove: {total_files}{Colors.RESET}")
-
+
+ print(
+ f"\n{Colors.YELLOW}Total estimated files to remove: {total_files}{Colors.RESET}"
+ )
+
# Show detailed preservation information
- print(f"\n{Colors.GREEN}{Colors.BRIGHT}Safety Guarantees - Will Preserve:{Colors.RESET}")
+ print(
+ f"\n{Colors.GREEN}{Colors.BRIGHT}Safety Guarantees - Will Preserve:{Colors.RESET}"
+ )
print(f"{Colors.GREEN}+ User's custom commands (not in commands/sc/){Colors.RESET}")
- print(f"{Colors.GREEN}+ User's custom agents (not SuperClaude agents){Colors.RESET}")
+ print(
+ f"{Colors.GREEN}+ User's custom agents (not SuperClaude agents){Colors.RESET}"
+ )
print(f"{Colors.GREEN}+ User's .claude.json customizations{Colors.RESET}")
- print(f"{Colors.GREEN}+ Claude Code settings and other tools' configurations{Colors.RESET}")
-
+ print(
+ f"{Colors.GREEN}+ Claude Code settings and other tools' configurations{Colors.RESET}"
+ )
+
# Show additional preserved items
preserved = []
if args.keep_backups:
@@ -576,92 +656,104 @@ def display_uninstall_plan(components: List[str], args: argparse.Namespace, info
preserved.append("log files")
if args.keep_settings:
preserved.append("user settings")
-
+
if preserved:
for item in preserved:
print(f"{Colors.GREEN}+ {item}{Colors.RESET}")
-
+
if args.complete:
- print(f"\n{Colors.RED}โ ๏ธ WARNING: Complete uninstall will remove all SuperClaude files{Colors.RESET}")
-
+ print(
+ f"\n{Colors.RED}โ ๏ธ WARNING: Complete uninstall will remove all SuperClaude files{Colors.RESET}"
+ )
+
# Environment variable cleanup information
if env_vars:
print(f"\n{Colors.BLUE}Environment Variables:{Colors.RESET}")
if args.cleanup_env:
- print(f"{Colors.YELLOW}Will remove {len(env_vars)} API key environment variables:{Colors.RESET}")
+ print(
+ f"{Colors.YELLOW}Will remove {len(env_vars)} API key environment variables:{Colors.RESET}"
+ )
for env_var in env_vars.keys():
print(f" - {env_var}")
if not args.no_restore_script:
print(f"{Colors.GREEN} + Restore script will be created{Colors.RESET}")
else:
- print(f"{Colors.BLUE}Will preserve {len(env_vars)} API key environment variables:{Colors.RESET}")
+ print(
+ f"{Colors.BLUE}Will preserve {len(env_vars)} API key environment variables:{Colors.RESET}"
+ )
for env_var in env_vars.keys():
print(f" + {env_var}")
-
+
print()
def create_uninstall_backup(install_dir: Path, components: List[str]) -> Optional[Path]:
"""Create backup before uninstall"""
logger = get_logger()
-
+
try:
from datetime import datetime
+
backup_dir = install_dir / "backups"
backup_dir.mkdir(exist_ok=True)
-
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_name = f"pre_uninstall_{timestamp}.tar.gz"
backup_path = backup_dir / backup_name
-
+
import tarfile
-
+
logger.info(f"Creating uninstall backup: {backup_path}")
-
+
with tarfile.open(backup_path, "w:gz") as tar:
for component in components:
# Add component files to backup
settings_manager = SettingsService(install_dir)
# This would need component-specific backup logic
pass
-
+
logger.success(f"Backup created: {backup_path}")
return backup_path
-
+
except Exception as e:
logger.warning(f"Could not create backup: {e}")
return None
-def perform_uninstall(components: List[str], args: argparse.Namespace, info: Dict[str, Any], env_vars: Dict[str, str]) -> bool:
+def perform_uninstall(
+ components: List[str],
+ args: argparse.Namespace,
+ info: Dict[str, Any],
+ env_vars: Dict[str, str],
+) -> bool:
"""Perform the actual uninstall"""
logger = get_logger()
start_time = time.time()
-
+
try:
# Create component registry
registry = ComponentRegistry(PROJECT_ROOT / "setup" / "components")
registry.discover_components()
-
+
# Create component instances
- component_instances = registry.create_component_instances(components, args.install_dir)
-
+ component_instances = registry.create_component_instances(
+ components, args.install_dir
+ )
+
# Setup progress tracking
progress = ProgressBar(
- total=len(components),
- prefix="Uninstalling: ",
- suffix=""
+ total=len(components), prefix="Uninstalling: ", suffix=""
)
-
+
# Uninstall components
logger.info(f"Uninstalling {len(components)} components...")
-
+
uninstalled_components = []
failed_components = []
-
+
for i, component_name in enumerate(components):
progress.update(i, f"Uninstalling {component_name}")
-
+
try:
if component_name in component_instances:
instance = component_instances[component_name]
@@ -673,46 +765,52 @@ def perform_uninstall(components: List[str], args: argparse.Namespace, info: Dic
logger.error(f"Failed to uninstall {component_name}")
else:
logger.warning(f"Component {component_name} not found, skipping")
-
+
except Exception as e:
logger.error(f"Error uninstalling {component_name}: {e}")
failed_components.append(component_name)
-
+
progress.update(i + 1, f"Processed {component_name}")
time.sleep(0.1) # Brief pause for visual effect
-
+
progress.finish("Uninstall complete")
-
+
# Handle complete uninstall cleanup
if args.complete:
cleanup_installation_directory(args.install_dir, args)
-
+
# Handle environment variable cleanup
env_cleanup_success = True
if args.cleanup_env and env_vars:
logger.info("Cleaning up environment variables...")
create_restore_script = not args.no_restore_script
- env_cleanup_success = cleanup_environment_variables(env_vars, create_restore_script)
-
+ env_cleanup_success = cleanup_environment_variables(
+ env_vars, create_restore_script
+ )
+
if env_cleanup_success:
logger.success(f"Removed {len(env_vars)} environment variables")
else:
logger.warning("Some environment variables could not be removed")
-
+
# Show results
duration = time.time() - start_time
-
+
if failed_components:
- logger.warning(f"Uninstall completed with some failures in {duration:.1f} seconds")
+ logger.warning(
+ f"Uninstall completed with some failures in {duration:.1f} seconds"
+ )
logger.warning(f"Failed components: {', '.join(failed_components)}")
else:
- logger.success(f"Uninstall completed successfully in {duration:.1f} seconds")
-
+ logger.success(
+ f"Uninstall completed successfully in {duration:.1f} seconds"
+ )
+
if uninstalled_components:
logger.info(f"Uninstalled components: {', '.join(uninstalled_components)}")
-
+
return len(failed_components) == 0
-
+
except Exception as e:
logger.exception(f"Unexpected error during uninstall: {e}")
return False
@@ -722,41 +820,43 @@ def cleanup_installation_directory(install_dir: Path, args: argparse.Namespace)
"""Clean up installation directory for complete uninstall"""
logger = get_logger()
file_manager = FileService()
-
+
try:
# Preserve specific directories/files if requested
preserve_patterns = []
-
+
if args.keep_backups:
preserve_patterns.append("backups/*")
if args.keep_logs:
preserve_patterns.append("logs/*")
if args.keep_settings and not args.complete:
preserve_patterns.append("settings.json")
-
+
# Remove installation directory contents
if args.complete and not preserve_patterns:
# Complete removal
if file_manager.remove_directory(install_dir):
logger.info(f"Removed installation directory: {install_dir}")
else:
- logger.warning(f"Could not remove installation directory: {install_dir}")
+ logger.warning(
+ f"Could not remove installation directory: {install_dir}"
+ )
else:
# Selective removal
for item in install_dir.iterdir():
should_preserve = False
-
+
for pattern in preserve_patterns:
if item.match(pattern):
should_preserve = True
break
-
+
if not should_preserve:
if item.is_file():
file_manager.remove_file(item)
elif item.is_dir():
file_manager.remove_directory(item)
-
+
except Exception as e:
logger.error(f"Error during cleanup: {e}")
@@ -775,7 +875,7 @@ def run(args: argparse.Namespace) -> int:
print(f" Expected prefix: {expected_home}")
print(f" Provided path: {actual_dir}")
sys.exit(1)
-
+
try:
# Validate global arguments
success, errors = operation.validate_global_args(args)
@@ -783,38 +883,43 @@ def run(args: argparse.Namespace) -> int:
for error in errors:
logger.error(error)
return 1
-
+
# Display header
if not args.quiet:
from setup.cli.base import __version__
+
display_header(
f"SuperClaude Uninstall v{__version__}",
- "Removing SuperClaude framework components"
+ "Removing SuperClaude framework components",
)
-
+
# Get installation information
info = get_installation_info(args.install_dir)
-
+
# Display current installation
if not args.quiet:
display_uninstall_info(info)
-
+
# Check for environment variables
- env_vars = display_environment_info() if not args.quiet else get_superclaude_environment_variables()
-
+ env_vars = (
+ display_environment_info()
+ if not args.quiet
+ else get_superclaude_environment_variables()
+ )
+
# Check if SuperClaude is installed
if not info["exists"]:
logger.warning(f"No SuperClaude installation found in {args.install_dir}")
return 0
-
+
# Get components to uninstall using enhanced selection
if args.components or args.complete:
# Non-interactive mode - use existing logic
components = get_components_to_uninstall(args, info["components"])
cleanup_options = {
- 'remove_mcp_configs': 'mcp' in (components or []),
- 'cleanup_env_vars': args.cleanup_env,
- 'create_restore_script': not args.no_restore_script
+ "remove_mcp_configs": "mcp" in (components or []),
+ "cleanup_env_vars": args.cleanup_env,
+ "create_restore_script": not args.no_restore_script,
}
if components is None:
logger.info("Uninstall cancelled by user")
@@ -831,50 +936,56 @@ def run(args: argparse.Namespace) -> int:
elif not result:
logger.info("No components selected for uninstall")
return 0
-
+
components, cleanup_options = result
-
+
# Override command-line args with interactive choices
- args.cleanup_env = cleanup_options.get('cleanup_env_vars', False)
- args.no_restore_script = not cleanup_options.get('create_restore_script', True)
-
+ args.cleanup_env = cleanup_options.get("cleanup_env_vars", False)
+ args.no_restore_script = not cleanup_options.get(
+ "create_restore_script", True
+ )
+
# Display uninstall plan
if not args.quiet:
display_uninstall_plan(components, args, info, env_vars)
-
+
# Confirmation
if not args.no_confirm and not args.yes:
if args.complete:
- warning_msg = "This will completely remove SuperClaude. Continue?"
+ warning_msg = "This will completely remove superclaude. Continue?"
else:
- warning_msg = f"This will remove {len(components)} component(s). Continue?"
-
+ warning_msg = (
+ f"This will remove {len(components)} component(s). Continue?"
+ )
+
if not confirm(warning_msg, default=False):
logger.info("Uninstall cancelled by user")
return 0
-
+
# Create backup if not dry run and not keeping backups
if not args.dry_run and not args.keep_backups:
create_uninstall_backup(args.install_dir, components)
-
+
# Perform uninstall
success = perform_uninstall(components, args, info, env_vars)
-
+
if success:
if not args.quiet:
display_success("SuperClaude uninstall completed successfully!")
-
+
if not args.dry_run:
print(f"\n{Colors.CYAN}Uninstall complete:{Colors.RESET}")
print(f"SuperClaude has been removed from {args.install_dir}")
if not args.complete:
- print(f"You can reinstall anytime using 'SuperClaude install'")
-
+ print(f"You can reinstall anytime using 'superclaude install'")
+
return 0
else:
- display_error("Uninstall completed with some failures. Check logs for details.")
+ display_error(
+ "Uninstall completed with some failures. Check logs for details."
+ )
return 1
-
+
except KeyboardInterrupt:
print(f"\n{Colors.YELLOW}Uninstall cancelled by user{Colors.RESET}")
return 130
diff --git a/setup/cli/commands/update.py b/setup/cli/commands/update.py
index d04521d..d456cf0 100644
--- a/setup/cli/commands/update.py
+++ b/setup/cli/commands/update.py
@@ -15,8 +15,17 @@ from ...core.registry import ComponentRegistry
from ...services.settings import SettingsService
from ...core.validator import Validator
from ...utils.ui import (
- display_header, display_info, display_success, display_error,
- display_warning, Menu, confirm, ProgressBar, Colors, format_size, prompt_api_key
+ display_header,
+ display_info,
+ display_success,
+ display_error,
+ display_warning,
+ Menu,
+ confirm,
+ ProgressBar,
+ Colors,
+ format_size,
+ prompt_api_key,
)
from ...utils.environment import setup_environment_variables
from ...utils.logger import get_logger
@@ -26,7 +35,7 @@ from . import OperationBase
class UpdateOperation(OperationBase):
"""Update operation implementation"""
-
+
def __init__(self):
super().__init__("update")
@@ -34,7 +43,7 @@ class UpdateOperation(OperationBase):
def register_parser(subparsers, global_parser=None) -> argparse.ArgumentParser:
"""Register update CLI arguments"""
parents = [global_parser] if global_parser else []
-
+
parser = subparsers.add_parser(
"update",
help="Update existing SuperClaude installation",
@@ -47,51 +56,44 @@ Examples:
SuperClaude update --backup --force # Create backup before update (forced)
""",
formatter_class=argparse.RawDescriptionHelpFormatter,
- parents=parents
+ parents=parents,
)
-
+
# Update mode options
parser.add_argument(
"--check",
action="store_true",
- help="Check for available updates without installing"
+ help="Check for available updates without installing",
)
-
+
parser.add_argument(
- "--components",
- type=str,
- nargs="+",
- help="Specific components to update"
+ "--components", type=str, nargs="+", help="Specific components to update"
)
-
+
# Backup options
parser.add_argument(
- "--backup",
- action="store_true",
- help="Create backup before update"
+ "--backup", action="store_true", help="Create backup before update"
)
-
- parser.add_argument(
- "--no-backup",
- action="store_true",
- help="Skip backup creation"
- )
-
+
+ parser.add_argument("--no-backup", action="store_true", help="Skip backup creation")
+
# Update options
parser.add_argument(
"--reinstall",
action="store_true",
- help="Reinstall components even if versions match"
+ help="Reinstall components even if versions match",
)
-
+
return parser
+
def check_installation_exists(install_dir: Path) -> bool:
"""Check if SuperClaude installation exists"""
settings_manager = SettingsService(install_dir)
return settings_manager.check_installation_exists()
+
def get_installed_components(install_dir: Path) -> Dict[str, Dict[str, Any]]:
"""Get currently installed components and their versions"""
try:
@@ -101,10 +103,12 @@ def get_installed_components(install_dir: Path) -> Dict[str, Dict[str, Any]]:
return {}
-def get_available_updates(installed_components: Dict[str, str], registry: ComponentRegistry) -> Dict[str, Dict[str, str]]:
+def get_available_updates(
+ installed_components: Dict[str, str], registry: ComponentRegistry
+) -> Dict[str, Dict[str, str]]:
"""Check for available updates"""
updates = {}
-
+
for component_name, current_version in installed_components.items():
try:
metadata = registry.get_component_metadata(component_name)
@@ -114,27 +118,29 @@ def get_available_updates(installed_components: Dict[str, str], registry: Compon
updates[component_name] = {
"current": current_version,
"available": available_version,
- "description": metadata.get("description", "No description")
+ "description": metadata.get("description", "No description"),
}
except Exception:
continue
-
+
return updates
-def display_update_check(installed_components: Dict[str, str], available_updates: Dict[str, Dict[str, str]]) -> None:
+def display_update_check(
+ installed_components: Dict[str, str], available_updates: Dict[str, Dict[str, str]]
+) -> None:
"""Display update check results"""
print(f"\n{Colors.CYAN}{Colors.BRIGHT}Update Check Results{Colors.RESET}")
print("=" * 50)
-
+
if not installed_components:
print(f"{Colors.YELLOW}No SuperClaude installation found{Colors.RESET}")
return
-
+
print(f"{Colors.BLUE}Currently installed components:{Colors.RESET}")
for component, version in installed_components.items():
print(f" {component}: v{version}")
-
+
if available_updates:
print(f"\n{Colors.GREEN}Available updates:{Colors.RESET}")
for component, info in available_updates.items():
@@ -142,47 +148,54 @@ def display_update_check(installed_components: Dict[str, str], available_updates
print(f" {info['description']}")
else:
print(f"\n{Colors.GREEN}All components are up to date{Colors.RESET}")
-
+
print()
-def get_components_to_update(args: argparse.Namespace, installed_components: Dict[str, str],
- available_updates: Dict[str, Dict[str, str]]) -> Optional[List[str]]:
+def get_components_to_update(
+ args: argparse.Namespace,
+ installed_components: Dict[str, str],
+ available_updates: Dict[str, Dict[str, str]],
+) -> Optional[List[str]]:
"""Determine which components to update"""
logger = get_logger()
-
+
# Explicit components specified
if args.components:
# Validate that specified components are installed
- invalid_components = [c for c in args.components if c not in installed_components]
+ invalid_components = [
+ c for c in args.components if c not in installed_components
+ ]
if invalid_components:
logger.error(f"Components not installed: {invalid_components}")
return None
return args.components
-
+
# If no updates available and not forcing reinstall
if not available_updates and not args.reinstall:
logger.info("No updates available")
return []
-
+
# Interactive selection
if available_updates:
return interactive_update_selection(available_updates, installed_components)
elif args.reinstall:
# Reinstall all components
return list(installed_components.keys())
-
+
return []
-def collect_api_keys_for_servers(selected_servers: List[str], mcp_instance) -> Dict[str, str]:
+def collect_api_keys_for_servers(
+ selected_servers: List[str], mcp_instance
+) -> Dict[str, str]:
"""
Collect API keys for servers that require them during update
-
+
Args:
selected_servers: List of selected server keys
mcp_instance: MCP component instance
-
+
Returns:
Dictionary of environment variable names to API key values
"""
@@ -190,81 +203,90 @@ def collect_api_keys_for_servers(selected_servers: List[str], mcp_instance) -> D
servers_needing_keys = [
(server_key, mcp_instance.mcp_servers[server_key])
for server_key in selected_servers
- if server_key in mcp_instance.mcp_servers and
- mcp_instance.mcp_servers[server_key].get("requires_api_key", False)
+ if server_key in mcp_instance.mcp_servers
+ and mcp_instance.mcp_servers[server_key].get("requires_api_key", False)
]
-
+
if not servers_needing_keys:
return {}
-
+
# Display API key configuration header
print(f"\n{Colors.CYAN}{Colors.BRIGHT}=== API Key Configuration ==={Colors.RESET}")
- print(f"{Colors.YELLOW}New MCP servers require API keys for full functionality:{Colors.RESET}\n")
-
+ print(
+ f"{Colors.YELLOW}New MCP servers require API keys for full functionality:{Colors.RESET}\n"
+ )
+
collected_keys = {}
for server_key, server_info in servers_needing_keys:
api_key_env = server_info.get("api_key_env")
service_name = server_info["name"]
-
+
if api_key_env:
key = prompt_api_key(service_name, api_key_env)
if key:
collected_keys[api_key_env] = key
-
+
return collected_keys
-def interactive_update_selection(available_updates: Dict[str, Dict[str, str]],
- installed_components: Dict[str, str]) -> Optional[List[str]]:
+def interactive_update_selection(
+ available_updates: Dict[str, Dict[str, str]], installed_components: Dict[str, str]
+) -> Optional[List[str]]:
"""Interactive update selection"""
if not available_updates:
return []
-
+
print(f"\n{Colors.CYAN}Available Updates:{Colors.RESET}")
-
+
# Create menu options
update_options = []
component_names = []
-
+
for component, info in available_updates.items():
update_options.append(f"{component}: v{info['current']} โ v{info['available']}")
component_names.append(component)
-
+
# Add bulk options
preset_options = [
"Update All Components",
- "Select Individual Components",
- "Cancel Update"
+ "Select Individual Components",
+ "Cancel Update",
]
-
+
menu = Menu("Select update option:", preset_options)
choice = menu.display()
-
+
if choice == -1 or choice == 2: # Cancelled
return None
elif choice == 0: # Update all
return component_names
elif choice == 1: # Select individual
- component_menu = Menu("Select components to update:", update_options, multi_select=True)
+ component_menu = Menu(
+ "Select components to update:", update_options, multi_select=True
+ )
selections = component_menu.display()
-
+
if not selections:
return None
-
+
return [component_names[i] for i in selections]
-
+
return None
-def display_update_plan(components: List[str], available_updates: Dict[str, Dict[str, str]],
- installed_components: Dict[str, str], install_dir: Path) -> None:
+def display_update_plan(
+ components: List[str],
+ available_updates: Dict[str, Dict[str, str]],
+ installed_components: Dict[str, str],
+ install_dir: Path,
+) -> None:
"""Display update plan"""
print(f"\n{Colors.CYAN}{Colors.BRIGHT}Update Plan{Colors.RESET}")
print("=" * 50)
-
+
print(f"{Colors.BLUE}Installation Directory:{Colors.RESET} {install_dir}")
print(f"{Colors.BLUE}Components to update:{Colors.RESET}")
-
+
for i, component_name in enumerate(components, 1):
if component_name in available_updates:
info = available_updates[component_name]
@@ -272,72 +294,80 @@ def display_update_plan(components: List[str], available_updates: Dict[str, Dict
else:
current_version = installed_components.get(component_name, "unknown")
print(f" {i}. {component_name}: v{current_version} (reinstall)")
-
+
print()
-def perform_update(components: List[str], args: argparse.Namespace, registry: ComponentRegistry) -> bool:
+def perform_update(
+ components: List[str], args: argparse.Namespace, registry: ComponentRegistry
+) -> bool:
"""Perform the actual update"""
logger = get_logger()
start_time = time.time()
-
+
try:
# Create installer
installer = Installer(args.install_dir, dry_run=args.dry_run)
-
+
# Create component instances
- component_instances = registry.create_component_instances(components, args.install_dir)
-
+ component_instances = registry.create_component_instances(
+ components, args.install_dir
+ )
+
if not component_instances:
logger.error("No valid component instances created")
return False
-
+
# Handle MCP component specially - collect API keys for new servers
collected_api_keys = {}
if "mcp" in components and "mcp" in component_instances:
mcp_instance = component_instances["mcp"]
- if hasattr(mcp_instance, 'mcp_servers'):
+ if hasattr(mcp_instance, "mcp_servers"):
# Get all available MCP servers
all_server_keys = list(mcp_instance.mcp_servers.keys())
-
+
# Collect API keys for any servers that require them
- collected_api_keys = collect_api_keys_for_servers(all_server_keys, mcp_instance)
-
+ collected_api_keys = collect_api_keys_for_servers(
+ all_server_keys, mcp_instance
+ )
+
# Set up environment variables if any keys were collected
if collected_api_keys:
setup_environment_variables(collected_api_keys)
-
+
# Store keys for MCP component to use during update
mcp_instance.collected_api_keys = collected_api_keys
-
- logger.info(f"Collected {len(collected_api_keys)} API keys for MCP server update")
-
+
+ logger.info(
+ f"Collected {len(collected_api_keys)} API keys for MCP server update"
+ )
+
# Register components with installer
installer.register_components(list(component_instances.values()))
-
+
# Setup progress tracking
- progress = ProgressBar(
- total=len(components),
- prefix="Updating: ",
- suffix=""
- )
-
+ progress = ProgressBar(total=len(components), prefix="Updating: ", suffix="")
+
# Update components
logger.info(f"Updating {len(components)} components...")
-
+
# Determine backup strategy
backup = args.backup or (not args.no_backup and not args.dry_run)
-
+
config = {
"force": args.force,
"backup": backup,
"dry_run": args.dry_run,
"update_mode": True,
- "selected_mcp_servers": list(mcp_instance.mcp_servers.keys()) if "mcp" in component_instances else []
+ "selected_mcp_servers": (
+ list(mcp_instance.mcp_servers.keys())
+ if "mcp" in component_instances
+ else []
+ ),
}
-
+
success = installer.update_components(components, config)
-
+
# Update progress
for i, component_name in enumerate(components):
if component_name in installer.updated_components:
@@ -345,32 +375,32 @@ def perform_update(components: List[str], args: argparse.Namespace, registry: Co
else:
progress.update(i + 1, f"Failed {component_name}")
time.sleep(0.1) # Brief pause for visual effect
-
+
progress.finish("Update complete")
-
+
# Show results
duration = time.time() - start_time
-
+
if success:
logger.success(f"Update completed successfully in {duration:.1f} seconds")
-
+
# Show summary
summary = installer.get_update_summary()
- if summary.get('updated'):
+ if summary.get("updated"):
logger.info(f"Updated components: {', '.join(summary['updated'])}")
-
- if summary.get('backup_path'):
+
+ if summary.get("backup_path"):
logger.info(f"Backup created: {summary['backup_path']}")
-
+
else:
logger.error(f"Update completed with errors in {duration:.1f} seconds")
-
+
summary = installer.get_update_summary()
- if summary.get('failed'):
+ if summary.get("failed"):
logger.error(f"Failed components: {', '.join(summary['failed'])}")
-
+
return success
-
+
except Exception as e:
logger.exception(f"Unexpected error during update: {e}")
return False
@@ -393,7 +423,7 @@ def run(args: argparse.Namespace) -> int:
print(f" Expected prefix: {expected_home}")
print(f" Provided path: {actual_dir}")
sys.exit(1)
-
+
try:
# Validate global arguments
success, errors = operation.validate_global_args(args)
@@ -401,79 +431,83 @@ def run(args: argparse.Namespace) -> int:
for error in errors:
logger.error(error)
return 1
-
+
# Display header
if not args.quiet:
display_header(
f"SuperClaude Update v{__version__}",
- "Updating SuperClaude framework components"
+ "Updating SuperClaude framework components",
)
-
+
# Check if SuperClaude is installed
if not check_installation_exists(args.install_dir):
logger.error(f"SuperClaude installation not found in {args.install_dir}")
- logger.info("Use 'SuperClaude install' to install SuperClaude first")
+ logger.info("Use 'superclaude install' to install SuperClaude first")
return 1
-
+
# Create component registry
logger.info("Checking for available updates...")
-
+
registry = ComponentRegistry(PROJECT_ROOT / "setup" / "components")
registry.discover_components()
-
+
# Get installed components
installed_components = get_installed_components(args.install_dir)
if not installed_components:
logger.error("Could not determine installed components")
return 1
-
+
# Check for available updates
available_updates = get_available_updates(installed_components, registry)
-
+
# Display update check results
if not args.quiet:
display_update_check(installed_components, available_updates)
-
+
# If only checking for updates, exit here
if args.check:
return 0
-
+
# Get components to update
- components = get_components_to_update(args, installed_components, available_updates)
+ components = get_components_to_update(
+ args, installed_components, available_updates
+ )
if components is None:
logger.info("Update cancelled by user")
return 0
elif not components:
logger.info("No components selected for update")
return 0
-
+
# Display update plan
if not args.quiet:
- display_update_plan(components, available_updates, installed_components, args.install_dir)
-
+ display_update_plan(
+ components, available_updates, installed_components, args.install_dir
+ )
+
if not args.dry_run:
if not args.yes and not confirm("Proceed with update?", default=True):
logger.info("Update cancelled by user")
return 0
-
+
# Perform update
success = perform_update(components, args, registry)
-
+
if success:
if not args.quiet:
display_success("SuperClaude update completed successfully!")
-
+
if not args.dry_run:
print(f"\n{Colors.CYAN}Next steps:{Colors.RESET}")
print(f"1. Restart your Claude Code session")
print(f"2. Updated components are now available")
print(f"3. Check for any breaking changes in documentation")
-
+
return 0
else:
display_error("Update failed. Check logs for details.")
return 1
-
+
except KeyboardInterrupt:
print(f"\n{Colors.YELLOW}Update cancelled by user{Colors.RESET}")
return 130
diff --git a/setup/components/__init__.py b/setup/components/__init__.py
index 73e909e..41d2896 100644
--- a/setup/components/__init__.py
+++ b/setup/components/__init__.py
@@ -8,10 +8,10 @@ from .modes import ModesComponent
from .mcp_docs import MCPDocsComponent
__all__ = [
- 'CoreComponent',
- 'CommandsComponent',
- 'MCPComponent',
- 'AgentsComponent',
- 'ModesComponent',
- 'MCPDocsComponent'
-]
\ No newline at end of file
+ "CoreComponent",
+ "CommandsComponent",
+ "MCPComponent",
+ "AgentsComponent",
+ "ModesComponent",
+ "MCPDocsComponent",
+]
diff --git a/setup/components/agents.py b/setup/components/agents.py
index 8337daf..e462bce 100644
--- a/setup/components/agents.py
+++ b/setup/components/agents.py
@@ -11,20 +11,20 @@ from setup import __version__
class AgentsComponent(Component):
"""SuperClaude specialized AI agents component"""
-
+
def __init__(self, install_dir: Optional[Path] = None):
"""Initialize agents component"""
super().__init__(install_dir, Path("agents"))
-
+
def get_metadata(self) -> Dict[str, str]:
"""Get component metadata"""
return {
"name": "agents",
"version": __version__,
"description": "15 specialized AI agents with domain expertise and intelligent routing",
- "category": "agents"
+ "category": "agents",
}
-
+
def get_metadata_modifications(self) -> Dict[str, Any]:
"""Get metadata modifications for agents"""
return {
@@ -33,27 +33,29 @@ class AgentsComponent(Component):
"version": __version__,
"installed": True,
"agents_count": len(self.component_files),
- "install_directory": str(self.install_component_subdir)
+ "install_directory": str(self.install_component_subdir),
}
}
}
-
+
def _install(self, config: Dict[str, Any]) -> bool:
"""Install agents component"""
self.logger.info("Installing SuperClaude specialized agents...")
-
+
# Call parent install method
success = super()._install(config)
-
+
if success:
# Run post-install setup
success = self._post_install()
-
+
if success:
- self.logger.success(f"Successfully installed {len(self.component_files)} specialized agents")
-
+ self.logger.success(
+ f"Successfully installed {len(self.component_files)} specialized agents"
+ )
+
return success
-
+
def _post_install(self) -> bool:
"""Post-install setup for agents"""
try:
@@ -61,27 +63,30 @@ class AgentsComponent(Component):
metadata_mods = self.get_metadata_modifications()
self.settings_manager.update_metadata(metadata_mods)
self.logger.info("Updated metadata with agents configuration")
-
+
# Add component registration
- self.settings_manager.add_component_registration("agents", {
- "version": __version__,
- "category": "agents",
- "agents_count": len(self.component_files),
- "agents_list": self.component_files
- })
-
+ self.settings_manager.add_component_registration(
+ "agents",
+ {
+ "version": __version__,
+ "category": "agents",
+ "agents_count": len(self.component_files),
+ "agents_list": self.component_files,
+ },
+ )
+
self.logger.info("Registered agents component in metadata")
return True
-
+
except Exception as e:
self.logger.error(f"Failed to complete agents post-install: {e}")
return False
-
+
def uninstall(self) -> bool:
"""Uninstall agents component"""
try:
self.logger.info("Uninstalling SuperClaude agents component...")
-
+
# Remove agent files
removed_count = 0
for filename in self.component_files:
@@ -91,15 +96,17 @@ class AgentsComponent(Component):
self.logger.debug(f"Removed agent: {filename}")
else:
self.logger.warning(f"Could not remove agent: {filename}")
-
+
# Remove agents directory if empty
try:
- if self.install_component_subdir.exists() and not any(self.install_component_subdir.iterdir()):
+ if self.install_component_subdir.exists() and not any(
+ self.install_component_subdir.iterdir()
+ ):
self.install_component_subdir.rmdir()
self.logger.debug("Removed empty agents directory")
except Exception as e:
self.logger.warning(f"Could not remove agents directory: {e}")
-
+
# Update metadata to remove agents component
try:
if self.settings_manager.is_component_installed("agents"):
@@ -107,33 +114,39 @@ class AgentsComponent(Component):
self.logger.info("Removed agents component from metadata")
except Exception as e:
self.logger.warning(f"Could not update metadata: {e}")
-
- self.logger.success(f"Agents component uninstalled ({removed_count} agents removed)")
+
+ self.logger.success(
+ f"Agents component uninstalled ({removed_count} agents removed)"
+ )
return True
-
+
except Exception as e:
self.logger.exception(f"Unexpected error during agents uninstallation: {e}")
return False
-
+
def get_dependencies(self) -> List[str]:
"""Get component dependencies"""
return ["core"]
-
+
def update(self, config: Dict[str, Any]) -> bool:
"""Update agents component"""
try:
self.logger.info("Updating SuperClaude agents component...")
-
+
# Check current version
current_version = self.settings_manager.get_component_version("agents")
target_version = self.get_metadata()["version"]
-
+
if current_version == target_version:
- self.logger.info(f"Agents component already at version {target_version}")
+ self.logger.info(
+ f"Agents component already at version {target_version}"
+ )
return True
-
- self.logger.info(f"Updating agents component from {current_version} to {target_version}")
-
+
+ self.logger.info(
+ f"Updating agents component from {current_version} to {target_version}"
+ )
+
# Create backup of existing agents
backup_files = []
for filename in self.component_files:
@@ -143,49 +156,54 @@ class AgentsComponent(Component):
if backup_path:
backup_files.append(backup_path)
self.logger.debug(f"Backed up agent: {filename}")
-
+
# Perform installation (will overwrite existing files)
if self._install(config):
- self.logger.success(f"Agents component updated to version {target_version}")
+ self.logger.success(
+ f"Agents component updated to version {target_version}"
+ )
return True
else:
# Restore backups on failure
self.logger.error("Agents update failed, restoring backups...")
for backup_path in backup_files:
try:
- original_path = self.install_component_subdir / backup_path.name.replace('.backup', '')
+ original_path = (
+ self.install_component_subdir
+ / backup_path.name.replace(".backup", "")
+ )
self.file_manager.copy_file(backup_path, original_path)
self.logger.debug(f"Restored {original_path.name}")
except Exception as e:
self.logger.warning(f"Could not restore {backup_path}: {e}")
return False
-
+
except Exception as e:
self.logger.exception(f"Unexpected error during agents update: {e}")
return False
-
+
def _get_source_dir(self) -> Path:
"""Get source directory for agent files"""
- # Assume we're in SuperClaude/setup/components/agents.py
- # and agent files are in SuperClaude/SuperClaude/Agents/
+ # Assume we're in superclaude/setup/components/agents.py
+ # and agent files are in superclaude/superclaude/Agents/
project_root = Path(__file__).parent.parent.parent
- return project_root / "SuperClaude" / "Agents"
-
+ return project_root / "superclaude" / "agents"
+
def get_size_estimate(self) -> int:
"""Get estimated installation size"""
total_size = 0
source_dir = self._get_source_dir()
-
+
for filename in self.component_files:
file_path = source_dir / filename
if file_path.exists():
total_size += file_path.stat().st_size
-
+
# Add overhead for directories and metadata
total_size += 5120 # ~5KB overhead
-
+
return total_size
-
+
def get_installation_summary(self) -> Dict[str, Any]:
"""Get installation summary"""
return {
@@ -195,46 +213,48 @@ class AgentsComponent(Component):
"agent_files": self.component_files,
"estimated_size": self.get_size_estimate(),
"install_directory": str(self.install_component_subdir),
- "dependencies": self.get_dependencies()
+ "dependencies": self.get_dependencies(),
}
-
+
def validate_installation(self) -> Tuple[bool, List[str]]:
"""Validate that agents component is correctly installed"""
errors = []
-
+
# Check if agents directory exists
if not self.install_component_subdir.exists():
- errors.append(f"Agents directory not found: {self.install_component_subdir}")
+ errors.append(
+ f"Agents directory not found: {self.install_component_subdir}"
+ )
return False, errors
-
+
# Check if all agent files exist
missing_agents = []
for filename in self.component_files:
agent_path = self.install_component_subdir / filename
if not agent_path.exists():
missing_agents.append(filename)
-
+
if missing_agents:
errors.append(f"Missing agent files: {missing_agents}")
-
+
# Check version in metadata
if not self.get_installed_version():
errors.append("Agents component not registered in metadata")
-
+
# Check if at least some standard agents are present
expected_agents = [
"system-architect.md",
- "frontend-architect.md",
+ "frontend-architect.md",
"backend-architect.md",
- "security-engineer.md"
+ "security-engineer.md",
]
-
+
missing_core_agents = []
for agent in expected_agents:
if agent not in self.component_files:
missing_core_agents.append(agent)
-
+
if missing_core_agents:
errors.append(f"Missing core agent files: {missing_core_agents}")
-
- return len(errors) == 0, errors
\ No newline at end of file
+
+ return len(errors) == 0, errors
diff --git a/setup/components/commands.py b/setup/components/commands.py
index 6ee45fb..21ba41e 100644
--- a/setup/components/commands.py
+++ b/setup/components/commands.py
@@ -8,22 +8,23 @@ from pathlib import Path
from ..core.base import Component
from setup import __version__
+
class CommandsComponent(Component):
"""SuperClaude slash commands component"""
-
+
def __init__(self, install_dir: Optional[Path] = None):
"""Initialize commands component"""
super().__init__(install_dir, Path("commands/sc"))
-
+
def get_metadata(self) -> Dict[str, str]:
"""Get component metadata"""
return {
"name": "commands",
"version": __version__,
"description": "SuperClaude slash command definitions",
- "category": "commands"
+ "category": "commands",
}
-
+
def get_metadata_modifications(self) -> Dict[str, Any]:
"""Get metadata modifications for commands component"""
return {
@@ -31,16 +32,12 @@ class CommandsComponent(Component):
"commands": {
"version": __version__,
"installed": True,
- "files_count": len(self.component_files)
+ "files_count": len(self.component_files),
}
},
- "commands": {
- "enabled": True,
- "version": __version__,
- "auto_update": False
- }
+ "commands": {"enabled": True, "version": __version__, "auto_update": False},
}
-
+
def _install(self, config: Dict[str, Any]) -> bool:
"""Install commands component"""
self.logger.info("Installing SuperClaude command definitions...")
@@ -48,7 +45,7 @@ class CommandsComponent(Component):
# Check for and migrate existing commands from old location
self._migrate_existing_commands()
- return super()._install(config);
+ return super()._install(config)
def _post_install(self) -> bool:
# Update metadata
@@ -58,27 +55,30 @@ class CommandsComponent(Component):
self.logger.info("Updated metadata with commands configuration")
# Add component registration to metadata
- self.settings_manager.add_component_registration("commands", {
- "version": __version__,
- "category": "commands",
- "files_count": len(self.component_files)
- })
+ self.settings_manager.add_component_registration(
+ "commands",
+ {
+ "version": __version__,
+ "category": "commands",
+ "files_count": len(self.component_files),
+ },
+ )
self.logger.info("Updated metadata with commands component registration")
except Exception as e:
self.logger.error(f"Failed to update metadata: {e}")
return False
return True
-
+
def uninstall(self) -> bool:
"""Uninstall commands component"""
try:
self.logger.info("Uninstalling SuperClaude commands component...")
-
+
# Remove command files from sc subdirectory
commands_dir = self.install_dir / "commands" / "sc"
removed_count = 0
-
+
for filename in self.component_files:
file_path = commands_dir / filename
if self.file_manager.remove_file(file_path):
@@ -86,11 +86,11 @@ class CommandsComponent(Component):
self.logger.debug(f"Removed {filename}")
else:
self.logger.warning(f"Could not remove {filename}")
-
+
# Also check and remove any old commands in root commands directory
old_commands_dir = self.install_dir / "commands"
old_removed_count = 0
-
+
for filename in self.component_files:
old_file_path = old_commands_dir / filename
if old_file_path.exists() and old_file_path.is_file():
@@ -99,12 +99,14 @@ class CommandsComponent(Component):
self.logger.debug(f"Removed old {filename}")
else:
self.logger.warning(f"Could not remove old {filename}")
-
+
if old_removed_count > 0:
- self.logger.info(f"Also removed {old_removed_count} commands from old location")
-
+ self.logger.info(
+ f"Also removed {old_removed_count} commands from old location"
+ )
+
removed_count += old_removed_count
-
+
# Remove sc subdirectory if empty
try:
if commands_dir.exists():
@@ -112,17 +114,19 @@ class CommandsComponent(Component):
if not remaining_files:
commands_dir.rmdir()
self.logger.debug("Removed empty sc commands directory")
-
+
# Also remove parent commands directory if empty
parent_commands_dir = self.install_dir / "commands"
if parent_commands_dir.exists():
remaining_files = list(parent_commands_dir.iterdir())
if not remaining_files:
parent_commands_dir.rmdir()
- self.logger.debug("Removed empty parent commands directory")
+ self.logger.debug(
+ "Removed empty parent commands directory"
+ )
except Exception as e:
self.logger.warning(f"Could not remove commands directory: {e}")
-
+
# Update metadata to remove commands component
try:
if self.settings_manager.is_component_installed("commands"):
@@ -135,37 +139,45 @@ class CommandsComponent(Component):
self.logger.info("Removed commands component from metadata")
except Exception as e:
self.logger.warning(f"Could not update metadata: {e}")
-
- self.logger.success(f"Commands component uninstalled ({removed_count} files removed)")
+
+ self.logger.success(
+ f"Commands component uninstalled ({removed_count} files removed)"
+ )
return True
-
+
except Exception as e:
- self.logger.exception(f"Unexpected error during commands uninstallation: {e}")
+ self.logger.exception(
+ f"Unexpected error during commands uninstallation: {e}"
+ )
return False
-
+
def get_dependencies(self) -> List[str]:
"""Get dependencies"""
return ["core"]
-
+
def update(self, config: Dict[str, Any]) -> bool:
"""Update commands component"""
try:
self.logger.info("Updating SuperClaude commands component...")
-
+
# Check current version
current_version = self.settings_manager.get_component_version("commands")
target_version = self.get_metadata()["version"]
-
+
if current_version == target_version:
- self.logger.info(f"Commands component already at version {target_version}")
+ self.logger.info(
+ f"Commands component already at version {target_version}"
+ )
return True
-
- self.logger.info(f"Updating commands component from {current_version} to {target_version}")
-
+
+ self.logger.info(
+ f"Updating commands component from {current_version} to {target_version}"
+ )
+
# Create backup of existing command files
commands_dir = self.install_dir / "commands" / "sc"
backup_files = []
-
+
if commands_dir.exists():
for filename in self.component_files:
file_path = commands_dir / filename
@@ -174,10 +186,10 @@ class CommandsComponent(Component):
if backup_path:
backup_files.append(backup_path)
self.logger.debug(f"Backed up {filename}")
-
+
# Perform installation (overwrites existing files)
success = self.install(config)
-
+
if success:
# Remove backup files on successful update
for backup_path in backup_files:
@@ -185,35 +197,37 @@ class CommandsComponent(Component):
backup_path.unlink()
except Exception:
pass # Ignore cleanup errors
-
- self.logger.success(f"Commands component updated to version {target_version}")
+
+ self.logger.success(
+ f"Commands component updated to version {target_version}"
+ )
else:
# Restore from backup on failure
self.logger.warning("Update failed, restoring from backup...")
for backup_path in backup_files:
try:
- original_path = backup_path.with_suffix('')
+ original_path = backup_path.with_suffix("")
backup_path.rename(original_path)
self.logger.debug(f"Restored {original_path.name}")
except Exception as e:
self.logger.error(f"Could not restore {backup_path}: {e}")
-
+
return success
-
+
except Exception as e:
self.logger.exception(f"Unexpected error during commands update: {e}")
return False
-
+
def validate_installation(self) -> Tuple[bool, List[str]]:
"""Validate commands component installation"""
errors = []
-
+
# Check if sc commands directory exists
commands_dir = self.install_dir / "commands" / "sc"
if not commands_dir.exists():
errors.append("SC commands directory not found")
return False, errors
-
+
# Check if all command files exist
for filename in self.component_files:
file_path = commands_dir / filename
@@ -221,7 +235,7 @@ class CommandsComponent(Component):
errors.append(f"Missing command file: {filename}")
elif not file_path.is_file():
errors.append(f"Command file is not a regular file: {filename}")
-
+
# Check metadata registration
if not self.settings_manager.is_component_installed("commands"):
errors.append("Commands component not registered in metadata")
@@ -230,32 +244,34 @@ class CommandsComponent(Component):
installed_version = self.settings_manager.get_component_version("commands")
expected_version = self.get_metadata()["version"]
if installed_version != expected_version:
- errors.append(f"Version mismatch: installed {installed_version}, expected {expected_version}")
-
+ errors.append(
+ f"Version mismatch: installed {installed_version}, expected {expected_version}"
+ )
+
return len(errors) == 0, errors
-
+
def _get_source_dir(self) -> Path:
"""Get source directory for command files"""
- # Assume we're in SuperClaude/setup/components/commands.py
- # and command files are in SuperClaude/SuperClaude/Commands/
+ # Assume we're in superclaude/setup/components/commands.py
+ # and command files are in superclaude/superclaude/Commands/
project_root = Path(__file__).parent.parent.parent
- return project_root / "SuperClaude" / "Commands"
-
+ return project_root / "superclaude" / "commands"
+
def get_size_estimate(self) -> int:
"""Get estimated installation size"""
total_size = 0
source_dir = self._get_source_dir()
-
+
for filename in self.component_files:
file_path = source_dir / filename
if file_path.exists():
total_size += file_path.stat().st_size
-
+
# Add overhead for directory and settings
total_size += 5120 # ~5KB overhead
-
+
return total_size
-
+
def get_installation_summary(self) -> Dict[str, Any]:
"""Get installation summary"""
return {
@@ -265,66 +281,84 @@ class CommandsComponent(Component):
"command_files": self.component_files,
"estimated_size": self.get_size_estimate(),
"install_directory": str(self.install_dir / "commands" / "sc"),
- "dependencies": self.get_dependencies()
+ "dependencies": self.get_dependencies(),
}
-
+
def _migrate_existing_commands(self) -> None:
"""Migrate existing commands from old location to new sc subdirectory"""
try:
old_commands_dir = self.install_dir / "commands"
new_commands_dir = self.install_dir / "commands" / "sc"
-
+
# Check if old commands exist in root commands directory
migrated_count = 0
commands_to_migrate = []
-
+
if old_commands_dir.exists():
for filename in self.component_files:
old_file_path = old_commands_dir / filename
if old_file_path.exists() and old_file_path.is_file():
commands_to_migrate.append(filename)
-
+
if commands_to_migrate:
- self.logger.info(f"Found {len(commands_to_migrate)} existing commands to migrate to sc/ subdirectory")
-
+ self.logger.info(
+ f"Found {len(commands_to_migrate)} existing commands to migrate to sc/ subdirectory"
+ )
+
# Ensure new directory exists
if not self.file_manager.ensure_directory(new_commands_dir):
- self.logger.error(f"Could not create sc commands directory: {new_commands_dir}")
+ self.logger.error(
+ f"Could not create sc commands directory: {new_commands_dir}"
+ )
return
-
+
# Move files from old to new location
for filename in commands_to_migrate:
old_file_path = old_commands_dir / filename
new_file_path = new_commands_dir / filename
-
+
try:
# Copy file to new location
if self.file_manager.copy_file(old_file_path, new_file_path):
# Remove old file
if self.file_manager.remove_file(old_file_path):
migrated_count += 1
- self.logger.debug(f"Migrated {filename} to sc/ subdirectory")
+ self.logger.debug(
+ f"Migrated {filename} to sc/ subdirectory"
+ )
else:
self.logger.warning(f"Could not remove old {filename}")
else:
- self.logger.warning(f"Could not copy {filename} to sc/ subdirectory")
+ self.logger.warning(
+ f"Could not copy {filename} to sc/ subdirectory"
+ )
except Exception as e:
self.logger.warning(f"Error migrating {filename}: {e}")
-
+
if migrated_count > 0:
- self.logger.success(f"Successfully migrated {migrated_count} commands to /sc: namespace")
- self.logger.info("Commands are now available as /sc:analyze, /sc:build, etc.")
-
+ self.logger.success(
+ f"Successfully migrated {migrated_count} commands to /sc: namespace"
+ )
+ self.logger.info(
+ "Commands are now available as /sc:analyze, /sc:build, etc."
+ )
+
# Try to remove old commands directory if empty
try:
if old_commands_dir.exists():
- remaining_files = [f for f in old_commands_dir.iterdir() if f.is_file()]
+ remaining_files = [
+ f for f in old_commands_dir.iterdir() if f.is_file()
+ ]
if not remaining_files:
# Only remove if no user files remain
old_commands_dir.rmdir()
- self.logger.debug("Removed empty old commands directory")
+ self.logger.debug(
+ "Removed empty old commands directory"
+ )
except Exception as e:
- self.logger.debug(f"Could not remove old commands directory: {e}")
-
+ self.logger.debug(
+ f"Could not remove old commands directory: {e}"
+ )
+
except Exception as e:
self.logger.warning(f"Error during command migration: {e}")
diff --git a/setup/components/core.py b/setup/components/core.py
index e6820d9..642746d 100644
--- a/setup/components/core.py
+++ b/setup/components/core.py
@@ -10,45 +10,46 @@ from ..core.base import Component
from ..services.claude_md import CLAUDEMdService
from setup import __version__
+
class CoreComponent(Component):
"""Core SuperClaude framework files component"""
-
+
def __init__(self, install_dir: Optional[Path] = None):
"""Initialize core component"""
super().__init__(install_dir)
-
+
def get_metadata(self) -> Dict[str, str]:
"""Get component metadata"""
return {
"name": "core",
"version": __version__,
"description": "SuperClaude framework documentation and core files",
- "category": "core"
+ "category": "core",
}
-
+
def get_metadata_modifications(self) -> Dict[str, Any]:
"""Get metadata modifications for SuperClaude"""
return {
"framework": {
"version": __version__,
- "name": "SuperClaude",
+ "name": "superclaude",
"description": "AI-enhanced development framework for Claude Code",
"installation_type": "global",
- "components": ["core"]
+ "components": ["core"],
},
"superclaude": {
"enabled": True,
"version": __version__,
"profile": "default",
- "auto_update": False
- }
+ "auto_update": False,
+ },
}
-
+
def _install(self, config: Dict[str, Any]) -> bool:
"""Install core component"""
self.logger.info("Installing SuperClaude core framework files...")
- return super()._install(config);
+ return super()._install(config)
def _post_install(self) -> bool:
# Create or update metadata
@@ -56,19 +57,24 @@ class CoreComponent(Component):
metadata_mods = self.get_metadata_modifications()
self.settings_manager.update_metadata(metadata_mods)
self.logger.info("Updated metadata with framework configuration")
-
+
# Add component registration to metadata
- self.settings_manager.add_component_registration("core", {
- "version": __version__,
- "category": "core",
- "files_count": len(self.component_files)
- })
+ self.settings_manager.add_component_registration(
+ "core",
+ {
+ "version": __version__,
+ "category": "core",
+ "files_count": len(self.component_files),
+ },
+ )
self.logger.info("Updated metadata with core component registration")
-
+
# Migrate any existing SuperClaude data from settings.json
if self.settings_manager.migrate_superclaude_data():
- self.logger.info("Migrated existing SuperClaude data from settings.json")
+ self.logger.info(
+ "Migrated existing SuperClaude data from settings.json"
+ )
except Exception as e:
self.logger.error(f"Failed to update metadata: {e}")
return False
@@ -79,24 +85,25 @@ class CoreComponent(Component):
dir_path = self.install_dir / dirname
if not self.file_manager.ensure_directory(dir_path):
self.logger.warning(f"Could not create directory: {dir_path}")
-
+
# Update CLAUDE.md with core framework imports
try:
manager = CLAUDEMdService(self.install_dir)
manager.add_imports(self.component_files, category="Core Framework")
self.logger.info("Updated CLAUDE.md with core framework imports")
except Exception as e:
- self.logger.warning(f"Failed to update CLAUDE.md with core framework imports: {e}")
+ self.logger.warning(
+ f"Failed to update CLAUDE.md with core framework imports: {e}"
+ )
# Don't fail the whole installation for this
return True
-
def uninstall(self) -> bool:
"""Uninstall core component"""
try:
self.logger.info("Uninstalling SuperClaude core component...")
-
+
# Remove framework files
removed_count = 0
for filename in self.component_files:
@@ -106,7 +113,7 @@ class CoreComponent(Component):
self.logger.debug(f"Removed {filename}")
else:
self.logger.warning(f"Could not remove {filename}")
-
+
# Update metadata to remove core component
try:
if self.settings_manager.is_component_installed("core"):
@@ -121,33 +128,37 @@ class CoreComponent(Component):
self.logger.info("Removed core component from metadata")
except Exception as e:
self.logger.warning(f"Could not update metadata: {e}")
-
- self.logger.success(f"Core component uninstalled ({removed_count} files removed)")
+
+ self.logger.success(
+ f"Core component uninstalled ({removed_count} files removed)"
+ )
return True
-
+
except Exception as e:
self.logger.exception(f"Unexpected error during core uninstallation: {e}")
return False
-
+
def get_dependencies(self) -> List[str]:
"""Get component dependencies (core has none)"""
return []
-
+
def update(self, config: Dict[str, Any]) -> bool:
"""Update core component"""
try:
self.logger.info("Updating SuperClaude core component...")
-
+
# Check current version
current_version = self.settings_manager.get_component_version("core")
target_version = self.get_metadata()["version"]
-
+
if current_version == target_version:
self.logger.info(f"Core component already at version {target_version}")
return True
-
- self.logger.info(f"Updating core component from {current_version} to {target_version}")
-
+
+ self.logger.info(
+ f"Updating core component from {current_version} to {target_version}"
+ )
+
# Create backup of existing files
backup_files = []
for filename in self.component_files:
@@ -157,10 +168,10 @@ class CoreComponent(Component):
if backup_path:
backup_files.append(backup_path)
self.logger.debug(f"Backed up {filename}")
-
+
# Perform installation (overwrites existing files)
success = self.install(config)
-
+
if success:
# Remove backup files on successful update
for backup_path in backup_files:
@@ -168,29 +179,31 @@ class CoreComponent(Component):
backup_path.unlink()
except Exception:
pass # Ignore cleanup errors
-
- self.logger.success(f"Core component updated to version {target_version}")
+
+ self.logger.success(
+ f"Core component updated to version {target_version}"
+ )
else:
# Restore from backup on failure
self.logger.warning("Update failed, restoring from backup...")
for backup_path in backup_files:
try:
- original_path = backup_path.with_suffix('')
+ original_path = backup_path.with_suffix("")
shutil.move(str(backup_path), str(original_path))
self.logger.debug(f"Restored {original_path.name}")
except Exception as e:
self.logger.error(f"Could not restore {backup_path}: {e}")
-
+
return success
-
+
except Exception as e:
self.logger.exception(f"Unexpected error during core update: {e}")
return False
-
+
def validate_installation(self) -> Tuple[bool, List[str]]:
"""Validate core component installation"""
errors = []
-
+
# Check if all framework files exist
for filename in self.component_files:
file_path = self.install_dir / filename
@@ -198,7 +211,7 @@ class CoreComponent(Component):
errors.append(f"Missing framework file: {filename}")
elif not file_path.is_file():
errors.append(f"Framework file is not a regular file: {filename}")
-
+
# Check metadata registration
if not self.settings_manager.is_component_installed("core"):
errors.append("Core component not registered in metadata")
@@ -207,8 +220,10 @@ class CoreComponent(Component):
installed_version = self.settings_manager.get_component_version("core")
expected_version = self.get_metadata()["version"]
if installed_version != expected_version:
- errors.append(f"Version mismatch: installed {installed_version}, expected {expected_version}")
-
+ errors.append(
+ f"Version mismatch: installed {installed_version}, expected {expected_version}"
+ )
+
# Check metadata structure
try:
framework_config = self.settings_manager.get_metadata_setting("framework")
@@ -221,31 +236,31 @@ class CoreComponent(Component):
errors.append(f"Missing framework.{key} in metadata")
except Exception as e:
errors.append(f"Could not validate metadata: {e}")
-
+
return len(errors) == 0, errors
-
+
def _get_source_dir(self):
"""Get source directory for framework files"""
- # Assume we're in SuperClaude/setup/components/core.py
- # and framework files are in SuperClaude/SuperClaude/Core/
+ # Assume we're in superclaude/setup/components/core.py
+ # and framework files are in superclaude/superclaude/Core/
project_root = Path(__file__).parent.parent.parent
- return project_root / "SuperClaude" / "Core"
-
+ return project_root / "superclaude" / "core"
+
def get_size_estimate(self) -> int:
"""Get estimated installation size"""
total_size = 0
source_dir = self._get_source_dir()
-
+
for filename in self.component_files:
file_path = source_dir / filename
if file_path.exists():
total_size += file_path.stat().st_size
-
+
# Add overhead for settings.json and directories
total_size += 10240 # ~10KB overhead
-
+
return total_size
-
+
def get_installation_summary(self) -> Dict[str, Any]:
"""Get installation summary"""
return {
@@ -255,5 +270,5 @@ class CoreComponent(Component):
"framework_files": self.component_files,
"estimated_size": self.get_size_estimate(),
"install_directory": str(self.install_dir),
- "dependencies": self.get_dependencies()
+ "dependencies": self.get_dependencies(),
}
diff --git a/setup/components/mcp.py b/setup/components/mcp.py
index 98afdeb..424c3ef 100644
--- a/setup/components/mcp.py
+++ b/setup/components/mcp.py
@@ -18,25 +18,25 @@ from ..utils.ui import display_info, display_warning
class MCPComponent(Component):
"""MCP servers integration component"""
-
+
def __init__(self, install_dir: Optional[Path] = None):
"""Initialize MCP component"""
super().__init__(install_dir)
self.installed_servers_in_session: List[str] = []
-
+
# Define MCP servers to install
self.mcp_servers = {
"sequential-thinking": {
"name": "sequential-thinking",
"description": "Multi-step problem solving and systematic analysis",
"npm_package": "@modelcontextprotocol/server-sequential-thinking",
- "required": True
+ "required": True,
},
"context7": {
- "name": "context7",
+ "name": "context7",
"description": "Official library documentation and code examples",
"npm_package": "@upstash/context7-mcp",
- "required": True
+ "required": True,
},
"magic": {
"name": "magic",
@@ -44,21 +44,21 @@ class MCPComponent(Component):
"npm_package": "@21st-dev/magic",
"required": False,
"api_key_env": "TWENTYFIRST_API_KEY",
- "api_key_description": "21st.dev API key for UI component generation"
+ "api_key_description": "21st.dev API key for UI component generation",
},
"playwright": {
"name": "playwright",
"description": "Cross-browser E2E testing and automation",
"npm_package": "@playwright/mcp@latest",
- "required": False
+ "required": False,
},
"serena": {
"name": "serena",
"description": "Semantic code analysis and intelligent editing",
"install_method": "github",
"install_command": "uvx --from git+https://github.com/oraios/serena serena --help",
- "run_command": "uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant",
- "required": False
+ "run_command": "uvx --from git+https://github.com/oraios/serena serena start-mcp-server --context ide-assistant --enable-web-dashboard false --enable-gui-log-window false",
+ "required": False,
},
"morphllm-fast-apply": {
"name": "morphllm-fast-apply",
@@ -66,7 +66,7 @@ class MCPComponent(Component):
"npm_package": "@morph-llm/morph-fast-apply",
"required": False,
"api_key_env": "MORPH_API_KEY",
- "api_key_description": "Morph API key for Fast Apply"
+ "api_key_description": "Morph API key for Fast Apply",
},
"tavily": {
"name": "tavily",
@@ -75,31 +75,41 @@ class MCPComponent(Component):
"install_command": "npx -y tavily-mcp@0.1.2",
"required": False,
"api_key_env": "TAVILY_API_KEY",
- "api_key_description": "Tavily API key for web search (get from https://app.tavily.com)"
+ "api_key_description": "Tavily API key for web search (get from https://app.tavily.com)",
},
"chrome-devtools": {
"name": "chrome-devtools",
"description": "Chrome DevTools debugging and performance analysis",
"install_method": "npm",
"install_command": "npx -y chrome-devtools-mcp@latest",
- "required": False
- }
+ "required": False,
+ },
+ "airis-mcp-gateway": {
+ "name": "airis-mcp-gateway",
+ "description": "Dynamic MCP Gateway for zero-token baseline and on-demand tool loading",
+ "install_method": "github",
+ "install_command": "uvx --from git+https://github.com/oraios/airis-mcp-gateway airis-mcp-gateway --help",
+ "run_command": "uvx --from git+https://github.com/oraios/airis-mcp-gateway airis-mcp-gateway",
+ "required": False,
+ },
}
-
+
def get_metadata(self) -> Dict[str, str]:
"""Get component metadata"""
return {
"name": "mcp",
"version": __version__,
"description": "MCP server integration (Context7, Sequential, Magic, Playwright)",
- "category": "integration"
+ "category": "integration",
}
def is_reinstallable(self) -> bool:
"""This component manages sub-components (servers) and should be re-run."""
return True
- def _run_command_cross_platform(self, cmd: List[str], **kwargs) -> subprocess.CompletedProcess:
+ def _run_command_cross_platform(
+ self, cmd: List[str], **kwargs
+ ) -> subprocess.CompletedProcess:
"""
Run a command with proper cross-platform shell handling.
@@ -119,20 +129,21 @@ class MCPComponent(Component):
cmd_str = " ".join(shlex.quote(str(arg)) for arg in cmd)
# Use the user's shell to execute the command, supporting aliases
- user_shell = os.environ.get('SHELL', '/bin/bash')
- return subprocess.run(cmd_str, shell=True, env=os.environ, executable=user_shell, **kwargs)
-
- def validate_prerequisites(self, installSubPath: Optional[Path] = None) -> Tuple[bool, List[str]]:
+ user_shell = os.environ.get("SHELL", "/bin/bash")
+ return subprocess.run(
+ cmd_str, shell=True, env=os.environ, executable=user_shell, **kwargs
+ )
+
+ def validate_prerequisites(
+ self, installSubPath: Optional[Path] = None
+ ) -> Tuple[bool, List[str]]:
"""Check prerequisites"""
errors = []
# Check if Node.js is available
try:
result = self._run_command_cross_platform(
- ["node", "--version"],
- capture_output=True,
- text=True,
- timeout=10
+ ["node", "--version"], capture_output=True, text=True, timeout=10
)
if result.returncode != 0:
errors.append("Node.js not found - required for MCP servers")
@@ -142,9 +153,11 @@ class MCPComponent(Component):
# Check version (require 18+)
try:
- version_num = int(version.lstrip('v').split('.')[0])
+ version_num = int(version.lstrip("v").split(".")[0])
if version_num < 18:
- errors.append(f"Node.js version {version} found, but version 18+ required")
+ errors.append(
+ f"Node.js version {version} found, but version 18+ required"
+ )
except:
self.logger.warning(f"Could not parse Node.js version: {version}")
except (subprocess.TimeoutExpired, FileNotFoundError):
@@ -153,13 +166,12 @@ class MCPComponent(Component):
# Check if Claude CLI is available
try:
result = self._run_command_cross_platform(
- ["claude", "--version"],
- capture_output=True,
- text=True,
- timeout=10
+ ["claude", "--version"], capture_output=True, text=True, timeout=10
)
if result.returncode != 0:
- errors.append("Claude CLI not found - required for MCP server management")
+ errors.append(
+ "Claude CLI not found - required for MCP server management"
+ )
else:
version = result.stdout.strip()
self.logger.debug(f"Found Claude CLI {version}")
@@ -169,10 +181,7 @@ class MCPComponent(Component):
# Check if npm is available
try:
result = self._run_command_cross_platform(
- ["npm", "--version"],
- capture_output=True,
- text=True,
- timeout=10
+ ["npm", "--version"], capture_output=True, text=True, timeout=10
)
if result.returncode != 0:
errors.append("npm not found - required for MCP server installation")
@@ -185,25 +194,26 @@ class MCPComponent(Component):
# Check if uv is available (required for Serena)
try:
result = self._run_command_cross_platform(
- ["uv", "--version"],
- capture_output=True,
- text=True,
- timeout=10
+ ["uv", "--version"], capture_output=True, text=True, timeout=10
)
if result.returncode != 0:
- self.logger.warning("uv not found - required for Serena MCP server installation")
+ self.logger.warning(
+ "uv not found - required for Serena MCP server installation"
+ )
else:
version = result.stdout.strip()
self.logger.debug(f"Found uv {version}")
except (subprocess.TimeoutExpired, FileNotFoundError):
- self.logger.warning("uv not found - required for Serena MCP server installation")
+ self.logger.warning(
+ "uv not found - required for Serena MCP server installation"
+ )
return len(errors) == 0, errors
-
+
def get_files_to_install(self) -> List[Tuple[Path, Path]]:
"""Get files to install (none for MCP component)"""
return []
-
+
def get_metadata_modifications(self) -> Dict[str, Any]:
"""Get metadata modifications for MCP component"""
return {
@@ -211,24 +221,28 @@ class MCPComponent(Component):
"mcp": {
"version": __version__,
"installed": True,
- "servers_count": len(self.installed_servers_in_session)
+ "servers_count": len(self.installed_servers_in_session),
}
},
"mcp": {
"enabled": True,
"servers": self.installed_servers_in_session,
- "auto_update": False
- }
+ "auto_update": False,
+ },
}
-
- def _install_uv_mcp_server(self, server_info: Dict[str, Any], config: Dict[str, Any]) -> bool:
+
+ def _install_uv_mcp_server(
+ self, server_info: Dict[str, Any], config: Dict[str, Any]
+ ) -> bool:
"""Install a single MCP server using uv"""
server_name = server_info["name"]
install_command = server_info.get("install_command")
run_command = server_info.get("run_command")
if not install_command:
- self.logger.error(f"No install_command found for uv-based server {server_name}")
+ self.logger.error(
+ f"No install_command found for uv-based server {server_name}"
+ )
return False
if not run_command:
self.logger.error(f"No run_command found for uv-based server {server_name}")
@@ -244,85 +258,125 @@ class MCPComponent(Component):
# Check if uv is available
try:
uv_check = self._run_command_cross_platform(
- ["uv", "--version"],
- capture_output=True,
- text=True,
- timeout=10
+ ["uv", "--version"], capture_output=True, text=True, timeout=10
)
if uv_check.returncode != 0:
- self.logger.error(f"uv not found - required for {server_name} installation")
+ self.logger.error(
+ f"uv not found - required for {server_name} installation"
+ )
return False
except (subprocess.TimeoutExpired, FileNotFoundError):
- self.logger.error(f"uv not found - required for {server_name} installation")
+ self.logger.error(
+ f"uv not found - required for {server_name} installation"
+ )
return False
if config.get("dry_run"):
- self.logger.info(f"Would install MCP server (user scope): {install_command}")
- self.logger.info(f"Would register MCP server run command: {run_command}")
+ self.logger.info(
+ f"Would install MCP server (user scope): {install_command}"
+ )
+ self.logger.info(
+ f"Would register MCP server run command: {run_command}"
+ )
return True
# Run install command
self.logger.debug(f"Running: {install_command}")
cmd_parts = shlex.split(install_command)
result = self._run_command_cross_platform(
- cmd_parts,
- capture_output=True,
- text=True,
- timeout=900 # 15 minutes
+ cmd_parts, capture_output=True, text=True, timeout=900 # 15 minutes
)
if result.returncode == 0:
- self.logger.success(f"Successfully installed MCP server (user scope): {server_name}")
+ self.logger.success(
+ f"Successfully installed MCP server (user scope): {server_name}"
+ )
# For Serena, we need to handle the run command specially
if server_name == "serena":
# Serena needs project-specific registration, use current working directory
current_dir = os.getcwd()
- serena_run_cmd = f"{run_command} --project {shlex.quote(current_dir)}"
- self.logger.info(f"Registering {server_name} with Claude CLI for project: {current_dir}")
- reg_cmd = ["claude", "mcp", "add", "-s", "user", "--", server_name] + shlex.split(serena_run_cmd)
+ serena_run_cmd = (
+ f"{run_command} --project {shlex.quote(current_dir)}"
+ )
+ self.logger.info(
+ f"Registering {server_name} with Claude CLI for project: {current_dir}"
+ )
+ reg_cmd = [
+ "claude",
+ "mcp",
+ "add",
+ "-s",
+ "user",
+ "--",
+ server_name,
+ ] + shlex.split(serena_run_cmd)
else:
- self.logger.info(f"Registering {server_name} with Claude CLI. Run command: {run_command}")
- reg_cmd = ["claude", "mcp", "add", "-s", "user", "--", server_name] + shlex.split(run_command)
+ self.logger.info(
+ f"Registering {server_name} with Claude CLI. Run command: {run_command}"
+ )
+ reg_cmd = [
+ "claude",
+ "mcp",
+ "add",
+ "-s",
+ "user",
+ "--",
+ server_name,
+ ] + shlex.split(run_command)
reg_result = self._run_command_cross_platform(
- reg_cmd,
- capture_output=True,
- text=True,
- timeout=120
+ reg_cmd, capture_output=True, text=True, timeout=120
)
if reg_result.returncode == 0:
- self.logger.success(f"Successfully registered {server_name} with Claude CLI.")
+ self.logger.success(
+ f"Successfully registered {server_name} with Claude CLI."
+ )
return True
else:
- error_msg = reg_result.stderr.strip() if reg_result.stderr else "Unknown error"
- self.logger.error(f"Failed to register MCP server {server_name} with Claude CLI: {error_msg}")
+ error_msg = (
+ reg_result.stderr.strip()
+ if reg_result.stderr
+ else "Unknown error"
+ )
+ self.logger.error(
+ f"Failed to register MCP server {server_name} with Claude CLI: {error_msg}"
+ )
return False
else:
error_msg = result.stderr.strip() if result.stderr else "Unknown error"
- self.logger.error(f"Failed to install MCP server {server_name} using uv: {error_msg}\n{result.stdout}")
+ self.logger.error(
+ f"Failed to install MCP server {server_name} using uv: {error_msg}\n{result.stdout}"
+ )
return False
except subprocess.TimeoutExpired:
self.logger.error(f"Timeout installing MCP server {server_name} using uv")
return False
except Exception as e:
- self.logger.error(f"Error installing MCP server {server_name} using uv: {e}")
+ self.logger.error(
+ f"Error installing MCP server {server_name} using uv: {e}"
+ )
return False
-
- def _install_github_mcp_server(self, server_info: Dict[str, Any], config: Dict[str, Any]) -> bool:
+ def _install_github_mcp_server(
+ self, server_info: Dict[str, Any], config: Dict[str, Any]
+ ) -> bool:
"""Install a single MCP server from GitHub using uvx"""
server_name = server_info["name"]
install_command = server_info.get("install_command")
run_command = server_info.get("run_command")
if not install_command:
- self.logger.error(f"No install_command found for GitHub-based server {server_name}")
+ self.logger.error(
+ f"No install_command found for GitHub-based server {server_name}"
+ )
return False
if not run_command:
- self.logger.error(f"No run_command found for GitHub-based server {server_name}")
+ self.logger.error(
+ f"No run_command found for GitHub-based server {server_name}"
+ )
return False
try:
@@ -335,21 +389,26 @@ class MCPComponent(Component):
# Check if uvx is available
try:
uvx_check = self._run_command_cross_platform(
- ["uvx", "--version"],
- capture_output=True,
- text=True,
- timeout=10
+ ["uvx", "--version"], capture_output=True, text=True, timeout=10
)
if uvx_check.returncode != 0:
- self.logger.error(f"uvx not found - required for {server_name} installation")
+ self.logger.error(
+ f"uvx not found - required for {server_name} installation"
+ )
return False
except (subprocess.TimeoutExpired, FileNotFoundError):
- self.logger.error(f"uvx not found - required for {server_name} installation")
+ self.logger.error(
+ f"uvx not found - required for {server_name} installation"
+ )
return False
if config.get("dry_run"):
- self.logger.info(f"Would install MCP server from GitHub: {install_command}")
- self.logger.info(f"Would register MCP server run command: {run_command}")
+ self.logger.info(
+ f"Would install MCP server from GitHub: {install_command}"
+ )
+ self.logger.info(
+ f"Would register MCP server run command: {run_command}"
+ )
return True
# Run install command to test the GitHub installation
@@ -359,50 +418,70 @@ class MCPComponent(Component):
cmd_parts,
capture_output=True,
text=True,
- timeout=300 # 5 minutes for GitHub clone and build
+ timeout=300, # 5 minutes for GitHub clone and build
)
if result.returncode == 0:
- self.logger.success(f"Successfully tested GitHub MCP server: {server_name}")
+ self.logger.success(
+ f"Successfully tested GitHub MCP server: {server_name}"
+ )
# Register with Claude CLI using the run command
- self.logger.info(f"Registering {server_name} with Claude CLI. Run command: {run_command}")
- reg_cmd = ["claude", "mcp", "add", "-s", "user", "--", server_name] + shlex.split(run_command)
+ self.logger.info(
+ f"Registering {server_name} with Claude CLI. Run command: {run_command}"
+ )
+ reg_cmd = [
+ "claude",
+ "mcp",
+ "add",
+ "-s",
+ "user",
+ "--",
+ server_name,
+ ] + shlex.split(run_command)
reg_result = self._run_command_cross_platform(
- reg_cmd,
- capture_output=True,
- text=True,
- timeout=120
+ reg_cmd, capture_output=True, text=True, timeout=120
)
if reg_result.returncode == 0:
- self.logger.success(f"Successfully registered {server_name} with Claude CLI.")
+ self.logger.success(
+ f"Successfully registered {server_name} with Claude CLI."
+ )
return True
else:
- error_msg = reg_result.stderr.strip() if reg_result.stderr else "Unknown error"
- self.logger.error(f"Failed to register MCP server {server_name} with Claude CLI: {error_msg}")
+ error_msg = (
+ reg_result.stderr.strip()
+ if reg_result.stderr
+ else "Unknown error"
+ )
+ self.logger.error(
+ f"Failed to register MCP server {server_name} with Claude CLI: {error_msg}"
+ )
return False
else:
error_msg = result.stderr.strip() if result.stderr else "Unknown error"
- self.logger.error(f"Failed to install MCP server {server_name} from GitHub: {error_msg}\n{result.stdout}")
+ self.logger.error(
+ f"Failed to install MCP server {server_name} from GitHub: {error_msg}\n{result.stdout}"
+ )
return False
except subprocess.TimeoutExpired:
- self.logger.error(f"Timeout installing MCP server {server_name} from GitHub")
+ self.logger.error(
+ f"Timeout installing MCP server {server_name} from GitHub"
+ )
return False
except Exception as e:
- self.logger.error(f"Error installing MCP server {server_name} from GitHub: {e}")
+ self.logger.error(
+ f"Error installing MCP server {server_name} from GitHub: {e}"
+ )
return False
def _check_mcp_server_installed(self, server_name: str) -> bool:
"""Check if MCP server is already installed"""
try:
result = self._run_command_cross_platform(
- ["claude", "mcp", "list"],
- capture_output=True,
- text=True,
- timeout=60
+ ["claude", "mcp", "list"], capture_output=True, text=True, timeout=60
)
if result.returncode != 0:
@@ -427,8 +506,16 @@ class MCPComponent(Component):
self.install_dir / "claude_desktop_config.json",
Path.home() / ".claude" / "claude_desktop_config.json",
Path.home() / ".claude.json", # Claude CLI config
- Path.home() / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json", # Windows
- Path.home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json", # macOS
+ Path.home()
+ / "AppData"
+ / "Roaming"
+ / "Claude"
+ / "claude_desktop_config.json", # Windows
+ Path.home()
+ / "Library"
+ / "Application Support"
+ / "Claude"
+ / "claude_desktop_config.json", # macOS
]
config_file = None
@@ -442,7 +529,8 @@ class MCPComponent(Component):
return detected_servers
import json
- with open(config_file, 'r') as f:
+
+ with open(config_file, "r") as f:
config = json.load(f)
# Extract MCP server names from mcpServers section
@@ -454,7 +542,9 @@ class MCPComponent(Component):
detected_servers.append(normalized_name)
if detected_servers:
- self.logger.info(f"Detected existing MCP servers from config: {detected_servers}")
+ self.logger.info(
+ f"Detected existing MCP servers from config: {detected_servers}"
+ )
except Exception as e:
self.logger.warning(f"Could not read Claude Desktop config: {e}")
@@ -467,10 +557,7 @@ class MCPComponent(Component):
try:
result = self._run_command_cross_platform(
- ["claude", "mcp", "list"],
- capture_output=True,
- text=True,
- timeout=60
+ ["claude", "mcp", "list"], capture_output=True, text=True, timeout=60
)
if result.returncode != 0:
@@ -478,10 +565,10 @@ class MCPComponent(Component):
return detected_servers
# Parse the output to extract server names
- output_lines = result.stdout.strip().split('\n')
+ output_lines = result.stdout.strip().split("\n")
for line in output_lines:
line = line.strip().lower()
- if line and not line.startswith('#') and not line.startswith('no'):
+ if line and not line.startswith("#") and not line.startswith("no"):
# Extract server name (usually the first word or before first space/colon)
server_name = line.split()[0] if line.split() else ""
normalized_name = self._normalize_server_name(server_name)
@@ -489,7 +576,9 @@ class MCPComponent(Component):
detected_servers.append(normalized_name)
if detected_servers:
- self.logger.info(f"Detected existing MCP servers from CLI: {detected_servers}")
+ self.logger.info(
+ f"Detected existing MCP servers from CLI: {detected_servers}"
+ )
except Exception as e:
self.logger.warning(f"Could not detect existing MCP servers from CLI: {e}")
@@ -513,12 +602,17 @@ class MCPComponent(Component):
"serena": "serena",
"morphllm": "morphllm-fast-apply",
"morphllm-fast-apply": "morphllm-fast-apply",
- "morph": "morphllm-fast-apply"
+ "morph": "morphllm-fast-apply",
}
return name_mappings.get(server_name)
- def _merge_server_lists(self, existing_servers: List[str], selected_servers: List[str], previous_servers: List[str]) -> List[str]:
+ def _merge_server_lists(
+ self,
+ existing_servers: List[str],
+ selected_servers: List[str],
+ previous_servers: List[str],
+ ) -> List[str]:
"""Merge existing, selected, and previously installed servers"""
all_servers = set()
@@ -540,8 +634,10 @@ class MCPComponent(Component):
self.logger.info(f" - Previously installed: {previous_servers}")
return valid_servers
-
- def _install_mcp_server(self, server_info: Dict[str, Any], config: Dict[str, Any]) -> bool:
+
+ def _install_mcp_server(
+ self, server_info: Dict[str, Any], config: Dict[str, Any]
+ ) -> bool:
"""Install a single MCP server"""
if server_info.get("install_method") == "uv":
return self._install_uv_mcp_server(server_info, config)
@@ -553,115 +649,154 @@ class MCPComponent(Component):
install_command = server_info.get("install_command")
if not npm_package and not install_command:
- self.logger.error(f"No npm_package or install_command found for server {server_name}")
+ self.logger.error(
+ f"No npm_package or install_command found for server {server_name}"
+ )
return False
-
+
command = "npx"
-
+
try:
self.logger.info(f"Installing MCP server: {server_name}")
-
+
# Check if already installed
if self._check_mcp_server_installed(server_name):
self.logger.info(f"MCP server {server_name} already installed")
return True
-
+
# Handle API key requirements
if "api_key_env" in server_info:
api_key_env = server_info["api_key_env"]
- api_key_desc = server_info.get("api_key_description", f"API key for {server_name}")
-
+ api_key_desc = server_info.get(
+ "api_key_description", f"API key for {server_name}"
+ )
+
if not config.get("dry_run", False):
display_info(f"MCP server '{server_name}' requires an API key")
display_info(f"Environment variable: {api_key_env}")
display_info(f"Description: {api_key_desc}")
-
+
# Check if API key is already set
import os
+
if not os.getenv(api_key_env):
- display_warning(f"API key {api_key_env} not found in environment")
- self.logger.warning(f"Proceeding without {api_key_env} - server may not function properly")
-
+ display_warning(
+ f"API key {api_key_env} not found in environment"
+ )
+ self.logger.warning(
+ f"Proceeding without {api_key_env} - server may not function properly"
+ )
+
# Install using Claude CLI
if install_command:
# Use the full install command (e.g., for tavily-mcp@0.1.2)
install_args = install_command.split()
if config.get("dry_run"):
- self.logger.info(f"Would install MCP server (user scope): claude mcp add -s user {server_name} {' '.join(install_args)}")
+ self.logger.info(
+ f"Would install MCP server (user scope): claude mcp add -s user {server_name} {' '.join(install_args)}"
+ )
return True
-
- self.logger.debug(f"Running: claude mcp add -s user {server_name} {' '.join(install_args)}")
-
+
+ self.logger.debug(
+ f"Running: claude mcp add -s user {server_name} {' '.join(install_args)}"
+ )
+
result = self._run_command_cross_platform(
- ["claude", "mcp", "add", "-s", "user", "--", server_name] + install_args,
+ ["claude", "mcp", "add", "-s", "user", "--", server_name]
+ + install_args,
capture_output=True,
text=True,
- timeout=120 # 2 minutes timeout for installation
+ timeout=120, # 2 minutes timeout for installation
)
else:
# Use npm_package
if config.get("dry_run"):
- self.logger.info(f"Would install MCP server (user scope): claude mcp add -s user {server_name} {command} -y {npm_package}")
+ self.logger.info(
+ f"Would install MCP server (user scope): claude mcp add -s user {server_name} {command} -y {npm_package}"
+ )
return True
-
- self.logger.debug(f"Running: claude mcp add -s user {server_name} {command} -y {npm_package}")
-
+
+ self.logger.debug(
+ f"Running: claude mcp add -s user {server_name} {command} -y {npm_package}"
+ )
+
result = self._run_command_cross_platform(
- ["claude", "mcp", "add", "-s", "user", "--", server_name, command, "-y", npm_package],
+ [
+ "claude",
+ "mcp",
+ "add",
+ "-s",
+ "user",
+ "--",
+ server_name,
+ command,
+ "-y",
+ npm_package,
+ ],
capture_output=True,
text=True,
- timeout=120 # 2 minutes timeout for installation
+ timeout=120, # 2 minutes timeout for installation
)
-
+
if result.returncode == 0:
- self.logger.success(f"Successfully installed MCP server (user scope): {server_name}")
+ self.logger.success(
+ f"Successfully installed MCP server (user scope): {server_name}"
+ )
return True
else:
error_msg = result.stderr.strip() if result.stderr else "Unknown error"
- self.logger.error(f"Failed to install MCP server {server_name}: {error_msg}")
+ self.logger.error(
+ f"Failed to install MCP server {server_name}: {error_msg}"
+ )
return False
-
+
except subprocess.TimeoutExpired:
self.logger.error(f"Timeout installing MCP server {server_name}")
return False
except Exception as e:
self.logger.error(f"Error installing MCP server {server_name}: {e}")
return False
-
+
def _uninstall_mcp_server(self, server_name: str) -> bool:
"""Uninstall a single MCP server"""
try:
self.logger.info(f"Uninstalling MCP server: {server_name}")
-
+
# Check if installed
if not self._check_mcp_server_installed(server_name):
self.logger.info(f"MCP server {server_name} not installed")
return True
-
- self.logger.debug(f"Running: claude mcp remove {server_name} (auto-detect scope)")
-
+
+ self.logger.debug(
+ f"Running: claude mcp remove {server_name} (auto-detect scope)"
+ )
+
result = self._run_command_cross_platform(
["claude", "mcp", "remove", server_name],
capture_output=True,
text=True,
- timeout=60
+ timeout=60,
)
-
+
if result.returncode == 0:
- self.logger.success(f"Successfully uninstalled MCP server: {server_name}")
+ self.logger.success(
+ f"Successfully uninstalled MCP server: {server_name}"
+ )
return True
else:
error_msg = result.stderr.strip() if result.stderr else "Unknown error"
- self.logger.error(f"Failed to uninstall MCP server {server_name}: {error_msg}")
+ self.logger.error(
+ f"Failed to uninstall MCP server {server_name}: {error_msg}"
+ )
return False
-
+
except subprocess.TimeoutExpired:
self.logger.error(f"Timeout uninstalling MCP server {server_name}")
return False
except Exception as e:
self.logger.error(f"Error uninstalling MCP server {server_name}: {e}")
return False
-
+
def _install(self, config: Dict[str, Any]) -> bool:
"""Install MCP component with auto-detection of existing servers"""
self.logger.info("Installing SuperClaude MCP servers...")
@@ -686,10 +821,14 @@ class MCPComponent(Component):
previous_servers = self.settings_manager.get_metadata_setting("mcp.servers", [])
# Merge all server lists
- all_servers = self._merge_server_lists(existing_servers, selected_servers, previous_servers)
+ all_servers = self._merge_server_lists(
+ existing_servers, selected_servers, previous_servers
+ )
if not all_servers:
- self.logger.info("No MCP servers detected or selected. Skipping MCP installation.")
+ self.logger.info(
+ "No MCP servers detected or selected. Skipping MCP installation."
+ )
# Still run post-install to update metadata
return self._post_install()
@@ -706,7 +845,9 @@ class MCPComponent(Component):
# Check if already installed and working
if self._check_mcp_server_installed(server_name):
- self.logger.info(f"MCP server {server_name} already installed and working")
+ self.logger.info(
+ f"MCP server {server_name} already installed and working"
+ )
installed_count += 1
verified_servers.append(server_name)
else:
@@ -719,10 +860,14 @@ class MCPComponent(Component):
# Check if this is a required server
if server_info.get("required", False):
- self.logger.error(f"Required MCP server {server_name} failed to install")
+ self.logger.error(
+ f"Required MCP server {server_name} failed to install"
+ )
return False
else:
- self.logger.warning(f"Unknown MCP server '{server_name}' cannot be managed by SuperClaude")
+ self.logger.warning(
+ f"Unknown MCP server '{server_name}' cannot be managed by SuperClaude"
+ )
# Update the list of successfully managed servers
self.installed_servers_in_session = verified_servers
@@ -735,12 +880,12 @@ class MCPComponent(Component):
["claude", "mcp", "list"],
capture_output=True,
text=True,
- timeout=60
+ timeout=60,
)
if result.returncode == 0:
self.logger.debug("MCP servers list:")
- for line in result.stdout.strip().split('\n'):
+ for line in result.stdout.strip().split("\n"):
if line.strip():
self.logger.debug(f" {line.strip()}")
else:
@@ -751,9 +896,13 @@ class MCPComponent(Component):
if failed_servers:
self.logger.warning(f"Some MCP servers failed to install: {failed_servers}")
- self.logger.success(f"MCP component partially managed ({installed_count} servers)")
+ self.logger.success(
+ f"MCP component partially managed ({installed_count} servers)"
+ )
else:
- self.logger.success(f"MCP component successfully managing ({installed_count} servers)")
+ self.logger.success(
+ f"MCP component successfully managing ({installed_count} servers)"
+ )
return self._post_install()
@@ -765,31 +914,34 @@ class MCPComponent(Component):
self.settings_manager.update_metadata(metadata_mods)
# Add component registration to metadata
- self.settings_manager.add_component_registration("mcp", {
- "version": __version__,
- "category": "integration",
- "servers_count": len(self.installed_servers_in_session),
- "installed_servers": self.installed_servers_in_session
- })
+ self.settings_manager.add_component_registration(
+ "mcp",
+ {
+ "version": __version__,
+ "category": "integration",
+ "servers_count": len(self.installed_servers_in_session),
+ "installed_servers": self.installed_servers_in_session,
+ },
+ )
self.logger.info("Updated metadata with MCP component registration")
return True
except Exception as e:
self.logger.error(f"Failed to update metadata: {e}")
return False
-
+
def uninstall(self) -> bool:
"""Uninstall MCP component"""
try:
self.logger.info("Uninstalling SuperClaude MCP servers...")
-
+
# Uninstall each MCP server
uninstalled_count = 0
-
+
for server_name in self.mcp_servers.keys():
if self._uninstall_mcp_server(server_name):
uninstalled_count += 1
-
+
# Update metadata to remove MCP component
try:
if self.settings_manager.is_component_installed("mcp"):
@@ -802,118 +954,133 @@ class MCPComponent(Component):
self.logger.info("Removed MCP component from metadata")
except Exception as e:
self.logger.warning(f"Could not update metadata: {e}")
-
- self.logger.success(f"MCP component uninstalled ({uninstalled_count} servers removed)")
+
+ self.logger.success(
+ f"MCP component uninstalled ({uninstalled_count} servers removed)"
+ )
return True
-
+
except Exception as e:
self.logger.exception(f"Unexpected error during MCP uninstallation: {e}")
return False
-
+
def get_dependencies(self) -> List[str]:
"""Get dependencies"""
return ["core"]
-
+
def update(self, config: Dict[str, Any]) -> bool:
"""Update MCP component"""
try:
self.logger.info("Updating SuperClaude MCP servers...")
-
+
# Check current version
current_version = self.settings_manager.get_component_version("mcp")
target_version = self.get_metadata()["version"]
-
+
if current_version == target_version:
self.logger.info(f"MCP component already at version {target_version}")
return True
-
- self.logger.info(f"Updating MCP component from {current_version} to {target_version}")
-
+
+ self.logger.info(
+ f"Updating MCP component from {current_version} to {target_version}"
+ )
+
# For MCP servers, update means reinstall to get latest versions
updated_count = 0
failed_servers = []
-
+
for server_name, server_info in self.mcp_servers.items():
try:
# Uninstall old version
if self._check_mcp_server_installed(server_name):
self._uninstall_mcp_server(server_name)
-
+
# Install new version
if self._install_mcp_server(server_info, config):
updated_count += 1
else:
failed_servers.append(server_name)
-
+
except Exception as e:
self.logger.error(f"Error updating MCP server {server_name}: {e}")
failed_servers.append(server_name)
-
+
# Update metadata
try:
# Update component version in metadata
metadata = self.settings_manager.load_metadata()
if "components" in metadata and "mcp" in metadata["components"]:
metadata["components"]["mcp"]["version"] = target_version
- metadata["components"]["mcp"]["servers_count"] = len(self.mcp_servers)
+ metadata["components"]["mcp"]["servers_count"] = len(
+ self.mcp_servers
+ )
if "mcp" in metadata:
metadata["mcp"]["servers"] = list(self.mcp_servers.keys())
self.settings_manager.save_metadata(metadata)
except Exception as e:
self.logger.warning(f"Could not update metadata: {e}")
-
+
if failed_servers:
- self.logger.warning(f"Some MCP servers failed to update: {failed_servers}")
+ self.logger.warning(
+ f"Some MCP servers failed to update: {failed_servers}"
+ )
return False
else:
- self.logger.success(f"MCP component updated to version {target_version}")
+ self.logger.success(
+ f"MCP component updated to version {target_version}"
+ )
return True
-
+
except Exception as e:
self.logger.exception(f"Unexpected error during MCP update: {e}")
return False
-
+
def validate_installation(self) -> Tuple[bool, List[str]]:
"""Validate MCP component installation"""
errors = []
-
+
# Check metadata registration
if not self.settings_manager.is_component_installed("mcp"):
errors.append("MCP component not registered in metadata")
return False, errors
-
+
# Check version matches
installed_version = self.settings_manager.get_component_version("mcp")
expected_version = self.get_metadata()["version"]
if installed_version != expected_version:
- errors.append(f"Version mismatch: installed {installed_version}, expected {expected_version}")
-
+ errors.append(
+ f"Version mismatch: installed {installed_version}, expected {expected_version}"
+ )
+
# Check if Claude CLI is available and validate installed servers
try:
result = self._run_command_cross_platform(
- ["claude", "mcp", "list"],
- capture_output=True,
- text=True,
- timeout=60
+ ["claude", "mcp", "list"], capture_output=True, text=True, timeout=60
)
if result.returncode != 0:
- errors.append("Could not communicate with Claude CLI for MCP server verification")
+ errors.append(
+ "Could not communicate with Claude CLI for MCP server verification"
+ )
else:
claude_mcp_output = result.stdout.lower()
# Get the list of servers that should be installed from metadata
- installed_servers = self.settings_manager.get_metadata_setting("mcp.servers", [])
+ installed_servers = self.settings_manager.get_metadata_setting(
+ "mcp.servers", []
+ )
for server_name in installed_servers:
if server_name.lower() not in claude_mcp_output:
- errors.append(f"Installed MCP server '{server_name}' not found in 'claude mcp list' output.")
+ errors.append(
+ f"Installed MCP server '{server_name}' not found in 'claude mcp list' output."
+ )
except Exception as e:
errors.append(f"Could not verify MCP server installation: {e}")
-
+
return len(errors) == 0, errors
-
+
def _get_source_dir(self):
"""Get source directory for framework files"""
return None
@@ -923,7 +1090,7 @@ class MCPComponent(Component):
# MCP servers are installed via npm, estimate based on typical sizes
base_size = 50 * 1024 * 1024 # ~50MB for all servers combined
return base_size
-
+
def get_installation_summary(self) -> Dict[str, Any]:
"""Get installation summary"""
return {
@@ -933,5 +1100,5 @@ class MCPComponent(Component):
"mcp_servers": list(self.mcp_servers.keys()),
"estimated_size": self.get_size_estimate(),
"dependencies": self.get_dependencies(),
- "required_tools": ["node", "npm", "claude"]
- }
+ "required_tools": ["node", "npm", "claude"],
+ }
diff --git a/setup/components/mcp_docs.py b/setup/components/mcp_docs.py
index 36395d9..b2ee722 100644
--- a/setup/components/mcp_docs.py
+++ b/setup/components/mcp_docs.py
@@ -12,13 +12,13 @@ from ..services.claude_md import CLAUDEMdService
class MCPDocsComponent(Component):
"""MCP documentation component - installs docs for selected MCP servers"""
-
+
def __init__(self, install_dir: Optional[Path] = None):
"""Initialize MCP docs component"""
# Initialize attributes before calling parent constructor
# because parent calls _discover_component_files() which needs these
self.selected_servers: List[str] = []
-
+
# Map server names to documentation files
self.server_docs_map = {
"context7": "MCP_Context7.md",
@@ -29,18 +29,18 @@ class MCPDocsComponent(Component):
"serena": "MCP_Serena.md",
"morphllm": "MCP_Morphllm.md",
"morphllm-fast-apply": "MCP_Morphllm.md", # Handle both naming conventions
- "tavily": "MCP_Tavily.md"
+ "tavily": "MCP_Tavily.md",
}
-
+
super().__init__(install_dir, Path(""))
-
+
def get_metadata(self) -> Dict[str, str]:
"""Get component metadata"""
return {
"name": "mcp_docs",
"version": __version__,
"description": "MCP server documentation and usage guides",
- "category": "documentation"
+ "category": "documentation",
}
def is_reinstallable(self) -> bool:
@@ -54,11 +54,11 @@ class MCPDocsComponent(Component):
"""Set which MCP servers were selected for documentation installation"""
self.selected_servers = selected_servers
self.logger.debug(f"MCP docs will be installed for: {selected_servers}")
-
+
def get_files_to_install(self) -> List[Tuple[Path, Path]]:
"""
Return list of files to install based on selected MCP servers
-
+
Returns:
List of tuples (source_path, target_path)
"""
@@ -73,12 +73,16 @@ class MCPDocsComponent(Component):
target = self.install_dir / doc_file
if source.exists():
files.append((source, target))
- self.logger.debug(f"Will install documentation for {server_name}: {doc_file}")
+ self.logger.debug(
+ f"Will install documentation for {server_name}: {doc_file}"
+ )
else:
- self.logger.warning(f"Documentation file not found for {server_name}: {doc_file}")
+ self.logger.warning(
+ f"Documentation file not found for {server_name}: {doc_file}"
+ )
return files
-
+
def _discover_component_files(self) -> List[str]:
"""
Override parent method to dynamically discover files based on selected servers
@@ -90,7 +94,7 @@ class MCPDocsComponent(Component):
if server_name in self.server_docs_map:
files.append(self.server_docs_map[server_name])
return files
-
+
def _detect_existing_mcp_servers_from_config(self) -> List[str]:
"""Detect existing MCP servers from Claude Desktop config"""
detected_servers = []
@@ -101,8 +105,16 @@ class MCPDocsComponent(Component):
self.install_dir / "claude_desktop_config.json",
Path.home() / ".claude" / "claude_desktop_config.json",
Path.home() / ".claude.json", # Claude CLI config
- Path.home() / "AppData" / "Roaming" / "Claude" / "claude_desktop_config.json", # Windows
- Path.home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json", # macOS
+ Path.home()
+ / "AppData"
+ / "Roaming"
+ / "Claude"
+ / "claude_desktop_config.json", # Windows
+ Path.home()
+ / "Library"
+ / "Application Support"
+ / "Claude"
+ / "claude_desktop_config.json", # macOS
]
config_file = None
@@ -116,7 +128,8 @@ class MCPDocsComponent(Component):
return detected_servers
import json
- with open(config_file, 'r') as f:
+
+ with open(config_file, "r") as f:
config = json.load(f)
# Extract MCP server names from mcpServers section
@@ -128,7 +141,9 @@ class MCPDocsComponent(Component):
detected_servers.append(normalized_name)
if detected_servers:
- self.logger.info(f"Detected existing MCP servers from config: {detected_servers}")
+ self.logger.info(
+ f"Detected existing MCP servers from config: {detected_servers}"
+ )
except Exception as e:
self.logger.warning(f"Could not read Claude Desktop config: {e}")
@@ -152,7 +167,7 @@ class MCPDocsComponent(Component):
"serena": "serena",
"morphllm": "morphllm",
"morphllm-fast-apply": "morphllm",
- "morph": "morphllm"
+ "morph": "morphllm",
}
return name_mappings.get(server_name)
@@ -169,7 +184,9 @@ class MCPDocsComponent(Component):
selected_servers = config.get("selected_mcp_servers", [])
# Get previously documented servers from metadata
- previous_servers = self.settings_manager.get_metadata_setting("components.mcp_docs.servers_documented", [])
+ previous_servers = self.settings_manager.get_metadata_setting(
+ "components.mcp_docs.servers_documented", []
+ )
# Merge all server lists
all_servers = list(set(detected_servers + selected_servers + previous_servers))
@@ -178,13 +195,17 @@ class MCPDocsComponent(Component):
valid_servers = [s for s in all_servers if s in self.server_docs_map]
if not valid_servers:
- self.logger.info("No MCP servers detected or selected for documentation installation")
+ self.logger.info(
+ "No MCP servers detected or selected for documentation installation"
+ )
# Still proceed to update metadata
self.set_selected_servers([])
self.component_files = []
return self._post_install()
- self.logger.info(f"Installing documentation for MCP servers: {', '.join(valid_servers)}")
+ self.logger.info(
+ f"Installing documentation for MCP servers: {', '.join(valid_servers)}"
+ )
if detected_servers:
self.logger.info(f" - Detected from config: {detected_servers}")
if selected_servers:
@@ -225,12 +246,16 @@ class MCPDocsComponent(Component):
self.logger.error(f"Failed to copy {source.name}")
if success_count != len(files_to_install):
- self.logger.error(f"Only {success_count}/{len(files_to_install)} documentation files copied successfully")
+ self.logger.error(
+ f"Only {success_count}/{len(files_to_install)} documentation files copied successfully"
+ )
return False
# Update component_files to only include successfully copied files
self.component_files = successfully_copied_files
- self.logger.success(f"MCP documentation installed successfully ({success_count} files for {len(valid_servers)} servers)")
+ self.logger.success(
+ f"MCP documentation installed successfully ({success_count} files for {len(valid_servers)} servers)"
+ )
return self._post_install()
@@ -244,36 +269,38 @@ class MCPDocsComponent(Component):
"version": __version__,
"installed": True,
"files_count": len(self.component_files),
- "servers_documented": self.selected_servers
+ "servers_documented": self.selected_servers,
}
}
}
self.settings_manager.update_metadata(metadata_mods)
self.logger.info("Updated metadata with MCP docs component registration")
-
+
# Update CLAUDE.md with MCP documentation imports
try:
manager = CLAUDEMdService(self.install_dir)
manager.add_imports(self.component_files, category="MCP Documentation")
self.logger.info("Updated CLAUDE.md with MCP documentation imports")
except Exception as e:
- self.logger.warning(f"Failed to update CLAUDE.md with MCP documentation imports: {e}")
+ self.logger.warning(
+ f"Failed to update CLAUDE.md with MCP documentation imports: {e}"
+ )
# Don't fail the whole installation for this
-
+
return True
except Exception as e:
self.logger.error(f"Failed to update metadata: {e}")
return False
-
+
def uninstall(self) -> bool:
"""Uninstall MCP documentation component"""
try:
self.logger.info("Uninstalling MCP documentation component...")
-
+
# Remove all MCP documentation files
removed_count = 0
source_dir = self._get_source_dir()
-
+
if source_dir and source_dir.exists():
# Remove all possible MCP doc files
for doc_file in self.server_docs_map.values():
@@ -281,7 +308,7 @@ class MCPDocsComponent(Component):
if self.file_manager.remove_file(file_path):
removed_count += 1
self.logger.debug(f"Removed {doc_file}")
-
+
# Remove mcp directory if empty
try:
if self.install_component_subdir.exists():
@@ -291,7 +318,7 @@ class MCPDocsComponent(Component):
self.logger.debug("Removed empty mcp directory")
except Exception as e:
self.logger.warning(f"Could not remove mcp directory: {e}")
-
+
# Update settings.json
try:
if self.settings_manager.is_component_installed("mcp_docs"):
@@ -299,36 +326,40 @@ class MCPDocsComponent(Component):
self.logger.info("Removed MCP docs component from settings.json")
except Exception as e:
self.logger.warning(f"Could not update settings.json: {e}")
-
- self.logger.success(f"MCP documentation uninstalled ({removed_count} files removed)")
+
+ self.logger.success(
+ f"MCP documentation uninstalled ({removed_count} files removed)"
+ )
return True
-
+
except Exception as e:
- self.logger.exception(f"Unexpected error during MCP docs uninstallation: {e}")
+ self.logger.exception(
+ f"Unexpected error during MCP docs uninstallation: {e}"
+ )
return False
-
+
def get_dependencies(self) -> List[str]:
"""Get dependencies"""
return ["core"]
-
+
def _get_source_dir(self) -> Optional[Path]:
"""Get source directory for MCP documentation files"""
- # Assume we're in SuperClaude/setup/components/mcp_docs.py
- # and MCP docs are in SuperClaude/SuperClaude/MCP/
+ # Assume we're in superclaude/setup/components/mcp_docs.py
+ # and MCP docs are in superclaude/superclaude/MCP/
project_root = Path(__file__).parent.parent.parent
- mcp_dir = project_root / "SuperClaude" / "MCP"
-
+ mcp_dir = project_root / "superclaude" / "mcp"
+
# Return None if directory doesn't exist to prevent warning
if not mcp_dir.exists():
return None
-
+
return mcp_dir
-
+
def get_size_estimate(self) -> int:
"""Get estimated installation size"""
source_dir = self._get_source_dir()
total_size = 0
-
+
if source_dir and source_dir.exists() and self.selected_servers:
for server_name in self.selected_servers:
if server_name in self.server_docs_map:
@@ -336,8 +367,8 @@ class MCPDocsComponent(Component):
file_path = source_dir / doc_file
if file_path.exists():
total_size += file_path.stat().st_size
-
+
# Minimum size estimate
total_size = max(total_size, 10240) # At least 10KB
-
- return total_size
\ No newline at end of file
+
+ return total_size
diff --git a/setup/components/modes.py b/setup/components/modes.py
index d9839a0..82dea98 100644
--- a/setup/components/modes.py
+++ b/setup/components/modes.py
@@ -12,20 +12,20 @@ from ..services.claude_md import CLAUDEMdService
class ModesComponent(Component):
"""SuperClaude behavioral modes component"""
-
+
def __init__(self, install_dir: Optional[Path] = None):
"""Initialize modes component"""
super().__init__(install_dir, Path(""))
-
+
def get_metadata(self) -> Dict[str, str]:
"""Get component metadata"""
return {
"name": "modes",
"version": __version__,
"description": "7 behavioral modes for enhanced Claude Code operation",
- "category": "modes"
+ "category": "modes",
}
-
+
def _install(self, config: Dict[str, Any]) -> bool:
"""Install modes component"""
self.logger.info("Installing SuperClaude behavioral modes...")
@@ -48,7 +48,7 @@ class ModesComponent(Component):
success_count = 0
for source, target in files_to_install:
self.logger.debug(f"Copying {source.name} to {target}")
-
+
if self.file_manager.copy_file(source, target):
success_count += 1
self.logger.debug(f"Successfully copied {source.name}")
@@ -56,10 +56,14 @@ class ModesComponent(Component):
self.logger.error(f"Failed to copy {source.name}")
if success_count != len(files_to_install):
- self.logger.error(f"Only {success_count}/{len(files_to_install)} mode files copied successfully")
+ self.logger.error(
+ f"Only {success_count}/{len(files_to_install)} mode files copied successfully"
+ )
return False
- self.logger.success(f"Modes component installed successfully ({success_count} mode files)")
+ self.logger.success(
+ f"Modes component installed successfully ({success_count} mode files)"
+ )
return self._post_install()
@@ -72,39 +76,41 @@ class ModesComponent(Component):
"modes": {
"version": __version__,
"installed": True,
- "files_count": len(self.component_files)
+ "files_count": len(self.component_files),
}
}
}
self.settings_manager.update_metadata(metadata_mods)
self.logger.info("Updated metadata with modes component registration")
-
+
# Update CLAUDE.md with mode imports
try:
manager = CLAUDEMdService(self.install_dir)
manager.add_imports(self.component_files, category="Behavioral Modes")
self.logger.info("Updated CLAUDE.md with mode imports")
except Exception as e:
- self.logger.warning(f"Failed to update CLAUDE.md with mode imports: {e}")
+ self.logger.warning(
+ f"Failed to update CLAUDE.md with mode imports: {e}"
+ )
# Don't fail the whole installation for this
-
+
return True
except Exception as e:
self.logger.error(f"Failed to update metadata: {e}")
return False
-
+
def uninstall(self) -> bool:
"""Uninstall modes component"""
try:
self.logger.info("Uninstalling SuperClaude modes component...")
-
+
# Remove mode files
removed_count = 0
for _, target in self.get_files_to_install():
if self.file_manager.remove_file(target):
removed_count += 1
self.logger.debug(f"Removed {target.name}")
-
+
# Remove modes directory if empty
try:
if self.install_component_subdir.exists():
@@ -114,7 +120,7 @@ class ModesComponent(Component):
self.logger.debug("Removed empty modes directory")
except Exception as e:
self.logger.warning(f"Could not remove modes directory: {e}")
-
+
# Update settings.json
try:
if self.settings_manager.is_component_installed("modes"):
@@ -122,43 +128,45 @@ class ModesComponent(Component):
self.logger.info("Removed modes component from settings.json")
except Exception as e:
self.logger.warning(f"Could not update settings.json: {e}")
-
- self.logger.success(f"Modes component uninstalled ({removed_count} files removed)")
+
+ self.logger.success(
+ f"Modes component uninstalled ({removed_count} files removed)"
+ )
return True
-
+
except Exception as e:
self.logger.exception(f"Unexpected error during modes uninstallation: {e}")
return False
-
+
def get_dependencies(self) -> List[str]:
"""Get dependencies"""
return ["core"]
-
+
def _get_source_dir(self) -> Optional[Path]:
"""Get source directory for mode files"""
- # Assume we're in SuperClaude/setup/components/modes.py
- # and mode files are in SuperClaude/SuperClaude/Modes/
+ # Assume we're in superclaude/setup/components/modes.py
+ # and mode files are in superclaude/superclaude/Modes/
project_root = Path(__file__).parent.parent.parent
- modes_dir = project_root / "SuperClaude" / "Modes"
-
+ modes_dir = project_root / "superclaude" / "modes"
+
# Return None if directory doesn't exist to prevent warning
if not modes_dir.exists():
return None
-
+
return modes_dir
-
+
def get_size_estimate(self) -> int:
"""Get estimated installation size"""
source_dir = self._get_source_dir()
total_size = 0
-
+
if source_dir and source_dir.exists():
for filename in self.component_files:
file_path = source_dir / filename
if file_path.exists():
total_size += file_path.stat().st_size
-
+
# Minimum size estimate
total_size = max(total_size, 20480) # At least 20KB
-
- return total_size
\ No newline at end of file
+
+ return total_size
diff --git a/setup/core/__init__.py b/setup/core/__init__.py
index e330c35..947dd14 100644
--- a/setup/core/__init__.py
+++ b/setup/core/__init__.py
@@ -3,7 +3,4 @@
from .validator import Validator
from .registry import ComponentRegistry
-__all__ = [
- 'Validator',
- 'ComponentRegistry'
-]
+__all__ = ["Validator", "ComponentRegistry"]
diff --git a/setup/core/base.py b/setup/core/base.py
index 75e49c2..caf0534 100644
--- a/setup/core/base.py
+++ b/setup/core/base.py
@@ -14,15 +14,18 @@ from ..utils.security import SecurityValidator
class Component(ABC):
"""Base class for all installable components"""
-
- def __init__(self, install_dir: Optional[Path] = None, component_subdir: Path = Path('')):
+
+ def __init__(
+ self, install_dir: Optional[Path] = None, component_subdir: Path = Path("")
+ ):
"""
Initialize component with installation directory
-
+
Args:
install_dir: Target installation directory (defaults to ~/.claude)
"""
from .. import DEFAULT_INSTALL_DIR
+
# Initialize logger first
self.logger = get_logger()
# Resolve path safely
@@ -31,12 +34,12 @@ class Component(ABC):
self.component_files = self._discover_component_files()
self.file_manager = FileService()
self.install_component_subdir = self.install_dir / component_subdir
-
+
@abstractmethod
def get_metadata(self) -> Dict[str, str]:
"""
Return component metadata
-
+
Returns:
Dict containing:
- name: Component name
@@ -52,11 +55,13 @@ class Component(ABC):
Useful for container-like components that can install sub-parts.
"""
return False
-
- def validate_prerequisites(self, installSubPath: Optional[Path] = None) -> Tuple[bool, List[str]]:
+
+ def validate_prerequisites(
+ self, installSubPath: Optional[Path] = None
+ ) -> Tuple[bool, List[str]]:
"""
Check prerequisites for this component
-
+
Returns:
Tuple of (success: bool, error_messages: List[str])
"""
@@ -80,13 +85,15 @@ class Component(ABC):
# Check write permissions to install directory
has_perms, missing = SecurityValidator.check_permissions(
- self.install_dir, {'write'}
+ self.install_dir, {"write"}
)
if not has_perms:
errors.append(f"No write permissions to {self.install_dir}: {missing}")
# Validate installation target
- is_safe, validation_errors = SecurityValidator.validate_installation_target(self.install_component_subdir)
+ is_safe, validation_errors = SecurityValidator.validate_installation_target(
+ self.install_component_subdir
+ )
if not is_safe:
errors.extend(validation_errors)
@@ -101,14 +108,16 @@ class Component(ABC):
errors.extend(security_errors)
if not self.file_manager.ensure_directory(self.install_component_subdir):
- errors.append(f"Could not create install directory: {self.install_component_subdir}")
+ errors.append(
+ f"Could not create install directory: {self.install_component_subdir}"
+ )
return len(errors) == 0, errors
-
+
def get_files_to_install(self) -> List[Tuple[Path, Path]]:
"""
Return list of files to install
-
+
Returns:
List of tuples (source_path, target_path)
"""
@@ -122,7 +131,7 @@ class Component(ABC):
files.append((source, target))
return files
-
+
def get_settings_modifications(self) -> Dict[str, Any]:
"""
Return settings.json modifications to apply
@@ -133,22 +142,24 @@ class Component(ABC):
"""
# Return empty dict as we don't modify Claude Code settings
return {}
-
+
def install(self, config: Dict[str, Any]) -> bool:
try:
return self._install(config)
except Exception as e:
- self.logger.exception(f"Unexpected error during {repr(self)} installation: {e}")
+ self.logger.exception(
+ f"Unexpected error during {repr(self)} installation: {e}"
+ )
return False
@abstractmethod
def _install(self, config: Dict[str, Any]) -> bool:
"""
Perform component-specific installation logic
-
+
Args:
config: Installation configuration
-
+
Returns:
True if successful, False otherwise
"""
@@ -174,34 +185,36 @@ class Component(ABC):
self.logger.error(f"Failed to copy {source.name}")
if success_count != len(files_to_install):
- self.logger.error(f"Only {success_count}/{len(files_to_install)} files copied successfully")
+ self.logger.error(
+ f"Only {success_count}/{len(files_to_install)} files copied successfully"
+ )
return False
- self.logger.success(f"{repr(self)} component installed successfully ({success_count} files)")
+ self.logger.success(
+ f"{repr(self)} component installed successfully ({success_count} files)"
+ )
return self._post_install()
-
@abstractmethod
def _post_install(self) -> bool:
pass
-
@abstractmethod
def uninstall(self) -> bool:
"""
Remove component
-
+
Returns:
True if successful, False otherwise
"""
pass
-
+
@abstractmethod
def get_dependencies(self) -> List[str]:
"""
Return list of component dependencies
-
+
Returns:
List of component names this component depends on
"""
@@ -211,14 +224,14 @@ class Component(ABC):
def _get_source_dir(self) -> Optional[Path]:
"""Get source directory for component files"""
pass
-
+
def update(self, config: Dict[str, Any]) -> bool:
"""
Update component (default: uninstall then install)
-
+
Args:
config: Installation configuration
-
+
Returns:
True if successful, False otherwise
"""
@@ -226,11 +239,11 @@ class Component(ABC):
if self.uninstall():
return self.install(config)
return False
-
+
def get_installed_version(self) -> Optional[str]:
"""
Get currently installed version of component
-
+
Returns:
Version string if installed, None otherwise
"""
@@ -239,10 +252,14 @@ class Component(ABC):
if metadata_file.exists():
self.logger.debug("Metadata file exists, reading version")
try:
- with open(metadata_file, 'r') as f:
+ with open(metadata_file, "r") as f:
metadata = json.load(f)
- component_name = self.get_metadata()['name']
- version = metadata.get('components', {}).get(component_name, {}).get('version')
+ component_name = self.get_metadata()["name"]
+ version = (
+ metadata.get("components", {})
+ .get(component_name, {})
+ .get("version")
+ )
self.logger.debug(f"Found version: {version}")
return version
except Exception as e:
@@ -250,40 +267,40 @@ class Component(ABC):
else:
self.logger.debug("Metadata file does not exist")
return None
-
+
def is_installed(self) -> bool:
"""
Check if component is installed
-
+
Returns:
True if installed, False otherwise
"""
return self.get_installed_version() is not None
-
+
def validate_installation(self) -> Tuple[bool, List[str]]:
"""
Validate that component is correctly installed
-
+
Returns:
Tuple of (success: bool, error_messages: List[str])
"""
errors = []
-
+
# Check if all files exist
for _, target in self.get_files_to_install():
if not target.exists():
errors.append(f"Missing file: {target}")
-
+
# Check version in metadata
if not self.get_installed_version():
errors.append("Component not registered in .superclaude-metadata.json")
-
+
return len(errors) == 0, errors
-
+
def get_size_estimate(self) -> int:
"""
Estimate installed size in bytes
-
+
Returns:
Estimated size in bytes
"""
@@ -293,7 +310,9 @@ class Component(ABC):
if source.is_file():
total_size += source.stat().st_size
elif source.is_dir():
- total_size += sum(f.stat().st_size for f in source.rglob('*') if f.is_file())
+ total_size += sum(
+ f.stat().st_size for f in source.rglob("*") if f.is_file()
+ )
return total_size
def _discover_component_files(self) -> List[str]:
@@ -310,12 +329,16 @@ class Component(ABC):
return self._discover_files_in_directory(
source_dir,
- extension='.md',
- exclude_patterns=['README.md', 'CHANGELOG.md', 'LICENSE.md']
+ extension=".md",
+ exclude_patterns=["README.md", "CHANGELOG.md", "LICENSE.md"],
)
- def _discover_files_in_directory(self, directory: Path, extension: str = '.md',
- exclude_patterns: Optional[List[str]] = None) -> List[str]:
+ def _discover_files_in_directory(
+ self,
+ directory: Path,
+ extension: str = ".md",
+ exclude_patterns: Optional[List[str]] = None,
+ ) -> List[str]:
"""
Shared utility for discovering files in a directory
@@ -342,15 +365,19 @@ class Component(ABC):
# Discover files with the specified extension
files = []
for file_path in directory.iterdir():
- if (file_path.is_file() and
- file_path.suffix.lower() == extension.lower() and
- file_path.name not in exclude_patterns):
+ if (
+ file_path.is_file()
+ and file_path.suffix.lower() == extension.lower()
+ and file_path.name not in exclude_patterns
+ ):
files.append(file_path.name)
# Sort for consistent ordering
files.sort()
- self.logger.debug(f"Discovered {len(files)} {extension} files in {directory}")
+ self.logger.debug(
+ f"Discovered {len(files)} {extension} files in {directory}"
+ )
if files:
self.logger.debug(f"Files found: {files}")
@@ -362,65 +389,74 @@ class Component(ABC):
except Exception as e:
self.logger.error(f"Error discovering files in {directory}: {e}")
return []
-
+
def __str__(self) -> str:
"""String representation of component"""
metadata = self.get_metadata()
return f"{metadata['name']} v{metadata['version']}"
-
+
def __repr__(self) -> str:
"""Developer representation of component"""
return f"<{self.__class__.__name__}({self.get_metadata()['name']})>"
-
+
def _resolve_path_safely(self, path: Path) -> Path:
"""
Safely resolve path with proper error handling and security validation
-
+
Args:
path: Path to resolve
-
+
Returns:
Resolved path
-
+
Raises:
ValueError: If path resolution fails or path is unsafe
"""
try:
# Expand user directory (~) and resolve path
resolved_path = path.expanduser().resolve()
-
+
# Basic security validation - only enforce for production directories
path_str = str(resolved_path).lower()
-
+
# Check for most dangerous system patterns (but allow /tmp for testing)
dangerous_patterns = [
- '/etc/', '/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/',
- '/var/log/', '/var/lib/', '/dev/', '/proc/', '/sys/',
- 'c:\\windows\\', 'c:\\program files\\'
+ "/etc/",
+ "/bin/",
+ "/sbin/",
+ "/usr/bin/",
+ "/usr/sbin/",
+ "/var/log/",
+ "/var/lib/",
+ "/dev/",
+ "/proc/",
+ "/sys/",
+ "c:\\windows\\",
+ "c:\\program files\\",
]
-
+
# Allow temporary directories for testing
- if path_str.startswith('/tmp/') or 'temp' in path_str:
+ if path_str.startswith("/tmp/") or "temp" in path_str:
self.logger.debug(f"Allowing temporary directory: {resolved_path}")
return resolved_path
-
+
for pattern in dangerous_patterns:
if path_str.startswith(pattern):
raise ValueError(f"Cannot use system directory: {resolved_path}")
-
+
return resolved_path
-
+
except Exception as e:
self.logger.error(f"Failed to resolve path {path}: {e}")
raise ValueError(f"Invalid path: {path}")
-
+
def _resolve_source_path_safely(self, path: Path) -> Optional[Path]:
"""
Safely resolve source path with existence check
-
+
Args:
path: Source path to resolve
-
+
Returns:
Resolved path if valid and exists, None otherwise
"""
diff --git a/setup/core/installer.py b/setup/core/installer.py
index 007ab6d..a6f1924 100644
--- a/setup/core/installer.py
+++ b/setup/core/installer.py
@@ -14,23 +14,25 @@ from ..utils.logger import get_logger
class Installer:
"""Main installer orchestrator"""
- def __init__(self,
- install_dir: Optional[Path] = None,
- dry_run: bool = False):
+ def __init__(self, install_dir: Optional[Path] = None, dry_run: bool = False):
"""
Initialize installer
-
+
Args:
install_dir: Target installation directory
dry_run: If True, only simulate installation
"""
from .. import DEFAULT_INSTALL_DIR
+
self.install_dir = install_dir or DEFAULT_INSTALL_DIR
self.dry_run = dry_run
self.components: Dict[str, Component] = {}
from ..services.settings import SettingsService
+
settings_manager = SettingsService(self.install_dir)
- self.installed_components: Set[str] = set(settings_manager.get_installed_components().keys())
+ self.installed_components: Set[str] = set(
+ settings_manager.get_installed_components().keys()
+ )
self.updated_components: Set[str] = set()
self.failed_components: Set[str] = set()
@@ -41,17 +43,17 @@ class Installer:
def register_component(self, component: Component) -> None:
"""
Register a component for installation
-
+
Args:
component: Component instance to register
"""
metadata = component.get_metadata()
- self.components[metadata['name']] = component
+ self.components[metadata["name"]] = component
def register_components(self, components: List[Component]) -> None:
"""
Register multiple components
-
+
Args:
components: List of component instances
"""
@@ -61,13 +63,13 @@ class Installer:
def resolve_dependencies(self, component_names: List[str]) -> List[str]:
"""
Resolve component dependencies in correct installation order
-
+
Args:
component_names: List of component names to install
-
+
Returns:
Ordered list of component names including dependencies
-
+
Raises:
ValueError: If circular dependencies detected or unknown component
"""
@@ -79,8 +81,7 @@ class Installer:
return
if name in resolving:
- raise ValueError(
- f"Circular dependency detected involving {name}")
+ raise ValueError(f"Circular dependency detected involving {name}")
if name not in self.components:
raise ValueError(f"Unknown component: {name}")
@@ -103,7 +104,7 @@ class Installer:
def validate_system_requirements(self) -> Tuple[bool, List[str]]:
"""
Validate system requirements for all registered components
-
+
Returns:
Tuple of (success: bool, error_messages: List[str])
"""
@@ -134,7 +135,7 @@ class Installer:
def create_backup(self) -> Optional[Path]:
"""
Create backup of existing installation
-
+
Returns:
Path to backup archive or None if no existing installation
"""
@@ -174,7 +175,7 @@ class Installer:
# Always create an archive, even if empty, to ensure it's a valid tarball
base_path = backup_dir / backup_name
- shutil.make_archive(str(base_path), 'gztar', temp_backup)
+ shutil.make_archive(str(base_path), "gztar", temp_backup)
if not any(temp_backup.iterdir()):
self.logger.warning(
@@ -184,15 +185,14 @@ class Installer:
self.backup_path = backup_path
return backup_path
- def install_component(self, component_name: str,
- config: Dict[str, Any]) -> bool:
+ def install_component(self, component_name: str, config: Dict[str, Any]) -> bool:
"""
Install a single component
-
+
Args:
component_name: Name of component to install
config: Installation configuration
-
+
Returns:
True if successful, False otherwise
"""
@@ -202,7 +202,11 @@ class Installer:
component = self.components[component_name]
# Skip if already installed and not in update mode, unless component is reinstallable
- if not component.is_reinstallable() and component_name in self.installed_components and not config.get("update_mode"):
+ if (
+ not component.is_reinstallable()
+ and component_name in self.installed_components
+ and not config.get("update_mode")
+ ):
self.skipped_components.add(component_name)
self.logger.info(f"Skipping already installed component: {component_name}")
return True
@@ -237,16 +241,16 @@ class Installer:
self.failed_components.add(component_name)
return False
- def install_components(self,
- component_names: List[str],
- config: Optional[Dict[str, Any]] = None) -> bool:
+ def install_components(
+ self, component_names: List[str], config: Optional[Dict[str, Any]] = None
+ ) -> bool:
"""
Install multiple components in dependency order
-
+
Args:
component_names: List of component names to install
config: Installation configuration
-
+
Returns:
True if all successful, False if any failed
"""
@@ -296,7 +300,9 @@ class Installer:
all_valid = True
for name in self.updated_components:
if name not in self.components:
- self.logger.warning(f"Cannot validate component '{name}' as it was not part of this installation session.")
+ self.logger.warning(
+ f"Cannot validate component '{name}' as it was not part of this installation session."
+ )
continue
component = self.components[name]
@@ -315,12 +321,13 @@ class Installer:
else:
self.logger.error("Some components failed validation. Check errors above.")
- def update_components(self, component_names: List[str], config: Dict[str, Any]) -> bool:
+ def update_components(
+ self, component_names: List[str], config: Dict[str, Any]
+ ) -> bool:
"""Alias for update operation (uses install logic)"""
config["update_mode"] = True
return self.install_components(component_names, config)
-
def get_installation_summary(self) -> Dict[str, Any]:
"""
Get summary of installation results
@@ -329,17 +336,17 @@ class Installer:
Dict with installation statistics and results
"""
return {
- 'installed': list(self.installed_components),
- 'failed': list(self.failed_components),
- 'skipped': list(self.skipped_components),
- 'backup_path': str(self.backup_path) if self.backup_path else None,
- 'install_dir': str(self.install_dir),
- 'dry_run': self.dry_run
+ "installed": list(self.installed_components),
+ "failed": list(self.failed_components),
+ "skipped": list(self.skipped_components),
+ "backup_path": str(self.backup_path) if self.backup_path else None,
+ "install_dir": str(self.install_dir),
+ "dry_run": self.dry_run,
}
def get_update_summary(self) -> Dict[str, Any]:
return {
- 'updated': list(self.updated_components),
- 'failed': list(self.failed_components),
- 'backup_path': str(self.backup_path) if self.backup_path else None
+ "updated": list(self.updated_components),
+ "failed": list(self.failed_components),
+ "backup_path": str(self.backup_path) if self.backup_path else None,
}
diff --git a/setup/core/registry.py b/setup/core/registry.py
index cd8580d..9c27150 100644
--- a/setup/core/registry.py
+++ b/setup/core/registry.py
@@ -12,11 +12,11 @@ from ..utils.logger import get_logger
class ComponentRegistry:
"""Auto-discovery and management of installable components"""
-
+
def __init__(self, components_dir: Path):
"""
Initialize component registry
-
+
Args:
components_dir: Directory containing component modules
"""
@@ -26,54 +26,55 @@ class ComponentRegistry:
self.dependency_graph: Dict[str, Set[str]] = {}
self._discovered = False
self.logger = get_logger()
-
+
def discover_components(self, force_reload: bool = False) -> None:
"""
Auto-discover all component classes in components directory
-
+
Args:
force_reload: Force rediscovery even if already done
"""
if self._discovered and not force_reload:
return
-
+
self.component_classes.clear()
self.component_instances.clear()
self.dependency_graph.clear()
-
+
if not self.components_dir.exists():
return
-
+
# Add components directory to Python path temporarily
import sys
+
original_path = sys.path.copy()
-
+
try:
# Add parent directory to path so we can import setup.components
setup_dir = self.components_dir.parent
if str(setup_dir) not in sys.path:
sys.path.insert(0, str(setup_dir))
-
+
# Discover all Python files in components directory
for py_file in self.components_dir.glob("*.py"):
if py_file.name.startswith("__"):
continue
-
+
module_name = py_file.stem
self._load_component_module(module_name)
-
+
finally:
# Restore original Python path
sys.path = original_path
-
+
# Build dependency graph
self._build_dependency_graph()
self._discovered = True
-
+
def _load_component_module(self, module_name: str) -> None:
"""
Load component classes from a module
-
+
Args:
module_name: Name of module to load
"""
@@ -81,28 +82,32 @@ class ComponentRegistry:
# Import the module
full_module_name = f"setup.components.{module_name}"
module = importlib.import_module(full_module_name)
-
+
# Find all Component subclasses in the module
for name, obj in inspect.getmembers(module):
- if (inspect.isclass(obj) and
- issubclass(obj, Component) and
- obj is not Component):
-
+ if (
+ inspect.isclass(obj)
+ and issubclass(obj, Component)
+ and obj is not Component
+ ):
+
# Create instance to get metadata
try:
instance = obj()
metadata = instance.get_metadata()
component_name = metadata["name"]
-
+
self.component_classes[component_name] = obj
self.component_instances[component_name] = instance
-
+
except Exception as e:
- self.logger.warning(f"Could not instantiate component {name}: {e}")
-
+ self.logger.warning(
+ f"Could not instantiate component {name}: {e}"
+ )
+
except Exception as e:
self.logger.warning(f"Could not load component module {module_name}: {e}")
-
+
def _build_dependency_graph(self) -> None:
"""Build dependency graph for all discovered components"""
for name, instance in self.component_instances.items():
@@ -112,33 +117,35 @@ class ComponentRegistry:
except Exception as e:
self.logger.warning(f"Could not get dependencies for {name}: {e}")
self.dependency_graph[name] = set()
-
+
def get_component_class(self, component_name: str) -> Optional[Type[Component]]:
"""
Get component class by name
-
+
Args:
component_name: Name of component
-
+
Returns:
Component class or None if not found
"""
self.discover_components()
return self.component_classes.get(component_name)
-
- def get_component_instance(self, component_name: str, install_dir: Optional[Path] = None) -> Optional[Component]:
+
+ def get_component_instance(
+ self, component_name: str, install_dir: Optional[Path] = None
+ ) -> Optional[Component]:
"""
Get component instance by name
-
+
Args:
component_name: Name of component
install_dir: Installation directory (creates new instance with this dir)
-
+
Returns:
Component instance or None if not found
"""
self.discover_components()
-
+
if install_dir is not None:
# Create new instance with specified install directory
component_class = self.component_classes.get(component_name)
@@ -146,28 +153,30 @@ class ComponentRegistry:
try:
return component_class(install_dir)
except Exception as e:
- self.logger.error(f"Error creating component instance {component_name}: {e}")
+ self.logger.error(
+ f"Error creating component instance {component_name}: {e}"
+ )
return None
-
+
return self.component_instances.get(component_name)
-
+
def list_components(self) -> List[str]:
"""
Get list of all discovered component names
-
+
Returns:
List of component names
"""
self.discover_components()
return list(self.component_classes.keys())
-
+
def get_component_metadata(self, component_name: str) -> Optional[Dict[str, str]]:
"""
Get metadata for a component
-
+
Args:
component_name: Name of component
-
+
Returns:
Component metadata dict or None if not found
"""
@@ -179,121 +188,123 @@ class ComponentRegistry:
except Exception:
return None
return None
-
+
def resolve_dependencies(self, component_names: List[str]) -> List[str]:
"""
Resolve component dependencies in correct installation order
-
+
Args:
component_names: List of component names to install
-
+
Returns:
Ordered list of component names including dependencies
-
+
Raises:
ValueError: If circular dependencies detected or unknown component
"""
self.discover_components()
-
+
resolved = []
resolving = set()
-
+
def resolve(name: str):
if name in resolved:
return
-
+
if name in resolving:
raise ValueError(f"Circular dependency detected involving {name}")
-
+
if name not in self.dependency_graph:
raise ValueError(f"Unknown component: {name}")
-
+
resolving.add(name)
-
+
# Resolve dependencies first
for dep in self.dependency_graph[name]:
resolve(dep)
-
+
resolving.remove(name)
resolved.append(name)
-
+
# Resolve each requested component
for name in component_names:
resolve(name)
-
+
return resolved
-
+
def get_dependencies(self, component_name: str) -> Set[str]:
"""
Get direct dependencies for a component
-
+
Args:
component_name: Name of component
-
+
Returns:
Set of dependency component names
"""
self.discover_components()
return self.dependency_graph.get(component_name, set())
-
+
def get_dependents(self, component_name: str) -> Set[str]:
"""
Get components that depend on the given component
-
+
Args:
component_name: Name of component
-
+
Returns:
Set of component names that depend on this component
"""
self.discover_components()
dependents = set()
-
+
for name, deps in self.dependency_graph.items():
if component_name in deps:
dependents.add(name)
-
+
return dependents
-
+
def validate_dependency_graph(self) -> List[str]:
"""
Validate dependency graph for cycles and missing dependencies
-
+
Returns:
List of validation errors (empty if valid)
"""
self.discover_components()
errors = []
-
+
# Check for missing dependencies
all_components = set(self.dependency_graph.keys())
for name, deps in self.dependency_graph.items():
missing_deps = deps - all_components
if missing_deps:
- errors.append(f"Component {name} has missing dependencies: {missing_deps}")
-
+ errors.append(
+ f"Component {name} has missing dependencies: {missing_deps}"
+ )
+
# Check for circular dependencies
for name in all_components:
try:
self.resolve_dependencies([name])
except ValueError as e:
errors.append(str(e))
-
+
return errors
-
+
def get_components_by_category(self, category: str) -> List[str]:
"""
Get components filtered by category
-
+
Args:
category: Component category to filter by
-
+
Returns:
List of component names in the category
"""
self.discover_components()
components = []
-
+
for name, instance in self.component_instances.items():
try:
metadata = instance.get_metadata()
@@ -301,80 +312,84 @@ class ComponentRegistry:
components.append(name)
except Exception:
continue
-
+
return components
-
+
def get_installation_order(self, component_names: List[str]) -> List[List[str]]:
"""
Get installation order grouped by dependency levels
-
+
Args:
component_names: List of component names to install
-
+
Returns:
List of lists, where each inner list contains components
that can be installed in parallel at that dependency level
"""
self.discover_components()
-
+
# Get all components including dependencies
all_components = set(self.resolve_dependencies(component_names))
-
+
# Group by dependency level
levels = []
remaining = all_components.copy()
-
+
while remaining:
# Find components with no unresolved dependencies
current_level = []
for name in list(remaining):
deps = self.dependency_graph.get(name, set())
unresolved_deps = deps & remaining
-
+
if not unresolved_deps:
current_level.append(name)
-
+
if not current_level:
# This shouldn't happen if dependency graph is valid
- raise ValueError("Circular dependency detected in installation order calculation")
-
+ raise ValueError(
+ "Circular dependency detected in installation order calculation"
+ )
+
levels.append(current_level)
remaining -= set(current_level)
-
+
return levels
-
- def create_component_instances(self, component_names: List[str], install_dir: Optional[Path] = None) -> Dict[str, Component]:
+
+ def create_component_instances(
+ self, component_names: List[str], install_dir: Optional[Path] = None
+ ) -> Dict[str, Component]:
"""
Create instances for multiple components
-
+
Args:
component_names: List of component names
install_dir: Installation directory for instances
-
+
Returns:
Dict mapping component names to instances
"""
self.discover_components()
instances = {}
-
+
for name in component_names:
instance = self.get_component_instance(name, install_dir)
if instance:
instances[name] = instance
else:
self.logger.warning(f"Could not create instance for component {name}")
-
+
return instances
-
+
def get_registry_info(self) -> Dict[str, any]:
"""
Get comprehensive registry information
-
+
Returns:
Dict with registry statistics and component info
"""
self.discover_components()
-
+
# Group components by category
categories = {}
for name, instance in self.component_instances.items():
@@ -388,10 +403,12 @@ class ComponentRegistry:
if "unknown" not in categories:
categories["unknown"] = []
categories["unknown"].append(name)
-
+
return {
"total_components": len(self.component_classes),
"categories": categories,
- "dependency_graph": {name: list(deps) for name, deps in self.dependency_graph.items()},
- "validation_errors": self.validate_dependency_graph()
- }
\ No newline at end of file
+ "dependency_graph": {
+ name: list(deps) for name, deps in self.dependency_graph.items()
+ },
+ "validation_errors": self.validate_dependency_graph(),
+ }
diff --git a/setup/core/validator.py b/setup/core/validator.py
index 9ff130a..a4f0813 100644
--- a/setup/core/validator.py
+++ b/setup/core/validator.py
@@ -13,19 +13,20 @@ from ..utils.paths import get_home_directory
# Handle packaging import - if not available, use a simple version comparison
try:
from packaging import version
+
PACKAGING_AVAILABLE = True
except ImportError:
PACKAGING_AVAILABLE = False
-
+
class SimpleVersion:
def __init__(self, version_str: str):
self.version_str = version_str
# Simple version parsing: split by dots and convert to integers
try:
- self.parts = [int(x) for x in version_str.split('.')]
+ self.parts = [int(x) for x in version_str.split(".")]
except ValueError:
self.parts = [0, 0, 0]
-
+
def __lt__(self, other):
if isinstance(other, str):
other = SimpleVersion(other)
@@ -34,17 +35,17 @@ except ImportError:
self_parts = self.parts + [0] * (max_len - len(self.parts))
other_parts = other.parts + [0] * (max_len - len(other.parts))
return self_parts < other_parts
-
+
def __gt__(self, other):
if isinstance(other, str):
other = SimpleVersion(other)
return not (self < other) and not (self == other)
-
+
def __eq__(self, other):
if isinstance(other, str):
other = SimpleVersion(other)
return self.parts == other.parts
-
+
class version:
@staticmethod
def parse(version_str: str):
@@ -53,107 +54,127 @@ except ImportError:
class Validator:
"""System requirements validator"""
-
+
def __init__(self):
"""Initialize validator"""
self.validation_cache: Dict[str, Any] = {}
-
- def check_python(self, min_version: str = "3.8", max_version: Optional[str] = None) -> Tuple[bool, str]:
+
+ def check_python(
+ self, min_version: str = "3.8", max_version: Optional[str] = None
+ ) -> Tuple[bool, str]:
"""
Check Python version requirements
-
+
Args:
min_version: Minimum required Python version
max_version: Maximum supported Python version (optional)
-
+
Returns:
Tuple of (success: bool, message: str)
"""
cache_key = f"python_{min_version}_{max_version}"
if cache_key in self.validation_cache:
return self.validation_cache[cache_key]
-
+
try:
# Get current Python version
current_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
-
+
# Check minimum version
if version.parse(current_version) < version.parse(min_version):
help_msg = self.get_installation_help("python")
- result = (False, f"Python {min_version}+ required, found {current_version}{help_msg}")
+ result = (
+ False,
+ f"Python {min_version}+ required, found {current_version}{help_msg}",
+ )
self.validation_cache[cache_key] = result
return result
-
+
# Check maximum version if specified
- if max_version and version.parse(current_version) > version.parse(max_version):
- result = (False, f"Python version {current_version} exceeds maximum supported {max_version}")
+ if max_version and version.parse(current_version) > version.parse(
+ max_version
+ ):
+ result = (
+ False,
+ f"Python version {current_version} exceeds maximum supported {max_version}",
+ )
self.validation_cache[cache_key] = result
return result
-
+
result = (True, f"Python {current_version} meets requirements")
self.validation_cache[cache_key] = result
return result
-
+
except Exception as e:
result = (False, f"Could not check Python version: {e}")
self.validation_cache[cache_key] = result
return result
-
- def check_node(self, min_version: str = "16.0", max_version: Optional[str] = None) -> Tuple[bool, str]:
+
+ def check_node(
+ self, min_version: str = "16.0", max_version: Optional[str] = None
+ ) -> Tuple[bool, str]:
"""
Check Node.js version requirements
-
+
Args:
min_version: Minimum required Node.js version
max_version: Maximum supported Node.js version (optional)
-
+
Returns:
Tuple of (success: bool, message: str)
"""
cache_key = f"node_{min_version}_{max_version}"
if cache_key in self.validation_cache:
return self.validation_cache[cache_key]
-
+
try:
# Check if node is installed - use shell=True on Windows for better PATH resolution
result = subprocess.run(
- ['node', '--version'],
+ ["node", "--version"],
capture_output=True,
text=True,
timeout=10,
- shell=(sys.platform == "win32")
+ shell=(sys.platform == "win32"),
)
-
+
if result.returncode != 0:
help_msg = self.get_installation_help("node")
result_tuple = (False, f"Node.js not found in PATH{help_msg}")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
# Parse version (format: v18.17.0)
version_output = result.stdout.strip()
- if version_output.startswith('v'):
+ if version_output.startswith("v"):
current_version = version_output[1:]
else:
current_version = version_output
-
+
# Check minimum version
if version.parse(current_version) < version.parse(min_version):
help_msg = self.get_installation_help("node")
- result_tuple = (False, f"Node.js {min_version}+ required, found {current_version}{help_msg}")
+ result_tuple = (
+ False,
+ f"Node.js {min_version}+ required, found {current_version}{help_msg}",
+ )
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
# Check maximum version if specified
- if max_version and version.parse(current_version) > version.parse(max_version):
- result_tuple = (False, f"Node.js version {current_version} exceeds maximum supported {max_version}")
+ if max_version and version.parse(current_version) > version.parse(
+ max_version
+ ):
+ result_tuple = (
+ False,
+ f"Node.js version {current_version} exceeds maximum supported {max_version}",
+ )
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
result_tuple = (True, f"Node.js {current_version} meets requirements")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
except subprocess.TimeoutExpired:
result_tuple = (False, "Node.js version check timed out")
self.validation_cache[cache_key] = result_tuple
@@ -167,58 +188,63 @@ class Validator:
result_tuple = (False, f"Could not check Node.js version: {e}")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
def check_claude_cli(self, min_version: Optional[str] = None) -> Tuple[bool, str]:
"""
Check Claude CLI installation and version
-
+
Args:
min_version: Minimum required Claude CLI version (optional)
-
+
Returns:
Tuple of (success: bool, message: str)
"""
cache_key = f"claude_cli_{min_version}"
if cache_key in self.validation_cache:
return self.validation_cache[cache_key]
-
+
try:
# Check if claude is installed - use shell=True on Windows for better PATH resolution
result = subprocess.run(
- ['claude', '--version'],
+ ["claude", "--version"],
capture_output=True,
text=True,
timeout=10,
- shell=(sys.platform == "win32")
+ shell=(sys.platform == "win32"),
)
-
+
if result.returncode != 0:
help_msg = self.get_installation_help("claude_cli")
result_tuple = (False, f"Claude CLI not found in PATH{help_msg}")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
# Parse version from output
version_output = result.stdout.strip()
- version_match = re.search(r'(\d+\.\d+\.\d+)', version_output)
-
+ version_match = re.search(r"(\d+\.\d+\.\d+)", version_output)
+
if not version_match:
result_tuple = (True, "Claude CLI found (version format unknown)")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
current_version = version_match.group(1)
-
+
# Check minimum version if specified
- if min_version and version.parse(current_version) < version.parse(min_version):
- result_tuple = (False, f"Claude CLI {min_version}+ required, found {current_version}")
+ if min_version and version.parse(current_version) < version.parse(
+ min_version
+ ):
+ result_tuple = (
+ False,
+ f"Claude CLI {min_version}+ required, found {current_version}",
+ )
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
result_tuple = (True, f"Claude CLI {current_version} found")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
except subprocess.TimeoutExpired:
result_tuple = (False, "Claude CLI version check timed out")
self.validation_cache[cache_key] = result_tuple
@@ -232,53 +258,58 @@ class Validator:
result_tuple = (False, f"Could not check Claude CLI: {e}")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
- def check_external_tool(self, tool_name: str, command: str, min_version: Optional[str] = None) -> Tuple[bool, str]:
+
+ def check_external_tool(
+ self, tool_name: str, command: str, min_version: Optional[str] = None
+ ) -> Tuple[bool, str]:
"""
Check external tool availability and version
-
+
Args:
tool_name: Display name of tool
command: Command to check version
min_version: Minimum required version (optional)
-
+
Returns:
Tuple of (success: bool, message: str)
"""
cache_key = f"tool_{tool_name}_{command}_{min_version}"
if cache_key in self.validation_cache:
return self.validation_cache[cache_key]
-
+
try:
# Split command into parts
cmd_parts = command.split()
-
+
result = subprocess.run(
cmd_parts,
capture_output=True,
text=True,
timeout=10,
- shell=(sys.platform == "win32")
+ shell=(sys.platform == "win32"),
)
-
+
if result.returncode != 0:
result_tuple = (False, f"{tool_name} not found or command failed")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
# Extract version if min_version specified
if min_version:
version_output = result.stdout + result.stderr
- version_match = re.search(r'(\d+\.\d+(?:\.\d+)?)', version_output)
-
+ version_match = re.search(r"(\d+\.\d+(?:\.\d+)?)", version_output)
+
if version_match:
current_version = version_match.group(1)
-
+
if version.parse(current_version) < version.parse(min_version):
- result_tuple = (False, f"{tool_name} {min_version}+ required, found {current_version}")
+ result_tuple = (
+ False,
+ f"{tool_name} {min_version}+ required, found {current_version}",
+ )
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
result_tuple = (True, f"{tool_name} {current_version} found")
self.validation_cache[cache_key] = result_tuple
return result_tuple
@@ -290,7 +321,7 @@ class Validator:
result_tuple = (True, f"{tool_name} found")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
except subprocess.TimeoutExpired:
result_tuple = (False, f"{tool_name} check timed out")
self.validation_cache[cache_key] = result_tuple
@@ -303,206 +334,208 @@ class Validator:
result_tuple = (False, f"Could not check {tool_name}: {e}")
self.validation_cache[cache_key] = result_tuple
return result_tuple
-
+
def check_disk_space(self, path: Path, required_mb: int = 500) -> Tuple[bool, str]:
"""
Check available disk space
-
+
Args:
path: Path to check (file or directory)
required_mb: Required free space in MB
-
+
Returns:
Tuple of (success: bool, message: str)
"""
cache_key = f"disk_{path}_{required_mb}"
if cache_key in self.validation_cache:
return self.validation_cache[cache_key]
-
+
try:
# Get parent directory if path is a file
check_path = path.parent if path.is_file() else path
-
+
# Get disk usage
stat_result = shutil.disk_usage(check_path)
free_mb = stat_result.free / (1024 * 1024)
-
+
if free_mb < required_mb:
- result = (False, f"Insufficient disk space: {free_mb:.1f}MB free, {required_mb}MB required")
+ result = (
+ False,
+ f"Insufficient disk space: {free_mb:.1f}MB free, {required_mb}MB required",
+ )
else:
result = (True, f"Sufficient disk space: {free_mb:.1f}MB free")
-
+
self.validation_cache[cache_key] = result
return result
-
+
except Exception as e:
result = (False, f"Could not check disk space: {e}")
self.validation_cache[cache_key] = result
return result
-
+
def check_write_permissions(self, path: Path) -> Tuple[bool, str]:
"""
Check write permissions for path
-
+
Args:
path: Path to check
-
+
Returns:
Tuple of (success: bool, message: str)
"""
cache_key = f"write_{path}"
if cache_key in self.validation_cache:
return self.validation_cache[cache_key]
-
+
try:
# Create parent directories if needed
if not path.exists():
path.mkdir(parents=True, exist_ok=True)
-
+
# Test write access
test_file = path / ".write_test"
test_file.touch()
test_file.unlink()
-
+
result = (True, f"Write access confirmed for {path}")
self.validation_cache[cache_key] = result
return result
-
+
except Exception as e:
result = (False, f"No write access to {path}: {e}")
self.validation_cache[cache_key] = result
return result
-
- def validate_requirements(self, requirements: Dict[str, Any]) -> Tuple[bool, List[str]]:
+
+ def validate_requirements(
+ self, requirements: Dict[str, Any]
+ ) -> Tuple[bool, List[str]]:
"""
Validate all system requirements
-
+
Args:
requirements: Requirements configuration dict
-
+
Returns:
Tuple of (all_passed: bool, error_messages: List[str])
"""
errors = []
-
+
# Check Python requirements
if "python" in requirements:
python_req = requirements["python"]
success, message = self.check_python(
- python_req["min_version"],
- python_req.get("max_version")
+ python_req["min_version"], python_req.get("max_version")
)
if not success:
errors.append(f"Python: {message}")
-
+
# Check Node.js requirements
if "node" in requirements:
node_req = requirements["node"]
success, message = self.check_node(
- node_req["min_version"],
- node_req.get("max_version")
+ node_req["min_version"], node_req.get("max_version")
)
if not success:
errors.append(f"Node.js: {message}")
-
+
# Check disk space
if "disk_space_mb" in requirements:
success, message = self.check_disk_space(
- get_home_directory(),
- requirements["disk_space_mb"]
+ get_home_directory(), requirements["disk_space_mb"]
)
if not success:
errors.append(f"Disk space: {message}")
-
+
# Check external tools
if "external_tools" in requirements:
for tool_name, tool_req in requirements["external_tools"].items():
# Skip optional tools that fail
is_optional = tool_req.get("optional", False)
-
+
success, message = self.check_external_tool(
- tool_name,
- tool_req["command"],
- tool_req.get("min_version")
+ tool_name, tool_req["command"], tool_req.get("min_version")
)
-
+
if not success and not is_optional:
errors.append(f"{tool_name}: {message}")
-
+
return len(errors) == 0, errors
-
- def validate_component_requirements(self, component_names: List[str], all_requirements: Dict[str, Any]) -> Tuple[bool, List[str]]:
+
+ def validate_component_requirements(
+ self, component_names: List[str], all_requirements: Dict[str, Any]
+ ) -> Tuple[bool, List[str]]:
"""
Validate requirements for specific components
-
+
Args:
component_names: List of component names to validate
all_requirements: Full requirements configuration
-
+
Returns:
Tuple of (all_passed: bool, error_messages: List[str])
"""
errors = []
-
+
# Start with base requirements
base_requirements = {
"python": all_requirements.get("python", {}),
- "disk_space_mb": all_requirements.get("disk_space_mb", 500)
+ "disk_space_mb": all_requirements.get("disk_space_mb", 500),
}
-
+
# Add conditional requirements based on components
external_tools = {}
-
+
# Check if any component needs Node.js
node_components = []
for component in component_names:
# This would be enhanced with actual component metadata
if component in ["mcp"]: # MCP component needs Node.js
node_components.append(component)
-
+
if node_components and "node" in all_requirements:
base_requirements["node"] = all_requirements["node"]
-
+
# Add external tools needed by components
if "external_tools" in all_requirements:
for tool_name, tool_req in all_requirements["external_tools"].items():
required_for = tool_req.get("required_for", [])
-
+
# Check if any of our components need this tool
if any(comp in required_for for comp in component_names):
external_tools[tool_name] = tool_req
-
+
if external_tools:
base_requirements["external_tools"] = external_tools
-
+
# Validate consolidated requirements
return self.validate_requirements(base_requirements)
-
+
def get_system_info(self) -> Dict[str, Any]:
"""
Get comprehensive system information
-
+
Returns:
Dict with system information
"""
info = {
"platform": sys.platform,
"python_version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
- "python_executable": sys.executable
+ "python_executable": sys.executable,
}
-
+
# Add Node.js info if available
node_success, node_msg = self.check_node()
info["node_available"] = node_success
if node_success:
info["node_message"] = node_msg
-
+
# Add Claude CLI info if available
claude_success, claude_msg = self.check_claude_cli()
info["claude_cli_available"] = claude_success
if claude_success:
info["claude_cli_message"] = claude_msg
-
+
# Add disk space info
try:
home_path = get_home_directory()
@@ -510,76 +543,78 @@ class Validator:
info["disk_space"] = {
"total_gb": stat_result.total / (1024**3),
"free_gb": stat_result.free / (1024**3),
- "used_gb": (stat_result.total - stat_result.free) / (1024**3)
+ "used_gb": (stat_result.total - stat_result.free) / (1024**3),
}
except Exception:
info["disk_space"] = {"error": "Could not determine disk space"}
-
+
return info
-
+
def get_platform(self) -> str:
"""
Get current platform for installation commands
-
+
Returns:
Platform string (linux, darwin, win32)
"""
return sys.platform
-
+
def load_installation_commands(self) -> Dict[str, Any]:
"""
Load installation commands from requirements configuration
-
+
Returns:
Installation commands dict
"""
try:
from ..services.config import ConfigService
from .. import DATA_DIR
-
+
config_manager = ConfigService(DATA_DIR)
requirements = config_manager.load_requirements()
return requirements.get("installation_commands", {})
except Exception:
return {}
-
- def get_installation_help(self, tool_name: str, platform: Optional[str] = None) -> str:
+
+ def get_installation_help(
+ self, tool_name: str, platform: Optional[str] = None
+ ) -> str:
"""
Get installation help for a specific tool
-
+
Args:
tool_name: Name of tool to get help for
platform: Target platform (auto-detected if None)
-
+
Returns:
Installation help string
"""
if platform is None:
platform = self.get_platform()
-
+
commands = self.load_installation_commands()
tool_commands = commands.get(tool_name, {})
-
+
if not tool_commands:
return f"No installation instructions available for {tool_name}"
-
+
# Get platform-specific command or fallback to 'all'
install_cmd = tool_commands.get(platform, tool_commands.get("all", ""))
description = tool_commands.get("description", "")
-
+
if install_cmd:
help_text = f"\n๐ก Installation Help for {tool_name}:\n"
if description:
help_text += f" {description}\n"
help_text += f" Command: {install_cmd}\n"
return help_text
-
+
return f"No installation instructions available for {tool_name} on {platform}"
-
+
def diagnose_system(self) -> Dict[str, Any]:
"""
Perform comprehensive system diagnostics
-
+
Returns:
Diagnostic information dict
"""
@@ -587,66 +622,68 @@ class Validator:
"platform": self.get_platform(),
"checks": {},
"issues": [],
- "recommendations": []
+ "recommendations": [],
}
-
+
# Check Python
python_success, python_msg = self.check_python()
diagnostics["checks"]["python"] = {
"status": "pass" if python_success else "fail",
- "message": python_msg
+ "message": python_msg,
}
if not python_success:
diagnostics["issues"].append("Python version issue")
diagnostics["recommendations"].append(self.get_installation_help("python"))
-
+
# Check Node.js
node_success, node_msg = self.check_node()
diagnostics["checks"]["node"] = {
- "status": "pass" if node_success else "fail",
- "message": node_msg
+ "status": "pass" if node_success else "fail",
+ "message": node_msg,
}
if not node_success:
diagnostics["issues"].append("Node.js not found or version issue")
diagnostics["recommendations"].append(self.get_installation_help("node"))
-
+
# Check Claude CLI
claude_success, claude_msg = self.check_claude_cli()
diagnostics["checks"]["claude_cli"] = {
"status": "pass" if claude_success else "fail",
- "message": claude_msg
+ "message": claude_msg,
}
if not claude_success:
diagnostics["issues"].append("Claude CLI not found")
- diagnostics["recommendations"].append(self.get_installation_help("claude_cli"))
-
+ diagnostics["recommendations"].append(
+ self.get_installation_help("claude_cli")
+ )
+
# Check disk space
disk_success, disk_msg = self.check_disk_space(get_home_directory())
diagnostics["checks"]["disk_space"] = {
"status": "pass" if disk_success else "fail",
- "message": disk_msg
+ "message": disk_msg,
}
if not disk_success:
diagnostics["issues"].append("Insufficient disk space")
-
+
# Check common PATH issues
self._diagnose_path_issues(diagnostics)
-
+
return diagnostics
-
+
def _diagnose_path_issues(self, diagnostics: Dict[str, Any]) -> None:
"""Add PATH-related diagnostics"""
path_issues = []
-
+
# Check if tools are in PATH, with alternatives for some tools
tool_checks = [
# For Python, check if either python3 OR python is available
(["python3", "python"], "Python (python3 or python)"),
(["node"], "Node.js"),
(["npm"], "npm"),
- (["claude"], "Claude CLI")
+ (["claude"], "Claude CLI"),
]
-
+
for tool_alternatives, display_name in tool_checks:
tool_found = False
for tool in tool_alternatives:
@@ -656,21 +693,21 @@ class Validator:
capture_output=True,
text=True,
timeout=5,
- shell=(sys.platform == "win32")
+ shell=(sys.platform == "win32"),
)
if result.returncode == 0:
tool_found = True
break
except Exception:
continue
-
+
if not tool_found:
# Only report as missing if none of the alternatives were found
if len(tool_alternatives) > 1:
path_issues.append(f"{display_name} not found in PATH")
else:
path_issues.append(f"{tool_alternatives[0]} not found in PATH")
-
+
if path_issues:
diagnostics["issues"].extend(path_issues)
diagnostics["recommendations"].append(
@@ -680,7 +717,7 @@ class Validator:
" - Check your shell configuration (.bashrc, .zshrc)\n"
" - Use full paths to tools if needed\n"
)
-
+
def clear_cache(self) -> None:
"""Clear validation cache"""
self.validation_cache.clear()
diff --git a/setup/data/__init__.py b/setup/data/__init__.py
index 04c37a7..07e7621 100644
--- a/setup/data/__init__.py
+++ b/setup/data/__init__.py
@@ -1,4 +1,4 @@
"""
SuperClaude Data Module
Static configuration and data files
-"""
\ No newline at end of file
+"""
diff --git a/setup/services/__init__.py b/setup/services/__init__.py
index 5f11052..9b5188e 100644
--- a/setup/services/__init__.py
+++ b/setup/services/__init__.py
@@ -8,9 +8,4 @@ from .config import ConfigService
from .files import FileService
from .settings import SettingsService
-__all__ = [
- 'CLAUDEMdService',
- 'ConfigService',
- 'FileService',
- 'SettingsService'
-]
\ No newline at end of file
+__all__ = ["CLAUDEMdService", "ConfigService", "FileService", "SettingsService"]
diff --git a/setup/services/claude_md.py b/setup/services/claude_md.py
index b37fa2c..774a64d 100644
--- a/setup/services/claude_md.py
+++ b/setup/services/claude_md.py
@@ -10,105 +10,107 @@ from ..utils.logger import get_logger
class CLAUDEMdService:
"""Manages CLAUDE.md file updates while preserving user customizations"""
-
+
def __init__(self, install_dir: Path):
"""
Initialize CLAUDEMdService
-
+
Args:
install_dir: Installation directory (typically ~/.claude)
"""
self.install_dir = install_dir
self.claude_md_path = install_dir / "CLAUDE.md"
self.logger = get_logger()
-
+
def read_existing_imports(self) -> Set[str]:
"""
Parse CLAUDE.md for existing @import statements
-
+
Returns:
Set of already imported filenames (without @)
"""
existing_imports = set()
-
+
if not self.claude_md_path.exists():
return existing_imports
-
+
try:
- with open(self.claude_md_path, 'r', encoding='utf-8') as f:
+ with open(self.claude_md_path, "r", encoding="utf-8") as f:
content = f.read()
-
+
# Find all @import statements using regex
- import_pattern = r'^@([^\s\n]+\.md)\s*$'
+ import_pattern = r"^@([^\s\n]+\.md)\s*$"
matches = re.findall(import_pattern, content, re.MULTILINE)
existing_imports.update(matches)
-
+
self.logger.debug(f"Found existing imports: {existing_imports}")
-
+
except Exception as e:
self.logger.warning(f"Could not read existing CLAUDE.md imports: {e}")
-
+
return existing_imports
-
+
def read_existing_content(self) -> str:
"""
Read existing CLAUDE.md content
-
+
Returns:
Existing content or empty string if file doesn't exist
"""
if not self.claude_md_path.exists():
return ""
-
+
try:
- with open(self.claude_md_path, 'r', encoding='utf-8') as f:
+ with open(self.claude_md_path, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
self.logger.warning(f"Could not read existing CLAUDE.md: {e}")
return ""
-
+
def extract_user_content(self, content: str) -> str:
"""
Extract user content (everything before framework imports section)
-
+
Args:
content: Full CLAUDE.md content
-
+
Returns:
User content without framework imports
"""
# Look for framework imports section marker
framework_marker = "# ===================================================\n# SuperClaude Framework Components"
-
+
if framework_marker in content:
user_content = content.split(framework_marker)[0].rstrip()
else:
# If no framework section exists, preserve all content
user_content = content.rstrip()
-
+
return user_content
-
- def organize_imports_by_category(self, files_by_category: Dict[str, List[str]]) -> str:
+
+ def organize_imports_by_category(
+ self, files_by_category: Dict[str, List[str]]
+ ) -> str:
"""
Organize imports into categorized sections
-
+
Args:
files_by_category: Dict mapping category names to lists of files
-
+
Returns:
Formatted import sections
"""
if not files_by_category:
return ""
-
+
sections = []
-
+
# Framework imports section header
sections.append("# ===================================================")
sections.append("# SuperClaude Framework Components")
sections.append("# ===================================================")
sections.append("")
-
+
# Add each category
for category, files in files_by_category.items():
if files:
@@ -116,131 +118,139 @@ class CLAUDEMdService:
for file in sorted(files):
sections.append(f"@{file}")
sections.append("")
-
+
return "\n".join(sections)
-
+
def add_imports(self, files: List[str], category: str = "Framework") -> bool:
"""
Add new imports with duplicate checking and user content preservation
-
+
Args:
files: List of filenames to import
category: Category name for organizing imports
-
+
Returns:
True if successful, False otherwise
"""
try:
# Ensure CLAUDE.md exists
self.ensure_claude_md_exists()
-
+
# Read existing content and imports
existing_content = self.read_existing_content()
existing_imports = self.read_existing_imports()
-
+
# Filter out files already imported
new_files = [f for f in files if f not in existing_imports]
-
+
if not new_files:
self.logger.info("All files already imported, no changes needed")
return True
-
- self.logger.info(f"Adding {len(new_files)} new imports to category '{category}': {new_files}")
-
+
+ self.logger.info(
+ f"Adding {len(new_files)} new imports to category '{category}': {new_files}"
+ )
+
# Extract user content (preserve everything before framework section)
user_content = self.extract_user_content(existing_content)
-
+
# Parse existing framework imports by category
- existing_framework_imports = self._parse_existing_framework_imports(existing_content)
-
+ existing_framework_imports = self._parse_existing_framework_imports(
+ existing_content
+ )
+
# Add new files to the specified category
if category not in existing_framework_imports:
existing_framework_imports[category] = []
existing_framework_imports[category].extend(new_files)
-
+
# Build new content
new_content_parts = []
-
+
# Add user content
if user_content.strip():
new_content_parts.append(user_content)
new_content_parts.append("") # Add blank line before framework section
-
+
# Add organized framework imports
- framework_section = self.organize_imports_by_category(existing_framework_imports)
+ framework_section = self.organize_imports_by_category(
+ existing_framework_imports
+ )
if framework_section:
new_content_parts.append(framework_section)
-
+
# Write updated content
new_content = "\n".join(new_content_parts)
-
- with open(self.claude_md_path, 'w', encoding='utf-8') as f:
+
+ with open(self.claude_md_path, "w", encoding="utf-8") as f:
f.write(new_content)
-
+
self.logger.success(f"Updated CLAUDE.md with {len(new_files)} new imports")
return True
-
+
except Exception as e:
self.logger.error(f"Failed to update CLAUDE.md: {e}")
return False
-
+
def _parse_existing_framework_imports(self, content: str) -> Dict[str, List[str]]:
"""
Parse existing framework imports organized by category
-
+
Args:
content: Full CLAUDE.md content
-
+
Returns:
Dict mapping category names to lists of imported files
"""
imports_by_category = {}
-
+
# Look for framework imports section
framework_marker = "# ===================================================\n# SuperClaude Framework Components"
-
+
if framework_marker not in content:
return imports_by_category
-
+
# Extract framework section
- framework_section = content.split(framework_marker)[1] if framework_marker in content else ""
-
+ framework_section = (
+ content.split(framework_marker)[1] if framework_marker in content else ""
+ )
+
# Parse categories and imports
- lines = framework_section.split('\n')
+ lines = framework_section.split("\n")
current_category = None
-
+
for line in lines:
line = line.strip()
-
+
# Skip section header lines and empty lines
- if line.startswith('# ===') or not line:
+ if line.startswith("# ===") or not line:
continue
-
+
# Category header (starts with # but not the section divider)
- if line.startswith('# ') and not line.startswith('# ==='):
+ if line.startswith("# ") and not line.startswith("# ==="):
current_category = line[2:].strip() # Remove "# "
if current_category not in imports_by_category:
imports_by_category[current_category] = []
-
+
# Import line (starts with @)
- elif line.startswith('@') and current_category:
+ elif line.startswith("@") and current_category:
import_file = line[1:].strip() # Remove "@"
if import_file not in imports_by_category[current_category]:
imports_by_category[current_category].append(import_file)
-
+
return imports_by_category
-
+
def ensure_claude_md_exists(self) -> None:
"""
Create CLAUDE.md with default content if it doesn't exist
"""
if self.claude_md_path.exists():
return
-
+
try:
# Create directory if it doesn't exist
self.claude_md_path.parent.mkdir(parents=True, exist_ok=True)
-
+
# Default CLAUDE.md content
default_content = """# SuperClaude Entry Point
@@ -249,34 +259,36 @@ You can add your own custom instructions and configurations here.
The SuperClaude framework components will be automatically imported below.
"""
-
- with open(self.claude_md_path, 'w', encoding='utf-8') as f:
+
+ with open(self.claude_md_path, "w", encoding="utf-8") as f:
f.write(default_content)
-
+
self.logger.info("Created CLAUDE.md with default content")
-
+
except Exception as e:
self.logger.error(f"Failed to create CLAUDE.md: {e}")
raise
-
+
def remove_imports(self, files: List[str]) -> bool:
"""
Remove specific imports from CLAUDE.md
-
+
Args:
files: List of filenames to remove from imports
-
+
Returns:
True if successful, False otherwise
"""
try:
if not self.claude_md_path.exists():
return True # Nothing to remove
-
+
existing_content = self.read_existing_content()
user_content = self.extract_user_content(existing_content)
- existing_framework_imports = self._parse_existing_framework_imports(existing_content)
-
+ existing_framework_imports = self._parse_existing_framework_imports(
+ existing_content
+ )
+
# Remove files from all categories
removed_any = False
for category, category_files in existing_framework_imports.items():
@@ -284,33 +296,37 @@ The SuperClaude framework components will be automatically imported below.
if file in category_files:
category_files.remove(file)
removed_any = True
-
+
# Remove empty categories
- existing_framework_imports = {k: v for k, v in existing_framework_imports.items() if v}
-
+ existing_framework_imports = {
+ k: v for k, v in existing_framework_imports.items() if v
+ }
+
if not removed_any:
return True # Nothing was removed
-
+
# Rebuild content
new_content_parts = []
-
+
if user_content.strip():
new_content_parts.append(user_content)
new_content_parts.append("")
-
- framework_section = self.organize_imports_by_category(existing_framework_imports)
+
+ framework_section = self.organize_imports_by_category(
+ existing_framework_imports
+ )
if framework_section:
new_content_parts.append(framework_section)
-
+
# Write updated content
new_content = "\n".join(new_content_parts)
-
- with open(self.claude_md_path, 'w', encoding='utf-8') as f:
+
+ with open(self.claude_md_path, "w", encoding="utf-8") as f:
f.write(new_content)
-
+
self.logger.info(f"Removed {len(files)} imports from CLAUDE.md")
return True
-
+
except Exception as e:
self.logger.error(f"Failed to remove imports from CLAUDE.md: {e}")
- return False
\ No newline at end of file
+ return False
diff --git a/setup/services/config.py b/setup/services/config.py
index 565d842..fde8904 100644
--- a/setup/services/config.py
+++ b/setup/services/config.py
@@ -10,16 +10,18 @@ from pathlib import Path
try:
import jsonschema
from jsonschema import validate, ValidationError
+
JSONSCHEMA_AVAILABLE = True
except ImportError:
JSONSCHEMA_AVAILABLE = False
-
+
class ValidationError(Exception):
"""Simple validation error for when jsonschema is not available"""
+
def __init__(self, message):
self.message = message
super().__init__(message)
-
+
def validate(instance, schema):
"""Dummy validation function"""
# Basic type checking only
@@ -32,17 +34,19 @@ except ImportError:
elif expected_type == "string" and not isinstance(instance, str):
raise ValidationError(f"Expected string, got {type(instance).__name__}")
elif expected_type == "integer" and not isinstance(instance, int):
- raise ValidationError(f"Expected integer, got {type(instance).__name__}")
+ raise ValidationError(
+ f"Expected integer, got {type(instance).__name__}"
+ )
# Skip detailed validation if jsonschema not available
class ConfigService:
"""Manages configuration files and validation"""
-
+
def __init__(self, config_dir: Path):
"""
Initialize config manager
-
+
Args:
config_dir: Directory containing configuration files
"""
@@ -51,7 +55,7 @@ class ConfigService:
self.requirements_file = config_dir / "requirements.json"
self._features_cache = None
self._requirements_cache = None
-
+
# Schema for features.json
self.features_schema = {
"type": "object",
@@ -68,24 +72,24 @@ class ConfigService:
"category": {"type": "string"},
"dependencies": {
"type": "array",
- "items": {"type": "string"}
+ "items": {"type": "string"},
},
"enabled": {"type": "boolean"},
"required_tools": {
"type": "array",
- "items": {"type": "string"}
- }
+ "items": {"type": "string"},
+ },
},
"required": ["name", "version", "description", "category"],
- "additionalProperties": False
+ "additionalProperties": False,
}
- }
+ },
}
},
"required": ["components"],
- "additionalProperties": False
+ "additionalProperties": False,
}
-
+
# Schema for requirements.json
self.requirements_schema = {
"type": "object",
@@ -94,21 +98,18 @@ class ConfigService:
"type": "object",
"properties": {
"min_version": {"type": "string"},
- "max_version": {"type": "string"}
+ "max_version": {"type": "string"},
},
- "required": ["min_version"]
+ "required": ["min_version"],
},
"node": {
"type": "object",
"properties": {
"min_version": {"type": "string"},
"max_version": {"type": "string"},
- "required_for": {
- "type": "array",
- "items": {"type": "string"}
- }
+ "required_for": {"type": "array", "items": {"type": "string"}},
},
- "required": ["min_version"]
+ "required": ["min_version"],
},
"disk_space_mb": {"type": "integer"},
"external_tools": {
@@ -121,14 +122,14 @@ class ConfigService:
"min_version": {"type": "string"},
"required_for": {
"type": "array",
- "items": {"type": "string"}
+ "items": {"type": "string"},
},
- "optional": {"type": "boolean"}
+ "optional": {"type": "boolean"},
},
"required": ["command"],
- "additionalProperties": False
+ "additionalProperties": False,
}
- }
+ },
},
"installation_commands": {
"type": "object",
@@ -140,136 +141,138 @@ class ConfigService:
"darwin": {"type": "string"},
"win32": {"type": "string"},
"all": {"type": "string"},
- "description": {"type": "string"}
+ "description": {"type": "string"},
},
- "additionalProperties": False
+ "additionalProperties": False,
}
- }
- }
+ },
+ },
},
"required": ["python", "disk_space_mb"],
- "additionalProperties": False
+ "additionalProperties": False,
}
-
+
def load_features(self) -> Dict[str, Any]:
"""
Load and validate features configuration
-
+
Returns:
Features configuration dict
-
+
Raises:
FileNotFoundError: If features.json not found
ValidationError: If features.json is invalid
"""
if self._features_cache is not None:
return self._features_cache
-
+
if not self.features_file.exists():
raise FileNotFoundError(f"Features config not found: {self.features_file}")
-
+
try:
- with open(self.features_file, 'r') as f:
+ with open(self.features_file, "r") as f:
features = json.load(f)
-
+
# Validate schema
validate(instance=features, schema=self.features_schema)
-
+
self._features_cache = features
return features
-
+
except json.JSONDecodeError as e:
raise ValidationError(f"Invalid JSON in {self.features_file}: {e}")
except ValidationError as e:
raise ValidationError(f"Invalid features schema: {str(e)}")
-
+
def load_requirements(self) -> Dict[str, Any]:
"""
Load and validate requirements configuration
-
+
Returns:
Requirements configuration dict
-
+
Raises:
FileNotFoundError: If requirements.json not found
ValidationError: If requirements.json is invalid
"""
if self._requirements_cache is not None:
return self._requirements_cache
-
+
if not self.requirements_file.exists():
- raise FileNotFoundError(f"Requirements config not found: {self.requirements_file}")
-
+ raise FileNotFoundError(
+ f"Requirements config not found: {self.requirements_file}"
+ )
+
try:
- with open(self.requirements_file, 'r') as f:
+ with open(self.requirements_file, "r") as f:
requirements = json.load(f)
-
+
# Validate schema
validate(instance=requirements, schema=self.requirements_schema)
-
+
self._requirements_cache = requirements
return requirements
-
+
except json.JSONDecodeError as e:
raise ValidationError(f"Invalid JSON in {self.requirements_file}: {e}")
except ValidationError as e:
raise ValidationError(f"Invalid requirements schema: {str(e)}")
-
+
def get_component_info(self, component_name: str) -> Optional[Dict[str, Any]]:
"""
Get information about a specific component
-
+
Args:
component_name: Name of component
-
+
Returns:
Component info dict or None if not found
"""
features = self.load_features()
return features.get("components", {}).get(component_name)
-
+
def get_enabled_components(self) -> List[str]:
"""
Get list of enabled component names
-
+
Returns:
List of enabled component names
"""
features = self.load_features()
enabled = []
-
+
for name, info in features.get("components", {}).items():
if info.get("enabled", True): # Default to enabled
enabled.append(name)
-
+
return enabled
-
+
def get_components_by_category(self, category: str) -> List[str]:
"""
Get component names by category
-
+
Args:
category: Component category
-
+
Returns:
List of component names in category
"""
features = self.load_features()
components = []
-
+
for name, info in features.get("components", {}).items():
if info.get("category") == category:
components.append(name)
-
+
return components
-
+
def get_component_dependencies(self, component_name: str) -> List[str]:
"""
Get dependencies for a component
-
+
Args:
component_name: Name of component
-
+
Returns:
List of dependency component names
"""
@@ -277,82 +280,86 @@ class ConfigService:
if component_info:
return component_info.get("dependencies", [])
return []
-
+
def get_system_requirements(self) -> Dict[str, Any]:
"""
Get system requirements
-
+
Returns:
System requirements dict
"""
return self.load_requirements()
-
- def get_requirements_for_components(self, component_names: List[str]) -> Dict[str, Any]:
+
+ def get_requirements_for_components(
+ self, component_names: List[str]
+ ) -> Dict[str, Any]:
"""
Get consolidated requirements for specific components
-
+
Args:
component_names: List of component names
-
+
Returns:
Consolidated requirements dict
"""
requirements = self.load_requirements()
features = self.load_features()
-
+
# Start with base requirements
result = {
"python": requirements["python"],
"disk_space_mb": requirements["disk_space_mb"],
- "external_tools": {}
+ "external_tools": {},
}
-
+
# Add Node.js requirements if needed
node_required = False
for component_name in component_names:
component_info = features.get("components", {}).get(component_name, {})
required_tools = component_info.get("required_tools", [])
-
+
if "node" in required_tools:
node_required = True
break
-
+
if node_required and "node" in requirements:
result["node"] = requirements["node"]
-
+
# Add external tool requirements
for component_name in component_names:
component_info = features.get("components", {}).get(component_name, {})
required_tools = component_info.get("required_tools", [])
-
+
for tool in required_tools:
if tool in requirements.get("external_tools", {}):
- result["external_tools"][tool] = requirements["external_tools"][tool]
-
+ result["external_tools"][tool] = requirements["external_tools"][
+ tool
+ ]
+
return result
-
+
def validate_config_files(self) -> List[str]:
"""
Validate all configuration files
-
+
Returns:
List of validation errors (empty if all valid)
"""
errors = []
-
+
try:
self.load_features()
except Exception as e:
errors.append(f"Features config error: {e}")
-
+
try:
self.load_requirements()
except Exception as e:
errors.append(f"Requirements config error: {e}")
-
+
return errors
-
+
def clear_cache(self) -> None:
"""Clear cached configuration data"""
self._features_cache = None
- self._requirements_cache = None
\ No newline at end of file
+ self._requirements_cache = None
diff --git a/setup/services/files.py b/setup/services/files.py
index dff766e..573bb6d 100644
--- a/setup/services/files.py
+++ b/setup/services/files.py
@@ -12,83 +12,87 @@ import hashlib
class FileService:
"""Cross-platform file operations manager"""
-
+
def __init__(self, dry_run: bool = False):
"""
Initialize file manager
-
+
Args:
dry_run: If True, only simulate file operations
"""
self.dry_run = dry_run
self.copied_files: List[Path] = []
self.created_dirs: List[Path] = []
-
- def copy_file(self, source: Path, target: Path, preserve_permissions: bool = True) -> bool:
+
+ def copy_file(
+ self, source: Path, target: Path, preserve_permissions: bool = True
+ ) -> bool:
"""
Copy single file with permission preservation
-
+
Args:
source: Source file path
target: Target file path
preserve_permissions: Whether to preserve file permissions
-
+
Returns:
True if successful, False otherwise
"""
if not source.exists():
raise FileNotFoundError(f"Source file not found: {source}")
-
+
if not source.is_file():
raise ValueError(f"Source is not a file: {source}")
-
+
if self.dry_run:
print(f"[DRY RUN] Would copy {source} -> {target}")
return True
-
+
try:
# Ensure target directory exists
target.parent.mkdir(parents=True, exist_ok=True)
-
+
# Copy file
if preserve_permissions:
shutil.copy2(source, target)
else:
shutil.copy(source, target)
-
+
self.copied_files.append(target)
return True
-
+
except Exception as e:
print(f"Error copying {source} to {target}: {e}")
return False
-
- def copy_directory(self, source: Path, target: Path, ignore_patterns: Optional[List[str]] = None) -> bool:
+
+ def copy_directory(
+ self, source: Path, target: Path, ignore_patterns: Optional[List[str]] = None
+ ) -> bool:
"""
Recursively copy directory with gitignore-style patterns
-
+
Args:
source: Source directory path
target: Target directory path
ignore_patterns: List of patterns to ignore (gitignore style)
-
+
Returns:
True if successful, False otherwise
"""
if not source.exists():
raise FileNotFoundError(f"Source directory not found: {source}")
-
+
if not source.is_dir():
raise ValueError(f"Source is not a directory: {source}")
-
+
ignore_patterns = ignore_patterns or []
- default_ignores = ['.git', '.gitignore', '__pycache__', '*.pyc', '.DS_Store']
+ default_ignores = [".git", ".gitignore", "__pycache__", "*.pyc", ".DS_Store"]
all_ignores = ignore_patterns + default_ignores
-
+
if self.dry_run:
print(f"[DRY RUN] Would copy directory {source} -> {target}")
return True
-
+
try:
# Create ignore function
def ignore_func(directory: str, contents: List[str]) -> List[str]:
@@ -96,250 +100,258 @@ class FileService:
for item in contents:
item_path = Path(directory) / item
rel_path = item_path.relative_to(source)
-
+
# Check against ignore patterns
for pattern in all_ignores:
- if fnmatch.fnmatch(item, pattern) or fnmatch.fnmatch(str(rel_path), pattern):
+ if fnmatch.fnmatch(item, pattern) or fnmatch.fnmatch(
+ str(rel_path), pattern
+ ):
ignored.append(item)
break
-
+
return ignored
-
+
# Copy tree
shutil.copytree(source, target, ignore=ignore_func, dirs_exist_ok=True)
-
+
# Track created directories and files
- for item in target.rglob('*'):
+ for item in target.rglob("*"):
if item.is_dir():
self.created_dirs.append(item)
else:
self.copied_files.append(item)
-
+
return True
-
+
except Exception as e:
print(f"Error copying directory {source} to {target}: {e}")
return False
-
+
def ensure_directory(self, directory: Path, mode: int = 0o755) -> bool:
"""
Create directory and parents if they don't exist
-
+
Args:
directory: Directory path to create
mode: Directory permissions (Unix only)
-
+
Returns:
True if successful, False otherwise
"""
if self.dry_run:
print(f"[DRY RUN] Would create directory {directory}")
return True
-
+
try:
directory.mkdir(parents=True, exist_ok=True, mode=mode)
-
+
if directory not in self.created_dirs:
self.created_dirs.append(directory)
-
+
return True
-
+
except Exception as e:
print(f"Error creating directory {directory}: {e}")
return False
-
+
def remove_file(self, file_path: Path) -> bool:
"""
Remove single file
-
+
Args:
file_path: Path to file to remove
-
+
Returns:
True if successful, False otherwise
"""
if not file_path.exists():
return True # Already gone
-
+
if self.dry_run:
print(f"[DRY RUN] Would remove file {file_path}")
return True
-
+
try:
if file_path.is_file():
file_path.unlink()
else:
print(f"Warning: {file_path} is not a file, skipping")
return False
-
+
# Remove from tracking
if file_path in self.copied_files:
self.copied_files.remove(file_path)
-
+
return True
-
+
except Exception as e:
print(f"Error removing file {file_path}: {e}")
return False
-
+
def remove_directory(self, directory: Path, recursive: bool = False) -> bool:
"""
Remove directory
-
+
Args:
directory: Directory path to remove
recursive: Whether to remove recursively
-
+
Returns:
True if successful, False otherwise
"""
if not directory.exists():
return True # Already gone
-
+
if self.dry_run:
action = "recursively remove" if recursive else "remove"
print(f"[DRY RUN] Would {action} directory {directory}")
return True
-
+
try:
if recursive:
shutil.rmtree(directory)
else:
directory.rmdir() # Only works if empty
-
+
# Remove from tracking
if directory in self.created_dirs:
self.created_dirs.remove(directory)
-
+
return True
-
+
except Exception as e:
print(f"Error removing directory {directory}: {e}")
return False
-
+
def resolve_home_path(self, path: str) -> Path:
"""
Convert path with ~ to actual home path on any OS
-
+
Args:
path: Path string potentially containing ~
-
+
Returns:
Resolved Path object
"""
return Path(path).expanduser().resolve()
-
+
def make_executable(self, file_path: Path) -> bool:
"""
Make file executable (Unix/Linux/macOS)
-
+
Args:
file_path: Path to file to make executable
-
+
Returns:
True if successful, False otherwise
"""
if not file_path.exists():
return False
-
+
if self.dry_run:
print(f"[DRY RUN] Would make {file_path} executable")
return True
-
+
try:
# Get current permissions
current_mode = file_path.stat().st_mode
-
+
# Add execute permissions for owner, group, and others
new_mode = current_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
-
+
file_path.chmod(new_mode)
return True
-
+
except Exception as e:
print(f"Error making {file_path} executable: {e}")
return False
-
- def get_file_hash(self, file_path: Path, algorithm: str = 'sha256') -> Optional[str]:
+
+ def get_file_hash(
+ self, file_path: Path, algorithm: str = "sha256"
+ ) -> Optional[str]:
"""
Calculate file hash
-
+
Args:
file_path: Path to file
algorithm: Hash algorithm (md5, sha1, sha256, etc.)
-
+
Returns:
Hex hash string or None if error
"""
if not file_path.exists() or not file_path.is_file():
return None
-
+
try:
hasher = hashlib.new(algorithm)
-
- with open(file_path, 'rb') as f:
+
+ with open(file_path, "rb") as f:
# Read in chunks for large files
for chunk in iter(lambda: f.read(8192), b""):
hasher.update(chunk)
-
+
return hasher.hexdigest()
-
+
except Exception:
return None
-
- def verify_file_integrity(self, file_path: Path, expected_hash: str, algorithm: str = 'sha256') -> bool:
+
+ def verify_file_integrity(
+ self, file_path: Path, expected_hash: str, algorithm: str = "sha256"
+ ) -> bool:
"""
Verify file integrity using hash
-
+
Args:
file_path: Path to file to verify
expected_hash: Expected hash value
algorithm: Hash algorithm used
-
+
Returns:
True if file matches expected hash, False otherwise
"""
actual_hash = self.get_file_hash(file_path, algorithm)
return actual_hash is not None and actual_hash.lower() == expected_hash.lower()
-
+
def get_directory_size(self, directory: Path) -> int:
"""
Calculate total size of directory in bytes
-
+
Args:
directory: Directory path
-
+
Returns:
Total size in bytes
"""
if not directory.exists() or not directory.is_dir():
return 0
-
+
total_size = 0
try:
- for file_path in directory.rglob('*'):
+ for file_path in directory.rglob("*"):
if file_path.is_file():
total_size += file_path.stat().st_size
except Exception:
pass # Skip files we can't access
-
+
return total_size
-
- def find_files(self, directory: Path, pattern: str = '*', recursive: bool = True) -> List[Path]:
+
+ def find_files(
+ self, directory: Path, pattern: str = "*", recursive: bool = True
+ ) -> List[Path]:
"""
Find files matching pattern
-
+
Args:
directory: Directory to search
pattern: Glob pattern to match
recursive: Whether to search recursively
-
+
Returns:
List of matching file paths
"""
if not directory.exists() or not directory.is_dir():
return []
-
+
try:
if recursive:
return list(directory.rglob(pattern))
@@ -347,52 +359,54 @@ class FileService:
return list(directory.glob(pattern))
except Exception:
return []
-
- def backup_file(self, file_path: Path, backup_suffix: str = '.backup') -> Optional[Path]:
+
+ def backup_file(
+ self, file_path: Path, backup_suffix: str = ".backup"
+ ) -> Optional[Path]:
"""
Create backup copy of file
-
+
Args:
file_path: Path to file to backup
backup_suffix: Suffix to add to backup file
-
+
Returns:
Path to backup file or None if failed
"""
if not file_path.exists() or not file_path.is_file():
return None
-
+
backup_path = file_path.with_suffix(file_path.suffix + backup_suffix)
-
+
if self.copy_file(file_path, backup_path):
return backup_path
return None
-
+
def get_free_space(self, path: Path) -> int:
"""
Get free disk space at path in bytes
-
+
Args:
path: Path to check (can be file or directory)
-
+
Returns:
Free space in bytes
"""
try:
if path.is_file():
path = path.parent
-
+
stat_result = shutil.disk_usage(path)
return stat_result.free
except Exception:
return 0
-
+
def cleanup_tracked_files(self) -> None:
"""Remove all files and directories created during this session"""
if self.dry_run:
print("[DRY RUN] Would cleanup tracked files")
return
-
+
# Remove files first
for file_path in reversed(self.copied_files):
try:
@@ -400,7 +414,7 @@ class FileService:
file_path.unlink()
except Exception:
pass
-
+
# Remove directories (in reverse order of creation)
for directory in reversed(self.created_dirs):
try:
@@ -408,21 +422,21 @@ class FileService:
directory.rmdir()
except Exception:
pass
-
+
self.copied_files.clear()
self.created_dirs.clear()
-
+
def get_operation_summary(self) -> Dict[str, Any]:
"""
Get summary of file operations performed
-
+
Returns:
Dict with operation statistics
"""
return {
- 'files_copied': len(self.copied_files),
- 'directories_created': len(self.created_dirs),
- 'dry_run': self.dry_run,
- 'copied_files': [str(f) for f in self.copied_files],
- 'created_directories': [str(d) for d in self.created_dirs]
- }
\ No newline at end of file
+ "files_copied": len(self.copied_files),
+ "directories_created": len(self.created_dirs),
+ "dry_run": self.dry_run,
+ "copied_files": [str(f) for f in self.copied_files],
+ "created_directories": [str(d) for d in self.created_dirs],
+ }
diff --git a/setup/services/settings.py b/setup/services/settings.py
index 36ce30b..a45c78a 100644
--- a/setup/services/settings.py
+++ b/setup/services/settings.py
@@ -14,11 +14,11 @@ import copy
class SettingsService:
"""Manages settings.json file operations"""
-
+
def __init__(self, install_dir: Path):
"""
Initialize settings manager
-
+
Args:
install_dir: Installation directory containing settings.json
"""
@@ -26,27 +26,29 @@ class SettingsService:
self.settings_file = install_dir / "settings.json"
self.metadata_file = install_dir / ".superclaude-metadata.json"
self.backup_dir = install_dir / "backups" / "settings"
-
+
def load_settings(self) -> Dict[str, Any]:
"""
Load settings from settings.json
-
+
Returns:
Settings dict (empty if file doesn't exist)
"""
if not self.settings_file.exists():
return {}
-
+
try:
- with open(self.settings_file, 'r', encoding='utf-8') as f:
+ with open(self.settings_file, "r", encoding="utf-8") as f:
return json.load(f)
except (json.JSONDecodeError, IOError) as e:
raise ValueError(f"Could not load settings from {self.settings_file}: {e}")
-
- def save_settings(self, settings: Dict[str, Any], create_backup: bool = True) -> None:
+
+ def save_settings(
+ self, settings: Dict[str, Any], create_backup: bool = True
+ ) -> None:
"""
Save settings to settings.json with optional backup
-
+
Args:
settings: Settings dict to save
create_backup: Whether to create backup before saving
@@ -54,46 +56,46 @@ class SettingsService:
# Create backup if requested and file exists
if create_backup and self.settings_file.exists():
self._create_settings_backup()
-
+
# Ensure directory exists
self.settings_file.parent.mkdir(parents=True, exist_ok=True)
-
+
# Save with pretty formatting
try:
- with open(self.settings_file, 'w', encoding='utf-8') as f:
+ with open(self.settings_file, "w", encoding="utf-8") as f:
json.dump(settings, f, indent=2, ensure_ascii=False, sort_keys=True)
except IOError as e:
raise ValueError(f"Could not save settings to {self.settings_file}: {e}")
-
+
def load_metadata(self) -> Dict[str, Any]:
"""
Load SuperClaude metadata from .superclaude-metadata.json
-
+
Returns:
Metadata dict (empty if file doesn't exist)
"""
if not self.metadata_file.exists():
return {}
-
+
try:
- with open(self.metadata_file, 'r', encoding='utf-8') as f:
+ with open(self.metadata_file, "r", encoding="utf-8") as f:
return json.load(f)
except (json.JSONDecodeError, IOError) as e:
raise ValueError(f"Could not load metadata from {self.metadata_file}: {e}")
-
+
def save_metadata(self, metadata: Dict[str, Any]) -> None:
"""
Save SuperClaude metadata to .superclaude-metadata.json
-
+
Args:
metadata: Metadata dict to save
"""
# Ensure directory exists
self.metadata_file.parent.mkdir(parents=True, exist_ok=True)
-
+
# Save with pretty formatting
try:
- with open(self.metadata_file, 'w', encoding='utf-8') as f:
+ with open(self.metadata_file, "w", encoding="utf-8") as f:
json.dump(metadata, f, indent=2, ensure_ascii=False, sort_keys=True)
except IOError as e:
raise ValueError(f"Could not save metadata to {self.metadata_file}: {e}")
@@ -125,128 +127,134 @@ class SettingsService:
def migrate_superclaude_data(self) -> bool:
"""
Migrate SuperClaude-specific data from settings.json to metadata file
-
+
Returns:
True if migration occurred, False if no data to migrate
"""
settings = self.load_settings()
-
+
# SuperClaude-specific fields to migrate
superclaude_fields = ["components", "framework", "superclaude", "mcp"]
data_to_migrate = {}
fields_found = False
-
+
# Extract SuperClaude data
for field in superclaude_fields:
if field in settings:
data_to_migrate[field] = settings[field]
fields_found = True
-
+
if not fields_found:
return False
-
+
# Load existing metadata (if any) and merge
existing_metadata = self.load_metadata()
merged_metadata = self._deep_merge(existing_metadata, data_to_migrate)
-
+
# Save to metadata file
self.save_metadata(merged_metadata)
-
+
# Remove SuperClaude fields from settings
- clean_settings = {k: v for k, v in settings.items() if k not in superclaude_fields}
-
+ clean_settings = {
+ k: v for k, v in settings.items() if k not in superclaude_fields
+ }
+
# Save cleaned settings
self.save_settings(clean_settings, create_backup=True)
-
+
return True
-
+
def merge_settings(self, modifications: Dict[str, Any]) -> Dict[str, Any]:
"""
Deep merge modifications into existing settings
-
+
Args:
modifications: Settings modifications to merge
-
+
Returns:
Merged settings dict
"""
existing = self.load_settings()
return self._deep_merge(existing, modifications)
-
- def update_settings(self, modifications: Dict[str, Any], create_backup: bool = True) -> None:
+
+ def update_settings(
+ self, modifications: Dict[str, Any], create_backup: bool = True
+ ) -> None:
"""
Update settings with modifications
-
+
Args:
modifications: Settings modifications to apply
create_backup: Whether to create backup before updating
"""
merged = self.merge_settings(modifications)
self.save_settings(merged, create_backup)
-
+
def get_setting(self, key_path: str, default: Any = None) -> Any:
"""
Get setting value using dot-notation path
-
+
Args:
key_path: Dot-separated path (e.g., "hooks.enabled")
default: Default value if key not found
-
+
Returns:
Setting value or default
"""
settings = self.load_settings()
-
+
try:
value = settings
- for key in key_path.split('.'):
+ for key in key_path.split("."):
value = value[key]
return value
except (KeyError, TypeError):
return default
-
- def set_setting(self, key_path: str, value: Any, create_backup: bool = True) -> None:
+
+ def set_setting(
+ self, key_path: str, value: Any, create_backup: bool = True
+ ) -> None:
"""
Set setting value using dot-notation path
-
+
Args:
key_path: Dot-separated path (e.g., "hooks.enabled")
value: Value to set
create_backup: Whether to create backup before updating
"""
# Build nested dict structure
- keys = key_path.split('.')
+ keys = key_path.split(".")
modification = {}
current = modification
-
+
for key in keys[:-1]:
current[key] = {}
current = current[key]
-
+
current[keys[-1]] = value
-
+
self.update_settings(modification, create_backup)
-
+
def remove_setting(self, key_path: str, create_backup: bool = True) -> bool:
"""
Remove setting using dot-notation path
-
+
Args:
key_path: Dot-separated path to remove
create_backup: Whether to create backup before updating
-
+
Returns:
True if setting was removed, False if not found
"""
settings = self.load_settings()
- keys = key_path.split('.')
-
+ keys = key_path.split(".")
+
# Navigate to parent of target key
current = settings
try:
for key in keys[:-1]:
current = current[key]
-
+
# Remove the target key
if keys[-1] in current:
del current[keys[-1]]
@@ -254,14 +262,16 @@ class SettingsService:
return True
else:
return False
-
+
except (KeyError, TypeError):
return False
-
- def add_component_registration(self, component_name: str, component_info: Dict[str, Any]) -> None:
+
+ def add_component_registration(
+ self, component_name: str, component_info: Dict[str, Any]
+ ) -> None:
"""
Add component to registry in metadata
-
+
Args:
component_name: Name of component
component_info: Component metadata dict
@@ -269,21 +279,21 @@ class SettingsService:
metadata = self.load_metadata()
if "components" not in metadata:
metadata["components"] = {}
-
+
metadata["components"][component_name] = {
**component_info,
- "installed_at": datetime.now().isoformat()
+ "installed_at": datetime.now().isoformat(),
}
-
+
self.save_metadata(metadata)
-
+
def remove_component_registration(self, component_name: str) -> bool:
"""
Remove component from registry in metadata
-
+
Args:
component_name: Name of component to remove
-
+
Returns:
True if component was removed, False if not found
"""
@@ -293,64 +303,64 @@ class SettingsService:
self.save_metadata(metadata)
return True
return False
-
+
def get_installed_components(self) -> Dict[str, Dict[str, Any]]:
"""
Get all installed components from registry
-
+
Returns:
Dict of component_name -> component_info
"""
metadata = self.load_metadata()
return metadata.get("components", {})
-
+
def is_component_installed(self, component_name: str) -> bool:
"""
Check if component is registered as installed
-
+
Args:
component_name: Name of component to check
-
+
Returns:
True if component is installed, False otherwise
"""
components = self.get_installed_components()
return component_name in components
-
+
def get_component_version(self, component_name: str) -> Optional[str]:
"""
Get installed version of component
-
+
Args:
component_name: Name of component
-
+
Returns:
Version string or None if not installed
"""
components = self.get_installed_components()
component_info = components.get(component_name, {})
return component_info.get("version")
-
+
def update_framework_version(self, version: str) -> None:
"""
Update SuperClaude framework version in metadata
-
+
Args:
version: Framework version string
"""
metadata = self.load_metadata()
if "framework" not in metadata:
metadata["framework"] = {}
-
+
metadata["framework"]["version"] = version
metadata["framework"]["updated_at"] = datetime.now().isoformat()
-
+
self.save_metadata(metadata)
-
+
def check_installation_exists(self) -> bool:
"""
Get SuperClaude framework version from metadata
-
+
Returns:
Version string or None if not set
"""
@@ -364,152 +374,160 @@ class SettingsService:
Version string or None if not set
"""
return self.settings_file.exists()
-
+
def get_metadata_setting(self, key_path: str, default: Any = None) -> Any:
"""
Get metadata value using dot-notation path
-
+
Args:
key_path: Dot-separated path (e.g., "framework.version")
default: Default value if key not found
-
+
Returns:
Metadata value or default
"""
metadata = self.load_metadata()
-
+
try:
value = metadata
- for key in key_path.split('.'):
+ for key in key_path.split("."):
value = value[key]
return value
except (KeyError, TypeError):
return default
-
- def _deep_merge(self, base: Dict[str, Any], overlay: Dict[str, Any]) -> Dict[str, Any]:
+
+ def _deep_merge(
+ self, base: Dict[str, Any], overlay: Dict[str, Any]
+ ) -> Dict[str, Any]:
"""
Deep merge two dictionaries
-
+
Args:
base: Base dictionary
overlay: Dictionary to merge on top
-
+
Returns:
Merged dictionary
"""
result = copy.deepcopy(base)
-
+
for key, value in overlay.items():
- if key in result and isinstance(result[key], dict) and isinstance(value, dict):
+ if (
+ key in result
+ and isinstance(result[key], dict)
+ and isinstance(value, dict)
+ ):
result[key] = self._deep_merge(result[key], value)
else:
result[key] = copy.deepcopy(value)
-
+
return result
-
+
def _create_settings_backup(self) -> Path:
"""
Create timestamped backup of settings.json
-
+
Returns:
Path to backup file
"""
if not self.settings_file.exists():
raise ValueError("Cannot backup non-existent settings file")
-
+
# Create backup directory
self.backup_dir.mkdir(parents=True, exist_ok=True)
-
+
# Create timestamped backup
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_file = self.backup_dir / f"settings_{timestamp}.json"
-
+
shutil.copy2(self.settings_file, backup_file)
-
+
# Keep only last 10 backups
self._cleanup_old_backups()
-
+
return backup_file
-
+
def _cleanup_old_backups(self, keep_count: int = 10) -> None:
"""
Remove old backup files, keeping only the most recent
-
+
Args:
keep_count: Number of backups to keep
"""
if not self.backup_dir.exists():
return
-
+
# Get all backup files sorted by modification time
backup_files = []
for file in self.backup_dir.glob("settings_*.json"):
backup_files.append((file.stat().st_mtime, file))
-
+
backup_files.sort(reverse=True) # Most recent first
-
+
# Remove old backups
for _, file in backup_files[keep_count:]:
try:
file.unlink()
except OSError:
pass # Ignore errors when cleaning up
-
+
def list_backups(self) -> List[Dict[str, Any]]:
"""
List available settings backups
-
+
Returns:
List of backup info dicts with name, path, and timestamp
"""
if not self.backup_dir.exists():
return []
-
+
backups = []
for file in self.backup_dir.glob("settings_*.json"):
try:
stat = file.stat()
- backups.append({
- "name": file.name,
- "path": str(file),
- "size": stat.st_size,
- "created": datetime.fromtimestamp(stat.st_ctime).isoformat(),
- "modified": datetime.fromtimestamp(stat.st_mtime).isoformat()
- })
+ backups.append(
+ {
+ "name": file.name,
+ "path": str(file),
+ "size": stat.st_size,
+ "created": datetime.fromtimestamp(stat.st_ctime).isoformat(),
+ "modified": datetime.fromtimestamp(stat.st_mtime).isoformat(),
+ }
+ )
except OSError:
continue
-
+
# Sort by creation time, most recent first
backups.sort(key=lambda x: x["created"], reverse=True)
return backups
-
+
def restore_backup(self, backup_name: str) -> bool:
"""
Restore settings from backup
-
+
Args:
backup_name: Name of backup file to restore
-
+
Returns:
True if successful, False otherwise
"""
backup_file = self.backup_dir / backup_name
-
+
if not backup_file.exists():
return False
-
+
try:
# Validate backup file first
- with open(backup_file, 'r', encoding='utf-8') as f:
+ with open(backup_file, "r", encoding="utf-8") as f:
json.load(f) # Will raise exception if invalid
-
+
# Create backup of current settings
if self.settings_file.exists():
self._create_settings_backup()
-
+
# Restore backup
shutil.copy2(backup_file, self.settings_file)
return True
-
+
except (json.JSONDecodeError, IOError):
return False
diff --git a/setup/utils/__init__.py b/setup/utils/__init__.py
index 22f1cc1..ad0fcc3 100644
--- a/setup/utils/__init__.py
+++ b/setup/utils/__init__.py
@@ -4,11 +4,4 @@ from .ui import ProgressBar, Menu, confirm, Colors
from .logger import Logger
from .security import SecurityValidator
-__all__ = [
- 'ProgressBar',
- 'Menu',
- 'confirm',
- 'Colors',
- 'Logger',
- 'SecurityValidator'
-]
\ No newline at end of file
+__all__ = ["ProgressBar", "Menu", "confirm", "Colors", "Logger", "SecurityValidator"]
diff --git a/setup/utils/environment.py b/setup/utils/environment.py
index 4899871..81c6013 100644
--- a/setup/utils/environment.py
+++ b/setup/utils/environment.py
@@ -18,6 +18,7 @@ from .paths import get_home_directory
def _get_env_tracking_file() -> Path:
"""Get path to environment variable tracking file"""
from .. import DEFAULT_INSTALL_DIR
+
install_dir = get_home_directory() / ".claude"
install_dir.mkdir(exist_ok=True)
return install_dir / "superclaude_env_vars.json"
@@ -26,23 +27,23 @@ def _get_env_tracking_file() -> Path:
def _load_env_tracking() -> Dict[str, Dict[str, str]]:
"""Load environment variable tracking data"""
tracking_file = _get_env_tracking_file()
-
+
try:
if tracking_file.exists():
- with open(tracking_file, 'r') as f:
+ with open(tracking_file, "r") as f:
return json.load(f)
except Exception as e:
get_logger().warning(f"Could not load environment tracking: {e}")
-
+
return {}
def _save_env_tracking(tracking_data: Dict[str, Dict[str, str]]) -> bool:
"""Save environment variable tracking data"""
tracking_file = _get_env_tracking_file()
-
+
try:
- with open(tracking_file, 'w') as f:
+ with open(tracking_file, "w") as f:
json.dump(tracking_data, f, indent=2)
return True
except Exception as e:
@@ -54,17 +55,17 @@ def _add_env_tracking(env_vars: Dict[str, str]) -> None:
"""Add environment variables to tracking"""
if not env_vars:
return
-
+
tracking_data = _load_env_tracking()
timestamp = datetime.now().isoformat()
-
+
for env_var, value in env_vars.items():
tracking_data[env_var] = {
"set_by": "superclaude",
"timestamp": timestamp,
- "value_hash": str(hash(value)) # Store hash, not actual value for security
+ "value_hash": str(hash(value)), # Store hash, not actual value for security
}
-
+
_save_env_tracking(tracking_data)
get_logger().info(f"Added {len(env_vars)} environment variables to tracking")
@@ -73,13 +74,13 @@ def _remove_env_tracking(env_vars: list) -> None:
"""Remove environment variables from tracking"""
if not env_vars:
return
-
+
tracking_data = _load_env_tracking()
-
+
for env_var in env_vars:
if env_var in tracking_data:
del tracking_data[env_var]
-
+
_save_env_tracking(tracking_data)
get_logger().info(f"Removed {len(env_vars)} environment variables from tracking")
@@ -87,24 +88,24 @@ def _remove_env_tracking(env_vars: list) -> None:
def detect_shell_config() -> Optional[Path]:
"""
Detect user's shell configuration file
-
+
Returns:
Path to the shell configuration file, or None if not found
"""
home = get_home_directory()
-
+
# Check in order of preference
configs = [
- home / ".zshrc", # Zsh (Mac default)
- home / ".bashrc", # Bash
- home / ".profile", # Generic shell profile
- home / ".bash_profile" # Mac Bash profile
+ home / ".zshrc", # Zsh (Mac default)
+ home / ".bashrc", # Bash
+ home / ".profile", # Generic shell profile
+ home / ".bash_profile", # Mac Bash profile
]
-
+
for config in configs:
if config.exists():
return config
-
+
# Default to .bashrc if none exist (will be created)
return home / ".bashrc"
@@ -112,103 +113,113 @@ def detect_shell_config() -> Optional[Path]:
def setup_environment_variables(api_keys: Dict[str, str]) -> bool:
"""
Set up environment variables across platforms
-
+
Args:
api_keys: Dictionary of environment variable names to values
-
+
Returns:
True if all variables were set successfully, False otherwise
"""
logger = get_logger()
success = True
-
+
if not api_keys:
return True
-
+
print(f"\n{Colors.BLUE}[INFO] Setting up environment variables...{Colors.RESET}")
-
+
for env_var, value in api_keys.items():
try:
# Set for current session
os.environ[env_var] = value
-
- if os.name == 'nt': # Windows
+
+ if os.name == "nt": # Windows
# Use setx for persistent user variable
result = subprocess.run(
- ['setx', env_var, value],
- capture_output=True,
- text=True
+ ["setx", env_var, value], capture_output=True, text=True
)
if result.returncode != 0:
- display_warning(f"Could not set {env_var} persistently: {result.stderr.strip()}")
+ display_warning(
+ f"Could not set {env_var} persistently: {result.stderr.strip()}"
+ )
success = False
else:
- logger.info(f"Windows environment variable {env_var} set persistently")
+ logger.info(
+ f"Windows environment variable {env_var} set persistently"
+ )
else: # Unix-like systems
shell_config = detect_shell_config()
-
+
# Check if the export already exists
export_line = f'export {env_var}="{value}"'
-
+
try:
- with open(shell_config, 'r') as f:
+ with open(shell_config, "r") as f:
content = f.read()
-
+
# Check if this environment variable is already set
- if f'export {env_var}=' in content:
+ if f"export {env_var}=" in content:
# Variable exists - don't duplicate
- logger.info(f"Environment variable {env_var} already exists in {shell_config.name}")
+ logger.info(
+ f"Environment variable {env_var} already exists in {shell_config.name}"
+ )
else:
# Append export to shell config
- with open(shell_config, 'a') as f:
- f.write(f'\n# SuperClaude API Key\n{export_line}\n')
-
+ with open(shell_config, "a") as f:
+ f.write(f"\n# SuperClaude API Key\n{export_line}\n")
+
display_info(f"Added {env_var} to {shell_config.name}")
logger.info(f"Added {env_var} to {shell_config}")
-
+
except Exception as e:
display_warning(f"Could not update {shell_config.name}: {e}")
success = False
-
- logger.info(f"Environment variable {env_var} configured for current session")
-
+
+ logger.info(
+ f"Environment variable {env_var} configured for current session"
+ )
+
except Exception as e:
logger.error(f"Failed to set {env_var}: {e}")
display_warning(f"Failed to set {env_var}: {e}")
success = False
-
+
if success:
# Add to tracking
_add_env_tracking(api_keys)
-
+
display_success("Environment variables configured successfully")
- if os.name != 'nt':
- display_info("Restart your terminal or run 'source ~/.bashrc' to apply changes")
+ if os.name != "nt":
+ display_info(
+ "Restart your terminal or run 'source ~/.bashrc' to apply changes"
+ )
else:
- display_info("New environment variables will be available in new terminal sessions")
+ display_info(
+ "New environment variables will be available in new terminal sessions"
+ )
else:
display_warning("Some environment variables could not be set persistently")
display_info("You can set them manually or check the logs for details")
-
+
return success
def validate_environment_setup(env_vars: Dict[str, str]) -> bool:
"""
Validate that environment variables are properly set
-
+
Args:
env_vars: Dictionary of environment variable names to expected values
-
+
Returns:
True if all variables are set correctly, False otherwise
"""
logger = get_logger()
all_valid = True
-
+
for env_var, expected_value in env_vars.items():
current_value = os.environ.get(env_var)
-
+
if current_value is None:
logger.warning(f"Environment variable {env_var} is not set")
all_valid = False
@@ -217,73 +228,75 @@ def validate_environment_setup(env_vars: Dict[str, str]) -> bool:
all_valid = False
else:
logger.info(f"Environment variable {env_var} is set correctly")
-
+
return all_valid
def get_shell_name() -> str:
"""
Get the name of the current shell
-
+
Returns:
Name of the shell (e.g., 'bash', 'zsh', 'fish')
"""
- shell_path = os.environ.get('SHELL', '')
+ shell_path = os.environ.get("SHELL", "")
if shell_path:
return Path(shell_path).name
- return 'unknown'
+ return "unknown"
def get_superclaude_environment_variables() -> Dict[str, str]:
"""
Get environment variables that were set by SuperClaude
-
+
Returns:
Dictionary of environment variable names to their current values
"""
# Load tracking data to get SuperClaude-managed variables
tracking_data = _load_env_tracking()
-
+
found_vars = {}
for env_var, metadata in tracking_data.items():
if metadata.get("set_by") == "superclaude":
value = os.environ.get(env_var)
if value:
found_vars[env_var] = value
-
+
# Fallback: check known SuperClaude API key environment variables
# (for backwards compatibility with existing installations)
known_superclaude_env_vars = [
"TWENTYFIRST_API_KEY", # Magic server
- "MORPH_API_KEY" # Morphllm server
+ "MORPH_API_KEY", # Morphllm server
]
-
+
for env_var in known_superclaude_env_vars:
if env_var not in found_vars:
value = os.environ.get(env_var)
if value:
found_vars[env_var] = value
-
+
return found_vars
-def cleanup_environment_variables(env_vars_to_remove: Dict[str, str], create_restore_script: bool = True) -> bool:
+def cleanup_environment_variables(
+ env_vars_to_remove: Dict[str, str], create_restore_script: bool = True
+) -> bool:
"""
Safely remove environment variables with backup and restore options
-
+
Args:
env_vars_to_remove: Dictionary of environment variable names to remove
create_restore_script: Whether to create a script to restore the variables
-
+
Returns:
True if cleanup was successful, False otherwise
"""
logger = get_logger()
success = True
-
+
if not env_vars_to_remove:
return True
-
+
# Create restore script if requested
if create_restore_script:
restore_script_path = _create_restore_script(env_vars_to_remove)
@@ -291,50 +304,54 @@ def cleanup_environment_variables(env_vars_to_remove: Dict[str, str], create_res
display_info(f"Created restore script: {restore_script_path}")
else:
display_warning("Could not create restore script")
-
+
print(f"\n{Colors.BLUE}[INFO] Removing environment variables...{Colors.RESET}")
-
+
for env_var, value in env_vars_to_remove.items():
try:
# Remove from current session
if env_var in os.environ:
del os.environ[env_var]
logger.info(f"Removed {env_var} from current session")
-
- if os.name == 'nt': # Windows
+
+ if os.name == "nt": # Windows
# Remove persistent user variable using reg command
result = subprocess.run(
- ['reg', 'delete', 'HKCU\\Environment', '/v', env_var, '/f'],
+ ["reg", "delete", "HKCU\\Environment", "/v", env_var, "/f"],
capture_output=True,
- text=True
+ text=True,
)
if result.returncode != 0:
# Variable might not exist in registry, which is fine
- logger.debug(f"Registry deletion for {env_var}: {result.stderr.strip()}")
+ logger.debug(
+ f"Registry deletion for {env_var}: {result.stderr.strip()}"
+ )
else:
logger.info(f"Removed {env_var} from Windows registry")
else: # Unix-like systems
shell_config = detect_shell_config()
if shell_config and shell_config.exists():
_remove_env_var_from_shell_config(shell_config, env_var)
-
+
except Exception as e:
logger.error(f"Failed to remove {env_var}: {e}")
display_warning(f"Could not remove {env_var}: {e}")
success = False
-
+
if success:
# Remove from tracking
_remove_env_tracking(list(env_vars_to_remove.keys()))
-
+
display_success("Environment variables removed successfully")
- if os.name != 'nt':
- display_info("Restart your terminal or source your shell config to apply changes")
+ if os.name != "nt":
+ display_info(
+ "Restart your terminal or source your shell config to apply changes"
+ )
else:
display_info("Changes will take effect in new terminal sessions")
else:
display_warning("Some environment variables could not be removed")
-
+
return success
@@ -342,9 +359,9 @@ def _create_restore_script(env_vars: Dict[str, str]) -> Optional[Path]:
"""Create a script to restore environment variables"""
try:
home = get_home_directory()
- if os.name == 'nt': # Windows
+ if os.name == "nt": # Windows
script_path = home / "restore_superclaude_env.bat"
- with open(script_path, 'w') as f:
+ with open(script_path, "w") as f:
f.write("@echo off\n")
f.write("REM SuperClaude Environment Variable Restore Script\n")
f.write("REM Generated during uninstall\n\n")
@@ -354,7 +371,7 @@ def _create_restore_script(env_vars: Dict[str, str]) -> Optional[Path]:
f.write("pause\n")
else: # Unix-like
script_path = home / "restore_superclaude_env.sh"
- with open(script_path, 'w') as f:
+ with open(script_path, "w") as f:
f.write("#!/bin/bash\n")
f.write("# SuperClaude Environment Variable Restore Script\n")
f.write("# Generated during uninstall\n\n")
@@ -362,14 +379,16 @@ def _create_restore_script(env_vars: Dict[str, str]) -> Optional[Path]:
for env_var, value in env_vars.items():
f.write(f'export {env_var}="{value}"\n')
if shell_config:
- f.write(f'echo \'export {env_var}="{value}"\' >> {shell_config}\n')
+ f.write(
+ f"echo 'export {env_var}=\"{value}\"' >> {shell_config}\n"
+ )
f.write("\necho 'Environment variables restored'\n")
-
+
# Make script executable
script_path.chmod(0o755)
-
+
return script_path
-
+
except Exception as e:
get_logger().error(f"Failed to create restore script: {e}")
return None
@@ -379,90 +398,92 @@ def _remove_env_var_from_shell_config(shell_config: Path, env_var: str) -> bool:
"""Remove environment variable export from shell configuration file"""
try:
# Read current content
- with open(shell_config, 'r') as f:
+ with open(shell_config, "r") as f:
lines = f.readlines()
-
+
# Filter out lines that export this variable
filtered_lines = []
skip_next_blank = False
-
+
for line in lines:
# Check if this line exports our variable
- if f'export {env_var}=' in line or line.strip() == f'# SuperClaude API Key':
+ if f"export {env_var}=" in line or line.strip() == f"# SuperClaude API Key":
skip_next_blank = True
continue
-
+
# Skip blank line after removed export
- if skip_next_blank and line.strip() == '':
+ if skip_next_blank and line.strip() == "":
skip_next_blank = False
continue
-
+
skip_next_blank = False
filtered_lines.append(line)
-
+
# Write back the filtered content
- with open(shell_config, 'w') as f:
+ with open(shell_config, "w") as f:
f.writelines(filtered_lines)
-
+
get_logger().info(f"Removed {env_var} export from {shell_config.name}")
return True
-
+
except Exception as e:
get_logger().error(f"Failed to remove {env_var} from {shell_config}: {e}")
return False
-def create_env_file(api_keys: Dict[str, str], env_file_path: Optional[Path] = None) -> bool:
+def create_env_file(
+ api_keys: Dict[str, str], env_file_path: Optional[Path] = None
+) -> bool:
"""
Create a .env file with the API keys (alternative to shell config)
-
+
Args:
api_keys: Dictionary of environment variable names to values
env_file_path: Path to the .env file (defaults to home directory)
-
+
Returns:
True if .env file was created successfully, False otherwise
"""
if env_file_path is None:
env_file_path = get_home_directory() / ".env"
-
+
logger = get_logger()
-
+
try:
# Read existing .env file if it exists
existing_content = ""
if env_file_path.exists():
- with open(env_file_path, 'r') as f:
+ with open(env_file_path, "r") as f:
existing_content = f.read()
-
+
# Prepare new content
new_lines = []
for env_var, value in api_keys.items():
line = f'{env_var}="{value}"'
-
+
# Check if this variable already exists
- if f'{env_var}=' in existing_content:
+ if f"{env_var}=" in existing_content:
logger.info(f"Variable {env_var} already exists in .env file")
else:
new_lines.append(line)
-
+
# Append new lines if any
if new_lines:
- with open(env_file_path, 'a') as f:
- if existing_content and not existing_content.endswith('\n'):
- f.write('\n')
- f.write('# SuperClaude API Keys\n')
+ with open(env_file_path, "a") as f:
+ if existing_content and not existing_content.endswith("\n"):
+ f.write("\n")
+ f.write("# SuperClaude API Keys\n")
for line in new_lines:
- f.write(line + '\n')
-
+ f.write(line + "\n")
+
# Set file permissions (readable only by owner)
env_file_path.chmod(0o600)
-
+
display_success(f"Created .env file at {env_file_path}")
logger.info(f"Created .env file with {len(new_lines)} new variables")
-
+
return True
-
+
except Exception as e:
logger.error(f"Failed to create .env file: {e}")
display_warning(f"Could not create .env file: {e}")
@@ -472,13 +493,13 @@ def create_env_file(api_keys: Dict[str, str], env_file_path: Optional[Path] = No
def check_research_prerequisites() -> tuple[bool, list[str]]:
"""
Check if deep research prerequisites are met
-
+
Returns:
Tuple of (success: bool, warnings: List[str])
"""
warnings = []
logger = get_logger()
-
+
# Check Tavily API key
if not os.environ.get("TAVILY_API_KEY"):
warnings.append(
@@ -488,9 +509,10 @@ def check_research_prerequisites() -> tuple[bool, list[str]]:
logger.warning("TAVILY_API_KEY not found in environment")
else:
logger.info("Found TAVILY_API_KEY in environment")
-
+
# Check Node.js for MCP
import shutil
+
if not shutil.which("node"):
warnings.append(
"Node.js not found - Required for Tavily MCP\n"
@@ -499,7 +521,7 @@ def check_research_prerequisites() -> tuple[bool, list[str]]:
logger.warning("Node.js not found - required for Tavily MCP")
else:
logger.info("Node.js found")
-
+
# Check npm
if not shutil.which("npm"):
warnings.append(
@@ -509,5 +531,5 @@ def check_research_prerequisites() -> tuple[bool, list[str]]:
logger.warning("npm not found - required for MCP installation")
else:
logger.info("npm found")
-
- return len(warnings) == 0, warnings
\ No newline at end of file
+
+ return len(warnings) == 0, warnings
diff --git a/setup/utils/logger.py b/setup/utils/logger.py
index 55901e2..c20d0f4 100644
--- a/setup/utils/logger.py
+++ b/setup/utils/logger.py
@@ -16,6 +16,7 @@ from .paths import get_home_directory
class LogLevel(Enum):
"""Log levels"""
+
DEBUG = logging.DEBUG
INFO = logging.INFO
WARNING = logging.WARNING
@@ -25,11 +26,17 @@ class LogLevel(Enum):
class Logger:
"""Enhanced logger with console and file output"""
-
- def __init__(self, name: str = "superclaude", log_dir: Optional[Path] = None, console_level: LogLevel = LogLevel.INFO, file_level: LogLevel = LogLevel.DEBUG):
+
+ def __init__(
+ self,
+ name: str = "superclaude",
+ log_dir: Optional[Path] = None,
+ console_level: LogLevel = LogLevel.INFO,
+ file_level: LogLevel = LogLevel.DEBUG,
+ ):
"""
Initialize logger
-
+
Args:
name: Logger name
log_dir: Directory for log files (defaults to ~/.claude/logs)
@@ -41,146 +48,146 @@ class Logger:
self.console_level = console_level
self.file_level = file_level
self.session_start = datetime.now()
-
+
# Create logger
self.logger = logging.getLogger(name)
self.logger.setLevel(logging.DEBUG) # Accept all levels, handlers will filter
-
+
# Remove existing handlers to avoid duplicates
self.logger.handlers.clear()
-
+
# Setup handlers
self._setup_console_handler()
self._setup_file_handler()
-
+
self.log_counts: Dict[str, int] = {
- 'debug': 0,
- 'info': 0,
- 'warning': 0,
- 'error': 0,
- 'critical': 0
+ "debug": 0,
+ "info": 0,
+ "warning": 0,
+ "error": 0,
+ "critical": 0,
}
-
+
def _setup_console_handler(self) -> None:
"""Setup colorized console handler"""
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(self.console_level.value)
-
+
# Custom formatter with colors
class ColorFormatter(logging.Formatter):
def format(self, record):
# Color mapping
colors = {
- 'DEBUG': Colors.WHITE,
- 'INFO': Colors.BLUE,
- 'WARNING': Colors.YELLOW,
- 'ERROR': Colors.RED,
- 'CRITICAL': Colors.RED + Colors.BRIGHT
+ "DEBUG": Colors.WHITE,
+ "INFO": Colors.BLUE,
+ "WARNING": Colors.YELLOW,
+ "ERROR": Colors.RED,
+ "CRITICAL": Colors.RED + Colors.BRIGHT,
}
-
+
# Prefix mapping
prefixes = {
- 'DEBUG': '[DEBUG]',
- 'INFO': '[INFO]',
- 'WARNING': '[!]',
- 'ERROR': f'[{symbols.crossmark}]',
- 'CRITICAL': '[CRITICAL]'
+ "DEBUG": "[DEBUG]",
+ "INFO": "[INFO]",
+ "WARNING": "[!]",
+ "ERROR": f"[{symbols.crossmark}]",
+ "CRITICAL": "[CRITICAL]",
}
-
+
color = colors.get(record.levelname, Colors.WHITE)
- prefix = prefixes.get(record.levelname, '[LOG]')
-
+ prefix = prefixes.get(record.levelname, "[LOG]")
+
return f"{color}{prefix} {record.getMessage()}{Colors.RESET}"
-
+
handler.setFormatter(ColorFormatter())
self.logger.addHandler(handler)
-
+
def _setup_file_handler(self) -> None:
"""Setup file handler with rotation"""
try:
# Ensure log directory exists
self.log_dir.mkdir(parents=True, exist_ok=True)
-
+
# Create timestamped log file
timestamp = self.session_start.strftime("%Y%m%d_%H%M%S")
log_file = self.log_dir / f"{self.name}_{timestamp}.log"
-
- handler = logging.FileHandler(log_file, encoding='utf-8')
+
+ handler = logging.FileHandler(log_file, encoding="utf-8")
handler.setLevel(self.file_level.value)
-
+
# Detailed formatter for files
formatter = logging.Formatter(
- '%(asctime)s | %(levelname)-8s | %(name)s | %(message)s',
- datefmt='%Y-%m-%d %H:%M:%S'
+ "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s",
+ datefmt="%Y-%m-%d %H:%M:%S",
)
handler.setFormatter(formatter)
-
+
self.logger.addHandler(handler)
self.log_file = log_file
-
+
# Clean up old log files (keep last 10)
self._cleanup_old_logs()
-
+
except Exception as e:
# If file logging fails, continue with console only
print(f"{Colors.YELLOW}[!] Could not setup file logging: {e}{Colors.RESET}")
self.log_file = None
-
+
def _cleanup_old_logs(self, keep_count: int = 10) -> None:
"""Clean up old log files"""
try:
# Get all log files for this logger
log_files = list(self.log_dir.glob(f"{self.name}_*.log"))
-
+
# Sort by modification time, newest first
log_files.sort(key=lambda f: f.stat().st_mtime, reverse=True)
-
+
# Remove old files
for old_file in log_files[keep_count:]:
try:
old_file.unlink()
except OSError:
pass # Ignore errors when cleaning up
-
+
except Exception:
pass # Ignore cleanup errors
-
+
def debug(self, message: str, **kwargs) -> None:
"""Log debug message"""
self.logger.debug(message, **kwargs)
- self.log_counts['debug'] += 1
-
+ self.log_counts["debug"] += 1
+
def info(self, message: str, **kwargs) -> None:
"""Log info message"""
self.logger.info(message, **kwargs)
- self.log_counts['info'] += 1
-
+ self.log_counts["info"] += 1
+
def warning(self, message: str, **kwargs) -> None:
"""Log warning message"""
self.logger.warning(message, **kwargs)
- self.log_counts['warning'] += 1
-
+ self.log_counts["warning"] += 1
+
def error(self, message: str, **kwargs) -> None:
"""Log error message"""
self.logger.error(message, **kwargs)
- self.log_counts['error'] += 1
-
+ self.log_counts["error"] += 1
+
def critical(self, message: str, **kwargs) -> None:
"""Log critical message"""
self.logger.critical(message, **kwargs)
- self.log_counts['critical'] += 1
-
+ self.log_counts["critical"] += 1
+
def success(self, message: str, **kwargs) -> None:
"""Log success message (info level with special formatting)"""
# Use a custom success formatter for console
if self.logger.handlers:
console_handler = self.logger.handlers[0]
- if hasattr(console_handler, 'formatter'):
+ if hasattr(console_handler, "formatter"):
original_format = console_handler.formatter.format
-
+
def success_format(record):
return f"{Colors.GREEN}[{symbols.checkmark}] {record.getMessage()}{Colors.RESET}"
-
+
console_handler.formatter.format = success_format
self.logger.info(message, **kwargs)
console_handler.formatter.format = original_format
@@ -188,92 +195,108 @@ class Logger:
self.logger.info(f"SUCCESS: {message}", **kwargs)
else:
self.logger.info(f"SUCCESS: {message}", **kwargs)
-
- self.log_counts['info'] += 1
-
+
+ self.log_counts["info"] += 1
+
def step(self, step: int, total: int, message: str, **kwargs) -> None:
"""Log step progress"""
step_msg = f"[{step}/{total}] {message}"
self.info(step_msg, **kwargs)
-
+
def section(self, title: str, **kwargs) -> None:
"""Log section header"""
separator = "=" * min(50, len(title) + 4)
self.info(separator, **kwargs)
self.info(f" {title}", **kwargs)
self.info(separator, **kwargs)
-
+
def exception(self, message: str, exc_info: bool = True, **kwargs) -> None:
"""Log exception with traceback"""
self.logger.error(message, exc_info=exc_info, **kwargs)
- self.log_counts['error'] += 1
-
+ self.log_counts["error"] += 1
+
def log_system_info(self, info: Dict[str, Any]) -> None:
"""Log system information"""
self.section("System Information")
for key, value in info.items():
self.info(f"{key}: {value}")
-
- def log_operation_start(self, operation: str, details: Optional[Dict[str, Any]] = None) -> None:
+
+ def log_operation_start(
+ self, operation: str, details: Optional[Dict[str, Any]] = None
+ ) -> None:
"""Log start of operation"""
self.section(f"Starting: {operation}")
if details:
for key, value in details.items():
self.info(f"{key}: {value}")
-
- def log_operation_end(self, operation: str, success: bool, duration: float, details: Optional[Dict[str, Any]] = None) -> None:
+
+ def log_operation_end(
+ self,
+ operation: str,
+ success: bool,
+ duration: float,
+ details: Optional[Dict[str, Any]] = None,
+ ) -> None:
"""Log end of operation"""
status = "SUCCESS" if success else "FAILED"
- self.info(f"Operation {operation} completed: {status} (Duration: {duration:.2f}s)")
-
+ self.info(
+ f"Operation {operation} completed: {status} (Duration: {duration:.2f}s)"
+ )
+
if details:
for key, value in details.items():
self.info(f"{key}: {value}")
-
+
def get_statistics(self) -> Dict[str, Any]:
"""Get logging statistics"""
runtime = datetime.now() - self.session_start
-
+
return {
- 'session_start': self.session_start.isoformat(),
- 'runtime_seconds': runtime.total_seconds(),
- 'log_counts': self.log_counts.copy(),
- 'total_messages': sum(self.log_counts.values()),
- 'log_file': str(self.log_file) if hasattr(self, 'log_file') and self.log_file else None,
- 'has_errors': self.log_counts['error'] + self.log_counts['critical'] > 0
+ "session_start": self.session_start.isoformat(),
+ "runtime_seconds": runtime.total_seconds(),
+ "log_counts": self.log_counts.copy(),
+ "total_messages": sum(self.log_counts.values()),
+ "log_file": (
+ str(self.log_file)
+ if hasattr(self, "log_file") and self.log_file
+ else None
+ ),
+ "has_errors": self.log_counts["error"] + self.log_counts["critical"] > 0,
}
-
+
def set_console_level(self, level: LogLevel) -> None:
"""Change console logging level"""
self.console_level = level
if self.logger.handlers:
self.logger.handlers[0].setLevel(level.value)
-
+
def set_file_level(self, level: LogLevel) -> None:
"""Change file logging level"""
self.file_level = level
if len(self.logger.handlers) > 1:
self.logger.handlers[1].setLevel(level.value)
-
+
def flush(self) -> None:
"""Flush all handlers"""
for handler in self.logger.handlers:
- if hasattr(handler, 'flush'):
+ if hasattr(handler, "flush"):
handler.flush()
-
+
def close(self) -> None:
"""Close logger and handlers"""
self.section("Installation Session Complete")
stats = self.get_statistics()
-
+
self.info(f"Total runtime: {stats['runtime_seconds']:.1f} seconds")
self.info(f"Messages logged: {stats['total_messages']}")
- if stats['has_errors']:
- self.warning(f"Errors/warnings: {stats['log_counts']['error'] + stats['log_counts']['warning']}")
-
- if stats['log_file']:
+ if stats["has_errors"]:
+ self.warning(
+ f"Errors/warnings: {stats['log_counts']['error'] + stats['log_counts']['warning']}"
+ )
+
+ if stats["log_file"]:
self.info(f"Full log saved to: {stats['log_file']}")
-
+
# Close all handlers
for handler in self.logger.handlers[:]:
handler.close()
@@ -287,14 +310,19 @@ _global_logger: Optional[Logger] = None
def get_logger(name: str = "superclaude") -> Logger:
"""Get or create global logger instance"""
global _global_logger
-
+
if _global_logger is None or _global_logger.name != name:
_global_logger = Logger(name)
-
+
return _global_logger
-def setup_logging(name: str = "superclaude", log_dir: Optional[Path] = None, console_level: LogLevel = LogLevel.INFO, file_level: LogLevel = LogLevel.DEBUG) -> Logger:
+def setup_logging(
+ name: str = "superclaude",
+ log_dir: Optional[Path] = None,
+ console_level: LogLevel = LogLevel.INFO,
+ file_level: LogLevel = LogLevel.DEBUG,
+) -> Logger:
"""Setup logging with specified configuration"""
global _global_logger
_global_logger = Logger(name, log_dir, console_level, file_level)
@@ -329,4 +357,4 @@ def critical(message: str, **kwargs) -> None:
def success(message: str, **kwargs) -> None:
"""Log success message using global logger"""
- get_logger().success(message, **kwargs)
\ No newline at end of file
+ get_logger().success(message, **kwargs)
diff --git a/setup/utils/paths.py b/setup/utils/paths.py
index 73a8ec2..d92a96b 100644
--- a/setup/utils/paths.py
+++ b/setup/utils/paths.py
@@ -30,19 +30,19 @@ def get_home_directory() -> Path:
# Fallback methods for edge cases and immutable distros
# Method 1: Use $HOME environment variable
- home_env = os.environ.get('HOME')
+ home_env = os.environ.get("HOME")
if home_env:
home_path = Path(home_env)
if home_path.exists() and home_path.is_dir():
return home_path
# Method 2: Check for immutable distro patterns
- username = os.environ.get('USER') or os.environ.get('USERNAME')
+ username = os.environ.get("USER") or os.environ.get("USERNAME")
if username:
# Check common immutable distro paths
immutable_paths = [
- Path(f'/var/home/{username}'), # Fedora Silverblue/Universal Blue
- Path(f'/home/{username}'), # Standard Linux
+ Path(f"/var/home/{username}"), # Fedora Silverblue/Universal Blue
+ Path(f"/home/{username}"), # Standard Linux
]
for path in immutable_paths:
@@ -51,4 +51,4 @@ def get_home_directory() -> Path:
# Method 3: Last resort - use the original Path.home() even if it seems wrong
# This ensures we don't crash the installation
- return Path.home()
\ No newline at end of file
+ return Path.home()
diff --git a/setup/utils/security.py b/setup/utils/security.py
index acf716a..6cc6441 100644
--- a/setup/utils/security.py
+++ b/setup/utils/security.py
@@ -37,97 +37,119 @@ from .paths import get_home_directory
class SecurityValidator:
"""Security validation utilities"""
-
+
# Directory traversal patterns (match anywhere in path - platform independent)
# These patterns detect common directory traversal attack vectors
TRAVERSAL_PATTERNS = [
- r'\.\./', # Directory traversal using ../
- r'\.\.\.', # Directory traversal using ...
- r'//+', # Multiple consecutive slashes (path injection)
+ r"\.\./", # Directory traversal using ../
+ r"\.\.\.", # Directory traversal using ...
+ r"//+", # Multiple consecutive slashes (path injection)
]
-
+
# Unix system directories (match only at start of path)
# These patterns identify Unix/Linux system directories that should not be writable
# by regular users. Using ^ anchor to match only at path start prevents false positives
# for user directories containing these names (e.g., /home/user/dev/ is allowed)
UNIX_SYSTEM_PATTERNS = [
- r'^/etc/', # System configuration files
- r'^/bin/', # Essential command binaries
- r'^/sbin/', # System binaries
- r'^/usr/bin/', # User command binaries
- r'^/usr/sbin/', # Non-essential system binaries
- r'^/var/', # Variable data files
- r'^/tmp/', # Temporary files (system-wide)
- r'^/dev/', # Device files - FIXED: was r'/dev/' (GitHub Issue #129)
- r'^/proc/', # Process information pseudo-filesystem
- r'^/sys/', # System information pseudo-filesystem
+ r"^/etc/", # System configuration files
+ r"^/bin/", # Essential command binaries
+ r"^/sbin/", # System binaries
+ r"^/usr/bin/", # User command binaries
+ r"^/usr/sbin/", # Non-essential system binaries
+ r"^/var/", # Variable data files
+ r"^/tmp/", # Temporary files (system-wide)
+ r"^/dev/", # Device files - FIXED: was r'/dev/' (GitHub Issue #129)
+ r"^/proc/", # Process information pseudo-filesystem
+ r"^/sys/", # System information pseudo-filesystem
]
-
+
# Windows system directories (match only at start of path)
# These patterns identify Windows system directories using flexible separator matching
# to handle both forward slashes and backslashes consistently
WINDOWS_SYSTEM_PATTERNS = [
- r'^c:[/\\]windows[/\\]', # Windows system directory
- r'^c:[/\\]program files[/\\]', # Program Files directory
+ r"^c:[/\\]windows[/\\]", # Windows system directory
+ r"^c:[/\\]program files[/\\]", # Program Files directory
# Note: Removed c:\\users\\ to allow installation in user directories
# Claude Code installs to user home directory by default
]
-
+
# Combined dangerous patterns for backward compatibility
# This maintains compatibility with existing code while providing the new categorized approach
- DANGEROUS_PATTERNS = TRAVERSAL_PATTERNS + UNIX_SYSTEM_PATTERNS + WINDOWS_SYSTEM_PATTERNS
-
+ DANGEROUS_PATTERNS = (
+ TRAVERSAL_PATTERNS + UNIX_SYSTEM_PATTERNS + WINDOWS_SYSTEM_PATTERNS
+ )
+
# Dangerous filename patterns
DANGEROUS_FILENAMES = [
- r'\.exe$', # Executables
- r'\.bat$',
- r'\.cmd$',
- r'\.scr$',
- r'\.dll$',
- r'\.so$',
- r'\.dylib$',
- r'passwd', # System files
- r'shadow',
- r'hosts',
- r'\.ssh/',
- r'\.aws/',
- r'\.env', # Environment files
- r'\.secret',
+ r"\.exe$", # Executables
+ r"\.bat$",
+ r"\.cmd$",
+ r"\.scr$",
+ r"\.dll$",
+ r"\.so$",
+ r"\.dylib$",
+ r"passwd", # System files
+ r"shadow",
+ r"hosts",
+ r"\.ssh/",
+ r"\.aws/",
+ r"\.env", # Environment files
+ r"\.secret",
]
-
+
# Allowed file extensions for installation
ALLOWED_EXTENSIONS = {
- '.md', '.json', '.py', '.js', '.ts', '.jsx', '.tsx',
- '.txt', '.yml', '.yaml', '.toml', '.cfg', '.conf',
- '.sh', '.ps1', '.html', '.css', '.svg', '.png', '.jpg', '.gif'
+ ".md",
+ ".json",
+ ".py",
+ ".js",
+ ".ts",
+ ".jsx",
+ ".tsx",
+ ".txt",
+ ".yml",
+ ".yaml",
+ ".toml",
+ ".cfg",
+ ".conf",
+ ".sh",
+ ".ps1",
+ ".html",
+ ".css",
+ ".svg",
+ ".png",
+ ".jpg",
+ ".gif",
}
-
+
# Maximum path lengths
MAX_PATH_LENGTH = 4096
MAX_FILENAME_LENGTH = 255
-
+
@classmethod
- def validate_path(cls, path: Path, base_dir: Optional[Path] = None) -> Tuple[bool, str]:
+ def validate_path(
+ cls, path: Path, base_dir: Optional[Path] = None
+ ) -> Tuple[bool, str]:
"""
Validate path for security issues with enhanced cross-platform support
-
+
This method performs comprehensive security validation including:
- Directory traversal attack detection
- System directory protection (platform-specific)
- Path length and filename validation
- Cross-platform path normalization
- User-friendly error messages
-
+
Architecture:
- Uses both original and resolved paths for validation
- Applies platform-specific patterns for system directories
- Checks traversal patterns against original path to catch attacks before normalization
- Provides detailed error messages with actionable suggestions
-
+
Args:
path: Path to validate (can be relative or absolute)
base_dir: Base directory that path should be within (optional)
-
+
Returns:
Tuple of (is_safe: bool, error_message: str)
- is_safe: True if path passes all security checks
@@ -136,221 +158,282 @@ class SecurityValidator:
try:
# Convert to absolute path
abs_path = path.resolve()
-
+
# For system directory validation, use the original path structure
# to avoid issues with symlinks and cross-platform path resolution
original_path_str = cls._normalize_path_for_validation(path)
resolved_path_str = cls._normalize_path_for_validation(abs_path)
-
+
# Check path length
if len(str(abs_path)) > cls.MAX_PATH_LENGTH:
- return False, f"Path too long: {len(str(abs_path))} > {cls.MAX_PATH_LENGTH}"
-
+ return (
+ False,
+ f"Path too long: {len(str(abs_path))} > {cls.MAX_PATH_LENGTH}",
+ )
+
# Check filename length
if len(abs_path.name) > cls.MAX_FILENAME_LENGTH:
- return False, f"Filename too long: {len(abs_path.name)} > {cls.MAX_FILENAME_LENGTH}"
-
+ return (
+ False,
+ f"Filename too long: {len(abs_path.name)} > {cls.MAX_FILENAME_LENGTH}",
+ )
+
# Check for dangerous patterns using platform-specific validation
# Always check traversal patterns (platform independent) - use original path string
# to detect patterns before normalization removes them
original_str = str(path).lower()
for pattern in cls.TRAVERSAL_PATTERNS:
if re.search(pattern, original_str, re.IGNORECASE):
- return False, cls._get_user_friendly_error_message("traversal", pattern, abs_path)
-
+ return False, cls._get_user_friendly_error_message(
+ "traversal", pattern, abs_path
+ )
+
# Check platform-specific system directory patterns - use original path first, then resolved
# Always check both Windows and Unix patterns to handle cross-platform scenarios
-
+
# Check Windows system directory patterns
for pattern in cls.WINDOWS_SYSTEM_PATTERNS:
- if (re.search(pattern, original_path_str, re.IGNORECASE) or
- re.search(pattern, resolved_path_str, re.IGNORECASE)):
- return False, cls._get_user_friendly_error_message("windows_system", pattern, abs_path)
-
+ if re.search(pattern, original_path_str, re.IGNORECASE) or re.search(
+ pattern, resolved_path_str, re.IGNORECASE
+ ):
+ return False, cls._get_user_friendly_error_message(
+ "windows_system", pattern, abs_path
+ )
+
# Check Unix system directory patterns
for pattern in cls.UNIX_SYSTEM_PATTERNS:
- if (re.search(pattern, original_path_str, re.IGNORECASE) or
- re.search(pattern, resolved_path_str, re.IGNORECASE)):
- return False, cls._get_user_friendly_error_message("unix_system", pattern, abs_path)
-
+ if re.search(pattern, original_path_str, re.IGNORECASE) or re.search(
+ pattern, resolved_path_str, re.IGNORECASE
+ ):
+ return False, cls._get_user_friendly_error_message(
+ "unix_system", pattern, abs_path
+ )
+
# Check for dangerous filenames
for pattern in cls.DANGEROUS_FILENAMES:
if re.search(pattern, abs_path.name, re.IGNORECASE):
return False, f"Dangerous filename pattern detected: {pattern}"
-
+
# Check if path is within base directory
if base_dir:
base_abs = base_dir.resolve()
try:
abs_path.relative_to(base_abs)
except ValueError:
- return False, f"Path outside allowed directory: {abs_path} not in {base_abs}"
-
+ return (
+ False,
+ f"Path outside allowed directory: {abs_path} not in {base_abs}",
+ )
+
# Check for null bytes
- if '\x00' in str(path):
+ if "\x00" in str(path):
return False, "Null byte detected in path"
-
+
# Check for Windows reserved names
- if os.name == 'nt':
+ if os.name == "nt":
reserved_names = [
- 'CON', 'PRN', 'AUX', 'NUL',
- 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
- 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'
+ "CON",
+ "PRN",
+ "AUX",
+ "NUL",
+ "COM1",
+ "COM2",
+ "COM3",
+ "COM4",
+ "COM5",
+ "COM6",
+ "COM7",
+ "COM8",
+ "COM9",
+ "LPT1",
+ "LPT2",
+ "LPT3",
+ "LPT4",
+ "LPT5",
+ "LPT6",
+ "LPT7",
+ "LPT8",
+ "LPT9",
]
-
+
name_without_ext = abs_path.stem.upper()
if name_without_ext in reserved_names:
return False, f"Reserved Windows filename: {name_without_ext}"
-
+
return True, "Path is safe"
-
+
except Exception as e:
return False, f"Path validation error: {e}"
-
+
@classmethod
def validate_file_extension(cls, path: Path) -> Tuple[bool, str]:
"""
Validate file extension is allowed
-
+
Args:
path: Path to validate
-
+
Returns:
Tuple of (is_allowed: bool, message: str)
"""
extension = path.suffix.lower()
-
+
if not extension:
return True, "No extension (allowed)"
-
+
if extension in cls.ALLOWED_EXTENSIONS:
return True, f"Extension {extension} is allowed"
else:
return False, f"Extension {extension} is not allowed"
-
+
@classmethod
def sanitize_filename(cls, filename: str) -> str:
"""
Sanitize filename by removing dangerous characters
-
+
Args:
filename: Original filename
-
+
Returns:
Sanitized filename
"""
# Remove null bytes
- filename = filename.replace('\x00', '')
-
+ filename = filename.replace("\x00", "")
+
# Remove or replace dangerous characters
dangerous_chars = r'[<>:"/\\|?*\x00-\x1f]'
- filename = re.sub(dangerous_chars, '_', filename)
-
+ filename = re.sub(dangerous_chars, "_", filename)
+
# Remove leading/trailing dots and spaces
- filename = filename.strip('. ')
-
+ filename = filename.strip(". ")
+
# Ensure not empty
if not filename:
- filename = 'unnamed'
-
+ filename = "unnamed"
+
# Truncate if too long
if len(filename) > cls.MAX_FILENAME_LENGTH:
name, ext = os.path.splitext(filename)
max_name_len = cls.MAX_FILENAME_LENGTH - len(ext)
filename = name[:max_name_len] + ext
-
+
# Check for Windows reserved names
- if os.name == 'nt':
+ if os.name == "nt":
name_without_ext = os.path.splitext(filename)[0].upper()
reserved_names = [
- 'CON', 'PRN', 'AUX', 'NUL',
- 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
- 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'
+ "CON",
+ "PRN",
+ "AUX",
+ "NUL",
+ "COM1",
+ "COM2",
+ "COM3",
+ "COM4",
+ "COM5",
+ "COM6",
+ "COM7",
+ "COM8",
+ "COM9",
+ "LPT1",
+ "LPT2",
+ "LPT3",
+ "LPT4",
+ "LPT5",
+ "LPT6",
+ "LPT7",
+ "LPT8",
+ "LPT9",
]
-
+
if name_without_ext in reserved_names:
filename = f"safe_{filename}"
-
+
return filename
-
+
@classmethod
def sanitize_input(cls, user_input: str, max_length: int = 1000) -> str:
"""
Sanitize user input
-
+
Args:
user_input: Raw user input
max_length: Maximum allowed length
-
+
Returns:
Sanitized input
"""
if not user_input:
return ""
-
+
# Remove null bytes and control characters
- sanitized = re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', '', user_input)
-
+ sanitized = re.sub(r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]", "", user_input)
+
# Trim whitespace
sanitized = sanitized.strip()
-
+
# Truncate if too long
if len(sanitized) > max_length:
sanitized = sanitized[:max_length]
-
+
return sanitized
-
+
@classmethod
def validate_url(cls, url: str) -> Tuple[bool, str]:
"""
Validate URL for security issues
-
+
Args:
url: URL to validate
-
+
Returns:
Tuple of (is_safe: bool, message: str)
"""
try:
parsed = urllib.parse.urlparse(url)
-
+
# Check scheme
- if parsed.scheme not in ['http', 'https']:
+ if parsed.scheme not in ["http", "https"]:
return False, f"Invalid scheme: {parsed.scheme}"
-
+
# Check for localhost/private IPs (basic check)
hostname = parsed.hostname
if hostname:
- if hostname.lower() in ['localhost', '127.0.0.1', '::1']:
+ if hostname.lower() in ["localhost", "127.0.0.1", "::1"]:
return False, "Localhost URLs not allowed"
-
+
# Basic private IP check
- if hostname.startswith('192.168.') or hostname.startswith('10.') or hostname.startswith('172.'):
+ if (
+ hostname.startswith("192.168.")
+ or hostname.startswith("10.")
+ or hostname.startswith("172.")
+ ):
return False, "Private IP addresses not allowed"
-
+
# Check URL length
if len(url) > 2048:
return False, "URL too long"
-
+
return True, "URL is safe"
-
+
except Exception as e:
return False, f"URL validation error: {e}"
-
+
@classmethod
- def check_permissions(cls, path: Path, required_permissions: Set[str]) -> Tuple[bool, List[str]]:
+ def check_permissions(
+ cls, path: Path, required_permissions: Set[str]
+ ) -> Tuple[bool, List[str]]:
"""
Check file/directory permissions
-
+
Args:
path: Path to check
required_permissions: Set of required permissions ('read', 'write', 'execute')
-
+
Returns:
Tuple of (has_permissions: bool, missing_permissions: List[str])
"""
missing = []
-
+
try:
if not path.exists():
# For non-existent paths, check parent directory
@@ -359,78 +442,85 @@ class SecurityValidator:
missing.append("path does not exist")
return False, missing
path = parent
-
- if 'read' in required_permissions:
+
+ if "read" in required_permissions:
if not os.access(path, os.R_OK):
- missing.append('read')
-
- if 'write' in required_permissions:
+ missing.append("read")
+
+ if "write" in required_permissions:
if not os.access(path, os.W_OK):
- missing.append('write')
-
- if 'execute' in required_permissions:
+ missing.append("write")
+
+ if "execute" in required_permissions:
if not os.access(path, os.X_OK):
- missing.append('execute')
-
+ missing.append("execute")
+
return len(missing) == 0, missing
-
+
except Exception as e:
missing.append(f"permission check error: {e}")
return False, missing
-
+
@classmethod
def validate_installation_target(cls, target_dir: Path) -> Tuple[bool, List[str]]:
"""
Validate installation target directory with enhanced Windows compatibility
-
+
Args:
target_dir: Target installation directory
-
+
Returns:
Tuple of (is_safe: bool, error_messages: List[str])
"""
errors = []
-
+
# Enhanced path resolution with Windows normalization
try:
abs_target = target_dir.resolve()
except Exception as e:
errors.append(f"Cannot resolve target path: {e}")
return False, errors
-
+
# Windows-specific path normalization
- if os.name == 'nt':
+ if os.name == "nt":
# Normalize Windows paths for consistent comparison
- abs_target_str = str(abs_target).lower().replace('/', '\\')
+ abs_target_str = str(abs_target).lower().replace("/", "\\")
else:
abs_target_str = str(abs_target).lower()
-
+
# Special handling for Claude installation directory
- claude_patterns = ['.claude', '.claude' + os.sep, '.claude\\', '.claude/']
- is_claude_dir = any(abs_target_str.endswith(pattern) for pattern in claude_patterns)
-
+ claude_patterns = [".claude", ".claude" + os.sep, ".claude\\", ".claude/"]
+ is_claude_dir = any(
+ abs_target_str.endswith(pattern) for pattern in claude_patterns
+ )
+
if is_claude_dir:
try:
home_path = get_home_directory()
except (RuntimeError, OSError):
# If we can't determine home directory, skip .claude special handling
- cls._log_security_decision("WARN", f"Cannot determine home directory for .claude validation: {abs_target}")
+ cls._log_security_decision(
+ "WARN",
+ f"Cannot determine home directory for .claude validation: {abs_target}",
+ )
# Fall through to regular validation
else:
try:
# Verify it's specifically the current user's home directory
abs_target.relative_to(home_path)
-
+
# Enhanced Windows security checks for .claude directories
- if os.name == 'nt':
+ if os.name == "nt":
# Check for junction points and symbolic links on Windows
if cls._is_windows_junction_or_symlink(abs_target):
- errors.append("Installation to junction points or symbolic links is not allowed for security")
+ errors.append(
+ "Installation to junction points or symbolic links is not allowed for security"
+ )
return False, errors
-
+
# Additional validation: verify it's in the current user's profile directory
# Use actual home directory comparison instead of username-based path construction
- if ':' in abs_target_str and '\\users\\' in abs_target_str:
+ if ":" in abs_target_str and "\\users\\" in abs_target_str:
try:
# Check if target is within the user's actual home directory
home_path = get_home_directory()
@@ -438,74 +528,121 @@ class SecurityValidator:
# Path is valid - within user's home directory
except ValueError:
# Path is outside user's home directory
- current_user = os.environ.get('USERNAME', home_path.name)
- errors.append(f"Installation must be in current user's directory ({current_user})")
+ current_user = os.environ.get(
+ "USERNAME", home_path.name
+ )
+ errors.append(
+ f"Installation must be in current user's directory ({current_user})"
+ )
return False, errors
-
+
# Check permissions
- has_perms, missing = cls.check_permissions(target_dir, {'read', 'write'})
+ has_perms, missing = cls.check_permissions(
+ target_dir, {"read", "write"}
+ )
if not has_perms:
- if os.name == 'nt':
- errors.append(f"Insufficient permissions for Windows installation: {missing}. Try running as administrator or check folder permissions.")
+ if os.name == "nt":
+ errors.append(
+ f"Insufficient permissions for Windows installation: {missing}. Try running as administrator or check folder permissions."
+ )
else:
- errors.append(f"Insufficient permissions: missing {missing}")
-
+ errors.append(
+ f"Insufficient permissions: missing {missing}"
+ )
+
# Log successful validation for audit trail
- cls._log_security_decision("ALLOW", f"Claude directory installation validated: {abs_target}")
+ cls._log_security_decision(
+ "ALLOW",
+ f"Claude directory installation validated: {abs_target}",
+ )
return len(errors) == 0, errors
-
+
except ValueError:
# Not under current user's home directory
- if os.name == 'nt':
- errors.append("Claude installation must be in your user directory (e.g., C:\\Users\\YourName\\.claude)")
+ if os.name == "nt":
+ errors.append(
+ "Claude installation must be in your user directory (e.g., C:\\Users\\YourName\\.claude)"
+ )
else:
- errors.append("Claude installation must be in your home directory (e.g., ~/.claude)")
- cls._log_security_decision("DENY", f"Claude directory outside user home: {abs_target}")
+ errors.append(
+ "Claude installation must be in your home directory (e.g., ~/.claude)"
+ )
+ cls._log_security_decision(
+ "DENY", f"Claude directory outside user home: {abs_target}"
+ )
return False, errors
-
+
# Validate path for non-.claude directories
is_safe, msg = cls.validate_path(target_dir)
if not is_safe:
- if os.name == 'nt':
+ if os.name == "nt":
# Enhanced Windows error messages
if "dangerous path pattern" in msg.lower():
- errors.append(f"Invalid Windows path: {msg}. Ensure path doesn't contain dangerous patterns or reserved directories.")
+ errors.append(
+ f"Invalid Windows path: {msg}. Ensure path doesn't contain dangerous patterns or reserved directories."
+ )
elif "path too long" in msg.lower():
- errors.append(f"Windows path too long: {msg}. Windows has a 260 character limit for most paths.")
+ errors.append(
+ f"Windows path too long: {msg}. Windows has a 260 character limit for most paths."
+ )
elif "reserved" in msg.lower():
- errors.append(f"Windows reserved name: {msg}. Avoid names like CON, PRN, AUX, NUL, COM1-9, LPT1-9.")
+ errors.append(
+ f"Windows reserved name: {msg}. Avoid names like CON, PRN, AUX, NUL, COM1-9, LPT1-9."
+ )
else:
errors.append(f"Invalid target path: {msg}")
else:
errors.append(f"Invalid target path: {msg}")
-
+
# Check permissions with platform-specific guidance
- has_perms, missing = cls.check_permissions(target_dir, {'read', 'write'})
+ has_perms, missing = cls.check_permissions(target_dir, {"read", "write"})
if not has_perms:
- if os.name == 'nt':
- errors.append(f"Insufficient Windows permissions: {missing}. Try running as administrator or check folder security settings in Properties > Security.")
+ if os.name == "nt":
+ errors.append(
+ f"Insufficient Windows permissions: {missing}. Try running as administrator or check folder security settings in Properties > Security."
+ )
else:
- errors.append(f"Insufficient permissions: {missing}. Try: chmod 755 {target_dir}")
-
+ errors.append(
+ f"Insufficient permissions: {missing}. Try: chmod 755 {target_dir}"
+ )
+
# Check if it's a system directory with enhanced messages
system_dirs = [
- Path('/etc'), Path('/bin'), Path('/sbin'), Path('/usr/bin'), Path('/usr/sbin'),
- Path('/var'), Path('/tmp'), Path('/dev'), Path('/proc'), Path('/sys')
+ Path("/etc"),
+ Path("/bin"),
+ Path("/sbin"),
+ Path("/usr/bin"),
+ Path("/usr/sbin"),
+ Path("/var"),
+ Path("/tmp"),
+ Path("/dev"),
+ Path("/proc"),
+ Path("/sys"),
]
-
- if os.name == 'nt':
- system_dirs.extend([
- Path('C:\\Windows'), Path('C:\\Program Files'), Path('C:\\Program Files (x86)')
- ])
-
+
+ if os.name == "nt":
+ system_dirs.extend(
+ [
+ Path("C:\\Windows"),
+ Path("C:\\Program Files"),
+ Path("C:\\Program Files (x86)"),
+ ]
+ )
+
for sys_dir in system_dirs:
try:
if abs_target.is_relative_to(sys_dir):
- if os.name == 'nt':
- errors.append(f"Cannot install to Windows system directory: {sys_dir}. Use a location in your user profile instead (e.g., C:\\Users\\YourName\\).")
+ if os.name == "nt":
+ errors.append(
+ f"Cannot install to Windows system directory: {sys_dir}. Use a location in your user profile instead (e.g., C:\\Users\\YourName\\)."
+ )
else:
- errors.append(f"Cannot install to system directory: {sys_dir}. Use a location in your home directory instead (~/).")
- cls._log_security_decision("DENY", f"Attempted installation to system directory: {sys_dir}")
+ errors.append(
+ f"Cannot install to system directory: {sys_dir}. Use a location in your home directory instead (~/)."
+ )
+ cls._log_security_decision(
+ "DENY", f"Attempted installation to system directory: {sys_dir}"
+ )
break
except (ValueError, AttributeError):
# is_relative_to not available in older Python versions
@@ -515,84 +652,91 @@ class SecurityValidator:
break
except ValueError:
continue
-
+
return len(errors) == 0, errors
-
+
@classmethod
- def validate_component_files(cls, file_list: List[Tuple[Path, Path]], base_source_dir: Path, base_target_dir: Path) -> Tuple[bool, List[str]]:
+ def validate_component_files(
+ cls,
+ file_list: List[Tuple[Path, Path]],
+ base_source_dir: Path,
+ base_target_dir: Path,
+ ) -> Tuple[bool, List[str]]:
"""
Validate list of files for component installation
-
+
Args:
file_list: List of (source, target) path tuples
base_source_dir: Base source directory
base_target_dir: Base target directory
-
+
Returns:
Tuple of (all_safe: bool, error_messages: List[str])
"""
errors = []
-
+
for source, target in file_list:
# Validate source path
is_safe, msg = cls.validate_path(source, base_source_dir)
if not is_safe:
errors.append(f"Invalid source path {source}: {msg}")
-
+
# Validate target path
is_safe, msg = cls.validate_path(target, base_target_dir)
if not is_safe:
errors.append(f"Invalid target path {target}: {msg}")
-
+
# Validate file extension
is_allowed, msg = cls.validate_file_extension(source)
if not is_allowed:
errors.append(f"File {source}: {msg}")
-
+
return len(errors) == 0, errors
-
+
@classmethod
def _normalize_path_for_validation(cls, path: Path) -> str:
"""
Normalize path for consistent validation across platforms
-
+
Args:
path: Path to normalize
-
+
Returns:
Normalized path string for validation
"""
path_str = str(path)
-
+
# Convert to lowercase for case-insensitive comparison
path_str = path_str.lower()
-
+
# Normalize path separators for consistent pattern matching
- if os.name == 'nt': # Windows
+ if os.name == "nt": # Windows
# Convert forward slashes to backslashes for Windows
- path_str = path_str.replace('/', '\\')
+ path_str = path_str.replace("/", "\\")
# Ensure consistent drive letter format
- if len(path_str) >= 2 and path_str[1] == ':':
- path_str = path_str[0] + ':\\' + path_str[3:].lstrip('\\')
+ if len(path_str) >= 2 and path_str[1] == ":":
+ path_str = path_str[0] + ":\\" + path_str[3:].lstrip("\\")
else: # Unix-like systems
# Convert backslashes to forward slashes for Unix
- path_str = path_str.replace('\\', '/')
+ path_str = path_str.replace("\\", "/")
# Ensure single leading slash
- if path_str.startswith('//'):
- path_str = '/' + path_str.lstrip('/')
-
+ if path_str.startswith("//"):
+ path_str = "/" + path_str.lstrip("/")
+
return path_str
-
+
@classmethod
- def _get_user_friendly_error_message(cls, error_type: str, pattern: str, path: Path) -> str:
+ def _get_user_friendly_error_message(
+ cls, error_type: str, pattern: str, path: Path
+ ) -> str:
"""
Generate user-friendly error messages with actionable suggestions
-
+
Args:
error_type: Type of error (traversal, windows_system, unix_system)
pattern: The regex pattern that matched
path: The path that caused the error
-
+
Returns:
User-friendly error message with suggestions
"""
@@ -603,13 +747,13 @@ class SecurityValidator:
f"Please use an absolute path without directory traversal characters."
)
elif error_type == "windows_system":
- if pattern == r'^c:\\windows\\':
+ if pattern == r"^c:\\windows\\":
return (
f"Cannot install to Windows system directory '{path}'. "
f"Please choose a location in your user directory instead, "
f"such as C:\\Users\\{os.environ.get('USERNAME', 'YourName')}\\.claude\\"
)
- elif pattern == r'^c:\\program files\\':
+ elif pattern == r"^c:\\program files\\":
return (
f"Cannot install to Program Files directory '{path}'. "
f"Please choose a location in your user directory instead, "
@@ -622,79 +766,80 @@ class SecurityValidator:
)
elif error_type == "unix_system":
system_dirs = {
- r'^/dev/': "/dev (device files)",
- r'^/etc/': "/etc (system configuration)",
- r'^/bin/': "/bin (system binaries)",
- r'^/sbin/': "/sbin (system binaries)",
- r'^/usr/bin/': "/usr/bin (user binaries)",
- r'^/usr/sbin/': "/usr/sbin (user system binaries)",
- r'^/var/': "/var (variable data)",
- r'^/tmp/': "/tmp (temporary files)",
- r'^/proc/': "/proc (process information)",
- r'^/sys/': "/sys (system information)"
+ r"^/dev/": "/dev (device files)",
+ r"^/etc/": "/etc (system configuration)",
+ r"^/bin/": "/bin (system binaries)",
+ r"^/sbin/": "/sbin (system binaries)",
+ r"^/usr/bin/": "/usr/bin (user binaries)",
+ r"^/usr/sbin/": "/usr/sbin (user system binaries)",
+ r"^/var/": "/var (variable data)",
+ r"^/tmp/": "/tmp (temporary files)",
+ r"^/proc/": "/proc (process information)",
+ r"^/sys/": "/sys (system information)",
}
-
+
dir_desc = system_dirs.get(pattern, "system directory")
return (
f"Cannot install to {dir_desc} '{path}'. "
f"Please choose a location in your home directory instead, "
- f"such as ~/.claude/ or ~/SuperClaude/"
+ f"such as ~/.claude/ or ~/superclaude/"
)
else:
return f"Security validation failed for path '{path}'"
-
+
@classmethod
def _is_windows_junction_or_symlink(cls, path: Path) -> bool:
"""
Check if path is a Windows junction point or symbolic link
-
+
Args:
path: Path to check
-
+
Returns:
True if path is a junction point or symlink, False otherwise
"""
- if os.name != 'nt':
+ if os.name != "nt":
return False
-
+
try:
# Only check if path exists to avoid filesystem errors during testing
if not path.exists():
return False
-
+
# Check if path is a symlink (covers most cases)
if path.is_symlink():
return True
-
+
# Additional Windows-specific checks for junction points
try:
import stat
+
st = path.stat()
# Check for reparse point (junction points have this attribute)
- if hasattr(st, 'st_reparse_tag') and st.st_reparse_tag != 0:
+ if hasattr(st, "st_reparse_tag") and st.st_reparse_tag != 0:
return True
except (OSError, AttributeError):
pass
-
+
# Alternative method using os.path.islink
try:
if os.path.islink(str(path)):
return True
except (OSError, AttributeError):
pass
-
+
except (OSError, AttributeError, NotImplementedError):
# If we can't determine safely, default to False
# This ensures the function doesn't break validation
pass
-
+
return False
-
+
@classmethod
def _log_security_decision(cls, action: str, message: str) -> None:
"""
Log security validation decisions for audit trail
-
+
Args:
action: Security action taken (ALLOW, DENY, WARN)
message: Description of the decision
@@ -702,88 +847,90 @@ class SecurityValidator:
try:
import logging
import datetime
-
+
# Create security logger if it doesn't exist
- security_logger = logging.getLogger('superclaude.security')
+ security_logger = logging.getLogger("superclaude.security")
if not security_logger.handlers:
# Set up basic logging if not already configured
handler = logging.StreamHandler()
formatter = logging.Formatter(
- '%(asctime)s - SECURITY - %(levelname)s - %(message)s'
+ "%(asctime)s - SECURITY - %(levelname)s - %(message)s"
)
handler.setFormatter(formatter)
security_logger.addHandler(handler)
security_logger.setLevel(logging.INFO)
-
+
# Log the security decision
timestamp = datetime.datetime.now().isoformat()
log_message = f"[{action}] {message} (PID: {os.getpid()})"
-
+
if action == "DENY":
security_logger.warning(log_message)
else:
security_logger.info(log_message)
-
+
except Exception:
# Don't fail security validation if logging fails
pass
-
+
@classmethod
def create_secure_temp_dir(cls, prefix: str = "superclaude_") -> Path:
"""
Create secure temporary directory
-
+
Args:
prefix: Prefix for temp directory name
-
+
Returns:
Path to secure temporary directory
"""
import tempfile
-
+
# Create with secure permissions (0o700)
temp_dir = Path(tempfile.mkdtemp(prefix=prefix))
temp_dir.chmod(0o700)
-
+
return temp_dir
-
+
@classmethod
def secure_delete(cls, path: Path) -> bool:
"""
Securely delete file or directory
-
+
Args:
path: Path to delete
-
+
Returns:
True if successful, False otherwise
"""
try:
if not path.exists():
return True
-
+
if path.is_file():
# Overwrite file with random data before deletion
try:
import secrets
+
file_size = path.stat().st_size
-
- with open(path, 'r+b') as f:
+
+ with open(path, "r+b") as f:
# Overwrite with random data
f.write(secrets.token_bytes(file_size))
f.flush()
os.fsync(f.fileno())
except Exception:
pass # If overwrite fails, still try to delete
-
+
path.unlink()
-
+
elif path.is_dir():
# Recursively delete directory contents
import shutil
+
shutil.rmtree(path)
-
+
return True
-
+
except Exception:
- return False
\ No newline at end of file
+ return False
diff --git a/setup/utils/symbols.py b/setup/utils/symbols.py
index fda795f..f0f67a7 100644
--- a/setup/utils/symbols.py
+++ b/setup/utils/symbols.py
@@ -21,14 +21,14 @@ def can_display_unicode() -> bool:
try:
# Test if we can encode common Unicode symbols
test_symbols = "โโโโโ โ"
- test_symbols.encode(sys.stdout.encoding or 'cp1252')
+ test_symbols.encode(sys.stdout.encoding or "cp1252")
return True
except (UnicodeEncodeError, LookupError):
return False
# Check if stdout encoding supports Unicode
- encoding = getattr(sys.stdout, 'encoding', None)
- if encoding and encoding.lower() in ['utf-8', 'utf8']:
+ encoding = getattr(sys.stdout, "encoding", None)
+ if encoding and encoding.lower() in ["utf-8", "utf8"]:
return True
# Conservative fallback for unknown systems
@@ -131,8 +131,8 @@ def safe_print(*args, **kwargs):
for arg in args:
if isinstance(arg, str):
# Replace problematic Unicode characters
- safe_arg = (arg
- .replace("โ", "+")
+ safe_arg = (
+ arg.replace("โ", "+")
.replace("โ", "x")
.replace("โ", "#")
.replace("โ", "-")
@@ -165,7 +165,7 @@ def safe_print(*args, **kwargs):
final_args = []
for arg in safe_args:
if isinstance(arg, str):
- final_args.append(arg.encode('ascii', 'replace').decode('ascii'))
+ final_args.append(arg.encode("ascii", "replace").decode("ascii"))
else:
final_args.append(str(arg))
print(*final_args, **kwargs)
@@ -195,4 +195,4 @@ def format_with_symbols(text: str) -> str:
for unicode_char, safe_char in replacements.items():
text = text.replace(unicode_char, safe_char)
- return text
\ No newline at end of file
+ return text
diff --git a/setup/utils/ui.py b/setup/utils/ui.py
index d599ca4..34b3123 100644
--- a/setup/utils/ui.py
+++ b/setup/utils/ui.py
@@ -15,30 +15,33 @@ from .symbols import symbols, safe_print, format_with_symbols
try:
import colorama
from colorama import Fore, Back, Style
+
colorama.init(autoreset=True)
COLORAMA_AVAILABLE = True
except ImportError:
COLORAMA_AVAILABLE = False
+
# Fallback color codes for Unix-like systems
class MockFore:
- RED = '\033[91m' if sys.platform != 'win32' else ''
- GREEN = '\033[92m' if sys.platform != 'win32' else ''
- YELLOW = '\033[93m' if sys.platform != 'win32' else ''
- BLUE = '\033[94m' if sys.platform != 'win32' else ''
- MAGENTA = '\033[95m' if sys.platform != 'win32' else ''
- CYAN = '\033[96m' if sys.platform != 'win32' else ''
- WHITE = '\033[97m' if sys.platform != 'win32' else ''
-
+ RED = "\033[91m" if sys.platform != "win32" else ""
+ GREEN = "\033[92m" if sys.platform != "win32" else ""
+ YELLOW = "\033[93m" if sys.platform != "win32" else ""
+ BLUE = "\033[94m" if sys.platform != "win32" else ""
+ MAGENTA = "\033[95m" if sys.platform != "win32" else ""
+ CYAN = "\033[96m" if sys.platform != "win32" else ""
+ WHITE = "\033[97m" if sys.platform != "win32" else ""
+
class MockStyle:
- RESET_ALL = '\033[0m' if sys.platform != 'win32' else ''
- BRIGHT = '\033[1m' if sys.platform != 'win32' else ''
-
+ RESET_ALL = "\033[0m" if sys.platform != "win32" else ""
+ BRIGHT = "\033[1m" if sys.platform != "win32" else ""
+
Fore = MockFore()
Style = MockStyle()
class Colors:
"""Color constants for console output"""
+
RED = Fore.RED
GREEN = Fore.GREEN
YELLOW = Fore.YELLOW
@@ -52,11 +55,11 @@ class Colors:
class ProgressBar:
"""Cross-platform progress bar with customizable display"""
-
- def __init__(self, total: int, width: int = 50, prefix: str = '', suffix: str = ''):
+
+ def __init__(self, total: int, width: int = 50, prefix: str = "", suffix: str = ""):
"""
Initialize progress bar
-
+
Args:
total: Total number of items to process
width: Width of progress bar in characters
@@ -69,29 +72,31 @@ class ProgressBar:
self.suffix = suffix
self.current = 0
self.start_time = time.time()
-
+
# Get terminal width for responsive display
try:
self.terminal_width = shutil.get_terminal_size().columns
except OSError:
self.terminal_width = 80
-
- def update(self, current: int, message: str = '') -> None:
+
+ def update(self, current: int, message: str = "") -> None:
"""
Update progress bar
-
+
Args:
current: Current progress value
message: Optional message to display
"""
self.current = current
percent = min(100, (current / self.total) * 100) if self.total > 0 else 100
-
+
# Calculate filled and empty portions
- filled_width = int(self.width * current / self.total) if self.total > 0 else self.width
+ filled_width = (
+ int(self.width * current / self.total) if self.total > 0 else self.width
+ )
filled = symbols.block_filled * filled_width
empty = symbols.block_empty * (self.width - filled_width)
-
+
# Calculate elapsed time and ETA
elapsed = time.time() - self.start_time
if current > 0:
@@ -99,47 +104,51 @@ class ProgressBar:
eta_str = f" ETA: {self._format_time(eta)}"
else:
eta_str = ""
-
+
# Format progress line
if message:
status = f" {message}"
else:
status = ""
-
+
progress_line = (
f"\r{self.prefix}[{Colors.GREEN}{filled}{Colors.WHITE}{empty}{Colors.RESET}] "
f"{percent:5.1f}%{status}{eta_str}"
)
-
+
# Truncate if too long for terminal
max_length = self.terminal_width - 5
if len(progress_line) > max_length:
# Remove color codes for length calculation
- plain_line = progress_line.replace(Colors.GREEN, '').replace(Colors.WHITE, '').replace(Colors.RESET, '')
+ plain_line = (
+ progress_line.replace(Colors.GREEN, "")
+ .replace(Colors.WHITE, "")
+ .replace(Colors.RESET, "")
+ )
if len(plain_line) > max_length:
progress_line = progress_line[:max_length] + "..."
-
- safe_print(progress_line, end='', flush=True)
-
- def increment(self, message: str = '') -> None:
+
+ safe_print(progress_line, end="", flush=True)
+
+ def increment(self, message: str = "") -> None:
"""
Increment progress by 1
-
+
Args:
message: Optional message to display
"""
self.update(self.current + 1, message)
-
- def finish(self, message: str = 'Complete') -> None:
+
+ def finish(self, message: str = "Complete") -> None:
"""
Complete progress bar
-
+
Args:
message: Completion message
"""
self.update(self.total, message)
print() # New line after completion
-
+
def _format_time(self, seconds: float) -> str:
"""Format time duration as human-readable string"""
if seconds < 60:
@@ -154,11 +163,11 @@ class ProgressBar:
class Menu:
"""Interactive menu system with keyboard navigation"""
-
+
def __init__(self, title: str, options: List[str], multi_select: bool = False):
"""
Initialize menu
-
+
Args:
title: Menu title
options: List of menu options
@@ -168,42 +177,46 @@ class Menu:
self.options = options
self.multi_select = multi_select
self.selected = set() if multi_select else None
-
+
def display(self) -> Union[int, List[int]]:
"""
Display menu and get user selection
-
+
Returns:
Selected option index (single) or list of indices (multi-select)
"""
print(f"\n{Colors.CYAN}{Colors.BRIGHT}{self.title}{Colors.RESET}")
print("=" * len(self.title))
-
+
for i, option in enumerate(self.options, 1):
if self.multi_select:
- marker = "[x]" if i-1 in (self.selected or set()) else "[ ]"
+ marker = "[x]" if i - 1 in (self.selected or set()) else "[ ]"
print(f"{Colors.YELLOW}{i:2d}.{Colors.RESET} {marker} {option}")
else:
print(f"{Colors.YELLOW}{i:2d}.{Colors.RESET} {option}")
-
+
if self.multi_select:
- print(f"\n{Colors.BLUE}Enter numbers separated by commas (e.g., 1,3,5) or 'all' for all options:{Colors.RESET}")
+ print(
+ f"\n{Colors.BLUE}Enter numbers separated by commas (e.g., 1,3,5) or 'all' for all options:{Colors.RESET}"
+ )
else:
- print(f"\n{Colors.BLUE}Enter your choice (1-{len(self.options)}):{Colors.RESET}")
-
+ print(
+ f"\n{Colors.BLUE}Enter your choice (1-{len(self.options)}):{Colors.RESET}"
+ )
+
while True:
try:
user_input = input("> ").strip().lower()
-
+
if self.multi_select:
- if user_input == 'all':
+ if user_input == "all":
return list(range(len(self.options)))
- elif user_input == '':
+ elif user_input == "":
return []
else:
# Parse comma-separated numbers
selections = []
- for part in user_input.split(','):
+ for part in user_input.split(","):
part = part.strip()
if part.isdigit():
idx = int(part) - 1
@@ -220,10 +233,12 @@ class Menu:
if 0 <= choice < len(self.options):
return choice
else:
- print(f"{Colors.RED}Invalid choice. Please enter a number between 1 and {len(self.options)}.{Colors.RESET}")
+ print(
+ f"{Colors.RED}Invalid choice. Please enter a number between 1 and {len(self.options)}.{Colors.RESET}"
+ )
else:
print(f"{Colors.RED}Please enter a valid number.{Colors.RESET}")
-
+
except (ValueError, KeyboardInterrupt) as e:
if isinstance(e, KeyboardInterrupt):
print(f"\n{Colors.YELLOW}Operation cancelled.{Colors.RESET}")
@@ -235,44 +250,46 @@ class Menu:
def confirm(message: str, default: bool = True) -> bool:
"""
Ask for user confirmation
-
+
Args:
message: Confirmation message
default: Default response if user just presses Enter
-
+
Returns:
True if confirmed, False otherwise
"""
suffix = "[Y/n]" if default else "[y/N]"
print(f"{Colors.BLUE}{message} {suffix}{Colors.RESET}")
-
+
while True:
try:
response = input("> ").strip().lower()
-
- if response == '':
+
+ if response == "":
return default
- elif response in ['y', 'yes', 'true', '1']:
+ elif response in ["y", "yes", "true", "1"]:
return True
- elif response in ['n', 'no', 'false', '0']:
+ elif response in ["n", "no", "false", "0"]:
return False
else:
- print(f"{Colors.RED}Please enter 'y' or 'n' (or press Enter for default).{Colors.RESET}")
-
+ print(
+ f"{Colors.RED}Please enter 'y' or 'n' (or press Enter for default).{Colors.RESET}"
+ )
+
except KeyboardInterrupt:
print(f"\n{Colors.YELLOW}Operation cancelled.{Colors.RESET}")
return False
-def display_header(title: str, subtitle: str = '') -> None:
+def display_header(title: str, subtitle: str = "") -> None:
"""
Display formatted header
-
+
Args:
title: Main title
subtitle: Optional subtitle
"""
- from SuperClaude import __author__, __email__
+ from superclaude import __author__, __email__
print(f"\n{Colors.CYAN}{Colors.BRIGHT}{'='*60}{Colors.RESET}")
print(f"{Colors.CYAN}{Colors.BRIGHT}{title:^60}{Colors.RESET}")
@@ -280,13 +297,13 @@ def display_header(title: str, subtitle: str = '') -> None:
print(f"{Colors.WHITE}{subtitle:^60}{Colors.RESET}")
# Display authors
- authors = [a.strip() for a in __author__.split(',')]
- emails = [e.strip() for e in __email__.split(',')]
+ authors = [a.strip() for a in __author__.split(",")]
+ emails = [e.strip() for e in __email__.split(",")]
author_lines = []
for i in range(len(authors)):
name = authors[i]
- email = emails[i] if i < len(emails) else ''
+ email = emails[i] if i < len(emails) else ""
author_lines.append(f"{name} <{email}>")
authors_str = " | ".join(author_lines)
@@ -297,20 +314,20 @@ def display_header(title: str, subtitle: str = '') -> None:
def display_authors() -> None:
"""Display author information"""
- from SuperClaude import __author__, __email__, __github__
+ from superclaude import __author__, __email__, __github__
print(f"\n{Colors.CYAN}{Colors.BRIGHT}{'='*60}{Colors.RESET}")
- print(f"{Colors.CYAN}{Colors.BRIGHT}{'SuperClaude Authors':^60}{Colors.RESET}")
+ print(f"{Colors.CYAN}{Colors.BRIGHT}{'superclaude Authors':^60}{Colors.RESET}")
print(f"{Colors.CYAN}{Colors.BRIGHT}{'='*60}{Colors.RESET}\n")
- authors = [a.strip() for a in __author__.split(',')]
- emails = [e.strip() for e in __email__.split(',')]
- github_users = [g.strip() for g in __github__.split(',')]
+ authors = [a.strip() for a in __author__.split(",")]
+ emails = [e.strip() for e in __email__.split(",")]
+ github_users = [g.strip() for g in __github__.split(",")]
for i in range(len(authors)):
name = authors[i]
- email = emails[i] if i < len(emails) else 'N/A'
- github = github_users[i] if i < len(github_users) else 'N/A'
+ email = emails[i] if i < len(emails) else "N/A"
+ github = github_users[i] if i < len(github_users) else "N/A"
print(f" {Colors.BRIGHT}{name}{Colors.RESET}")
print(f" Email: {Colors.YELLOW}{email}{Colors.RESET}")
@@ -345,10 +362,10 @@ def display_step(step: int, total: int, message: str) -> None:
print(f"{Colors.CYAN}[{step}/{total}] {message}{Colors.RESET}")
-def display_table(headers: List[str], rows: List[List[str]], title: str = '') -> None:
+def display_table(headers: List[str], rows: List[List[str]], title: str = "") -> None:
"""
Display data in table format
-
+
Args:
headers: Column headers
rows: Data rows
@@ -356,64 +373,80 @@ def display_table(headers: List[str], rows: List[List[str]], title: str = '') ->
"""
if not rows:
return
-
+
# Calculate column widths
col_widths = [len(header) for header in headers]
for row in rows:
for i, cell in enumerate(row):
if i < len(col_widths):
col_widths[i] = max(col_widths[i], len(str(cell)))
-
+
# Display title
if title:
print(f"\n{Colors.CYAN}{Colors.BRIGHT}{title}{Colors.RESET}")
print()
-
+
# Display headers
- header_line = " | ".join(f"{header:<{col_widths[i]}}" for i, header in enumerate(headers))
+ header_line = " | ".join(
+ f"{header:<{col_widths[i]}}" for i, header in enumerate(headers)
+ )
print(f"{Colors.YELLOW}{header_line}{Colors.RESET}")
print("-" * len(header_line))
-
+
# Display rows
for row in rows:
- row_line = " | ".join(f"{str(cell):<{col_widths[i]}}" for i, cell in enumerate(row))
+ row_line = " | ".join(
+ f"{str(cell):<{col_widths[i]}}" for i, cell in enumerate(row)
+ )
print(row_line)
-
+
print()
def prompt_api_key(service_name: str, env_var_name: str) -> Optional[str]:
"""
Prompt for API key with security and UX best practices
-
+
Args:
service_name: Human-readable service name (e.g., "Magic", "Morphllm")
env_var_name: Environment variable name (e.g., "TWENTYFIRST_API_KEY")
-
+
Returns:
API key string if provided, None if skipped
"""
- print(f"{Colors.BLUE}[API KEY] {service_name} requires: {Colors.BRIGHT}{env_var_name}{Colors.RESET}")
- print(f"{Colors.WHITE}Visit the service documentation to obtain your API key{Colors.RESET}")
- print(f"{Colors.YELLOW}Press Enter to skip (you can set this manually later){Colors.RESET}")
-
+ print(
+ f"{Colors.BLUE}[API KEY] {service_name} requires: {Colors.BRIGHT}{env_var_name}{Colors.RESET}"
+ )
+ print(
+ f"{Colors.WHITE}Visit the service documentation to obtain your API key{Colors.RESET}"
+ )
+ print(
+ f"{Colors.YELLOW}Press Enter to skip (you can set this manually later){Colors.RESET}"
+ )
+
try:
# Use getpass for hidden input
api_key = getpass.getpass(f"Enter {env_var_name}: ").strip()
-
+
if not api_key:
- print(f"{Colors.YELLOW}[SKIPPED] {env_var_name} - set manually later{Colors.RESET}")
+ print(
+ f"{Colors.YELLOW}[SKIPPED] {env_var_name} - set manually later{Colors.RESET}"
+ )
return None
-
+
# Basic validation (non-empty, reasonable length)
if len(api_key) < 10:
- print(f"{Colors.RED}[WARNING] API key seems too short. Continue anyway? (y/N){Colors.RESET}")
+ print(
+ f"{Colors.RED}[WARNING] API key seems too short. Continue anyway? (y/N){Colors.RESET}"
+ )
if not confirm("", default=False):
return None
-
- safe_print(f"{Colors.GREEN}[{symbols.checkmark}] {env_var_name} configured{Colors.RESET}")
+
+ safe_print(
+ f"{Colors.GREEN}[{symbols.checkmark}] {env_var_name} configured{Colors.RESET}"
+ )
return api_key
-
+
except KeyboardInterrupt:
safe_print(f"\n{Colors.YELLOW}[SKIPPED] {env_var_name}{Colors.RESET}")
return None
@@ -430,16 +463,17 @@ def wait_for_key(message: str = "Press Enter to continue...") -> None:
def clear_screen() -> None:
"""Clear terminal screen"""
import os
- os.system('cls' if os.name == 'nt' else 'clear')
+
+ os.system("cls" if os.name == "nt" else "clear")
class StatusSpinner:
"""Simple status spinner for long operations"""
-
+
def __init__(self, message: str = "Working..."):
"""
Initialize spinner
-
+
Args:
message: Message to display with spinner
"""
@@ -447,35 +481,39 @@ class StatusSpinner:
self.spinning = False
self.chars = symbols.spinner_chars
self.current = 0
-
+
def start(self) -> None:
"""Start spinner in background thread"""
import threading
-
+
def spin():
while self.spinning:
char = self.chars[self.current % len(self.chars)]
- safe_print(f"\r{Colors.BLUE}{char} {self.message}{Colors.RESET}", end='', flush=True)
+ safe_print(
+ f"\r{Colors.BLUE}{char} {self.message}{Colors.RESET}",
+ end="",
+ flush=True,
+ )
self.current += 1
time.sleep(0.1)
-
+
self.spinning = True
self.thread = threading.Thread(target=spin, daemon=True)
self.thread.start()
-
- def stop(self, final_message: str = '') -> None:
+
+ def stop(self, final_message: str = "") -> None:
"""
Stop spinner
-
+
Args:
final_message: Final message to display
"""
self.spinning = False
- if hasattr(self, 'thread'):
+ if hasattr(self, "thread"):
self.thread.join(timeout=0.2)
-
+
# Clear spinner line
- safe_print(f"\r{' ' * (len(self.message) + 5)}\r", end='')
+ safe_print(f"\r{' ' * (len(self.message) + 5)}\r", end="")
if final_message:
safe_print(final_message)
@@ -483,7 +521,7 @@ class StatusSpinner:
def format_size(size_bytes: int) -> str:
"""Format file size in human-readable format"""
- for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
+ for unit in ["B", "KB", "MB", "GB", "TB"]:
if size_bytes < 1024.0:
return f"{size_bytes:.1f} {unit}"
size_bytes /= 1024.0
@@ -510,5 +548,5 @@ def truncate_text(text: str, max_length: int, suffix: str = "...") -> str:
"""Truncate text to maximum length with optional suffix"""
if len(text) <= max_length:
return text
-
- return text[:max_length - len(suffix)] + suffix
+
+ return text[: max_length - len(suffix)] + suffix
diff --git a/setup/utils/updater.py b/setup/utils/updater.py
index 896935b..f0981eb 100644
--- a/setup/utils/updater.py
+++ b/setup/utils/updater.py
@@ -22,94 +22,97 @@ from .paths import get_home_directory
class UpdateChecker:
"""Handles automatic update checking for SuperClaude"""
-
- PYPI_URL = "https://pypi.org/pypi/SuperClaude/json"
+
+ PYPI_URL = "https://pypi.org/pypi/superclaude/json"
CACHE_FILE = get_home_directory() / ".claude" / ".update_check"
CHECK_INTERVAL = 86400 # 24 hours in seconds
TIMEOUT = 2 # seconds
-
+
def __init__(self, current_version: str):
"""
Initialize update checker
-
+
Args:
current_version: Current installed version
"""
self.current_version = current_version
self.logger = get_logger()
-
+
def should_check_update(self, force: bool = False) -> bool:
"""
Determine if we should check for updates based on last check time
-
+
Args:
force: Force check regardless of last check time
-
+
Returns:
True if update check should be performed
"""
if force:
return True
-
+
if not self.CACHE_FILE.exists():
return True
-
+
try:
- with open(self.CACHE_FILE, 'r') as f:
+ with open(self.CACHE_FILE, "r") as f:
data = json.load(f)
- last_check = data.get('last_check', 0)
-
+ last_check = data.get("last_check", 0)
+
# Check if 24 hours have passed
if time.time() - last_check > self.CHECK_INTERVAL:
return True
-
+
except (json.JSONDecodeError, KeyError):
return True
-
+
return False
-
+
def save_check_timestamp(self):
"""Save the current timestamp as last check time"""
self.CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
-
+
data = {}
if self.CACHE_FILE.exists():
try:
- with open(self.CACHE_FILE, 'r') as f:
+ with open(self.CACHE_FILE, "r") as f:
data = json.load(f)
except:
pass
-
- data['last_check'] = time.time()
-
- with open(self.CACHE_FILE, 'w') as f:
+
+ data["last_check"] = time.time()
+
+ with open(self.CACHE_FILE, "w") as f:
json.dump(data, f)
-
+
def get_latest_version(self) -> Optional[str]:
"""
Query PyPI for the latest version of SuperClaude
-
+
Returns:
Latest version string or None if check fails
"""
try:
# Create request with timeout
req = urllib.request.Request(
- self.PYPI_URL,
- headers={'User-Agent': 'SuperClaude-Updater'}
+ self.PYPI_URL, headers={"User-Agent": "superclaude-Updater"}
)
-
+
# Set timeout for the request
with urllib.request.urlopen(req, timeout=self.TIMEOUT) as response:
data = json.loads(response.read().decode())
- latest = data.get('info', {}).get('version')
-
+ latest = data.get("info", {}).get("version")
+
if self.logger:
self.logger.debug(f"Latest PyPI version: {latest}")
-
+
return latest
-
- except (urllib.error.URLError, urllib.error.HTTPError, json.JSONDecodeError) as e:
+
+ except (
+ urllib.error.URLError,
+ urllib.error.HTTPError,
+ json.JSONDecodeError,
+ ) as e:
if self.logger:
self.logger.debug(f"Failed to check PyPI: {e}")
return None
@@ -117,14 +120,14 @@ class UpdateChecker:
if self.logger:
self.logger.debug(f"Unexpected error checking updates: {e}")
return None
-
+
def compare_versions(self, latest: str) -> bool:
"""
Compare current version with latest version
-
+
Args:
latest: Latest version string
-
+
Returns:
True if update is available
"""
@@ -132,183 +135,195 @@ class UpdateChecker:
return version.parse(latest) > version.parse(self.current_version)
except Exception:
return False
-
+
def detect_installation_method(self) -> str:
"""
Detect how SuperClaude was installed (pip, pipx, etc.)
-
+
Returns:
Installation method string
"""
# Check pipx first
try:
result = subprocess.run(
- ['pipx', 'list'],
- capture_output=True,
- text=True,
- timeout=2
+ ["pipx", "list"], capture_output=True, text=True, timeout=2
)
- if 'SuperClaude' in result.stdout or 'superclaude' in result.stdout:
- return 'pipx'
+ if "superclaude" in result.stdout or "superclaude" in result.stdout:
+ return "pipx"
except:
pass
-
+
# Check if pip installation exists
try:
result = subprocess.run(
- [sys.executable, '-m', 'pip', 'show', 'SuperClaude'],
+ [sys.executable, "-m", "pip", "show", "superclaude"],
capture_output=True,
text=True,
- timeout=2
+ timeout=2,
)
if result.returncode == 0:
# Check if it's a user installation
- if '--user' in result.stdout or get_home_directory() in Path(result.stdout):
- return 'pip-user'
- return 'pip'
+ if "--user" in result.stdout or get_home_directory() in Path(
+ result.stdout
+ ):
+ return "pip-user"
+ return "pip"
except:
pass
-
- return 'unknown'
-
+
+ return "unknown"
+
def get_update_command(self) -> str:
"""
Get the appropriate update command based on installation method
-
+
Returns:
Update command string
"""
method = self.detect_installation_method()
-
+
commands = {
- 'pipx': 'pipx upgrade SuperClaude',
- 'pip-user': 'pip install --upgrade --user SuperClaude',
- 'pip': 'pip install --upgrade SuperClaude',
- 'unknown': 'pip install --upgrade SuperClaude'
+ "pipx": "pipx upgrade SuperClaude",
+ "pip-user": "pip install --upgrade --user SuperClaude",
+ "pip": "pip install --upgrade SuperClaude",
+ "unknown": "pip install --upgrade SuperClaude",
}
-
- return commands.get(method, commands['unknown'])
-
+
+ return commands.get(method, commands["unknown"])
+
def show_update_banner(self, latest: str, auto_update: bool = False) -> bool:
"""
Display update available banner
-
+
Args:
latest: Latest version available
auto_update: Whether to auto-update without prompting
-
+
Returns:
True if user wants to update
"""
update_cmd = self.get_update_command()
-
+
# Display banner
- print(f"\n{Colors.CYAN}+================================================+{Colors.RESET}")
- print(f"{Colors.CYAN}โ{Colors.YELLOW} ๐ Update Available: {self.current_version} โ {latest} {Colors.CYAN}โ{Colors.RESET}")
- print(f"{Colors.CYAN}โ{Colors.GREEN} Run: {update_cmd:<30} {Colors.CYAN}โ{Colors.RESET}")
- print(f"{Colors.CYAN}+================================================+{Colors.RESET}\n")
-
+ print(
+ f"\n{Colors.CYAN}+================================================+{Colors.RESET}"
+ )
+ print(
+ f"{Colors.CYAN}โ{Colors.YELLOW} ๐ Update Available: {self.current_version} โ {latest} {Colors.CYAN}โ{Colors.RESET}"
+ )
+ print(
+ f"{Colors.CYAN}โ{Colors.GREEN} Run: {update_cmd:<30} {Colors.CYAN}โ{Colors.RESET}"
+ )
+ print(
+ f"{Colors.CYAN}+================================================+{Colors.RESET}\n"
+ )
+
if auto_update:
return True
-
+
# Check if running in non-interactive mode
if not sys.stdin.isatty():
return False
-
+
# Prompt user
try:
- response = input(f"{Colors.YELLOW}Would you like to update now? (y/N): {Colors.RESET}").strip().lower()
- return response in ['y', 'yes']
+ response = (
+ input(
+ f"{Colors.YELLOW}Would you like to update now? (y/N): {Colors.RESET}"
+ )
+ .strip()
+ .lower()
+ )
+ return response in ["y", "yes"]
except (EOFError, KeyboardInterrupt):
return False
-
+
def perform_update(self) -> bool:
"""
Execute the update command
-
+
Returns:
True if update succeeded
"""
update_cmd = self.get_update_command()
-
- print(f"{Colors.CYAN}๐ Updating SuperClaude...{Colors.RESET}")
-
+
+ print(f"{Colors.CYAN}๐ Updating superclaude...{Colors.RESET}")
+
try:
- result = subprocess.run(
- update_cmd.split(),
- capture_output=False,
- text=True
- )
-
+ result = subprocess.run(update_cmd.split(), capture_output=False, text=True)
+
if result.returncode == 0:
display_success("Update completed successfully!")
- print(f"{Colors.YELLOW}Please restart SuperClaude to use the new version.{Colors.RESET}")
+ print(
+ f"{Colors.YELLOW}Please restart SuperClaude to use the new version.{Colors.RESET}"
+ )
return True
else:
display_warning("Update failed. Please run manually:")
print(f" {update_cmd}")
return False
-
+
except Exception as e:
display_warning(f"Could not auto-update: {e}")
print(f"Please run manually: {update_cmd}")
return False
-
+
def check_and_notify(self, force: bool = False, auto_update: bool = False) -> bool:
"""
Main method to check for updates and notify user
-
+
Args:
force: Force check regardless of last check time
auto_update: Automatically update if available
-
+
Returns:
True if update was performed
"""
# Check if we should skip based on environment variable
- if os.getenv('SUPERCLAUDE_NO_UPDATE_CHECK', '').lower() in ['true', '1', 'yes']:
+ if os.getenv("SUPERCLAUDE_NO_UPDATE_CHECK", "").lower() in ["true", "1", "yes"]:
return False
-
+
# Check if auto-update is enabled via environment
- if os.getenv('SUPERCLAUDE_AUTO_UPDATE', '').lower() in ['true', '1', 'yes']:
+ if os.getenv("SUPERCLAUDE_AUTO_UPDATE", "").lower() in ["true", "1", "yes"]:
auto_update = True
-
+
# Check if enough time has passed
if not self.should_check_update(force):
return False
-
+
# Get latest version
latest = self.get_latest_version()
if not latest:
return False
-
+
# Save timestamp
self.save_check_timestamp()
-
+
# Compare versions
if not self.compare_versions(latest):
return False
-
+
# Show banner and potentially update
if self.show_update_banner(latest, auto_update):
return self.perform_update()
-
+
return False
def check_for_updates(current_version: str = None, **kwargs) -> bool:
"""
Convenience function to check for updates
-
+
Args:
current_version: Current installed version (defaults to reading from setup)
**kwargs: Additional arguments passed to check_and_notify
-
+
Returns:
True if update was performed
"""
if current_version is None:
from setup import __version__
+
current_version = __version__
checker = UpdateChecker(current_version)
- return checker.check_and_notify(**kwargs)
\ No newline at end of file
+ return checker.check_and_notify(**kwargs)
diff --git a/SuperClaude/__init__.py b/superclaude/__init__.py
similarity index 100%
rename from SuperClaude/__init__.py
rename to superclaude/__init__.py
diff --git a/SuperClaude/__main__.py b/superclaude/__main__.py
similarity index 68%
rename from SuperClaude/__main__.py
rename to superclaude/__main__.py
index 08c4d2b..cc1da19 100644
--- a/SuperClaude/__main__.py
+++ b/superclaude/__main__.py
@@ -34,8 +34,13 @@ else:
# Try to import utilities from the setup package
try:
from setup.utils.ui import (
- display_header, display_info, display_success, display_error,
- display_warning, Colors, display_authors
+ display_header,
+ display_info,
+ display_success,
+ display_error,
+ display_warning,
+ Colors,
+ display_authors,
)
from setup.utils.logger import setup_logging, get_logger, LogLevel
from setup import DEFAULT_INSTALL_DIR
@@ -44,13 +49,27 @@ except ImportError:
class Colors:
RED = YELLOW = GREEN = CYAN = RESET = ""
- def display_error(msg): print(f"[ERROR] {msg}")
- def display_warning(msg): print(f"[WARN] {msg}")
- def display_success(msg): print(f"[OK] {msg}")
- def display_info(msg): print(f"[INFO] {msg}")
- def display_header(title, subtitle): print(f"{title} - {subtitle}")
- def get_logger(): return None
- def setup_logging(*args, **kwargs): pass
+ def display_error(msg):
+ print(f"[ERROR] {msg}")
+
+ def display_warning(msg):
+ print(f"[WARN] {msg}")
+
+ def display_success(msg):
+ print(f"[OK] {msg}")
+
+ def display_info(msg):
+ print(f"[INFO] {msg}")
+
+ def display_header(title, subtitle):
+ print(f"{title} - {subtitle}")
+
+ def get_logger():
+ return None
+
+ def setup_logging(*args, **kwargs):
+ pass
+
class LogLevel:
ERROR = 40
INFO = 20
@@ -61,22 +80,40 @@ def create_global_parser() -> argparse.ArgumentParser:
"""Create shared parser for global flags used by all commands"""
global_parser = argparse.ArgumentParser(add_help=False)
- global_parser.add_argument("--verbose", "-v", action="store_true",
- help="Enable verbose logging")
- global_parser.add_argument("--quiet", "-q", action="store_true",
- help="Suppress all output except errors")
- global_parser.add_argument("--install-dir", type=Path, default=DEFAULT_INSTALL_DIR,
- help=f"Target installation directory (default: {DEFAULT_INSTALL_DIR})")
- global_parser.add_argument("--dry-run", action="store_true",
- help="Simulate operation without making changes")
- global_parser.add_argument("--force", action="store_true",
- help="Force execution, skipping checks")
- global_parser.add_argument("--yes", "-y", action="store_true",
- help="Automatically answer yes to all prompts")
- global_parser.add_argument("--no-update-check", action="store_true",
- help="Skip checking for updates")
- global_parser.add_argument("--auto-update", action="store_true",
- help="Automatically install updates without prompting")
+ global_parser.add_argument(
+ "--verbose", "-v", action="store_true", help="Enable verbose logging"
+ )
+ global_parser.add_argument(
+ "--quiet", "-q", action="store_true", help="Suppress all output except errors"
+ )
+ global_parser.add_argument(
+ "--install-dir",
+ type=Path,
+ default=DEFAULT_INSTALL_DIR,
+ help=f"Target installation directory (default: {DEFAULT_INSTALL_DIR})",
+ )
+ global_parser.add_argument(
+ "--dry-run",
+ action="store_true",
+ help="Simulate operation without making changes",
+ )
+ global_parser.add_argument(
+ "--force", action="store_true", help="Force execution, skipping checks"
+ )
+ global_parser.add_argument(
+ "--yes",
+ "-y",
+ action="store_true",
+ help="Automatically answer yes to all prompts",
+ )
+ global_parser.add_argument(
+ "--no-update-check", action="store_true", help="Skip checking for updates"
+ )
+ global_parser.add_argument(
+ "--auto-update",
+ action="store_true",
+ help="Automatically install updates without prompting",
+ )
return global_parser
@@ -95,17 +132,22 @@ Examples:
SuperClaude backup --create
""",
formatter_class=argparse.RawDescriptionHelpFormatter,
- parents=[global_parser]
+ parents=[global_parser],
)
- from SuperClaude import __version__
- parser.add_argument("--version", action="version", version=f"SuperClaude {__version__}")
- parser.add_argument("--authors", action="store_true", help="Show author information and exit")
+ from superclaude import __version__
+
+ parser.add_argument(
+ "--version", action="version", version=f"SuperClaude {__version__}"
+ )
+ parser.add_argument(
+ "--authors", action="store_true", help="Show author information and exit"
+ )
subparsers = parser.add_subparsers(
dest="operation",
title="Operations",
- description="Framework operations to perform"
+ description="Framework operations to perform",
)
return parser, subparsers, global_parser
@@ -128,7 +170,9 @@ def setup_global_environment(args: argparse.Namespace):
# Log startup context
logger = get_logger()
if logger:
- logger.debug(f"SuperClaude called with operation: {getattr(args, 'operation', 'None')}")
+ logger.debug(
+ f"SuperClaude called with operation: {getattr(args, 'operation', 'None')}"
+ )
logger.debug(f"Arguments: {vars(args)}")
@@ -138,7 +182,7 @@ def get_operation_modules() -> Dict[str, str]:
"install": "Install SuperClaude framework components",
"update": "Update existing SuperClaude installation",
"uninstall": "Remove SuperClaude installation",
- "backup": "Backup and restore operations"
+ "backup": "Backup and restore operations",
}
@@ -158,13 +202,17 @@ def register_operation_parsers(subparsers, global_parser) -> Dict[str, Callable]
operations = {}
for name, desc in get_operation_modules().items():
module = load_operation_module(name)
- if module and hasattr(module, 'register_parser') and hasattr(module, 'run'):
+ if module and hasattr(module, "register_parser") and hasattr(module, "run"):
module.register_parser(subparsers, global_parser)
operations[name] = module.run
else:
# If module doesn't exist, register a stub parser and fallback to legacy
- parser = subparsers.add_parser(name, help=f"{desc} (legacy fallback)", parents=[global_parser])
- parser.add_argument("--legacy", action="store_true", help="Use legacy script")
+ parser = subparsers.add_parser(
+ name, help=f"{desc} (legacy fallback)", parents=[global_parser]
+ )
+ parser.add_argument(
+ "--legacy", action="store_true", help="Use legacy script"
+ )
operations[name] = None
return operations
@@ -183,7 +231,7 @@ def handle_legacy_fallback(op: str, args: argparse.Namespace) -> int:
# Convert args into CLI flags
for k, v in vars(args).items():
- if k in ['operation', 'install_dir'] or v in [None, False]:
+ if k in ["operation", "install_dir"] or v in [None, False]:
continue
flag = f"--{k.replace('_', '-')}"
if v is True:
@@ -209,20 +257,24 @@ def main() -> int:
if args.authors:
display_authors()
return 0
-
+
# Check for updates unless disabled
- if not args.quiet and not getattr(args, 'no_update_check', False):
+ if not args.quiet and not getattr(args, "no_update_check", False):
try:
from setup.utils.updater import check_for_updates
+
# Check for updates in the background
- from SuperClaude import __version__
+ from superclaude import __version__
+
updated = check_for_updates(
current_version=__version__,
- auto_update=getattr(args, 'auto_update', False)
+ auto_update=getattr(args, "auto_update", False),
)
# If updated, suggest restart
if updated:
- print("\n๐ SuperClaude was updated. Please restart to use the new version.")
+ print(
+ "\n๐ SuperClaude was updated. Please restart to use the new version."
+ )
return 0
except ImportError:
# Updater module not available, skip silently
@@ -234,8 +286,12 @@ def main() -> int:
# No operation provided? Show help manually unless in quiet mode
if not args.operation:
if not args.quiet:
- from SuperClaude import __version__
- display_header(f"SuperClaude Framework v{__version__}", "Unified CLI for all operations")
+ from superclaude import __version__
+
+ display_header(
+ f"SuperClaude Framework v{__version__}",
+ "Unified CLI for all operations",
+ )
print(f"{Colors.CYAN}Available operations:{Colors.RESET}")
for op, desc in get_operation_modules().items():
print(f" {op:<12} {desc}")
@@ -261,7 +317,9 @@ def main() -> int:
else:
# Fallback to legacy script
if logger:
- logger.warning(f"Module for '{args.operation}' missing, using legacy fallback")
+ logger.warning(
+ f"Module for '{args.operation}' missing, using legacy fallback"
+ )
return handle_legacy_fallback(args.operation, args)
except KeyboardInterrupt:
@@ -280,5 +338,3 @@ def main() -> int:
# Entrypoint guard
if __name__ == "__main__":
sys.exit(main())
-
-
diff --git a/SuperClaude/Agents/__init__.py b/superclaude/agents/__init__.py
similarity index 100%
rename from SuperClaude/Agents/__init__.py
rename to superclaude/agents/__init__.py
diff --git a/SuperClaude/Agents/backend-architect.md b/superclaude/agents/backend-architect.md
similarity index 100%
rename from SuperClaude/Agents/backend-architect.md
rename to superclaude/agents/backend-architect.md
diff --git a/SuperClaude/Agents/business-panel-experts.md b/superclaude/agents/business-panel-experts.md
similarity index 100%
rename from SuperClaude/Agents/business-panel-experts.md
rename to superclaude/agents/business-panel-experts.md
diff --git a/SuperClaude/Agents/deep-research-agent.md b/superclaude/agents/deep-research-agent.md
similarity index 100%
rename from SuperClaude/Agents/deep-research-agent.md
rename to superclaude/agents/deep-research-agent.md
diff --git a/SuperClaude/Agents/devops-architect.md b/superclaude/agents/devops-architect.md
similarity index 100%
rename from SuperClaude/Agents/devops-architect.md
rename to superclaude/agents/devops-architect.md
diff --git a/SuperClaude/Agents/frontend-architect.md b/superclaude/agents/frontend-architect.md
similarity index 100%
rename from SuperClaude/Agents/frontend-architect.md
rename to superclaude/agents/frontend-architect.md
diff --git a/SuperClaude/Agents/learning-guide.md b/superclaude/agents/learning-guide.md
similarity index 100%
rename from SuperClaude/Agents/learning-guide.md
rename to superclaude/agents/learning-guide.md
diff --git a/SuperClaude/Agents/performance-engineer.md b/superclaude/agents/performance-engineer.md
similarity index 100%
rename from SuperClaude/Agents/performance-engineer.md
rename to superclaude/agents/performance-engineer.md
diff --git a/SuperClaude/Agents/pm-agent.md b/superclaude/agents/pm-agent.md
similarity index 62%
rename from SuperClaude/Agents/pm-agent.md
rename to superclaude/agents/pm-agent.md
index f657ded..dbfe591 100644
--- a/SuperClaude/Agents/pm-agent.md
+++ b/superclaude/agents/pm-agent.md
@@ -7,12 +7,265 @@ category: meta
# PM Agent (Project Management Agent)
## Triggers
+- **Session Start (MANDATORY)**: ALWAYS activates to restore context from Serena MCP memory
- **Post-Implementation**: After any task completion requiring documentation
- **Mistake Detection**: Immediate analysis when errors or bugs occur
+- **State Questions**: "ใฉใใพใง้ฒใใงใ", "็พ็ถ", "้ฒๆ" trigger context report
- **Monthly Maintenance**: Regular documentation health reviews
- **Manual Invocation**: `/sc:pm` command for explicit PM Agent activation
- **Knowledge Gap**: When patterns emerge requiring documentation
+## Session Lifecycle (Serena MCP Memory Integration)
+
+PM Agent maintains continuous context across sessions using Serena MCP memory operations.
+
+### Session Start Protocol (Auto-Executes Every Time)
+
+```yaml
+Activation Trigger:
+ - EVERY Claude Code session start (no user command needed)
+ - "ใฉใใพใง้ฒใใงใ", "็พ็ถ", "้ฒๆ" queries
+
+Context Restoration:
+ 1. list_memories() โ Check for existing PM Agent state
+ 2. read_memory("pm_context") โ Restore overall project context
+ 3. read_memory("current_plan") โ What are we working on
+ 4. read_memory("last_session") โ What was done previously
+ 5. read_memory("next_actions") โ What to do next
+
+User Report:
+ ๅๅ: [last session summary]
+ ้ฒๆ: [current progress status]
+ ไปๅ: [planned next actions]
+ ่ชฒ้ก: [blockers or issues]
+
+Ready for Work:
+ - User can immediately continue from last checkpoint
+ - No need to re-explain context or goals
+ - PM Agent knows project state, architecture, patterns
+```
+
+### During Work (Continuous PDCA Cycle)
+
+```yaml
+1. Plan Phase (ไปฎ่ชฌ - Hypothesis):
+ Actions:
+ - write_memory("plan", goal_statement)
+ - Create docs/temp/hypothesis-YYYY-MM-DD.md
+ - Define what to implement and why
+ - Identify success criteria
+
+ Example Memory:
+ plan: "Implement user authentication with JWT"
+ hypothesis: "Use Supabase Auth + Kong Gateway pattern"
+ success_criteria: "Login works, tokens validated via Kong"
+
+2. Do Phase (ๅฎ้จ - Experiment):
+ Actions:
+ - TodoWrite for task tracking (3+ steps required)
+ - write_memory("checkpoint", progress) every 30min
+ - Create docs/temp/experiment-YYYY-MM-DD.md
+ - Record ่ฉฆ่ก้ฏ่ชค (trial and error), errors, solutions
+
+ Example Memory:
+ checkpoint: "Implemented login form, testing Kong routing"
+ errors_encountered: ["CORS issue", "JWT validation failed"]
+ solutions_applied: ["Added Kong CORS plugin", "Fixed JWT secret"]
+
+3. Check Phase (่ฉไพก - Evaluation):
+ Actions:
+ - think_about_task_adherence() โ Self-evaluation
+ - "ไฝใใใพใใใฃใ๏ผไฝใๅคฑๆ๏ผ" (What worked? What failed?)
+ - Create docs/temp/lessons-YYYY-MM-DD.md
+ - Assess against success criteria
+
+ Example Evaluation:
+ what_worked: "Kong Gateway pattern prevented auth bypass"
+ what_failed: "Forgot organization_id in initial implementation"
+ lessons: "ALWAYS check multi-tenancy docs before queries"
+
+4. Act Phase (ๆนๅ - Improvement):
+ Actions:
+ - Success โ Move docs/temp/experiment-* โ docs/patterns/[pattern-name].md (ๆธ
ๆธ)
+ - Failure โ Create docs/mistakes/mistake-YYYY-MM-DD.md (้ฒๆญข็ญ)
+ - Update CLAUDE.md if global pattern discovered
+ - write_memory("summary", outcomes)
+
+ Example Actions:
+ success: docs/patterns/supabase-auth-kong-pattern.md created
+ mistake_documented: docs/mistakes/organization-id-forgotten-2025-10-13.md
+ claude_md_updated: Added "ALWAYS include organization_id" rule
+```
+
+### Session End Protocol
+
+```yaml
+Final Checkpoint:
+ 1. think_about_whether_you_are_done()
+ - Verify all tasks completed or documented as blocked
+ - Ensure no partial implementations left
+
+ 2. write_memory("last_session", summary)
+ - What was accomplished
+ - What issues were encountered
+ - What was learned
+
+ 3. write_memory("next_actions", todo_list)
+ - Specific next steps for next session
+ - Blockers to resolve
+ - Documentation to update
+
+Documentation Cleanup:
+ 1. Move docs/temp/ โ docs/patterns/ or docs/mistakes/
+ - Success patterns โ docs/patterns/
+ - Failures with prevention โ docs/mistakes/
+
+ 2. Update formal documentation:
+ - CLAUDE.md (if global pattern)
+ - Project docs/*.md (if project-specific)
+
+ 3. Remove outdated temporary files:
+ - Delete old hypothesis files (>7 days)
+ - Archive completed experiment logs
+
+State Preservation:
+ - write_memory("pm_context", complete_state)
+ - Ensure next session can resume seamlessly
+ - No context loss between sessions
+```
+
+## PDCA Self-Evaluation Pattern
+
+PM Agent continuously evaluates its own performance using the PDCA cycle:
+
+```yaml
+Plan (ไปฎ่ชฌ็ๆ):
+ - "What am I trying to accomplish?"
+ - "What approach should I take?"
+ - "What are the success criteria?"
+ - "What could go wrong?"
+
+Do (ๅฎ้จๅฎ่ก):
+ - Execute planned approach
+ - Monitor for deviations from plan
+ - Record unexpected issues
+ - Adapt strategy as needed
+
+Check (่ชๅทฑ่ฉไพก):
+ Think About Questions:
+ - "Did I follow the architecture patterns?" (think_about_task_adherence)
+ - "Did I read all relevant documentation first?"
+ - "Did I check for existing implementations?"
+ - "Am I truly done?" (think_about_whether_you_are_done)
+ - "What mistakes did I make?"
+ - "What did I learn?"
+
+Act (ๆนๅๅฎ่ก):
+ Success Path:
+ - Extract successful pattern
+ - Document in docs/patterns/
+ - Update CLAUDE.md if global
+ - Create reusable template
+
+ Failure Path:
+ - Root cause analysis
+ - Document in docs/mistakes/
+ - Create prevention checklist
+ - Update anti-patterns documentation
+```
+
+## Documentation Strategy (Trial-and-Error to Knowledge)
+
+PM Agent uses a systematic documentation strategy to transform trial-and-error into reusable knowledge:
+
+```yaml
+Temporary Documentation (docs/temp/):
+ Purpose: Trial-and-error, experimentation, hypothesis testing
+ Files:
+ - hypothesis-YYYY-MM-DD.md: Initial plan and approach
+ - experiment-YYYY-MM-DD.md: Implementation log, errors, solutions
+ - lessons-YYYY-MM-DD.md: Reflections, what worked, what failed
+
+ Characteristics:
+ - ่ฉฆ่ก้ฏ่ชค OK (trial and error welcome)
+ - Raw notes and observations
+ - Not polished or formal
+ - Temporary (moved or deleted after 7 days)
+
+Formal Documentation (docs/patterns/):
+ Purpose: Successful patterns ready for reuse
+ Trigger: Successful implementation with verified results
+ Process:
+ - Read docs/temp/experiment-*.md
+ - Extract successful approach
+ - Clean up and formalize (ๆธ
ๆธ)
+ - Add concrete examples
+ - Include "Last Verified" date
+
+ Example:
+ docs/temp/experiment-2025-10-13.md
+ โ Success โ
+ docs/patterns/supabase-auth-kong-pattern.md
+
+Mistake Documentation (docs/mistakes/):
+ Purpose: Error records with prevention strategies
+ Trigger: Mistake detected, root cause identified
+ Process:
+ - What Happened (็พ่ฑก)
+ - Root Cause (ๆ นๆฌๅๅ )
+ - Why Missed (ใชใ่ฆ้ใใใ)
+ - Fix Applied (ไฟฎๆญฃๅ
ๅฎน)
+ - Prevention Checklist (้ฒๆญข็ญ)
+ - Lesson Learned (ๆ่จ)
+
+ Example:
+ docs/temp/experiment-2025-10-13.md
+ โ Failure โ
+ docs/mistakes/organization-id-forgotten-2025-10-13.md
+
+Evolution Pattern:
+ Trial-and-Error (docs/temp/)
+ โ
+ Success โ Formal Pattern (docs/patterns/)
+ Failure โ Mistake Record (docs/mistakes/)
+ โ
+ Accumulate Knowledge
+ โ
+ Extract Best Practices โ CLAUDE.md
+```
+
+## Memory Operations Reference
+
+PM Agent uses specific Serena MCP memory operations:
+
+```yaml
+Session Start (MANDATORY):
+ - list_memories() โ Check what memories exist
+ - read_memory("pm_context") โ Overall project state
+ - read_memory("last_session") โ Previous session summary
+ - read_memory("next_actions") โ Planned next steps
+
+During Work (Checkpoints):
+ - write_memory("plan", goal) โ Save current plan
+ - write_memory("checkpoint", progress) โ Save progress every 30min
+ - write_memory("decision", rationale) โ Record important decisions
+
+Self-Evaluation (Critical):
+ - think_about_task_adherence() โ "Am I following patterns?"
+ - think_about_collected_information() โ "Do I have enough context?"
+ - think_about_whether_you_are_done() โ "Is this truly complete?"
+
+Session End (MANDATORY):
+ - write_memory("last_session", summary) โ What was accomplished
+ - write_memory("next_actions", todos) โ What to do next
+ - write_memory("pm_context", state) โ Complete project state
+
+Monthly Maintenance:
+ - Review all memories โ Prune outdated
+ - Update documentation โ Merge duplicates
+ - Quality check โ Verify freshness
+```
+
## Behavioral Mindset
Think like a continuous learning system that transforms experiences into knowledge. After every significant implementation, immediately document what was learned. When mistakes occur, stop and analyze root causes before continuing. Monthly, prune and optimize documentation to maintain high signal-to-noise ratio.
diff --git a/SuperClaude/Agents/python-expert.md b/superclaude/agents/python-expert.md
similarity index 100%
rename from SuperClaude/Agents/python-expert.md
rename to superclaude/agents/python-expert.md
diff --git a/SuperClaude/Agents/quality-engineer.md b/superclaude/agents/quality-engineer.md
similarity index 100%
rename from SuperClaude/Agents/quality-engineer.md
rename to superclaude/agents/quality-engineer.md
diff --git a/SuperClaude/Agents/refactoring-expert.md b/superclaude/agents/refactoring-expert.md
similarity index 100%
rename from SuperClaude/Agents/refactoring-expert.md
rename to superclaude/agents/refactoring-expert.md
diff --git a/SuperClaude/Agents/requirements-analyst.md b/superclaude/agents/requirements-analyst.md
similarity index 100%
rename from SuperClaude/Agents/requirements-analyst.md
rename to superclaude/agents/requirements-analyst.md
diff --git a/SuperClaude/Agents/root-cause-analyst.md b/superclaude/agents/root-cause-analyst.md
similarity index 100%
rename from SuperClaude/Agents/root-cause-analyst.md
rename to superclaude/agents/root-cause-analyst.md
diff --git a/SuperClaude/Agents/security-engineer.md b/superclaude/agents/security-engineer.md
similarity index 100%
rename from SuperClaude/Agents/security-engineer.md
rename to superclaude/agents/security-engineer.md
diff --git a/SuperClaude/Agents/socratic-mentor.md b/superclaude/agents/socratic-mentor.md
similarity index 100%
rename from SuperClaude/Agents/socratic-mentor.md
rename to superclaude/agents/socratic-mentor.md
diff --git a/SuperClaude/Agents/system-architect.md b/superclaude/agents/system-architect.md
similarity index 100%
rename from SuperClaude/Agents/system-architect.md
rename to superclaude/agents/system-architect.md
diff --git a/SuperClaude/Agents/technical-writer.md b/superclaude/agents/technical-writer.md
similarity index 100%
rename from SuperClaude/Agents/technical-writer.md
rename to superclaude/agents/technical-writer.md
diff --git a/SuperClaude/Commands/__init__.py b/superclaude/commands/__init__.py
similarity index 100%
rename from SuperClaude/Commands/__init__.py
rename to superclaude/commands/__init__.py
diff --git a/SuperClaude/Commands/analyze.md b/superclaude/commands/analyze.md
similarity index 100%
rename from SuperClaude/Commands/analyze.md
rename to superclaude/commands/analyze.md
diff --git a/SuperClaude/Commands/brainstorm.md b/superclaude/commands/brainstorm.md
similarity index 100%
rename from SuperClaude/Commands/brainstorm.md
rename to superclaude/commands/brainstorm.md
diff --git a/SuperClaude/Commands/build.md b/superclaude/commands/build.md
similarity index 100%
rename from SuperClaude/Commands/build.md
rename to superclaude/commands/build.md
diff --git a/SuperClaude/Commands/business-panel.md b/superclaude/commands/business-panel.md
similarity index 100%
rename from SuperClaude/Commands/business-panel.md
rename to superclaude/commands/business-panel.md
diff --git a/SuperClaude/Commands/cleanup.md b/superclaude/commands/cleanup.md
similarity index 100%
rename from SuperClaude/Commands/cleanup.md
rename to superclaude/commands/cleanup.md
diff --git a/SuperClaude/Commands/design.md b/superclaude/commands/design.md
similarity index 100%
rename from SuperClaude/Commands/design.md
rename to superclaude/commands/design.md
diff --git a/SuperClaude/Commands/document.md b/superclaude/commands/document.md
similarity index 100%
rename from SuperClaude/Commands/document.md
rename to superclaude/commands/document.md
diff --git a/SuperClaude/Commands/estimate.md b/superclaude/commands/estimate.md
similarity index 100%
rename from SuperClaude/Commands/estimate.md
rename to superclaude/commands/estimate.md
diff --git a/SuperClaude/Commands/explain.md b/superclaude/commands/explain.md
similarity index 100%
rename from SuperClaude/Commands/explain.md
rename to superclaude/commands/explain.md
diff --git a/SuperClaude/Commands/git.md b/superclaude/commands/git.md
similarity index 100%
rename from SuperClaude/Commands/git.md
rename to superclaude/commands/git.md
diff --git a/SuperClaude/Commands/help.md b/superclaude/commands/help.md
similarity index 100%
rename from SuperClaude/Commands/help.md
rename to superclaude/commands/help.md
diff --git a/SuperClaude/Commands/implement.md b/superclaude/commands/implement.md
similarity index 100%
rename from SuperClaude/Commands/implement.md
rename to superclaude/commands/implement.md
diff --git a/SuperClaude/Commands/improve.md b/superclaude/commands/improve.md
similarity index 100%
rename from SuperClaude/Commands/improve.md
rename to superclaude/commands/improve.md
diff --git a/SuperClaude/Commands/index.md b/superclaude/commands/index.md
similarity index 100%
rename from SuperClaude/Commands/index.md
rename to superclaude/commands/index.md
diff --git a/SuperClaude/Commands/load.md b/superclaude/commands/load.md
similarity index 100%
rename from SuperClaude/Commands/load.md
rename to superclaude/commands/load.md
diff --git a/superclaude/commands/pm.md b/superclaude/commands/pm.md
new file mode 100644
index 0000000..1ef6155
--- /dev/null
+++ b/superclaude/commands/pm.md
@@ -0,0 +1,592 @@
+---
+name: pm
+description: "Project Manager Agent - Default orchestration agent that coordinates all sub-agents and manages workflows seamlessly"
+category: orchestration
+complexity: meta
+mcp-servers: [sequential, context7, magic, playwright, morphllm, serena, tavily, chrome-devtools]
+personas: [pm-agent]
+---
+
+# /sc:pm - Project Manager Agent (Always Active)
+
+> **Always-Active Foundation Layer**: PM Agent is NOT a mode - it's the DEFAULT operating foundation that runs automatically at every session start. Users never need to manually invoke it; PM Agent seamlessly orchestrates all interactions with continuous context preservation across sessions.
+
+## Auto-Activation Triggers
+- **Session Start (MANDATORY)**: ALWAYS activates to restore context via Serena MCP memory
+- **All User Requests**: Default entry point for all interactions unless explicit sub-agent override
+- **State Questions**: "ใฉใใพใง้ฒใใงใ", "็พ็ถ", "้ฒๆ" trigger context report
+- **Vague Requests**: "ไฝใใใ", "ๅฎ่ฃ
ใใใ", "ใฉใใใใฐ" trigger discovery mode
+- **Multi-Domain Tasks**: Cross-functional coordination requiring multiple specialists
+- **Complex Projects**: Systematic planning and PDCA cycle execution
+
+## Context Trigger Pattern
+```
+# Default (no command needed - PM Agent handles all interactions)
+"Build authentication system for my app"
+
+# Explicit PM Agent invocation (optional)
+/sc:pm [request] [--strategy brainstorm|direct|wave] [--verbose]
+
+# Override to specific sub-agent (optional)
+/sc:implement "user profile" --agent backend
+```
+
+## Session Lifecycle (Serena MCP Memory Integration)
+
+### Session Start Protocol (Auto-Executes Every Time)
+```yaml
+1. Context Restoration:
+ - list_memories() โ Check for existing PM Agent state
+ - read_memory("pm_context") โ Restore overall context
+ - read_memory("current_plan") โ What are we working on
+ - read_memory("last_session") โ What was done previously
+ - read_memory("next_actions") โ What to do next
+
+2. Report to User:
+ "ๅๅ: [last session summary]
+ ้ฒๆ: [current progress status]
+ ไปๅ: [planned next actions]
+ ่ชฒ้ก: [blockers or issues]"
+
+3. Ready for Work:
+ User can immediately continue from last checkpoint
+ No need to re-explain context or goals
+```
+
+### During Work (Continuous PDCA Cycle)
+```yaml
+1. Plan (ไปฎ่ชฌ):
+ - write_memory("plan", goal_statement)
+ - Create docs/temp/hypothesis-YYYY-MM-DD.md
+ - Define what to implement and why
+
+2. Do (ๅฎ้จ):
+ - TodoWrite for task tracking
+ - write_memory("checkpoint", progress) every 30min
+ - Update docs/temp/experiment-YYYY-MM-DD.md
+ - Record่ฉฆ่ก้ฏ่ชค, errors, solutions
+
+3. Check (่ฉไพก):
+ - think_about_task_adherence() โ Self-evaluation
+ - "ไฝใใใพใใใฃใ๏ผไฝใๅคฑๆ๏ผ"
+ - Update docs/temp/lessons-YYYY-MM-DD.md
+ - Assess against goals
+
+4. Act (ๆนๅ):
+ - Success โ docs/patterns/[pattern-name].md (ๆธ
ๆธ)
+ - Failure โ docs/mistakes/mistake-YYYY-MM-DD.md (้ฒๆญข็ญ)
+ - Update CLAUDE.md if global pattern
+ - write_memory("summary", outcomes)
+```
+
+### Session End Protocol
+```yaml
+1. Final Checkpoint:
+ - think_about_whether_you_are_done()
+ - write_memory("last_session", summary)
+ - write_memory("next_actions", todo_list)
+
+2. Documentation Cleanup:
+ - Move docs/temp/ โ docs/patterns/ or docs/mistakes/
+ - Update formal documentation
+ - Remove outdated temporary files
+
+3. State Preservation:
+ - write_memory("pm_context", complete_state)
+ - Ensure next session can resume seamlessly
+```
+
+## Behavioral Flow
+1. **Request Analysis**: Parse user intent, classify complexity, identify required domains
+2. **Strategy Selection**: Choose execution approach (Brainstorming, Direct, Multi-Agent, Wave)
+3. **Sub-Agent Delegation**: Auto-select optimal specialists without manual routing
+4. **MCP Orchestration**: Dynamically load tools per phase, unload after completion
+5. **Progress Monitoring**: Track execution via TodoWrite, validate quality gates
+6. **Self-Improvement**: Document continuously (implementations, mistakes, patterns)
+7. **PDCA Evaluation**: Continuous self-reflection and improvement cycle
+
+Key behaviors:
+- **Seamless Orchestration**: Users interact only with PM Agent, sub-agents work transparently
+- **Auto-Delegation**: Intelligent routing to domain specialists based on task analysis
+- **Zero-Token Efficiency**: Dynamic MCP tool loading via Docker Gateway integration
+- **Self-Documenting**: Automatic knowledge capture in project docs and CLAUDE.md
+
+## MCP Integration (Docker Gateway Pattern)
+
+### Zero-Token Baseline
+- **Start**: No MCP tools loaded (gateway URL only)
+- **Load**: On-demand tool activation per execution phase
+- **Unload**: Tool removal after phase completion
+- **Cache**: Strategic tool retention for sequential phases
+
+### Phase-Based Tool Loading
+```yaml
+Discovery Phase:
+ Load: [sequential, context7]
+ Execute: Requirements analysis, pattern research
+ Unload: After requirements complete
+
+Design Phase:
+ Load: [sequential, magic]
+ Execute: Architecture planning, UI mockups
+ Unload: After design approval
+
+Implementation Phase:
+ Load: [context7, magic, morphllm]
+ Execute: Code generation, bulk transformations
+ Unload: After implementation complete
+
+Testing Phase:
+ Load: [playwright, sequential]
+ Execute: E2E testing, quality validation
+ Unload: After tests pass
+```
+
+## Sub-Agent Orchestration Patterns
+
+### Vague Feature Request Pattern
+```
+User: "ใขใใชใซ่ช่จผๆฉ่ฝไฝใใใ"
+
+PM Agent Workflow:
+ 1. Activate Brainstorming Mode
+ โ Socratic questioning to discover requirements
+ 2. Delegate to requirements-analyst
+ โ Create formal PRD with acceptance criteria
+ 3. Delegate to system-architect
+ โ Architecture design (JWT, OAuth, Supabase Auth)
+ 4. Delegate to security-engineer
+ โ Threat modeling, security patterns
+ 5. Delegate to backend-architect
+ โ Implement authentication middleware
+ 6. Delegate to quality-engineer
+ โ Security testing, integration tests
+ 7. Delegate to technical-writer
+ โ Documentation, update CLAUDE.md
+
+Output: Complete authentication system with docs
+```
+
+### Clear Implementation Pattern
+```
+User: "Fix the login form validation bug in LoginForm.tsx:45"
+
+PM Agent Workflow:
+ 1. Load: [context7] for validation patterns
+ 2. Analyze: Read LoginForm.tsx, identify root cause
+ 3. Delegate to refactoring-expert
+ โ Fix validation logic, add missing tests
+ 4. Delegate to quality-engineer
+ โ Validate fix, run regression tests
+ 5. Document: Update self-improvement-workflow.md
+
+Output: Fixed bug with tests and documentation
+```
+
+### Multi-Domain Complex Project Pattern
+```
+User: "Build a real-time chat feature with video calling"
+
+PM Agent Workflow:
+ 1. Delegate to requirements-analyst
+ โ User stories, acceptance criteria
+ 2. Delegate to system-architect
+ โ Architecture (Supabase Realtime, WebRTC)
+ 3. Phase 1 (Parallel):
+ - backend-architect: Realtime subscriptions
+ - backend-architect: WebRTC signaling
+ - security-engineer: Security review
+ 4. Phase 2 (Parallel):
+ - frontend-architect: Chat UI components
+ - frontend-architect: Video calling UI
+ - Load magic: Component generation
+ 5. Phase 3 (Sequential):
+ - Integration: Chat + video
+ - Load playwright: E2E testing
+ 6. Phase 4 (Parallel):
+ - quality-engineer: Testing
+ - performance-engineer: Optimization
+ - security-engineer: Security audit
+ 7. Phase 5:
+ - technical-writer: User guide
+ - Update architecture docs
+
+Output: Production-ready real-time chat with video
+```
+
+## Tool Coordination
+- **TodoWrite**: Hierarchical task tracking across all phases
+- **Task**: Advanced delegation for complex multi-agent coordination
+- **Write/Edit/MultiEdit**: Cross-agent code generation and modification
+- **Read/Grep/Glob**: Context gathering for sub-agent coordination
+- **sequentialthinking**: Structured reasoning for complex delegation decisions
+
+## Key Patterns
+- **Default Orchestration**: PM Agent handles all user interactions by default
+- **Auto-Delegation**: Intelligent sub-agent selection without manual routing
+- **Phase-Based MCP**: Dynamic tool loading/unloading for resource efficiency
+- **Self-Improvement**: Continuous documentation of implementations and patterns
+
+## Examples
+
+### Default Usage (No Command Needed)
+```
+# User simply describes what they want
+User: "Need to add payment processing to the app"
+
+# PM Agent automatically handles orchestration
+PM Agent: Analyzing requirements...
+ โ Delegating to requirements-analyst for specification
+ โ Coordinating backend-architect + security-engineer
+ โ Engaging payment processing implementation
+ โ Quality validation with testing
+ โ Documentation update
+
+Output: Complete payment system implementation
+```
+
+### Explicit Strategy Selection
+```
+/sc:pm "Improve application security" --strategy wave
+
+# Wave mode for large-scale security audit
+PM Agent: Initiating comprehensive security analysis...
+ โ Wave 1: Security engineer audits (authentication, authorization)
+ โ Wave 2: Backend architect reviews (API security, data validation)
+ โ Wave 3: Quality engineer tests (penetration testing, vulnerability scanning)
+ โ Wave 4: Documentation (security policies, incident response)
+
+Output: Comprehensive security improvements with documentation
+```
+
+### Brainstorming Mode
+```
+User: "Maybe we could improve the user experience?"
+
+PM Agent: Activating Brainstorming Mode...
+ ๐ค Discovery Questions:
+ - What specific UX challenges are users facing?
+ - Which workflows are most problematic?
+ - Have you gathered user feedback or analytics?
+ - What are your improvement priorities?
+
+ ๐ Brief: [Generate structured improvement plan]
+
+Output: Clear UX improvement roadmap with priorities
+```
+
+### Manual Sub-Agent Override (Optional)
+```
+# User can still specify sub-agents directly if desired
+/sc:implement "responsive navbar" --agent frontend
+
+# PM Agent delegates to specified agent
+PM Agent: Routing to frontend-architect...
+ โ Frontend specialist handles implementation
+ โ PM Agent monitors progress and quality gates
+
+Output: Frontend-optimized implementation
+```
+
+## Self-Correcting Execution (Root Cause First)
+
+### Core Principle
+**Never retry the same approach without understanding WHY it failed.**
+
+```yaml
+Error Detection Protocol:
+ 1. Error Occurs:
+ โ STOP: Never re-execute the same command immediately
+ โ Question: "ใชใใใฎใจใฉใผใๅบใใฎใ๏ผ"
+
+ 2. Root Cause Investigation (MANDATORY):
+ - context7: Official documentation research
+ - WebFetch: Stack Overflow, GitHub Issues, community solutions
+ - Grep: Codebase pattern analysis for similar issues
+ - Read: Related files and configuration inspection
+ โ Document: "ใจใฉใผใฎๅๅ ใฏ[X]ใ ใจๆใใใใใชใใชใ[่จผๆ Y]"
+
+ 3. Hypothesis Formation:
+ - Create docs/pdca/[feature]/hypothesis-error-fix.md
+ - State: "ๅๅ ใฏ[X]ใๆ นๆ : [Y]ใ่งฃๆฑบ็ญ: [Z]"
+ - Rationale: "[ใชใใใฎๆนๆณใชใ่งฃๆฑบใใใ]"
+
+ 4. Solution Design (MUST BE DIFFERENT):
+ - Previous Approach A failed โ Design Approach B
+ - NOT: Approach A failed โ Retry Approach A
+ - Verify: Is this truly a different method?
+
+ 5. Execute New Approach:
+ - Implement solution based on root cause understanding
+ - Measure: Did it fix the actual problem?
+
+ 6. Learning Capture:
+ - Success โ write_memory("learning/solutions/[error_type]", solution)
+ - Failure โ Return to Step 2 with new hypothesis
+ - Document: docs/pdca/[feature]/do.md (trial-and-error log)
+
+Anti-Patterns (็ตถๅฏพ็ฆๆญข):
+ โ "ใจใฉใผใๅบใใใใไธๅใใฃใฆใฟใใ"
+ โ "ๅ่ฉฆ่ก: 1ๅ็ฎ... 2ๅ็ฎ... 3ๅ็ฎ..."
+ โ "ใฟใคใ ใขใฆใใ ใใๅพ
ใกๆ้ใๅขใใใ" (root cause็ก่ฆ)
+ โ "WarningใใใใฉๅใใใOK" (ๅฐๆฅ็ใชๆ่ก็่ฒ ๅต)
+
+Correct Patterns (ๅฟ
้ ):
+ โ
"ใจใฉใผใๅบใใๅ
ฌๅผใใญใฅใกใณใใง่ชฟๆป"
+ โ
"ๅๅ : ็ฐๅขๅคๆฐๆช่จญๅฎใใชใๅฟ
่ฆ๏ผไปๆงใ็่งฃ"
+ โ
"่งฃๆฑบ็ญ: .env่ฟฝๅ + ่ตทๅๆใใชใใผใทใงใณๅฎ่ฃ
"
+ โ
"ๅญฆ็ฟ: ๆฌกๅใใ็ฐๅขๅคๆฐใใงใใฏใๆๅใซๅฎ่ก"
+```
+
+### Warning/Error Investigation Culture
+
+**Rule: ๅ
จใฆใฎ่ญฆๅใปใจใฉใผใซ่ๅณใๆใฃใฆ่ชฟๆปใใ**
+
+```yaml
+Zero Tolerance for Dismissal:
+
+ Warning Detected:
+ 1. NEVER dismiss with "probably not important"
+ 2. ALWAYS investigate:
+ - context7: Official documentation lookup
+ - WebFetch: "What does this warning mean?"
+ - Understanding: "Why is this being warned?"
+
+ 3. Categorize Impact:
+ - Critical: Must fix immediately (security, data loss)
+ - Important: Fix before completion (deprecation, performance)
+ - Informational: Document why safe to ignore (with evidence)
+
+ 4. Document Decision:
+ - If fixed: Why it was important + what was learned
+ - If ignored: Why safe + evidence + future implications
+
+ Example - Correct Behavior:
+ Warning: "Deprecated API usage in auth.js:45"
+
+ PM Agent Investigation:
+ 1. context7: "React useEffect deprecated pattern"
+ 2. Finding: Cleanup function signature changed in React 18
+ 3. Impact: Will break in React 19 (timeline: 6 months)
+ 4. Action: Refactor to new pattern immediately
+ 5. Learning: Deprecation = future breaking change
+ 6. Document: docs/pdca/[feature]/do.md
+
+ Example - Wrong Behavior (็ฆๆญข):
+ Warning: "Deprecated API usage"
+ PM Agent: "Probably fine, ignoring" โ NEVER DO THIS
+
+Quality Mindset:
+ - Warnings = Future technical debt
+ - "Works now" โ "Production ready"
+ - Investigate thoroughly = Higher code quality
+ - Learn from every warning = Continuous improvement
+```
+
+### Memory Key Schema (Standardized)
+
+**Pattern: `[category]/[subcategory]/[identifier]`**
+
+Inspired by: Kubernetes namespaces, Git refs, Prometheus metrics
+
+```yaml
+session/:
+ session/context # Complete PM state snapshot
+ session/last # Previous session summary
+ session/checkpoint # Progress snapshots (30-min intervals)
+
+plan/:
+ plan/[feature]/hypothesis # Plan phase: ไปฎ่ชฌใป่จญ่จ
+ plan/[feature]/architecture # Architecture decisions
+ plan/[feature]/rationale # Why this approach chosen
+
+execution/:
+ execution/[feature]/do # Do phase: ๅฎ้จใป่ฉฆ่ก้ฏ่ชค
+ execution/[feature]/errors # Error log with timestamps
+ execution/[feature]/solutions # Solution attempts log
+
+evaluation/:
+ evaluation/[feature]/check # Check phase: ่ฉไพกใปๅๆ
+ evaluation/[feature]/metrics # Quality metrics (coverage, performance)
+ evaluation/[feature]/lessons # What worked, what failed
+
+learning/:
+ learning/patterns/[name] # Reusable success patterns
+ learning/solutions/[error] # Error solution database
+ learning/mistakes/[timestamp] # Failure analysis with prevention
+
+project/:
+ project/context # Project understanding
+ project/architecture # System architecture
+ project/conventions # Code style, naming patterns
+
+Example Usage:
+ write_memory("session/checkpoint", current_state)
+ write_memory("plan/auth/hypothesis", hypothesis_doc)
+ write_memory("execution/auth/do", experiment_log)
+ write_memory("evaluation/auth/check", analysis)
+ write_memory("learning/patterns/supabase-auth", success_pattern)
+ write_memory("learning/solutions/jwt-config-error", solution)
+```
+
+### PDCA Document Structure (Normalized)
+
+**Location: `docs/pdca/[feature-name]/`**
+
+```yaml
+Structure (ๆ็ขบใปใใใใใใ):
+ docs/pdca/[feature-name]/
+ โโโ plan.md # Plan: ไปฎ่ชฌใป่จญ่จ
+ โโโ do.md # Do: ๅฎ้จใป่ฉฆ่ก้ฏ่ชค
+ โโโ check.md # Check: ่ฉไพกใปๅๆ
+ โโโ act.md # Act: ๆนๅใปๆฌกใขใฏใทใงใณ
+
+Template - plan.md:
+ # Plan: [Feature Name]
+
+ ## Hypothesis
+ [ไฝใๅฎ่ฃ
ใใใใใชใใใฎใขใใญใผใใ]
+
+ ## Expected Outcomes (ๅฎ้็)
+ - Test Coverage: 45% โ 85%
+ - Implementation Time: ~4 hours
+ - Security: OWASP compliance
+
+ ## Risks & Mitigation
+ - [Risk 1] โ [ๅฏพ็ญ]
+ - [Risk 2] โ [ๅฏพ็ญ]
+
+Template - do.md:
+ # Do: [Feature Name]
+
+ ## Implementation Log (ๆ็ณปๅ)
+ - 10:00 Started auth middleware implementation
+ - 10:30 Error: JWTError - SUPABASE_JWT_SECRET undefined
+ โ Investigation: context7 "Supabase JWT configuration"
+ โ Root Cause: Missing environment variable
+ โ Solution: Add to .env + startup validation
+ - 11:00 Tests passing, coverage 87%
+
+ ## Learnings During Implementation
+ - Environment variables need startup validation
+ - Supabase Auth requires JWT secret for token validation
+
+Template - check.md:
+ # Check: [Feature Name]
+
+ ## Results vs Expectations
+ | Metric | Expected | Actual | Status |
+ |--------|----------|--------|--------|
+ | Test Coverage | 80% | 87% | โ
Exceeded |
+ | Time | 4h | 3.5h | โ
Under |
+ | Security | OWASP | Pass | โ
Compliant |
+
+ ## What Worked Well
+ - Root cause analysis prevented repeat errors
+ - Context7 official docs were accurate
+
+ ## What Failed / Challenges
+ - Initial assumption about JWT config was wrong
+ - Needed 2 investigation cycles to find root cause
+
+Template - act.md:
+ # Act: [Feature Name]
+
+ ## Success Pattern โ Formalization
+ Created: docs/patterns/supabase-auth-integration.md
+
+ ## Learnings โ Global Rules
+ CLAUDE.md Updated:
+ - Always validate environment variables at startup
+ - Use context7 for official configuration patterns
+
+ ## Checklist Updates
+ docs/checklists/new-feature-checklist.md:
+ - [ ] Environment variables documented
+ - [ ] Startup validation implemented
+ - [ ] Security scan passed
+
+Lifecycle:
+ 1. Start: Create docs/pdca/[feature]/plan.md
+ 2. Work: Continuously update docs/pdca/[feature]/do.md
+ 3. Complete: Create docs/pdca/[feature]/check.md
+ 4. Success โ Formalize:
+ - Move to docs/patterns/[feature].md
+ - Create docs/pdca/[feature]/act.md
+ - Update CLAUDE.md if globally applicable
+ 5. Failure โ Learn:
+ - Create docs/mistakes/[feature]-YYYY-MM-DD.md
+ - Create docs/pdca/[feature]/act.md with prevention
+ - Update checklists with new validation steps
+```
+
+## Self-Improvement Integration
+
+### Implementation Documentation
+```yaml
+After each successful implementation:
+ - Create docs/patterns/[feature-name].md (ๆธ
ๆธ)
+ - Document architecture decisions in ADR format
+ - Update CLAUDE.md with new best practices
+ - write_memory("learning/patterns/[name]", reusable_pattern)
+```
+
+### Mistake Recording
+```yaml
+When errors occur:
+ - Create docs/mistakes/[feature]-YYYY-MM-DD.md
+ - Document root cause analysis (WHY did it fail)
+ - Create prevention checklist
+ - write_memory("learning/mistakes/[timestamp]", failure_analysis)
+ - Update anti-patterns documentation
+```
+
+### Monthly Maintenance
+```yaml
+Regular documentation health:
+ - Remove outdated patterns and deprecated approaches
+ - Merge duplicate documentation
+ - Update version numbers and dependencies
+ - Prune noise, keep essential knowledge
+ - Review docs/pdca/ โ Archive completed cycles
+```
+
+## Boundaries
+
+**Will:**
+- Orchestrate all user interactions and automatically delegate to appropriate specialists
+- Provide seamless experience without requiring manual agent selection
+- Dynamically load/unload MCP tools for resource efficiency
+- Continuously document implementations, mistakes, and patterns
+- Transparently report delegation decisions and progress
+
+**Will Not:**
+- Bypass quality gates or compromise standards for speed
+- Make unilateral technical decisions without appropriate sub-agent expertise
+- Execute without proper planning for complex multi-domain projects
+- Skip documentation or self-improvement recording steps
+
+**User Control:**
+- Default: PM Agent auto-delegates (seamless)
+- Override: Explicit `--agent [name]` for direct sub-agent access
+- Both options available simultaneously (no user downside)
+
+## Performance Optimization
+
+### Resource Efficiency
+- **Zero-Token Baseline**: Start with no MCP tools (gateway only)
+- **Dynamic Loading**: Load tools only when needed per phase
+- **Strategic Unloading**: Remove tools after phase completion
+- **Parallel Execution**: Concurrent sub-agent delegation when independent
+
+### Quality Assurance
+- **Domain Expertise**: Route to specialized agents for quality
+- **Cross-Validation**: Multiple agent perspectives for complex decisions
+- **Quality Gates**: Systematic validation at phase transitions
+- **User Feedback**: Incorporate user guidance throughout execution
+
+### Continuous Learning
+- **Pattern Recognition**: Identify recurring successful patterns
+- **Mistake Prevention**: Document errors with prevention checklist
+- **Documentation Pruning**: Monthly cleanup to remove noise
+- **Knowledge Synthesis**: Codify learnings in CLAUDE.md and docs/
diff --git a/SuperClaude/Commands/reflect.md b/superclaude/commands/reflect.md
similarity index 100%
rename from SuperClaude/Commands/reflect.md
rename to superclaude/commands/reflect.md
diff --git a/SuperClaude/Commands/research.md b/superclaude/commands/research.md
similarity index 100%
rename from SuperClaude/Commands/research.md
rename to superclaude/commands/research.md
diff --git a/SuperClaude/Commands/save.md b/superclaude/commands/save.md
similarity index 100%
rename from SuperClaude/Commands/save.md
rename to superclaude/commands/save.md
diff --git a/SuperClaude/Commands/select-tool.md b/superclaude/commands/select-tool.md
similarity index 100%
rename from SuperClaude/Commands/select-tool.md
rename to superclaude/commands/select-tool.md
diff --git a/SuperClaude/Commands/spawn.md b/superclaude/commands/spawn.md
similarity index 100%
rename from SuperClaude/Commands/spawn.md
rename to superclaude/commands/spawn.md
diff --git a/SuperClaude/Commands/spec-panel.md b/superclaude/commands/spec-panel.md
similarity index 100%
rename from SuperClaude/Commands/spec-panel.md
rename to superclaude/commands/spec-panel.md
diff --git a/SuperClaude/Commands/task.md b/superclaude/commands/task.md
similarity index 100%
rename from SuperClaude/Commands/task.md
rename to superclaude/commands/task.md
diff --git a/SuperClaude/Commands/test.md b/superclaude/commands/test.md
similarity index 100%
rename from SuperClaude/Commands/test.md
rename to superclaude/commands/test.md
diff --git a/SuperClaude/Commands/troubleshoot.md b/superclaude/commands/troubleshoot.md
similarity index 100%
rename from SuperClaude/Commands/troubleshoot.md
rename to superclaude/commands/troubleshoot.md
diff --git a/SuperClaude/Commands/workflow.md b/superclaude/commands/workflow.md
similarity index 98%
rename from SuperClaude/Commands/workflow.md
rename to superclaude/commands/workflow.md
index 9b73d8f..32cb781 100644
--- a/SuperClaude/Commands/workflow.md
+++ b/superclaude/commands/workflow.md
@@ -58,7 +58,7 @@ Key behaviors:
### Systematic PRD Workflow
```
-/sc:workflow ClaudeDocs/PRD/feature-spec.md --strategy systematic --depth deep
+/sc:workflow Claudedocs/PRD/feature-spec.md --strategy systematic --depth deep
# Comprehensive PRD analysis with systematic workflow generation
# Multi-persona coordination for complete implementation strategy
```
diff --git a/SuperClaude/Core/BUSINESS_PANEL_EXAMPLES.md b/superclaude/core/BUSINESS_PANEL_EXAMPLES.md
similarity index 100%
rename from SuperClaude/Core/BUSINESS_PANEL_EXAMPLES.md
rename to superclaude/core/BUSINESS_PANEL_EXAMPLES.md
diff --git a/SuperClaude/Core/BUSINESS_SYMBOLS.md b/superclaude/core/BUSINESS_SYMBOLS.md
similarity index 100%
rename from SuperClaude/Core/BUSINESS_SYMBOLS.md
rename to superclaude/core/BUSINESS_SYMBOLS.md
diff --git a/SuperClaude/Core/FLAGS.md b/superclaude/core/FLAGS.md
similarity index 100%
rename from SuperClaude/Core/FLAGS.md
rename to superclaude/core/FLAGS.md
diff --git a/SuperClaude/Core/PRINCIPLES.md b/superclaude/core/PRINCIPLES.md
similarity index 100%
rename from SuperClaude/Core/PRINCIPLES.md
rename to superclaude/core/PRINCIPLES.md
diff --git a/SuperClaude/Core/RESEARCH_CONFIG.md b/superclaude/core/RESEARCH_CONFIG.md
similarity index 100%
rename from SuperClaude/Core/RESEARCH_CONFIG.md
rename to superclaude/core/RESEARCH_CONFIG.md
diff --git a/SuperClaude/Core/RULES.md b/superclaude/core/RULES.md
similarity index 100%
rename from SuperClaude/Core/RULES.md
rename to superclaude/core/RULES.md
diff --git a/SuperClaude/Core/__init__.py b/superclaude/core/__init__.py
similarity index 100%
rename from SuperClaude/Core/__init__.py
rename to superclaude/core/__init__.py
diff --git a/SuperClaude/Examples/deep_research_workflows.md b/superclaude/examples/deep_research_workflows.md
similarity index 100%
rename from SuperClaude/Examples/deep_research_workflows.md
rename to superclaude/examples/deep_research_workflows.md
diff --git a/SuperClaude/MCP/MCP_Chrome-DevTools.md b/superclaude/mcp/MCP_Chrome-DevTools.md
similarity index 100%
rename from SuperClaude/MCP/MCP_Chrome-DevTools.md
rename to superclaude/mcp/MCP_Chrome-DevTools.md
diff --git a/SuperClaude/MCP/MCP_Context7.md b/superclaude/mcp/MCP_Context7.md
similarity index 100%
rename from SuperClaude/MCP/MCP_Context7.md
rename to superclaude/mcp/MCP_Context7.md
diff --git a/SuperClaude/MCP/MCP_Magic.md b/superclaude/mcp/MCP_Magic.md
similarity index 100%
rename from SuperClaude/MCP/MCP_Magic.md
rename to superclaude/mcp/MCP_Magic.md
diff --git a/SuperClaude/MCP/MCP_Morphllm.md b/superclaude/mcp/MCP_Morphllm.md
similarity index 100%
rename from SuperClaude/MCP/MCP_Morphllm.md
rename to superclaude/mcp/MCP_Morphllm.md
diff --git a/SuperClaude/MCP/MCP_Playwright.md b/superclaude/mcp/MCP_Playwright.md
similarity index 100%
rename from SuperClaude/MCP/MCP_Playwright.md
rename to superclaude/mcp/MCP_Playwright.md
diff --git a/SuperClaude/MCP/MCP_Sequential.md b/superclaude/mcp/MCP_Sequential.md
similarity index 100%
rename from SuperClaude/MCP/MCP_Sequential.md
rename to superclaude/mcp/MCP_Sequential.md
diff --git a/SuperClaude/MCP/MCP_Serena.md b/superclaude/mcp/MCP_Serena.md
similarity index 100%
rename from SuperClaude/MCP/MCP_Serena.md
rename to superclaude/mcp/MCP_Serena.md
diff --git a/SuperClaude/MCP/MCP_Tavily.md b/superclaude/mcp/MCP_Tavily.md
similarity index 100%
rename from SuperClaude/MCP/MCP_Tavily.md
rename to superclaude/mcp/MCP_Tavily.md
diff --git a/SuperClaude/MCP/__init__.py b/superclaude/mcp/__init__.py
similarity index 100%
rename from SuperClaude/MCP/__init__.py
rename to superclaude/mcp/__init__.py
diff --git a/SuperClaude/MCP/configs/context7.json b/superclaude/mcp/configs/context7.json
similarity index 100%
rename from SuperClaude/MCP/configs/context7.json
rename to superclaude/mcp/configs/context7.json
diff --git a/SuperClaude/MCP/configs/magic.json b/superclaude/mcp/configs/magic.json
similarity index 100%
rename from SuperClaude/MCP/configs/magic.json
rename to superclaude/mcp/configs/magic.json
diff --git a/SuperClaude/MCP/configs/morphllm.json b/superclaude/mcp/configs/morphllm.json
similarity index 100%
rename from SuperClaude/MCP/configs/morphllm.json
rename to superclaude/mcp/configs/morphllm.json
diff --git a/SuperClaude/MCP/configs/playwright.json b/superclaude/mcp/configs/playwright.json
similarity index 100%
rename from SuperClaude/MCP/configs/playwright.json
rename to superclaude/mcp/configs/playwright.json
diff --git a/SuperClaude/MCP/configs/sequential.json b/superclaude/mcp/configs/sequential.json
similarity index 100%
rename from SuperClaude/MCP/configs/sequential.json
rename to superclaude/mcp/configs/sequential.json
diff --git a/SuperClaude/MCP/configs/serena-docker.json b/superclaude/mcp/configs/serena-docker.json
similarity index 100%
rename from SuperClaude/MCP/configs/serena-docker.json
rename to superclaude/mcp/configs/serena-docker.json
diff --git a/SuperClaude/MCP/configs/serena.json b/superclaude/mcp/configs/serena.json
similarity index 100%
rename from SuperClaude/MCP/configs/serena.json
rename to superclaude/mcp/configs/serena.json
diff --git a/SuperClaude/MCP/configs/tavily.json b/superclaude/mcp/configs/tavily.json
similarity index 100%
rename from SuperClaude/MCP/configs/tavily.json
rename to superclaude/mcp/configs/tavily.json
diff --git a/SuperClaude/Modes/MODE_Brainstorming.md b/superclaude/modes/MODE_Brainstorming.md
similarity index 100%
rename from SuperClaude/Modes/MODE_Brainstorming.md
rename to superclaude/modes/MODE_Brainstorming.md
diff --git a/SuperClaude/Modes/MODE_Business_Panel.md b/superclaude/modes/MODE_Business_Panel.md
similarity index 100%
rename from SuperClaude/Modes/MODE_Business_Panel.md
rename to superclaude/modes/MODE_Business_Panel.md
diff --git a/SuperClaude/Modes/MODE_DeepResearch.md b/superclaude/modes/MODE_DeepResearch.md
similarity index 100%
rename from SuperClaude/Modes/MODE_DeepResearch.md
rename to superclaude/modes/MODE_DeepResearch.md
diff --git a/SuperClaude/Modes/MODE_Introspection.md b/superclaude/modes/MODE_Introspection.md
similarity index 100%
rename from SuperClaude/Modes/MODE_Introspection.md
rename to superclaude/modes/MODE_Introspection.md
diff --git a/SuperClaude/Modes/MODE_Orchestration.md b/superclaude/modes/MODE_Orchestration.md
similarity index 100%
rename from SuperClaude/Modes/MODE_Orchestration.md
rename to superclaude/modes/MODE_Orchestration.md
diff --git a/SuperClaude/Modes/MODE_Task_Management.md b/superclaude/modes/MODE_Task_Management.md
similarity index 100%
rename from SuperClaude/Modes/MODE_Task_Management.md
rename to superclaude/modes/MODE_Task_Management.md
diff --git a/SuperClaude/Modes/MODE_Token_Efficiency.md b/superclaude/modes/MODE_Token_Efficiency.md
similarity index 100%
rename from SuperClaude/Modes/MODE_Token_Efficiency.md
rename to superclaude/modes/MODE_Token_Efficiency.md
diff --git a/SuperClaude/Modes/__init__.py b/superclaude/modes/__init__.py
similarity index 100%
rename from SuperClaude/Modes/__init__.py
rename to superclaude/modes/__init__.py
diff --git a/tests/test_get_components.py b/tests/test_get_components.py
index cce3526..bbb8b8f 100644
--- a/tests/test_get_components.py
+++ b/tests/test_get_components.py
@@ -3,23 +3,26 @@ from unittest.mock import patch, MagicMock
import argparse
from setup.cli.commands.install import get_components_to_install
+
class TestGetComponents:
- @patch('setup.cli.commands.install.select_mcp_servers')
+ @patch("setup.cli.commands.install.select_mcp_servers")
def test_get_components_to_install_interactive_mcp(self, mock_select_mcp):
# Arrange
mock_registry = MagicMock()
mock_config_manager = MagicMock()
mock_config_manager._installation_context = {}
- mock_select_mcp.return_value = ['magic']
+ mock_select_mcp.return_value = ["magic"]
- args = argparse.Namespace(components=['mcp'])
+ args = argparse.Namespace(components=["mcp"])
# Act
components = get_components_to_install(args, mock_registry, mock_config_manager)
# Assert
mock_select_mcp.assert_called_once()
- assert 'mcp' in components
- assert 'mcp_docs' in components # Should be added automatically
- assert hasattr(mock_config_manager, '_installation_context')
- assert mock_config_manager._installation_context['selected_mcp_servers'] == ['magic']
+ assert "mcp" in components
+ assert "mcp_docs" in components # Should be added automatically
+ assert hasattr(mock_config_manager, "_installation_context")
+ assert mock_config_manager._installation_context["selected_mcp_servers"] == [
+ "magic"
+ ]
diff --git a/tests/test_install_command.py b/tests/test_install_command.py
index 9f92821..ed4eaf7 100644
--- a/tests/test_install_command.py
+++ b/tests/test_install_command.py
@@ -4,34 +4,43 @@ from unittest.mock import patch, MagicMock, ANY
import argparse
from setup.cli.commands import install
+
class TestInstallCommand:
- @patch('setup.cli.commands.install.get_components_to_install')
- @patch('setup.cli.commands.install.ComponentRegistry')
- @patch('setup.cli.commands.install.ConfigService')
- @patch('setup.cli.commands.install.Validator')
- @patch('setup.cli.commands.install.display_installation_plan')
- @patch('setup.cli.commands.install.perform_installation')
- @patch('setup.cli.commands.install.confirm', return_value=True)
- @patch('setup.cli.commands.install.validate_system_requirements', return_value=True)
- @patch('pathlib.Path.home')
+ @patch("setup.cli.commands.install.get_components_to_install")
+ @patch("setup.cli.commands.install.ComponentRegistry")
+ @patch("setup.cli.commands.install.ConfigService")
+ @patch("setup.cli.commands.install.Validator")
+ @patch("setup.cli.commands.install.display_installation_plan")
+ @patch("setup.cli.commands.install.perform_installation")
+ @patch("setup.cli.commands.install.confirm", return_value=True)
+ @patch("setup.cli.commands.install.validate_system_requirements", return_value=True)
+ @patch("pathlib.Path.home")
def test_run_resolves_dependencies_before_planning(
- self, mock_home, mock_validate_reqs, mock_confirm, mock_perform,
- mock_display, mock_validator, mock_config, mock_registry_class,
- mock_get_components, tmp_path
+ self,
+ mock_home,
+ mock_validate_reqs,
+ mock_confirm,
+ mock_perform,
+ mock_display,
+ mock_validator,
+ mock_config,
+ mock_registry_class,
+ mock_get_components,
+ tmp_path,
):
# Arrange
mock_home.return_value = tmp_path
install_dir = tmp_path / ".claude"
mock_args = argparse.Namespace(
- components=['mcp'],
+ components=["mcp"],
install_dir=install_dir,
- quiet=True, # to avoid calling display_header
+ quiet=True, # to avoid calling display_header
yes=True,
force=False,
dry_run=False,
diagnose=False,
- list_components=False
+ list_components=False,
)
mock_registry_instance = MagicMock()
@@ -41,18 +50,18 @@ class TestInstallCommand:
mock_config.return_value = mock_config_instance
mock_config_instance.validate_config_files.return_value = []
- mock_get_components.return_value = ['mcp']
- mock_registry_instance.resolve_dependencies.return_value = ['core', 'mcp']
+ mock_get_components.return_value = ["mcp"]
+ mock_registry_instance.resolve_dependencies.return_value = ["core", "mcp"]
# Act
install.run(mock_args)
# Assert
# Check that resolve_dependencies was called with the initial list
- mock_registry_instance.resolve_dependencies.assert_called_once_with(['mcp'])
+ mock_registry_instance.resolve_dependencies.assert_called_once_with(["mcp"])
# Check that display_installation_plan was not called because of quiet=True
mock_display.assert_not_called()
# Check that perform_installation was called with the resolved list
- mock_perform.assert_called_once_with(['core', 'mcp'], mock_args, ANY)
+ mock_perform.assert_called_once_with(["core", "mcp"], mock_args, ANY)
diff --git a/tests/test_installer.py b/tests/test_installer.py
index ee6fd77..8f94342 100644
--- a/tests/test_installer.py
+++ b/tests/test_installer.py
@@ -6,6 +6,7 @@ import tempfile
from unittest.mock import MagicMock
from setup.core.installer import Installer
+
class TestInstaller:
def test_create_backup_empty_dir(self):
with tempfile.TemporaryDirectory() as temp_dir_str:
@@ -33,7 +34,7 @@ class TestInstaller:
def test_skips_already_installed_component(self):
# Create a mock component that is NOT reinstallable
mock_component = MagicMock()
- mock_component.get_metadata.return_value = {'name': 'test_component'}
+ mock_component.get_metadata.return_value = {"name": "test_component"}
mock_component.is_reinstallable.return_value = False
mock_component.install.return_value = True
mock_component.validate_prerequisites.return_value = (True, [])
@@ -42,18 +43,18 @@ class TestInstaller:
installer.register_component(mock_component)
# Simulate component is already installed
- installer.installed_components = {'test_component'}
+ installer.installed_components = {"test_component"}
- installer.install_component('test_component', {})
+ installer.install_component("test_component", {})
# Assert that the install method was NOT called
mock_component.install.assert_not_called()
- assert 'test_component' in installer.skipped_components
+ assert "test_component" in installer.skipped_components
def test_installs_reinstallable_component(self):
# Create a mock component that IS reinstallable
mock_component = MagicMock()
- mock_component.get_metadata.return_value = {'name': 'reinstallable_component'}
+ mock_component.get_metadata.return_value = {"name": "reinstallable_component"}
mock_component.is_reinstallable.return_value = True
mock_component.install.return_value = True
mock_component.validate_prerequisites.return_value = (True, [])
@@ -62,30 +63,30 @@ class TestInstaller:
installer.register_component(mock_component)
# Simulate component is already installed
- installer.installed_components = {'reinstallable_component'}
+ installer.installed_components = {"reinstallable_component"}
- installer.install_component('reinstallable_component', {})
+ installer.install_component("reinstallable_component", {})
# Assert that the install method WAS called
mock_component.install.assert_called_once()
- assert 'reinstallable_component' not in installer.skipped_components
+ assert "reinstallable_component" not in installer.skipped_components
def test_post_install_validation_only_validates_updated_components(self):
# Arrange
installer = Installer()
mock_comp1 = MagicMock()
- mock_comp1.get_metadata.return_value = {'name': 'comp1'}
+ mock_comp1.get_metadata.return_value = {"name": "comp1"}
mock_comp1.validate_installation.return_value = (True, [])
mock_comp2 = MagicMock()
- mock_comp2.get_metadata.return_value = {'name': 'comp2'}
+ mock_comp2.get_metadata.return_value = {"name": "comp2"}
mock_comp2.validate_installation.return_value = (True, [])
installer.register_component(mock_comp1)
installer.register_component(mock_comp2)
- installer.updated_components = {'comp1'}
+ installer.updated_components = {"comp1"}
# Act
installer._run_post_install_validation()
diff --git a/tests/test_mcp_component.py b/tests/test_mcp_component.py
index ad02c65..0cbb228 100644
--- a/tests/test_mcp_component.py
+++ b/tests/test_mcp_component.py
@@ -3,20 +3,24 @@ from pathlib import Path
from unittest.mock import MagicMock, patch
from setup.components.mcp import MCPComponent
+
class TestMCPComponent:
- @patch('setup.components.mcp.MCPComponent._post_install', return_value=True)
- @patch('setup.components.mcp.MCPComponent.validate_prerequisites', return_value=(True, []))
- @patch('setup.components.mcp.MCPComponent._install_mcp_server')
- def test_install_selected_servers_only(self, mock_install_mcp_server, mock_validate_prereqs, mock_post_install):
+ @patch("setup.components.mcp.MCPComponent._post_install", return_value=True)
+ @patch(
+ "setup.components.mcp.MCPComponent.validate_prerequisites",
+ return_value=(True, []),
+ )
+ @patch("setup.components.mcp.MCPComponent._install_mcp_server")
+ def test_install_selected_servers_only(
+ self, mock_install_mcp_server, mock_validate_prereqs, mock_post_install
+ ):
mock_install_mcp_server.return_value = True
- component = MCPComponent(install_dir=Path('/fake/dir'))
+ component = MCPComponent(install_dir=Path("/fake/dir"))
component.installed_servers_in_session = []
# Simulate selecting only the 'magic' server
- config = {
- "selected_mcp_servers": ["magic"]
- }
+ config = {"selected_mcp_servers": ["magic"]}
success = component._install(config)
@@ -30,18 +34,23 @@ class TestMCPComponent:
called_args, _ = mock_install_mcp_server.call_args
server_info_arg = called_args[0]
- assert server_info_arg['name'] == 'magic'
- assert server_info_arg['npm_package'] == '@21st-dev/magic'
+ assert server_info_arg["name"] == "magic"
+ assert server_info_arg["npm_package"] == "@21st-dev/magic"
- @patch('subprocess.run')
+ @patch("subprocess.run")
def test_validate_installation_success(self, mock_subprocess_run):
- component = MCPComponent(install_dir=Path('/fake/dir'))
+ component = MCPComponent(install_dir=Path("/fake/dir"))
# Mock settings manager
component.settings_manager = MagicMock()
component.settings_manager.is_component_installed.return_value = True
- component.settings_manager.get_component_version.return_value = component.get_metadata()['version']
- component.settings_manager.get_metadata_setting.return_value = ['magic', 'playwright']
+ component.settings_manager.get_component_version.return_value = (
+ component.get_metadata()["version"]
+ )
+ component.settings_manager.get_metadata_setting.return_value = [
+ "magic",
+ "playwright",
+ ]
# Mock `claude mcp list` output
mock_subprocess_run.return_value.returncode = 0
@@ -52,15 +61,20 @@ class TestMCPComponent:
assert success is True
assert not errors
- @patch('subprocess.run')
+ @patch("subprocess.run")
def test_validate_installation_failure(self, mock_subprocess_run):
- component = MCPComponent(install_dir=Path('/fake/dir'))
+ component = MCPComponent(install_dir=Path("/fake/dir"))
# Mock settings manager
component.settings_manager = MagicMock()
component.settings_manager.is_component_installed.return_value = True
- component.settings_manager.get_component_version.return_value = component.get_metadata()['version']
- component.settings_manager.get_metadata_setting.return_value = ['magic', 'playwright']
+ component.settings_manager.get_component_version.return_value = (
+ component.get_metadata()["version"]
+ )
+ component.settings_manager.get_metadata_setting.return_value = [
+ "magic",
+ "playwright",
+ ]
# Mock `claude mcp list` output - 'playwright' is missing
mock_subprocess_run.return_value.returncode = 0
diff --git a/tests/test_mcp_docs_component.py b/tests/test_mcp_docs_component.py
index d9ea72e..15dd0c6 100644
--- a/tests/test_mcp_docs_component.py
+++ b/tests/test_mcp_docs_component.py
@@ -3,31 +3,37 @@ from pathlib import Path
from unittest.mock import MagicMock, patch
from setup.components.mcp_docs import MCPDocsComponent
+
class TestMCPDocsComponent:
- @patch('setup.components.mcp_docs.MCPDocsComponent._post_install', return_value=True)
+ @patch(
+ "setup.components.mcp_docs.MCPDocsComponent._post_install", return_value=True
+ )
def test_install_calls_post_install_even_if_no_docs(self, mock_post_install):
- component = MCPDocsComponent(install_dir=Path('/fake/dir'))
+ component = MCPDocsComponent(install_dir=Path("/fake/dir"))
# Simulate no servers selected
- config = {
- "selected_mcp_servers": []
- }
+ config = {"selected_mcp_servers": []}
success = component._install(config)
assert success is True
mock_post_install.assert_called_once()
- @patch('setup.components.mcp_docs.MCPDocsComponent._post_install', return_value=True)
- @patch('setup.components.mcp_docs.MCPDocsComponent.get_files_to_install', return_value=[])
- @patch('setup.core.base.Component.validate_prerequisites', return_value=(True, []))
- def test_install_calls_post_install_if_docs_not_found(self, mock_validate_prereqs, mock_get_files, mock_post_install):
- component = MCPDocsComponent(install_dir=Path('/tmp/fake_dir'))
+ @patch(
+ "setup.components.mcp_docs.MCPDocsComponent._post_install", return_value=True
+ )
+ @patch(
+ "setup.components.mcp_docs.MCPDocsComponent.get_files_to_install",
+ return_value=[],
+ )
+ @patch("setup.core.base.Component.validate_prerequisites", return_value=(True, []))
+ def test_install_calls_post_install_if_docs_not_found(
+ self, mock_validate_prereqs, mock_get_files, mock_post_install
+ ):
+ component = MCPDocsComponent(install_dir=Path("/tmp/fake_dir"))
# Simulate a server was selected, but the doc file doesn't exist
- config = {
- "selected_mcp_servers": ["some_server_with_no_doc_file"]
- }
+ config = {"selected_mcp_servers": ["some_server_with_no_doc_file"]}
success = component._install(config)
diff --git a/tests/test_ui.py b/tests/test_ui.py
index de1e47a..a253c60 100644
--- a/tests/test_ui.py
+++ b/tests/test_ui.py
@@ -5,11 +5,13 @@ import io
from setup.utils.ui import display_authors
-@patch('sys.stdout', new_callable=io.StringIO)
+
+@patch("sys.stdout", new_callable=io.StringIO)
def test_display_header_with_authors(mock_stdout):
- # Mock the author and email info from SuperClaude/__init__.py
- with patch('SuperClaude.__author__', "Author One, Author Two"), \
- patch('SuperClaude.__email__', "one@example.com, two@example.com"):
+ # Mock the author and email info from superclaude/__init__.py
+ with patch("superclaude.__author__", "Author One, Author Two"), patch(
+ "superclaude.__email__", "one@example.com, two@example.com"
+ ):
display_header("Test Title", "Test Subtitle")
@@ -21,12 +23,13 @@ def test_display_header_with_authors(mock_stdout):
assert "Author Two " in output
assert "Author One | Author Two " in output
-@patch('sys.stdout', new_callable=io.StringIO)
+
+@patch("sys.stdout", new_callable=io.StringIO)
def test_display_authors(mock_stdout):
- # Mock the author, email, and github info from SuperClaude/__init__.py
- with patch('SuperClaude.__author__', "Author One, Author Two"), \
- patch('SuperClaude.__email__', "one@example.com, two@example.com"), \
- patch('SuperClaude.__github__', "user1, user2"):
+ # Mock the author, email, and github info from superclaude/__init__.py
+ with patch("superclaude.__author__", "Author One, Author Two"), patch(
+ "superclaude.__email__", "one@example.com, two@example.com"
+ ), patch("superclaude.__github__", "user1, user2"):
display_authors()