diff --git a/CLAUDE.md b/CLAUDE.md index b2144d3..c61f15f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,478 +1,195 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +This file provides guidance to Claude Code when working with code in this repository. ## Project Overview -This repository contains Claude Code plugins for project management: +**Repository:** support-claude-mktplace +**Version:** 2.2.0 +**Status:** Production Ready -1. **`projman`** - Single-repository project management plugin with Gitea integration -2. **`projman-pmo`** - Multi-project PMO coordination plugin -3. **`claude-config-maintainer`** - CLAUDE.md optimization and maintenance plugin -4. **`cmdb-assistant`** - NetBox CMDB integration for infrastructure management +A Claude Code plugin marketplace containing: -These plugins transform a proven 15-sprint workflow into reusable, distributable tools for managing software development with Claude Code, Gitea, and agile methodologies. +| Plugin | Description | Version | +|--------|-------------|---------| +| `projman` | Sprint planning and project management with Gitea integration | 2.2.0 | +| `claude-config-maintainer` | CLAUDE.md optimization and maintenance | 1.0.0 | +| `cmdb-assistant` | NetBox CMDB integration for infrastructure management | 1.0.0 | +| `project-hygiene` | Post-task cleanup automation via hooks | 0.1.0 | -**Status:** projman v1.0.0 complete with full Gitea integration +## Quick Start -## File Creation Governance +```bash +# Validate marketplace compliance +./scripts/validate-marketplace.sh -### Allowed Root Files +# Run projman commands (in a target project with plugin installed) +/sprint-plan # Start sprint planning +/sprint-status # Check progress +/review # Pre-close code quality review +/test-check # Verify tests before close +/sprint-close # Complete sprint +``` -Only these files may exist at the repository root: - -- `CLAUDE.md` - This file -- `README.md` - Repository overview -- `LICENSE` - License file -- `CHANGELOG.md` - Version history -- `.gitignore` - Git ignore rules -- `.env.example` - Environment template (if needed) - -### Allowed Root Directories - -Only these directories may exist at the repository root: - -| Directory | Purpose | -|-----------|---------| -| `.claude/` | Claude Code local settings | -| `.claude-plugin/` | Marketplace manifest | -| `.claude-plugins/` | Local marketplace definitions | -| `.scratch/` | Transient work (auto-cleaned) | -| `docs/` | Documentation | -| `hooks/` | Shared hooks (if any) | -| `plugins/` | All plugins (projman, projman-pmo, project-hygiene, cmdb-assistant, claude-config-maintainer) | -| `scripts/` | Setup and maintenance scripts | - -### File Creation Rules - -1. **No new root files** - Do not create files directly in the repository root unless listed above -2. **No new root directories** - Do not create top-level directories without explicit approval -3. **Transient work goes in `.scratch/`** - Any temporary files, test outputs, or exploratory work must be created in `.scratch/` -4. **Clean up after tasks** - Delete files in `.scratch/` when the task is complete -5. **Documentation location** - All documentation goes in `docs/` with appropriate subdirectory: - - `docs/references/` - Reference specifications and summaries - - `docs/architecture/` - Architecture diagrams (Draw.io files) - - `docs/workflows/` - Workflow documentation -6. **No output files** - Do not leave generated output, logs, or test results outside designated directories - -### Enforcement - -Before creating any file, verify: - -1. Is this file type allowed in the target location? -2. If temporary, am I using `.scratch/`? -3. If documentation, am I using the correct `docs/` subdirectory? -4. Will this file be cleaned up after the task? - -**Violation of these rules creates technical debt and project chaos.** - -## Path Verification (MANDATORY) - -### Before Generating Any Prompt or Creating Any File - -**This is non-negotiable. Failure to follow causes structural damage.** - -1. **READ `docs/CANONICAL-PATHS.md` FIRST** - - This file is the single source of truth - - Never infer paths from memory or context - - Never assume paths based on conversation history - -2. **List All Paths** - - Before generating a prompt, list every file path it will create/modify - - Show the list to the user - -3. **Verify Each Path** - - Check each path against `docs/CANONICAL-PATHS.md` - - If a path is not in that file, STOP and ask - -4. **Show Verification** - - Present a verification table to user: - ``` - | Path | Matches CANONICAL-PATHS.md? | - |------|----------------------------| - | plugins/projman/... | ✅ Yes | - ``` - -5. **Get Confirmation** - - User must confirm paths are correct before proceeding - -### Relative Path Rules - -- Plugin to bundled MCP server: `${CLAUDE_PLUGIN_ROOT}/mcp-servers/{server}` -- Marketplace to plugin: `./../../../plugins/{plugin-name}` -- **ALWAYS calculate from CANONICAL-PATHS.md, never from memory** - -### Recovery Protocol - -If you suspect paths are wrong: -1. Read `docs/CANONICAL-PATHS.md` -2. Compare actual structure against documented structure -3. Report discrepancies -4. Generate corrective prompt if needed - -## Core Architecture - -### Three-Agent Model - -The plugins implement a three-agent architecture that mirrors the proven workflow: - -**Planner Agent** (`agents/planner.md`) -- Performs architecture analysis and sprint planning -- Creates detailed planning documents -- Makes architectural decisions -- Creates Gitea issues with appropriate labels -- Personality: Asks clarifying questions, thinks through edge cases, never rushes - -**Orchestrator Agent** (`agents/orchestrator.md`) -- Coordinates sprint execution -- Generates lean execution prompts (not full docs) -- Tracks progress and updates documentation -- Handles Git operations (commit, merge, cleanup) -- Manages task dependencies -- Personality: Concise, action-oriented, tracks details meticulously - -**Executor Agent** (`agents/executor.md`) -- Implements features according to execution prompts -- Writes clean, tested code -- Follows architectural decisions from planning -- Generates completion reports -- Personality: Implementation-focused, follows specs precisely - -### MCP Server Integration - -**Gitea MCP Server** (Python) - bundled in projman plugin - -**Issue Tools:** -- `list_issues` - Query issues with filters -- `get_issue` - Fetch single issue details -- `create_issue` - Create new issue with labels -- `update_issue` - Modify existing issue -- `add_comment` - Add comments to issues -- `get_labels` - Fetch org + repo label taxonomy -- `suggest_labels` - Analyze context and suggest appropriate labels - -**Milestone Tools:** -- `list_milestones` - List sprint milestones -- `get_milestone` - Get milestone details -- `create_milestone` - Create sprint milestone -- `update_milestone` - Update/close milestone - -**Dependency Tools:** -- `list_issue_dependencies` - Get issue dependencies -- `create_issue_dependency` - Create dependency between issues -- `get_execution_order` - Get parallel execution batches - -**Wiki Tools (Gitea Wiki):** -- `list_wiki_pages` - List wiki pages -- `get_wiki_page` - Fetch specific page content -- `create_wiki_page` - Create new wiki page -- `create_lesson` - Create lessons learned document -- `search_lessons` - Search past lessons by tags - -**Validation Tools:** -- `validate_repo_org` - Check repo belongs to organization -- `get_branch_protection` - Check branch protection rules -- `create_label` - Create missing required labels - -**Key Architecture Points:** -- MCP servers are **bundled inside each plugin** at `plugins/{plugin}/mcp-servers/` -- This ensures plugins work when cached by Claude Code (only plugin directory is cached) -- Configuration uses hybrid approach (system-level + project-level) -- All plugins reference `${CLAUDE_PLUGIN_ROOT}/mcp-servers/` in their `.mcp.json` files - -## Branch-Aware Security Model - -Plugin behavior adapts to the current Git branch to prevent accidental changes: - -**Development Mode** (`development`, `feat/*`) -- Full access to all operations -- Can create Gitea issues -- Can modify all files - -**Staging Mode** (`staging`) -- Read-only for application code -- Can modify `.env` files -- Can create issues to document needed fixes -- Warns on attempted code changes - -**Production Mode** (`main`) -- Read-only for application code -- Emergency-only `.env` modifications -- Can create incident issues -- Blocks code changes - -This behavior is implemented in both CLAUDE.md (file-level) and plugin agents (tool-level). - -## Label Taxonomy System - -The project uses a sophisticated 43-label taxonomy at organization level: - -**Organization Labels (27):** -- Agent/2, Complexity/3, Efforts/5, Priority/4, Risk/3, Source/4, Type/6 - -**Repository Labels (16):** -- Component/9, Tech/7 - -**Important Labels:** -- `Type/Refactor` - For architectural changes and code restructuring (exclusive Type label) -- Used for service extraction, architecture modifications, technical debt - -The label system includes: -- `skills/label-taxonomy/labels-reference.md` - Local reference synced from Gitea -- Label suggestion logic that detects appropriate labels from context -- `/labels-sync` command to review and sync changes from Gitea - -## Lessons Learned System - -**Critical Feature:** After 15 sprints without lesson capture, repeated mistakes occurred (e.g., Claude Code infinite loops on similar issues 2-3 times). - -**Gitea Wiki Structure:** -Lessons learned are stored in the Gitea repository's built-in wiki under `lessons-learned/sprints/`. - -**Workflow:** -- Orchestrator captures lessons at sprint close via Gitea Wiki MCP tools -- Planner searches relevant lessons at sprint start using `search_lessons` -- Tags enable cross-project lesson discovery -- Focus on preventable repetitions, not every detail -- Web interface available through Gitea Wiki - -## Development Workflow - -### Build Order - -1. **Phase 1-8:** Build `projman` plugin first (single-repo) -2. **Phase 9-11:** Build `pmo` plugin second (multi-project) -3. **Phase 12:** Production deployment - -See [docs/reference-material/projman-implementation-plan.md](docs/reference-material/projman-implementation-plan.md) for the complete 12-phase implementation plan. - -### Repository Structure (DEFINITIVE) - -⚠️ **See `docs/CANONICAL-PATHS.md` for the authoritative path reference - THIS IS THE SINGLE SOURCE OF TRUTH** +## Repository Structure ``` -personal-projects/support-claude-mktplace/ +support-claude-mktplace/ ├── .claude-plugin/ -│ └── marketplace.json -├── plugins/ # ← ALL PLUGINS (with bundled MCP servers) -│ ├── projman/ # ← PROJECT PLUGIN -│ │ ├── .claude-plugin/ -│ │ │ └── plugin.json -│ │ ├── .mcp.json # Points to ${CLAUDE_PLUGIN_ROOT}/mcp-servers/ -│ │ ├── mcp-servers/ # ← MCP servers BUNDLED IN plugin -│ │ │ └── gitea/ # Gitea + Wiki tools -│ │ │ ├── .venv/ -│ │ │ ├── requirements.txt -│ │ │ ├── mcp_server/ -│ │ │ └── tests/ -│ │ ├── commands/ -│ │ │ ├── sprint-plan.md -│ │ │ ├── sprint-start.md -│ │ │ ├── sprint-status.md -│ │ │ ├── sprint-close.md -│ │ │ ├── labels-sync.md -│ │ │ └── initial-setup.md -│ │ ├── agents/ -│ │ │ ├── planner.md -│ │ │ ├── orchestrator.md -│ │ │ └── executor.md -│ │ ├── skills/ -│ │ │ └── label-taxonomy/ -│ │ │ └── labels-reference.md -│ │ ├── README.md -│ │ └── CONFIGURATION.md -│ ├── projman-pmo/ # ← PMO PLUGIN -│ │ ├── .claude-plugin/ -│ │ │ └── plugin.json +│ └── marketplace.json # Marketplace manifest +├── plugins/ +│ ├── projman/ # Sprint management (v2.2.0) +│ │ ├── .claude-plugin/plugin.json │ │ ├── .mcp.json -│ │ ├── commands/ -│ │ ├── agents/ -│ │ │ └── pmo-coordinator.md -│ │ └── README.md -│ ├── cmdb-assistant/ # ← CMDB PLUGIN -│ │ ├── .claude-plugin/ -│ │ │ └── plugin.json -│ │ ├── .mcp.json # Points to ${CLAUDE_PLUGIN_ROOT}/mcp-servers/ -│ │ ├── mcp-servers/ # ← MCP servers BUNDLED IN plugin -│ │ │ └── netbox/ -│ │ │ ├── .venv/ -│ │ │ ├── requirements.txt -│ │ │ └── mcp_server/ -│ │ ├── commands/ -│ │ └── agents/ -│ └── project-hygiene/ # ← CLEANUP PLUGIN -│ └── ... -├── scripts/ # Setup and maintenance scripts -│ ├── setup.sh -│ └── post-update.sh +│ │ ├── mcp-servers/gitea/ # Bundled MCP server +│ │ ├── commands/ # 8 commands +│ │ │ ├── sprint-plan.md, sprint-start.md, sprint-status.md +│ │ │ ├── sprint-close.md, labels-sync.md, initial-setup.md +│ │ │ ├── review.md, test-check.md # NEW in v2.2.0 +│ │ ├── agents/ # 4 agents +│ │ │ ├── planner.md, orchestrator.md, executor.md +│ │ │ └── code-reviewer.md # NEW in v2.2.0 +│ │ └── skills/label-taxonomy/ +│ ├── claude-config-maintainer/ +│ ├── cmdb-assistant/ +│ └── project-hygiene/ +├── scripts/ +│ ├── setup.sh, post-update.sh +│ └── validate-marketplace.sh # NEW in v2.2.0 └── docs/ + ├── CANONICAL-PATHS.md # Single source of truth for paths + └── references/ ``` -### Key Design Decisions - -**MCP Servers (Bundled in Plugins):** -- **Gitea MCP**: Issues, labels, wiki, milestones, dependencies (bundled in projman) -- **NetBox MCP**: Infrastructure management (bundled in cmdb-assistant) -- Servers are **bundled inside each plugin** that needs them -- This ensures plugins work when cached by Claude Code - -**Python Implementation:** -- Python chosen over Node.js for MCP servers -- Better suited for configuration management and modular code -- Easier to maintain and extend -- Virtual environment (.venv) per MCP server - -**Hybrid Configuration:** -- **System-level**: `~/.config/claude/gitea.env` (credentials) -- **Project-level**: `project-root/.env` (repository specification) -- Merge strategy: project overrides system -- Benefits: Single token per service, easy multi-project setup - -**Skills as Knowledge, Not Orchestrators:** -- Skills provide supporting knowledge loaded when relevant -- Agents are the primary interface -- Reduces token usage -- Makes knowledge reusable across agents - -**Branch Detection:** -- Two layers: CLAUDE.md (file access) + Plugin agents (tool usage) -- Defense in depth approach -- Plugin works with or without CLAUDE.md - -## Multi-Project Context (PMO Plugin) - -The `projman-pmo` plugin coordinates interdependent projects across an organization. Example use cases: -- Main product repository -- Marketing/documentation sites -- Extracted services -- Supporting tools - -PMO plugin adds: -- Cross-project issue aggregation (all repos in organization) -- Dependency tracking and visualization -- Resource allocation across projects -- Deployment coordination -- Multi-project prioritization -- Company-wide lessons learned search - -**Configuration Difference:** -- PMO operates at company level (no `GITEA_REPO`) -- Accesses all repositories in organization -- Aggregates issues and lessons across projects - -Build PMO plugin AFTER projman is working and validated. - -## Testing Approach - -**Local Marketplace:** -Create local marketplace for plugin development: -``` -~/projman-dev-marketplace/ -├── .claude-plugin/ -│ └── marketplace.json -└── projman/ # Symlink to plugin directory -``` - -**Integration Testing:** -Test in a real repository with actual Gitea instance before distribution. - -**Success Metrics:** -- Sprint planning time reduced 40% -- Manual steps eliminated: 10+ per sprint -- Lessons learned capture rate: 100% (vs 0% before) -- Label accuracy on issues: 90%+ -- User satisfaction: Better than current manual workflow - -## Important Notes - -- **Never modify docker-compose files with 'version' attribute** - It's obsolete -- **Focus on implementation, not over-engineering** - This system has been validated over 15 sprints -- **Lessons learned is critical** - Prevents repeated mistakes (e.g., Claude infinite loops) -- **Type/Refactor label** - Newly implemented at org level for architectural work -- **Branch detection must be 100% reliable** - Prevents production accidents -- **Python for MCP servers** - Use Python 3.8+ with virtual environments -- **CLI tools forbidden** - Use MCP tools exclusively, never CLI tools like `tea` or `gh` - ## CRITICAL: Rules You MUST Follow -### DO NOT MODIFY .gitignore Without Explicit Permission -- This is a **private repository** - credentials in `.env` files are intentional -- **NEVER** add `.env` or `.env.*` to .gitignore -- **NEVER** add venv patterns unless explicitly asked -- If you think something should be ignored, ASK FIRST +### File Operations +- **NEVER** create files in repository root unless listed in "Allowed Root Files" +- **NEVER** modify `.gitignore` without explicit permission +- **ALWAYS** use `.scratch/` for temporary/exploratory work +- **ALWAYS** verify paths against `docs/CANONICAL-PATHS.md` before creating files -### Plugin Structure Requirements -- **plugin.json MUST be in `.claude-plugin/` directory** - NOT in plugin root -- Every plugin in the repo MUST be listed in the marketplace.json -- After creating/modifying a plugin, VERIFY it's in the marketplace +### Plugin Development +- **plugin.json MUST be in `.claude-plugin/` directory** (not plugin root) +- **Every plugin MUST be listed in marketplace.json** +- **MCP servers MUST use venv python path**: `${CLAUDE_PLUGIN_ROOT}/mcp-servers/{name}/.venv/bin/python` +- **CLI tools forbidden** - Use MCP tools exclusively (never `tea`, `gh`, etc.) -### Hooks Syntax (Claude Code Official) -- **Valid events**: `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `SessionStart`, `SessionEnd`, `Notification`, `Stop`, `SubagentStop`, `PreCompact` -- **INVALID events**: `task-completed`, `file-changed`, `git-commit-msg-needed` (these DO NOT exist) -- Hooks schema: -```json -{ - "hooks": { - "EventName": [ - { - "matcher": "optional-pattern", - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/path/to/script.sh" - } - ] - } - ] - } -} +### Hooks (Valid Events Only) +`PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `SessionStart`, `SessionEnd`, `Notification`, `Stop`, `SubagentStop`, `PreCompact` + +**INVALID:** `task-completed`, `file-changed`, `git-commit-msg-needed` + +### Allowed Root Files +`CLAUDE.md`, `README.md`, `LICENSE`, `CHANGELOG.md`, `.gitignore`, `.env.example` + +### Allowed Root Directories +`.claude/`, `.claude-plugin/`, `.claude-plugins/`, `.scratch/`, `docs/`, `hooks/`, `plugins/`, `scripts/` + +## Architecture + +### Four-Agent Model (projman v2.2.0) + +| Agent | Personality | Responsibilities | +|-------|-------------|------------------| +| **Planner** | Thoughtful, methodical | Sprint planning, architecture analysis, issue creation, lesson search | +| **Orchestrator** | Concise, action-oriented | Sprint execution, parallel batching, Git operations, lesson capture | +| **Executor** | Implementation-focused | Code implementation, branch management, MR creation | +| **Code Reviewer** | Thorough, practical | Pre-close quality review, security scan, test verification | + +### MCP Server Tools (Gitea) + +| Category | Tools | +|----------|-------| +| Issues | `list_issues`, `get_issue`, `create_issue`, `update_issue`, `add_comment` | +| Labels | `get_labels`, `suggest_labels`, `create_label` | +| Milestones | `list_milestones`, `get_milestone`, `create_milestone`, `update_milestone` | +| Dependencies | `list_issue_dependencies`, `create_issue_dependency`, `get_execution_order` | +| Wiki | `list_wiki_pages`, `get_wiki_page`, `create_wiki_page`, `create_lesson`, `search_lessons` | +| Validation | `validate_repo_org`, `get_branch_protection` | + +### Hybrid Configuration + +| Level | Location | Purpose | +|-------|----------|---------| +| System | `~/.config/claude/gitea.env` | Credentials (GITEA_URL, GITEA_TOKEN, GITEA_ORG) | +| Project | `.env` in project root | Repository specification (GITEA_REPO) | + +### Branch-Aware Security + +| Branch Pattern | Mode | Capabilities | +|----------------|------|--------------| +| `development`, `feat/*` | Development | Full access | +| `staging` | Staging | Read-only code, can create issues | +| `main`, `master` | Production | Read-only, emergency only | + +## Label Taxonomy + +43 labels total: 27 organization + 16 repository + +**Organization:** Agent/2, Complexity/3, Efforts/5, Priority/4, Risk/3, Source/4, Type/6 +**Repository:** Component/9, Tech/7 + +Sync with `/labels-sync` command. + +## Lessons Learned System + +Stored in Gitea Wiki under `lessons-learned/sprints/`. + +**Workflow:** +1. Orchestrator captures at sprint close via MCP tools +2. Planner searches at sprint start using `search_lessons` +3. Tags enable cross-project discovery + +## Common Operations + +### Adding a New Plugin + +1. Create `plugins/{name}/.claude-plugin/plugin.json` +2. Add entry to `.claude-plugin/marketplace.json` +3. Create `README.md` and `claude-md-integration.md` +4. Run `./scripts/validate-marketplace.sh` +5. Update `CHANGELOG.md` + +### Adding a Command to projman + +1. Create `plugins/projman/commands/{name}.md` +2. Update `plugins/projman/README.md` +3. Update marketplace description if significant + +### Validation + +```bash +./scripts/validate-marketplace.sh # Validates all manifests ``` -### MCP Server Configuration -- MCP servers MUST use venv python: `${CLAUDE_PLUGIN_ROOT}/../../mcp-servers/NAME/.venv/bin/python` -- NEVER use bare `python` command - always use venv path -- Test MCP servers after any config change +## Path Verification Protocol -### Before Completing Any Plugin Work -1. Verify plugin.json is in `.claude-plugin/` directory -2. Verify plugin is listed in marketplace.json -3. Test MCP server configs load correctly -4. Verify hooks use valid event types -5. Check .gitignore wasn't modified inappropriately +**Before creating any file:** + +1. Read `docs/CANONICAL-PATHS.md` +2. List all paths to be created/modified +3. Verify each against canonical paths +4. If not in canonical paths, STOP and ask ## Documentation Index -This repository contains comprehensive planning documentation: +| Document | Purpose | +|----------|---------| +| `docs/CANONICAL-PATHS.md` | **Single source of truth** for paths | +| `docs/UPDATING.md` | Update guide for the marketplace | +| `plugins/projman/CONFIGURATION.md` | Projman setup guide | +| `plugins/projman/README.md` | Projman full documentation | -- **`docs/CANONICAL-PATHS.md`** - ⚠️ SINGLE SOURCE OF TRUTH for all paths (MANDATORY reading before any file operations) -- **`docs/DOCUMENT-INDEX.md`** - Complete guide to all planning documents -- **`docs/projman-implementation-plan-updated.md`** - Full 12-phase implementation plan -- **`docs/projman-python-quickstart.md`** - Python-specific implementation guide -- **`docs/two-mcp-architecture-guide.md`** - Deep dive into two-MCP architecture +## Version History -**Start with:** `docs/DOCUMENT-INDEX.md` for navigation guidance +| Version | Date | Highlights | +|---------|------|------------| +| 2.2.0 | 2026-01-20 | `/review`, `/test-check` commands, code-reviewer agent, validation script, marketplace compliance | +| 2.1.0 | Previous | Canonical paths, initial-setup command, documentation improvements | +| 2.0.0 | Previous | Full Gitea integration, wiki, milestones, dependencies, parallel execution | +| 0.1.0 | Initial | Basic plugin structure | -## Recent Updates (Updated: 2025-06-11) +--- -### Planning Phase Complete -- Comprehensive 12-phase implementation plan finalized -- Architecture decisions documented and validated -- Two-MCP-server approach confirmed (Gitea + Wiki.js) -- Python selected for MCP server implementation -- Hybrid configuration strategy defined (system + project level) -- Wiki.js structure planned with configurable base path -- Repository structure designed with shared MCP servers - -### Key Architectural Decisions Made -1. **Shared MCP Servers**: Both plugins use the same MCP codebase at `mcp-servers/` -2. **Mode Detection**: MCP servers detect project vs company-wide mode via environment variables -3. **Python Implementation**: MCP servers written in Python (not Node.js) for better configuration handling -4. **Wiki.js Integration**: Lessons learned and documentation moved to Wiki.js for better collaboration -5. **Hybrid Config**: System-level credentials + project-level paths for flexibility - -### Next Steps -- Begin Phase 1.1a: Gitea MCP Server implementation -- Set up Python virtual environments -- Create configuration loaders -- Implement core Gitea tools (issues, labels) -- Write integration tests +**Last Updated:** 2026-01-20 | **Current Version:** 2.2.0 diff --git a/docs/CANONICAL-PATHS.md b/docs/CANONICAL-PATHS.md index 21b7440..3ce5994 100644 --- a/docs/CANONICAL-PATHS.md +++ b/docs/CANONICAL-PATHS.md @@ -2,7 +2,7 @@ **This file defines ALL valid paths in this repository. No exceptions. No inference. No assumptions.** -Last Updated: 2025-12-15 +Last Updated: 2026-01-20 --- @@ -16,7 +16,8 @@ support-claude-mktplace/ ├── .scratch/ # Transient work (auto-cleaned) ├── docs/ # All documentation │ ├── architecture/ # Draw.io diagrams and specs -│ ├── references/ # Reference specifications +│ ├── CANONICAL-PATHS.md # This file - single source of truth +│ ├── UPDATING.md # Update guide │ └── workflows/ # Workflow documentation ├── hooks/ # Shared hooks (if any) ├── plugins/ # ALL plugins with bundled MCP servers @@ -90,10 +91,10 @@ MCP servers are now **bundled inside each plugin** to ensure they work when plug | Type | Location | |------|----------| -| Reference specs | `docs/references/` | | Architecture diagrams | `docs/architecture/` | | Workflow docs | `docs/workflows/` | | This file | `docs/CANONICAL-PATHS.md` | +| Update guide | `docs/UPDATING.md` | --- @@ -157,6 +158,7 @@ MCP servers are bundled inside each plugin (not shared at root) because: | Date | Change | By | |------|--------|-----| +| 2026-01-20 | Removed docs/references/ (obsolete planning docs) | Claude Code | | 2026-01-19 | Added claude-md-integration.md path pattern for plugin integration snippets | Claude Code | | 2025-12-15 | Restructured: MCP servers now bundled in plugins | Claude Code | | 2025-12-12 | Initial creation | Claude Code | diff --git a/docs/UPDATING.md b/docs/UPDATING.md index 70182a1..12a085c 100644 --- a/docs/UPDATING.md +++ b/docs/UPDATING.md @@ -15,7 +15,7 @@ git pull origin main ## What the Post-Update Script Does -1. **Updates Python dependencies** for Gitea and Wiki.js MCP servers +1. **Updates Python dependencies** for MCP servers 2. **Shows recent changelog entries** so you know what changed 3. **Validates your configuration** is still compatible @@ -30,7 +30,6 @@ If the changelog mentions new environment variables: 1. Check the variable name and purpose in the changelog 2. Add it to the appropriate config file: - Gitea variables → `~/.config/claude/gitea.env` - - Wiki.js variables → `~/.config/claude/wikijs.env` - Project variables → `.env` in your project root ### New MCP Server Features @@ -38,7 +37,7 @@ If the changelog mentions new environment variables: If a new MCP server tool is added: 1. The post-update script handles dependency installation -2. Check `docs/references/MCP-*.md` for usage documentation +2. Check `plugins/projman/README.md` for usage documentation 3. New tools are available immediately after update ### Breaking Changes @@ -51,15 +50,7 @@ Breaking changes will be clearly marked in CHANGELOG.md with migration instructi ```bash # Rebuild virtual environment -cd mcp-servers/gitea -rm -rf .venv -python3 -m venv .venv -source .venv/bin/activate -pip install -r requirements.txt -deactivate - -# Repeat for wikijs -cd ../wikijs +cd plugins/projman/mcp-servers/gitea rm -rf .venv python3 -m venv .venv source .venv/bin/activate @@ -76,7 +67,7 @@ deactivate ### MCP server won't start 1. Check Python version: `python3 --version` (requires 3.10+) -2. Verify venv exists: `ls mcp-servers/gitea/.venv` +2. Verify venv exists: `ls plugins/projman/mcp-servers/gitea/.venv` 3. Check logs for specific errors ## Version Pinning @@ -88,7 +79,7 @@ To stay on a specific version: git tag # Checkout specific version -git checkout v1.0.0 +git checkout v2.2.0 # Run post-update ./scripts/post-update.sh @@ -96,6 +87,7 @@ git checkout v1.0.0 ## Getting Help -- Check `docs/references/` for component documentation +- Check `plugins/projman/README.md` for projman documentation +- Check `plugins/projman/CONFIGURATION.md` for setup guide - Review CHANGELOG.md for recent changes - Search existing issues in Gitea diff --git a/docs/references/MCP-GITEA.md b/docs/references/MCP-GITEA.md deleted file mode 100644 index c63ff8a..0000000 --- a/docs/references/MCP-GITEA.md +++ /dev/null @@ -1,1268 +0,0 @@ -# Gitea MCP Server Reference - -## Overview - -The Gitea MCP Server provides integration with Gitea for issue management, label operations, and repository tracking. It's shared by both `projman` and `projman-pmo` plugins, detecting its operating mode based on environment variables. - -**Location:** `mcp-servers/gitea/` (repository root) - -**Key Features:** -- Issue CRUD operations -- Label taxonomy management (43-label system) -- Mode detection (project-scoped vs company-wide) -- Hybrid configuration (system + project level) -- Python 3.11+ implementation - ---- - -## Architecture - -### Mode Detection - -The MCP server operates in two modes based on environment variables: - -**Project Mode (projman):** -- When `GITEA_REPO` is present -- Operates on single repository -- Used by projman plugin - -**Company Mode (pmo):** -- When `GITEA_REPO` is absent -- Operates on all repositories in organization -- Used by projman-pmo plugin - -```python -# mcp-servers/gitea/mcp_server/config.py -def load(self): - # ... load configs ... - - self.repo = os.getenv('GITEA_REPO') # Optional - - if self.repo: - self.mode = 'project' - logger.info(f"Running in project mode: {self.repo}") - else: - self.mode = 'company' - logger.info("Running in company-wide mode (PMO)") - - return { - 'api_url': self.api_url, - 'api_token': self.api_token, - 'owner': self.owner, - 'repo': self.repo, - 'mode': self.mode - } -``` - ---- - -## Configuration - -### System-Level Configuration - -**File:** `~/.config/claude/gitea.env` - -```bash -GITEA_API_URL=https://gitea.example.com/api/v1 -GITEA_API_TOKEN=your_gitea_token -GITEA_OWNER=bandit -``` - -**Generating Gitea API Token:** - -1. Log into Gitea: https://gitea.example.com -2. Navigate to: **Settings** → **Applications** → **Manage Access Tokens** -3. Click **Generate New Token** -4. Token configuration: - - **Token Name:** `claude-code-mcp` - - **Required Permissions:** - - ✅ `repo` (all) - Read/write access to repositories, issues, labels - - ✅ `read:org` - Read organization information and labels - - ✅ `read:user` - Read user information -5. Click **Generate Token** -6. **Important:** Copy the token immediately (shown only once) -7. Add to configuration file (see setup below) - -**Setup:** -```bash -# Create config directory -mkdir -p ~/.config/claude - -# Create gitea.env -cat > ~/.config/claude/gitea.env << EOF -GITEA_API_URL=https://gitea.example.com/api/v1 -GITEA_API_TOKEN=your_token_here -GITEA_OWNER=bandit -EOF - -# Secure the file (important!) -chmod 600 ~/.config/claude/gitea.env - -# Verify setup -cat ~/.config/claude/gitea.env -``` - -### Project-Level Configuration - -**File:** `project-root/.env` - -```bash -# Repository name (project mode only) -GITEA_REPO=cuisineflow -``` - -**Setup:** -```bash -# In each project root -echo "GITEA_REPO=cuisineflow" > .env - -# Add to .gitignore -echo ".env" >> .gitignore -``` - -### Configuration Loading Strategy - -```python -# mcp-servers/gitea/mcp_server/config.py -from pathlib import Path -from dotenv import load_dotenv -import os -from typing import Dict, Optional - -class GiteaConfig: - """Hybrid configuration loader""" - - def __init__(self): - self.api_url: Optional[str] = None - self.api_token: Optional[str] = None - self.owner: Optional[str] = None - self.repo: Optional[str] = None - self.mode: str = 'project' - - def load(self) -> Dict[str, str]: - """ - Load configuration from system and project levels. - Project-level configuration overrides system-level. - """ - # Load system config - system_config = Path.home() / '.config' / 'claude' / 'gitea.env' - if system_config.exists(): - load_dotenv(system_config) - else: - raise FileNotFoundError( - f"System config not found: {system_config}\n" - "Create it with: mkdir -p ~/.config/claude && " - "cat > ~/.config/claude/gitea.env" - ) - - # Load project config (overrides system) - project_config = Path.cwd() / '.env' - if project_config.exists(): - load_dotenv(project_config, override=True) - - # Extract values - self.api_url = os.getenv('GITEA_API_URL') - self.api_token = os.getenv('GITEA_API_TOKEN') - self.owner = os.getenv('GITEA_OWNER') - self.repo = os.getenv('GITEA_REPO') # Optional for PMO - - # Detect mode - self.mode = 'project' if self.repo else 'company' - - # Validate required variables - self._validate() - - return { - 'api_url': self.api_url, - 'api_token': self.api_token, - 'owner': self.owner, - 'repo': self.repo, - 'mode': self.mode - } - - def _validate(self) -> None: - """Validate that required configuration is present""" - required = { - 'GITEA_API_URL': self.api_url, - 'GITEA_API_TOKEN': self.api_token, - 'GITEA_OWNER': self.owner - } - - missing = [key for key, value in required.items() if not value] - - if missing: - raise ValueError( - f"Missing required configuration: {', '.join(missing)}\n" - "Check your ~/.config/claude/gitea.env file" - ) -``` - ---- - -## Directory Structure - -``` -mcp-servers/gitea/ -├── .venv/ # Python virtual environment -├── requirements.txt # Python dependencies -├── .env.example # Configuration template -├── mcp_server/ -│ ├── __init__.py -│ ├── server.py # MCP server entry point -│ ├── config.py # Configuration loader -│ ├── gitea_client.py # Gitea API client -│ └── tools/ -│ ├── __init__.py -│ ├── issues.py # Issue CRUD tools -│ └── labels.py # Label management tools -└── tests/ - ├── test_config.py - ├── test_gitea_client.py - └── test_tools.py -``` - ---- - -## Dependencies - -**File:** `mcp-servers/gitea/requirements.txt` - -```txt -mcp>=0.9.0 # MCP SDK from Anthropic -python-dotenv>=1.0.0 # Environment variable loading -requests>=2.31.0 # HTTP client for Gitea API -pydantic>=2.5.0 # Data validation -pytest>=7.4.3 # Testing framework -pytest-asyncio>=0.23.0 # Async testing support -``` - -**Python Version:** 3.10+ required - -**Installation:** -```bash -cd mcp-servers/gitea -python -m venv .venv -source .venv/bin/activate # Linux/Mac -# or .venv\Scripts\activate # Windows -pip install -r requirements.txt -``` - ---- - -## Gitea API Client - -```python -# mcp-servers/gitea/mcp_server/gitea_client.py -import requests -from typing import List, Dict, Optional -from .config import GiteaConfig - -class GiteaClient: - """Client for interacting with Gitea API""" - - def __init__(self): - config = GiteaConfig() - config_dict = config.load() - - self.base_url = config_dict['api_url'] - self.token = config_dict['api_token'] - self.owner = config_dict['owner'] - self.repo = config_dict.get('repo') # Optional for PMO - self.mode = config_dict['mode'] - - self.session = requests.Session() - self.session.headers.update({ - 'Authorization': f'token {self.token}', - 'Content-Type': 'application/json' - }) - - def list_issues( - self, - state: str = 'open', - labels: Optional[List[str]] = None, - repo: Optional[str] = None - ) -> List[Dict]: - """ - List issues from Gitea repository. - - Args: - state: Issue state (open, closed, all) - labels: Filter by labels - repo: Override configured repo (for PMO multi-repo) - """ - target_repo = repo or self.repo - if not target_repo: - raise ValueError("Repository not specified") - - url = f"{self.base_url}/repos/{self.owner}/{target_repo}/issues" - params = {'state': state} - - if labels: - params['labels'] = ','.join(labels) - - response = self.session.get(url, params=params) - response.raise_for_status() - return response.json() - - def get_issue( - self, - issue_number: int, - repo: Optional[str] = None - ) -> Dict: - """Get specific issue details""" - target_repo = repo or self.repo - if not target_repo: - raise ValueError("Repository not specified") - - url = f"{self.base_url}/repos/{self.owner}/{target_repo}/issues/{issue_number}" - response = self.session.get(url) - response.raise_for_status() - return response.json() - - def create_issue( - self, - title: str, - body: str, - labels: Optional[List[str]] = None, - repo: Optional[str] = None - ) -> Dict: - """Create a new issue in Gitea""" - target_repo = repo or self.repo - if not target_repo: - raise ValueError("Repository not specified") - - url = f"{self.base_url}/repos/{self.owner}/{target_repo}/issues" - data = { - 'title': title, - 'body': body - } - - if labels: - data['labels'] = labels - - response = self.session.post(url, json=data) - response.raise_for_status() - return response.json() - - def update_issue( - self, - issue_number: int, - title: Optional[str] = None, - body: Optional[str] = None, - state: Optional[str] = None, - labels: Optional[List[str]] = None, - repo: Optional[str] = None - ) -> Dict: - """Update existing issue""" - target_repo = repo or self.repo - if not target_repo: - raise ValueError("Repository not specified") - - url = f"{self.base_url}/repos/{self.owner}/{target_repo}/issues/{issue_number}" - data = {} - - if title is not None: - data['title'] = title - if body is not None: - data['body'] = body - if state is not None: - data['state'] = state - if labels is not None: - data['labels'] = labels - - response = self.session.patch(url, json=data) - response.raise_for_status() - return response.json() - - def add_comment( - self, - issue_number: int, - comment: str, - repo: Optional[str] = None - ) -> Dict: - """Add comment to issue""" - target_repo = repo or self.repo - if not target_repo: - raise ValueError("Repository not specified") - - url = f"{self.base_url}/repos/{self.owner}/{target_repo}/issues/{issue_number}/comments" - data = {'body': comment} - - response = self.session.post(url, json=data) - response.raise_for_status() - return response.json() - - def get_labels( - self, - repo: Optional[str] = None - ) -> List[Dict]: - """Get all labels from repository""" - target_repo = repo or self.repo - if not target_repo: - raise ValueError("Repository not specified") - - url = f"{self.base_url}/repos/{self.owner}/{target_repo}/labels" - response = self.session.get(url) - response.raise_for_status() - return response.json() - - def get_org_labels(self) -> List[Dict]: - """Get organization-level labels""" - url = f"{self.base_url}/orgs/{self.owner}/labels" - response = self.session.get(url) - response.raise_for_status() - return response.json() - - # PMO-specific methods - - def list_repos(self) -> List[Dict]: - """List all repositories in organization (PMO mode)""" - url = f"{self.base_url}/orgs/{self.owner}/repos" - response = self.session.get(url) - response.raise_for_status() - return response.json() - - def aggregate_issues( - self, - state: str = 'open', - labels: Optional[List[str]] = None - ) -> Dict[str, List[Dict]]: - """ - Fetch issues across all repositories (PMO mode). - Returns dict keyed by repository name. - """ - repos = self.list_repos() - aggregated = {} - - for repo in repos: - repo_name = repo['name'] - try: - issues = self.list_issues( - state=state, - labels=labels, - repo=repo_name - ) - if issues: - aggregated[repo_name] = issues - except Exception as e: - # Log error but continue with other repos - print(f"Error fetching issues from {repo_name}: {e}") - - return aggregated -``` - ---- - -## MCP Server Implementation - -### Overview - -The MCP (Model Context Protocol) server exposes Gitea tools to Claude Code via JSON-RPC 2.0 over stdio. - -**Communication Flow:** -``` -Claude Code <--> stdio <--> MCP Server <--> Gitea API -``` - -### Server Entry Point - -**File:** `mcp-servers/gitea/mcp_server/server.py` - -```python -""" -MCP Server entry point for Gitea integration. -""" -import asyncio -import logging -import json -from mcp.server import Server -from mcp.server.stdio import stdio_server -from mcp.types import Tool, TextContent - -from .config import GiteaConfig -from .gitea_client import GiteaClient -from .tools.issues import IssueTools -from .tools.labels import LabelTools - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -class GiteaMCPServer: - """MCP Server for Gitea integration""" - - def __init__(self): - self.server = Server("gitea-mcp") - self.config = None - self.client = None - self.issue_tools = None - self.label_tools = None - - async def initialize(self): - """Initialize server and load configuration""" - try: - config_loader = GiteaConfig() - self.config = config_loader.load() - - self.client = GiteaClient() - self.issue_tools = IssueTools(self.client) - self.label_tools = LabelTools(self.client) - - logger.info(f"Gitea MCP Server initialized in {self.config['mode']} mode") - except Exception as e: - logger.error(f"Failed to initialize: {e}") - raise - - def setup_tools(self): - """Register all available tools with the MCP server""" - - @self.server.list_tools() - async def list_tools() -> list[Tool]: - """Return list of available tools""" - return [ - Tool( - name="list_issues", - description="List issues from Gitea repository", - inputSchema={ - "type": "object", - "properties": { - "state": { - "type": "string", - "enum": ["open", "closed", "all"], - "default": "open" - }, - "labels": { - "type": "array", - "items": {"type": "string"} - }, - "repo": {"type": "string"} - } - } - ), - Tool( - name="get_issue", - description="Get specific issue details", - inputSchema={ - "type": "object", - "properties": { - "issue_number": {"type": "integer"}, - "repo": {"type": "string"} - }, - "required": ["issue_number"] - } - ), - Tool( - name="create_issue", - description="Create a new issue in Gitea", - inputSchema={ - "type": "object", - "properties": { - "title": {"type": "string"}, - "body": {"type": "string"}, - "labels": { - "type": "array", - "items": {"type": "string"} - }, - "repo": {"type": "string"} - }, - "required": ["title", "body"] - } - ), - Tool( - name="update_issue", - description="Update existing issue", - inputSchema={ - "type": "object", - "properties": { - "issue_number": {"type": "integer"}, - "title": {"type": "string"}, - "body": {"type": "string"}, - "state": { - "type": "string", - "enum": ["open", "closed"] - }, - "labels": { - "type": "array", - "items": {"type": "string"} - }, - "repo": {"type": "string"} - }, - "required": ["issue_number"] - } - ), - Tool( - name="add_comment", - description="Add comment to issue", - inputSchema={ - "type": "object", - "properties": { - "issue_number": {"type": "integer"}, - "comment": {"type": "string"}, - "repo": {"type": "string"} - }, - "required": ["issue_number", "comment"] - } - ), - Tool( - name="get_labels", - description="Get all available labels (org + repo)", - inputSchema={ - "type": "object", - "properties": { - "repo": {"type": "string"} - } - } - ), - Tool( - name="suggest_labels", - description="Analyze context and suggest appropriate labels", - inputSchema={ - "type": "object", - "properties": { - "context": {"type": "string"} - }, - "required": ["context"] - } - ), - Tool( - name="aggregate_issues", - description="Fetch issues across all repositories (PMO mode)", - inputSchema={ - "type": "object", - "properties": { - "state": { - "type": "string", - "enum": ["open", "closed", "all"], - "default": "open" - }, - "labels": { - "type": "array", - "items": {"type": "string"} - } - } - } - ) - ] - - @self.server.call_tool() - async def call_tool(name: str, arguments: dict) -> list[TextContent]: - """Handle tool invocation""" - try: - # Route to appropriate tool handler - if name == "list_issues": - result = await self.issue_tools.list_issues(**arguments) - elif name == "get_issue": - result = await self.issue_tools.get_issue(**arguments) - elif name == "create_issue": - result = await self.issue_tools.create_issue(**arguments) - elif name == "update_issue": - result = await self.issue_tools.update_issue(**arguments) - elif name == "add_comment": - result = await self.issue_tools.add_comment(**arguments) - elif name == "get_labels": - result = await self.label_tools.get_labels(**arguments) - elif name == "suggest_labels": - result = await self.label_tools.suggest_labels(**arguments) - elif name == "aggregate_issues": - result = await self.issue_tools.aggregate_issues(**arguments) - else: - raise ValueError(f"Unknown tool: {name}") - - return [TextContent( - type="text", - text=json.dumps(result, indent=2) - )] - - except Exception as e: - logger.error(f"Tool {name} failed: {e}") - return [TextContent( - type="text", - text=f"Error: {str(e)}" - )] - - async def run(self): - """Run the MCP server""" - await self.initialize() - self.setup_tools() - - async with stdio_server() as (read_stream, write_stream): - await self.server.run( - read_stream, - write_stream, - self.server.create_initialization_options() - ) - - -async def main(): - """Main entry point""" - server = GiteaMCPServer() - await server.run() - - -if __name__ == "__main__": - asyncio.run(main()) -``` - -### Tool Implementation with Async Wrappers - -Since the Gitea client uses `requests` (synchronous), but MCP tools must be async: - -```python -# mcp-servers/gitea/mcp_server/tools/issues.py -import asyncio - -class IssueTools: - def __init__(self, gitea_client): - self.gitea = gitea_client - - async def list_issues(self, state='open', labels=None, repo=None): - """ - List issues from repository. - - Wraps sync Gitea client method in executor for async compatibility. - """ - loop = asyncio.get_event_loop() - return await loop.run_in_executor( - None, - self.gitea.list_issues, - state, - labels, - repo - ) - - async def create_issue(self, title, body, labels=None, repo=None): - """Create new issue""" - loop = asyncio.get_event_loop() - return await loop.run_in_executor( - None, - self.gitea.create_issue, - title, - body, - labels, - repo - ) - - # Other methods follow same pattern -``` - -### Branch Detection in MCP Tools - -Implement branch-aware security at the MCP level: - -```python -# mcp-servers/gitea/mcp_server/tools/issues.py -import subprocess - -class IssueTools: - def _get_current_branch(self) -> str: - """Get current git branch""" - try: - result = subprocess.run( - ['git', 'rev-parse', '--abbrev-ref', 'HEAD'], - capture_output=True, - text=True, - check=True - ) - return result.stdout.strip() - except subprocess.CalledProcessError: - return "unknown" - - def _check_branch_permissions(self, operation: str) -> bool: - """Check if operation is allowed on current branch""" - branch = self._get_current_branch() - - # Production branches (read-only except incidents) - if branch in ['main', 'master'] or branch.startswith('prod/'): - return operation in ['list_issues', 'get_issue', 'get_labels'] - - # Staging branches (read-only for code) - if branch == 'staging' or branch.startswith('stage/'): - return operation in ['list_issues', 'get_issue', 'get_labels', 'create_issue'] - - # Development branches (full access) - if branch in ['development', 'develop'] or branch.startswith(('feat/', 'feature/', 'dev/')): - return True - - # Unknown branch - be restrictive - return False - - async def create_issue(self, title, body, labels=None, repo=None): - """Create issue with branch check""" - if not self._check_branch_permissions('create_issue'): - branch = self._get_current_branch() - raise PermissionError( - f"Cannot create issues on branch '{branch}'. " - f"Switch to a development branch to create issues." - ) - - loop = asyncio.get_event_loop() - return await loop.run_in_executor( - None, - self.gitea.create_issue, - title, - body, - labels, - repo - ) -``` - -### Testing the MCP Server - -**Manual testing:** -```bash -cd mcp-servers/gitea -source .venv/bin/activate -python -m mcp_server.server -``` - -**Unit tests with mocks:** -```python -# tests/test_server.py -import pytest -from unittest.mock import Mock, patch - -@pytest.mark.asyncio -async def test_server_initialization(): - """Test server initializes correctly""" - from mcp_server.server import GiteaMCPServer - - with patch('mcp_server.server.GiteaClient'): - server = GiteaMCPServer() - await server.initialize() - - assert server.client is not None - assert server.config is not None -``` - -**Integration tests with real API:** -```python -# tests/test_integration.py -import pytest - -@pytest.mark.integration -@pytest.mark.asyncio -async def test_list_issues_real_api(): - """Test against real Gitea instance""" - from mcp_server.server import GiteaMCPServer - - server = GiteaMCPServer() - await server.initialize() - - result = await server.issue_tools.list_issues(state='open') - assert isinstance(result, list) -``` - -**Run tests:** -```bash -# Unit tests only (with mocks) -pytest tests/ -m "not integration" - -# Integration tests (requires Gitea access) -pytest tests/ -m integration - -# All tests -pytest tests/ -``` - ---- - -## Label Taxonomy System - -### Dynamic Label System - -The label taxonomy is **fetched dynamically from Gitea** at runtime. The current system has 44 labels: - -**Organization Labels (28):** -- Agent/2 -- Complexity/3 -- Efforts/5 -- Priority/4 -- Risk/3 -- Source/4 -- Type/6 (includes Type/Bug, Type/Feature, Type/Refactor, Type/Documentation, Type/Test, Type/Chore) - -**Repository Labels (16):** -- Component/9 (Backend, Frontend, API, Database, Auth, Deploy, Testing, Docs, Infra) -- Tech/7 (Python, JavaScript, Docker, PostgreSQL, Redis, Vue, FastAPI) - -**Note:** Label count and composition may change. The `/labels-sync` command fetches the latest labels from Gitea and updates suggestion logic accordingly. - -### Label Suggestion Logic - -```python -# mcp-servers/gitea/mcp_server/tools/labels.py -from typing import List, Dict -import re - -class LabelTools: - def __init__(self, gitea_client): - self.gitea = gitea_client - - async def get_labels(self, repo: str = None) -> List[Dict]: - """Get all labels (org + repo)""" - org_labels = self.gitea.get_org_labels() - - if repo or self.gitea.repo: - target_repo = repo or self.gitea.repo - repo_labels = self.gitea.get_labels(target_repo) - return org_labels + repo_labels - - return org_labels - - async def suggest_labels(self, context: str) -> List[str]: - """ - Analyze context and suggest appropriate labels. - - Args: - context: Issue title + description or sprint context - """ - suggested = [] - context_lower = context.lower() - - # Type detection (exclusive - only one) - if any(word in context_lower for word in ['bug', 'error', 'fix', 'broken']): - suggested.append('Type/Bug') - elif any(word in context_lower for word in ['refactor', 'extract', 'restructure', 'architecture', 'service extraction']): - suggested.append('Type/Refactor') - elif any(word in context_lower for word in ['feature', 'add', 'implement', 'new']): - suggested.append('Type/Feature') - elif any(word in context_lower for word in ['docs', 'documentation', 'readme']): - suggested.append('Type/Documentation') - elif any(word in context_lower for word in ['test', 'testing', 'spec']): - suggested.append('Type/Test') - elif any(word in context_lower for word in ['chore', 'maintenance', 'update']): - suggested.append('Type/Chore') - - # Priority detection - if any(word in context_lower for word in ['critical', 'urgent', 'blocker', 'blocking']): - suggested.append('Priority/Critical') - elif any(word in context_lower for word in ['high', 'important', 'asap']): - suggested.append('Priority/High') - elif any(word in context_lower for word in ['low', 'nice-to-have', 'optional']): - suggested.append('Priority/Low') - else: - suggested.append('Priority/Medium') - - # Component detection (based on keywords) - component_keywords = { - 'Component/Backend': ['backend', 'server', 'api', 'database', 'service'], - 'Component/Frontend': ['frontend', 'ui', 'interface', 'react', 'vue'], - 'Component/API': ['api', 'endpoint', 'rest', 'graphql'], - 'Component/Database': ['database', 'db', 'sql', 'migration', 'schema'], - 'Component/Auth': ['auth', 'authentication', 'login', 'oauth', 'token'], - 'Component/Deploy': ['deploy', 'deployment', 'docker', 'kubernetes'], - 'Component/Testing': ['test', 'testing', 'spec', 'jest', 'pytest'], - 'Component/Docs': ['docs', 'documentation', 'readme', 'guide'] - } - - for label, keywords in component_keywords.items(): - if any(keyword in context_lower for keyword in keywords): - suggested.append(label) - - # Source detection (based on git branch or context) - if 'development' in context_lower or 'dev/' in context_lower: - suggested.append('Source/Development') - elif 'staging' in context_lower: - suggested.append('Source/Staging') - elif 'production' in context_lower or 'prod' in context_lower: - suggested.append('Source/Production') - - return suggested -``` - ---- - -## MCP Tools - -### Issue Tools - -```python -# mcp-servers/gitea/mcp_server/tools/issues.py -class IssueTools: - def __init__(self, gitea_client): - self.gitea = gitea_client - - async def list_issues(self, state='open', labels=None, repo=None): - """List issues in repository""" - return self.gitea.list_issues(state=state, labels=labels, repo=repo) - - async def get_issue(self, issue_number, repo=None): - """Get specific issue details""" - return self.gitea.get_issue(issue_number, repo=repo) - - async def create_issue(self, title, body, labels=None, repo=None): - """Create new issue""" - return self.gitea.create_issue(title, body, labels=labels, repo=repo) - - async def update_issue(self, issue_number, title=None, body=None, state=None, labels=None, repo=None): - """Update existing issue""" - return self.gitea.update_issue( - issue_number, - title=title, - body=body, - state=state, - labels=labels, - repo=repo - ) - - async def add_comment(self, issue_number, comment, repo=None): - """Add comment to issue""" - return self.gitea.add_comment(issue_number, comment, repo=repo) - - # PMO-specific - async def aggregate_issues(self, state='open', labels=None): - """Aggregate issues across all repositories (PMO mode)""" - if self.gitea.mode != 'company': - raise ValueError("aggregate_issues only available in company mode") - return self.gitea.aggregate_issues(state=state, labels=labels) -``` - ---- - -## Testing - -### Unit Tests - -```python -# tests/test_config.py -import pytest -from pathlib import Path -from mcp_server.config import GiteaConfig - -def test_load_system_config(tmp_path, monkeypatch): - """Test loading system-level configuration""" - # Mock home directory - config_dir = tmp_path / '.config' / 'claude' - config_dir.mkdir(parents=True) - - config_file = config_dir / 'gitea.env' - config_file.write_text( - "GITEA_API_URL=https://test.com/api/v1\n" - "GITEA_API_TOKEN=test_token\n" - "GITEA_OWNER=test_owner\n" - ) - - monkeypatch.setenv('HOME', str(tmp_path)) - - config = GiteaConfig() - result = config.load() - - assert result['api_url'] == 'https://test.com/api/v1' - assert result['api_token'] == 'test_token' - assert result['owner'] == 'test_owner' - assert result['mode'] == 'company' # No repo specified - -def test_project_config_override(tmp_path, monkeypatch): - """Test that project config overrides system config""" - # Set up system config - system_config_dir = tmp_path / '.config' / 'claude' - system_config_dir.mkdir(parents=True) - - system_config = system_config_dir / 'gitea.env' - system_config.write_text( - "GITEA_API_URL=https://test.com/api/v1\n" - "GITEA_API_TOKEN=test_token\n" - "GITEA_OWNER=test_owner\n" - ) - - # Set up project config - project_dir = tmp_path / 'project' - project_dir.mkdir() - - project_config = project_dir / '.env' - project_config.write_text("GITEA_REPO=test_repo\n") - - monkeypatch.setenv('HOME', str(tmp_path)) - monkeypatch.chdir(project_dir) - - config = GiteaConfig() - result = config.load() - - assert result['repo'] == 'test_repo' - assert result['mode'] == 'project' - -def test_missing_required_config(): - """Test error handling for missing configuration""" - with pytest.raises(FileNotFoundError): - config = GiteaConfig() - config.load() -``` - -### Integration Tests - -```python -# tests/test_gitea_client.py -import pytest -from mcp_server.gitea_client import GiteaClient - -@pytest.fixture -def gitea_client(): - """Fixture providing configured Gitea client""" - return GiteaClient() - -def test_list_issues(gitea_client): - """Test listing issues from Gitea""" - issues = gitea_client.list_issues(state='open') - assert isinstance(issues, list) - -def test_create_issue(gitea_client): - """Test creating an issue in Gitea""" - issue = gitea_client.create_issue( - title="Test Issue", - body="Test body", - labels=["Type/Bug", "Priority/Low"] - ) - assert issue['title'] == "Test Issue" - assert any(label['name'] == "Type/Bug" for label in issue['labels']) - -def test_get_labels(gitea_client): - """Test fetching labels""" - labels = gitea_client.get_labels() - assert isinstance(labels, list) - assert len(labels) > 0 - -def test_pmo_mode_aggregate_issues(): - """Test PMO mode aggregation (no repo specified)""" - # Set up client without repo - client = GiteaClient() # Should detect company mode - - if client.mode == 'company': - aggregated = client.aggregate_issues(state='open') - assert isinstance(aggregated, dict) - # Each key should be a repo name - for repo_name, issues in aggregated.items(): - assert isinstance(issues, list) -``` - -### Running Tests - -```bash -# Activate virtual environment -source .venv/bin/activate - -# Run all tests -pytest - -# Run with coverage -pytest --cov=mcp_server --cov-report=html - -# Run specific test file -pytest tests/test_config.py - -# Run with verbose output -pytest -v -``` - ---- - -## Performance Optimization - -### Caching - -```python -from functools import lru_cache - -@lru_cache(maxsize=128) -def get_labels_cached(self, repo: str) -> List[Dict]: - """Cached label retrieval to reduce API calls""" - return self.get_labels(repo) -``` - -### Retry Logic - -```python -import time -from typing import Callable - -def retry_on_failure(max_retries=3, delay=1): - """Decorator for retrying failed API calls""" - def decorator(func: Callable): - def wrapper(*args, **kwargs): - for attempt in range(max_retries): - try: - return func(*args, **kwargs) - except requests.exceptions.RequestException as e: - if attempt == max_retries - 1: - raise - time.sleep(delay * (attempt + 1)) - return wrapper - return decorator - -@retry_on_failure(max_retries=3) -def list_issues(self, state='open', labels=None, repo=None): - """List issues with automatic retry""" - # Implementation -``` - ---- - -## Troubleshooting - -### Common Issues - -**Issue:** Module not found -```bash -# Solution: Ensure PYTHONPATH is set in .mcp.json -"env": { - "PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/gitea" -} -``` - -**Issue:** Configuration not loading -```bash -# Solution: Check file permissions -chmod 600 ~/.config/claude/gitea.env - -# Verify file exists -cat ~/.config/claude/gitea.env -``` - -**Issue:** API authentication failing -```bash -# Solution: Test token manually -curl -H "Authorization: token YOUR_TOKEN" \ - https://your-gitea.com/api/v1/user -``` - -**Issue:** PMO mode not working -```bash -# Solution: Ensure GITEA_REPO is NOT set -# Check environment variables -env | grep GITEA -``` - ---- - -## Security - -### Best Practices - -1. **Token Storage:** - - Store tokens in `~/.config/claude/gitea.env` - - Set file permissions to 600 - - Never commit tokens to git - -2. **Input Validation:** - - Validate all user input before API calls - - Sanitize issue titles and descriptions - - Prevent injection attacks - -3. **Error Handling:** - - Don't leak tokens in error messages - - Log errors without sensitive data - - Provide user-friendly error messages - -4. **API Rate Limiting:** - - Implement exponential backoff - - Cache frequently accessed data - - Batch requests where possible - ---- - -## Next Steps - -1. **Set up system configuration** -2. **Create virtual environment** -3. **Install dependencies** -4. **Run tests against actual Gitea instance** -5. **Integrate with projman plugin** diff --git a/docs/references/MCP-WIKIJS.md b/docs/references/MCP-WIKIJS.md deleted file mode 100644 index 5ba9e9e..0000000 --- a/docs/references/MCP-WIKIJS.md +++ /dev/null @@ -1,1507 +0,0 @@ -# Wiki.js MCP Server Reference - -## Overview - -The Wiki.js MCP Server provides integration with Wiki.js for documentation management, lessons learned capture, and knowledge base operations. It's shared by both `projman` and `projman-pmo` plugins, detecting its operating mode based on environment variables. - -**Location:** `mcp-servers/wikijs/` (repository root) - -**Key Features:** -- Documentation page management (CRUD) -- Lessons learned capture and search -- Tag-based organization -- GraphQL API integration -- Mode detection (project-scoped vs company-wide) -- Hybrid configuration (system + project level) -- Python 3.11+ with async/await - ---- - -## Architecture - -### Mode Detection - -The MCP server operates in two modes based on environment variables: - -**Project Mode (projman):** -- When `WIKIJS_PROJECT` is present -- Operates within project path: `/your-org/projects/my-project` -- Used by projman plugin - -**Company Mode (pmo):** -- When `WIKIJS_PROJECT` is absent -- Operates on entire namespace: `/your-org` -- Used by projman-pmo plugin - -```python -# mcp-servers/wikijs/mcp_server/config.py -def load(self): - # ... load configs ... - - self.base_path = os.getenv('WIKIJS_BASE_PATH') # /your-org - self.project_path = os.getenv('WIKIJS_PROJECT') # projects/my-project (optional) - - # Compose full path - if self.project_path: - self.full_path = f"{self.base_path}/{self.project_path}" - self.mode = 'project' - else: - self.full_path = self.base_path - self.mode = 'company' - - return { - 'api_url': self.api_url, - 'api_token': self.api_token, - 'base_path': self.base_path, - 'project_path': self.project_path, - 'full_path': self.full_path, - 'mode': self.mode - } -``` - ---- - -## Wiki.js Structure - -### Company-Wide Organization - -``` -Wiki.js: https://wiki.your-company.com -└── /your-org/ # Base path - ├── projects/ # Project-specific documentation - │ ├── my-project/ - │ │ ├── lessons-learned/ - │ │ │ ├── sprints/ - │ │ │ │ ├── sprint-01-auth.md - │ │ │ │ ├── sprint-02-api.md - │ │ │ │ └── ... - │ │ │ ├── patterns/ - │ │ │ │ ├── service-extraction.md - │ │ │ │ └── database-migration.md - │ │ │ └── INDEX.md - │ │ └── documentation/ - │ │ ├── architecture/ - │ │ ├── api/ - │ │ └── deployment/ - │ ├── my-project-site/ - │ │ ├── lessons-learned/ - │ │ └── documentation/ - │ ├── intuit-engine/ - │ │ ├── lessons-learned/ - │ │ └── documentation/ - │ └── company-site/ - │ ├── lessons-learned/ - │ └── documentation/ - ├── company/ # Company-wide documentation - │ ├── processes/ - │ │ ├── onboarding.md - │ │ ├── deployment.md - │ │ └── code-review.md - │ ├── standards/ - │ │ ├── python-style-guide.md - │ │ ├── api-design.md - │ │ └── security.md - │ └── tools/ - │ ├── gitea-guide.md - │ ├── wikijs-guide.md - │ └── claude-plugins.md - └── shared/ # Cross-project resources - ├── architecture-patterns/ - │ ├── microservices.md - │ ├── api-gateway.md - │ └── database-per-service.md - ├── best-practices/ - │ ├── error-handling.md - │ ├── logging.md - │ └── testing.md - └── tech-stack/ - ├── python-ecosystem.md - ├── docker.md - └── ci-cd.md -``` - -### Path Resolution - -**Project Mode (projman):** -- Full path = `{WIKIJS_BASE_PATH}/{WIKIJS_PROJECT}` -- Example: `/your-org/projects/my-project` - -**Company Mode (pmo):** -- Full path = `{WIKIJS_BASE_PATH}` -- Example: `/your-org` - ---- - -## Configuration - -### System-Level Configuration - -**File:** `~/.config/claude/wikijs.env` - -```bash -WIKIJS_API_URL=https://wiki.your-company.com/graphql -WIKIJS_API_TOKEN=your_wikijs_token -WIKIJS_BASE_PATH=/your-org -``` - -**Generating Wiki.js API Token:** - -1. Log into Wiki.js: https://wiki.your-company.com -2. Navigate to: **User Menu (top-right)** → **Administration** -3. In the sidebar, go to: **API Access** -4. Click **Create New Token** -5. Token configuration: - - **Name:** `claude-code-mcp` - - **Expiration:** Never (or set appropriate expiration) - - **Required Permissions:** - - ✅ Read pages - - ✅ Create pages - - ✅ Update pages - - ✅ Manage tags - - ✅ Search -6. Click **Generate** -7. **Important:** Copy the token immediately (shown only once) -8. Add to configuration file (see setup below) - -**Setup:** -```bash -# Create config directory -mkdir -p ~/.config/claude - -# Create wikijs.env -cat > ~/.config/claude/wikijs.env << EOF -WIKIJS_API_URL=https://wiki.your-company.com/graphql -WIKIJS_API_TOKEN=your_token_here -WIKIJS_BASE_PATH=/your-org -EOF - -# Secure the file (important!) -chmod 600 ~/.config/claude/wikijs.env - -# Verify setup -cat ~/.config/claude/wikijs.env -``` - -### Project-Level Configuration - -**File:** `project-root/.env` - -```bash -# Wiki.js project path (relative to base path) -WIKIJS_PROJECT=projects/my-project -``` - -**Setup:** -```bash -# In each project root -echo "WIKIJS_PROJECT=projects/my-project" >> .env - -# Add to .gitignore (if not already) -echo ".env" >> .gitignore -``` - -### Configuration Loading Strategy - -```python -# mcp-servers/wikijs/mcp_server/config.py -from pathlib import Path -from dotenv import load_dotenv -import os -from typing import Dict, Optional - -class WikiJSConfig: - """Hybrid configuration loader for Wiki.js""" - - def __init__(self): - self.api_url: Optional[str] = None - self.api_token: Optional[str] = None - self.base_path: Optional[str] = None - self.project_path: Optional[str] = None - self.full_path: Optional[str] = None - self.mode: str = 'project' - - def load(self) -> Dict[str, str]: - """ - Load Wiki.js configuration from system and project levels. - Composes full path from base_path + project_path. - """ - # Load system config - system_config = Path.home() / '.config' / 'claude' / 'wikijs.env' - if system_config.exists(): - load_dotenv(system_config) - else: - raise FileNotFoundError( - f"System config not found: {system_config}\n" - "Create it with: cat > ~/.config/claude/wikijs.env" - ) - - # Load project config (if exists, optional for PMO) - project_config = Path.cwd() / '.env' - if project_config.exists(): - load_dotenv(project_config, override=True) - - # Extract values - self.api_url = os.getenv('WIKIJS_API_URL') - self.api_token = os.getenv('WIKIJS_API_TOKEN') - self.base_path = os.getenv('WIKIJS_BASE_PATH') # /your-org - self.project_path = os.getenv('WIKIJS_PROJECT') # projects/my-project (optional) - - # Compose full path - if self.project_path: - self.full_path = f"{self.base_path}/{self.project_path}" - self.mode = 'project' - else: - # PMO mode - entire company namespace - self.full_path = self.base_path - self.mode = 'company' - - # Validate required variables - self._validate() - - return { - 'api_url': self.api_url, - 'api_token': self.api_token, - 'base_path': self.base_path, - 'project_path': self.project_path, - 'full_path': self.full_path, - 'mode': self.mode - } - - def _validate(self) -> None: - """Validate that required configuration is present""" - required = { - 'WIKIJS_API_URL': self.api_url, - 'WIKIJS_API_TOKEN': self.api_token, - 'WIKIJS_BASE_PATH': self.base_path - } - - missing = [key for key, value in required.items() if not value] - - if missing: - raise ValueError( - f"Missing required configuration: {', '.join(missing)}\n" - "Check your ~/.config/claude/wikijs.env file" - ) -``` - ---- - -## Directory Structure - -``` -mcp-servers/wikijs/ -├── .venv/ # Python virtual environment -├── requirements.txt # Python dependencies -├── .env.example # Configuration template -├── mcp_server/ -│ ├── __init__.py -│ ├── server.py # MCP server entry point -│ ├── config.py # Configuration loader -│ ├── wikijs_client.py # GraphQL client -│ └── tools/ -│ ├── __init__.py -│ ├── pages.py # Page CRUD tools -│ ├── lessons_learned.py # Lessons learned tools -│ └── documentation.py # Documentation tools -└── tests/ - ├── test_config.py - ├── test_wikijs_client.py - └── test_tools.py -``` - ---- - -## Dependencies - -**File:** `mcp-servers/wikijs/requirements.txt` - -```txt -mcp>=0.9.0 # MCP SDK from Anthropic -python-dotenv>=1.0.0 # Environment variable loading -gql>=3.4.0 # GraphQL client for Wiki.js -aiohttp>=3.9.0 # Async HTTP -pydantic>=2.5.0 # Data validation -pytest>=7.4.3 # Testing framework -pytest-asyncio>=0.23.0 # Async testing support -``` - -**Python Version:** 3.10+ required - -**Installation:** -```bash -cd mcp-servers/wikijs -python -m venv .venv -source .venv/bin/activate # Linux/Mac -# or .venv\Scripts\activate # Windows -pip install -r requirements.txt -``` - ---- - -## Wiki.js GraphQL Client - -```python -# mcp-servers/wikijs/mcp_server/wikijs_client.py -from gql import gql, Client -from gql.transport.aiohttp import AIOHTTPTransport -from typing import List, Dict, Optional -from .config import WikiJSConfig - -class WikiJSClient: - """Client for interacting with Wiki.js GraphQL API""" - - def __init__(self): - config = WikiJSConfig() - config_dict = config.load() - - self.api_url = config_dict['api_url'] - self.api_token = config_dict['api_token'] - self.base_path = config_dict['base_path'] - self.project_path = config_dict.get('project_path') - self.full_path = config_dict['full_path'] - self.mode = config_dict['mode'] - - # Set up GraphQL client - transport = AIOHTTPTransport( - url=self.api_url, - headers={'Authorization': f'Bearer {self.api_token}'} - ) - self.client = Client( - transport=transport, - fetch_schema_from_transport=True - ) - - async def search_pages( - self, - query: str, - path: Optional[str] = None, - tags: Optional[List[str]] = None - ) -> List[Dict]: - """ - Search pages in Wiki.js within a specific path. - - Args: - query: Search query string - path: Optional path to search within (defaults to full_path) - tags: Optional list of tags to filter by - """ - search_path = path or self.full_path - - gql_query = gql(""" - query SearchPages($query: String!, $path: String) { - pages { - search(query: $query, path: $path) { - results { - id - path - title - description - tags - updatedAt - } - } - } - } - """) - - result = await self.client.execute( - gql_query, - variable_values={'query': query, 'path': search_path} - ) - - pages = result['pages']['search']['results'] - - # Filter by tags if specified - if tags: - pages = [ - p for p in pages - if any(tag in p['tags'] for tag in tags) - ] - - return pages - - async def get_page(self, path: str) -> Dict: - """Fetch a specific page by path""" - gql_query = gql(""" - query GetPage($path: String!) { - pages { - single(path: $path) { - id - path - title - description - content - tags - createdAt - updatedAt - } - } - } - """) - - result = await self.client.execute( - gql_query, - variable_values={'path': path} - ) - return result['pages']['single'] - - async def create_page( - self, - path: str, - title: str, - content: str, - tags: List[str], - description: str = "" - ) -> Dict: - """ - Create a new page in Wiki.js. - - Args: - path: Full path for the page - title: Page title - content: Page content (markdown) - tags: List of tags - description: Optional description - """ - gql_mutation = gql(""" - mutation CreatePage( - $path: String!, - $title: String!, - $content: String!, - $tags: [String]!, - $description: String - ) { - pages { - create( - path: $path, - title: $title, - content: $content, - tags: $tags, - description: $description, - isPublished: true, - editor: "markdown" - ) { - responseResult { - succeeded - errorCode - message - } - page { - id - path - title - } - } - } - } - """) - - result = await self.client.execute( - gql_mutation, - variable_values={ - 'path': path, - 'title': title, - 'content': content, - 'tags': tags, - 'description': description - } - ) - return result['pages']['create'] - - async def update_page( - self, - page_id: int, - content: str, - tags: Optional[List[str]] = None - ) -> Dict: - """Update existing page""" - variables = { - 'id': page_id, - 'content': content - } - - if tags is not None: - variables['tags'] = tags - - gql_mutation = gql(""" - mutation UpdatePage( - $id: Int!, - $content: String!, - $tags: [String] - ) { - pages { - update( - id: $id, - content: $content, - tags: $tags - ) { - responseResult { - succeeded - errorCode - message - } - } - } - } - """) - - result = await self.client.execute(gql_mutation, variable_values=variables) - return result['pages']['update'] - - async def list_pages(self, path: str) -> List[Dict]: - """List all pages within a path""" - gql_query = gql(""" - query ListPages($path: String!) { - pages { - list(path: $path, orderBy: TITLE) { - id - path - title - description - tags - updatedAt - } - } - } - """) - - result = await self.client.execute( - gql_query, - variable_values={'path': path} - ) - return result['pages']['list'] - - # Lessons Learned Specific Methods - - async def create_lesson( - self, - sprint_name: str, - lesson_content: str, - tags: List[str] - ) -> Dict: - """ - Create a lessons learned document for a sprint. - - Args: - sprint_name: Sprint identifier (e.g., "sprint-16-intuit-engine") - lesson_content: Full lesson markdown content - tags: Tags for categorization - """ - # Compose path within project's lessons-learned/sprints/ - lesson_path = f"{self.full_path}/lessons-learned/sprints/{sprint_name}" - title = f"Sprint {sprint_name.split('-')[1]}: {' '.join(sprint_name.split('-')[2:]).title()}" - - return await self.create_page( - path=lesson_path, - title=title, - content=lesson_content, - tags=tags, - description=f"Lessons learned from {sprint_name}" - ) - - async def search_lessons( - self, - query: str, - tags: Optional[List[str]] = None - ) -> List[Dict]: - """ - Search lessons learned within the current project. - - Args: - query: Search keywords - tags: Optional tags to filter by - """ - lessons_path = f"{self.full_path}/lessons-learned" - return await self.search_pages( - query=query, - path=lessons_path, - tags=tags - ) - - async def update_index( - self, - sprint_name: str, - tags: List[str] - ) -> Dict: - """ - Update lessons learned INDEX.md with new sprint entry. - - Args: - sprint_name: Sprint identifier - tags: Tags for categorization - """ - index_path = f"{self.full_path}/lessons-learned/INDEX.md" - - # Get current index - try: - index_page = await self.get_page(index_path) - current_content = index_page['content'] - page_id = index_page['id'] - except: - # Index doesn't exist, create it - current_content = "# Lessons Learned Index\n\n## By Sprint\n\n## By Tags\n" - create_result = await self.create_page( - path=index_path, - title="Lessons Learned Index", - content=current_content, - tags=["index", "lessons-learned"], - description="Index of all lessons learned" - ) - page_id = create_result['page']['id'] - - # Add new entry - sprint_link = f"- [Sprint {sprint_name}](sprints/{sprint_name}) {' '.join(['#' + tag for tag in tags])}\n" - - # Insert after "## By Sprint" header - lines = current_content.split('\n') - insert_index = None - for i, line in enumerate(lines): - if line.startswith('## By Sprint'): - insert_index = i + 1 - break - - if insert_index: - lines.insert(insert_index, sprint_link) - new_content = '\n'.join(lines) - else: - new_content = current_content + "\n" + sprint_link - - # Update index - return await self.update_page(page_id, new_content) - - # PMO Multi-Project Methods - - async def search_all_projects( - self, - query: str, - tags: Optional[List[str]] = None - ) -> Dict[str, List[Dict]]: - """ - Search lessons across all projects (PMO mode). - Returns results grouped by project. - """ - all_projects_path = f"{self.base_path}/projects" - results = await self.search_pages( - query=query, - path=all_projects_path, - tags=tags - ) - - # Group by project - by_project = {} - for result in results: - # Extract project name from path - # e.g., "/your-org/projects/my-project/..." -> "my-project" - path_parts = result['path'].split('/') - if len(path_parts) >= 4: - project = path_parts[3] - if project not in by_project: - by_project[project] = [] - by_project[project].append(result) - - return by_project - - async def get_shared_docs(self, category: str) -> List[Dict]: - """ - Access company-wide shared documentation. - - Args: - category: Category within shared/ (e.g., "architecture-patterns") - """ - shared_path = f"{self.base_path}/shared/{category}" - return await self.list_pages(path=shared_path) - - async def create_pattern_doc( - self, - pattern_name: str, - content: str, - tags: List[str] - ) -> Dict: - """ - Create a pattern document in shared/architecture-patterns. - - Args: - pattern_name: Pattern identifier (e.g., "service-extraction") - content: Pattern documentation (markdown) - tags: Tags for categorization - """ - pattern_path = f"{self.base_path}/shared/architecture-patterns/{pattern_name}" - title = pattern_name.replace('-', ' ').title() - - return await self.create_page( - path=pattern_path, - title=title, - content=content, - tags=tags, - description=f"Architecture pattern: {title}" - ) -``` - ---- - -## MCP Tools - -### Page Management Tools - -```python -# mcp-servers/wikijs/mcp_server/tools/pages.py -class PageTools: - def __init__(self, wikijs_client): - self.wikijs = wikijs_client - - async def search_pages(self, query, path=None, tags=None): - """Search Wiki.js pages""" - return await self.wikijs.search_pages(query, path, tags) - - async def get_page(self, path): - """Get specific page""" - return await self.wikijs.get_page(path) - - async def create_page(self, path, title, content, tags): - """Create new page""" - return await self.wikijs.create_page(path, title, content, tags) - - async def update_page(self, page_id, content, tags=None): - """Update existing page""" - return await self.wikijs.update_page(page_id, content, tags) - - async def list_pages(self, path): - """List all pages within a path""" - return await self.wikijs.list_pages(path) -``` - -### Lessons Learned Tools - -```python -# mcp-servers/wikijs/mcp_server/tools/lessons_learned.py -class LessonsLearnedTools: - def __init__(self, wikijs_client): - self.wikijs = wikijs_client - - async def create_lesson(self, sprint_name, content, tags): - """ - Create lessons learned document. - - Args: - sprint_name: Sprint identifier - content: Lesson content (markdown) - tags: Categorization tags - """ - result = await self.wikijs.create_lesson(sprint_name, content, tags) - - # Update index - await self.wikijs.update_index(sprint_name, tags) - - return result - - async def search_lessons(self, query, tags=None): - """ - Search past lessons within current project. - - Args: - query: Search keywords - tags: Optional tag filters - """ - return await self.wikijs.search_lessons(query, tags) - - async def search_all_projects(self, query, tags=None): - """ - Search lessons across all projects (PMO mode). - - Args: - query: Search keywords - tags: Optional tag filters - - Returns: - Dict keyed by project name - """ - if self.wikijs.mode != 'company': - raise ValueError("search_all_projects only available in company mode") - - return await self.wikijs.search_all_projects(query, tags) - - async def get_lessons_by_tag(self, tag): - """Retrieve all lessons with a specific tag""" - return await self.wikijs.search_lessons( - query="*", - tags=[tag] - ) -``` - -### Documentation Tools - -```python -# mcp-servers/wikijs/mcp_server/tools/documentation.py -class DocumentationTools: - def __init__(self, wikijs_client): - self.wikijs = wikijs_client - - async def create_architecture_doc(self, name, content, tags): - """Create architecture documentation""" - doc_path = f"{self.wikijs.full_path}/documentation/architecture/{name}" - return await self.wikijs.create_page( - path=doc_path, - title=name.replace('-', ' ').title(), - content=content, - tags=tags - ) - - async def create_api_doc(self, name, content, tags): - """Create API documentation""" - doc_path = f"{self.wikijs.full_path}/documentation/api/{name}" - return await self.wikijs.create_page( - path=doc_path, - title=name.replace('-', ' ').title(), - content=content, - tags=tags - ) - - async def get_shared_patterns(self): - """Get company-wide architecture patterns""" - return await self.wikijs.get_shared_docs("architecture-patterns") - - async def get_shared_best_practices(self): - """Get company-wide best practices""" - return await self.wikijs.get_shared_docs("best-practices") - - async def create_pattern(self, pattern_name, content, tags): - """ - Create shared architecture pattern (PMO mode). - - Args: - pattern_name: Pattern identifier - content: Pattern documentation - tags: Categorization tags - """ - if self.wikijs.mode != 'company': - raise ValueError("create_pattern only available in company mode") - - return await self.wikijs.create_pattern_doc(pattern_name, content, tags) -``` - ---- - -## Lessons Learned Workflow - -### Lesson Template - -```markdown -# Sprint [Number]: [Name] - Lessons Learned - -**Date:** [Date] -**Issue:** #[number] -**Sprint Duration:** [X weeks] - -## Summary - -Brief overview of what was accomplished and major outcomes. - -## What Went Wrong - -- **Issue 1:** Description and impact - - **Root Cause:** Why it happened - - **Prevention:** How to avoid in future - -- **Issue 2:** ... - -## What Worked Well - -- **Success 1:** What worked and why - - **Replication:** How to repeat this success - -- **Success 2:** ... - -## Claude Code Issues - -- **Loop 1:** Description of infinite loop or blocking issue - - **Trigger:** What caused it - - **Resolution:** How it was fixed - - **Prevention:** How to avoid - -## Architecture Insights - -- **Decision 1:** Architectural decision made - - **Rationale:** Why this approach - - **Trade-offs:** What was compromised - -- **Insight 1:** Technical learning - - **Application:** Where else this applies - -## Action Items - -- [ ] Task 1 -- [ ] Task 2 - -## Tags - -#service-extraction #api #refactoring #claude-code-loops -``` - -### Capture Flow - -``` -User: /sprint-close - -Agent: Let's capture lessons learned... - - What went wrong that we should avoid next time? -User: [Response] - -Agent: What decisions worked really well? -User: [Response] - -Agent: Were there any Claude Code issues that caused loops/blocks? -User: [Response] - -Agent: Any architectural insights for similar future work? -User: [Response] - -Agent: I'll create a lesson in Wiki.js: - Path: /your-org/projects/my-project/lessons-learned/sprints/sprint-16-intuit-engine - - Tags detected: - #service-extraction #api #refactoring #claude-code-loops - - Creating page in Wiki.js... ✅ - Updating INDEX.md... ✅ - - View at: https://wiki.your-company.com/your-org/projects/my-project/lessons-learned/sprints/sprint-16-intuit-engine -``` - ---- - -## Testing - -### Unit Tests - -```python -# tests/test_config.py -import pytest -from pathlib import Path -from mcp_server.config import WikiJSConfig - -def test_load_system_config(tmp_path, monkeypatch): - """Test loading system-level configuration""" - config_dir = tmp_path / '.config' / 'claude' - config_dir.mkdir(parents=True) - - config_file = config_dir / 'wikijs.env' - config_file.write_text( - "WIKIJS_API_URL=https://wiki.test.com/graphql\n" - "WIKIJS_API_TOKEN=test_token\n" - "WIKIJS_BASE_PATH=/test-base\n" - ) - - monkeypatch.setenv('HOME', str(tmp_path)) - - config = WikiJSConfig() - result = config.load() - - assert result['api_url'] == 'https://wiki.test.com/graphql' - assert result['api_token'] == 'test_token' - assert result['base_path'] == '/test-base' - assert result['mode'] == 'company' # No project specified - -def test_project_config_path_composition(tmp_path, monkeypatch): - """Test path composition with project config""" - system_config_dir = tmp_path / '.config' / 'claude' - system_config_dir.mkdir(parents=True) - - system_config = system_config_dir / 'wikijs.env' - system_config.write_text( - "WIKIJS_API_URL=https://wiki.test.com/graphql\n" - "WIKIJS_API_TOKEN=test_token\n" - "WIKIJS_BASE_PATH=/your-org\n" - ) - - project_dir = tmp_path / 'project' - project_dir.mkdir() - - project_config = project_dir / '.env' - project_config.write_text("WIKIJS_PROJECT=projects/my-project\n") - - monkeypatch.setenv('HOME', str(tmp_path)) - monkeypatch.chdir(project_dir) - - config = WikiJSConfig() - result = config.load() - - assert result['project_path'] == 'projects/my-project' - assert result['full_path'] == '/your-org/projects/my-project' - assert result['mode'] == 'project' -``` - -### Integration Tests - -```python -# tests/test_wikijs_client.py -import pytest -import asyncio -from mcp_server.wikijs_client import WikiJSClient - -@pytest.fixture -def wikijs_client(): - """Fixture providing configured Wiki.js client""" - return WikiJSClient() - -@pytest.mark.asyncio -async def test_search_pages(wikijs_client): - """Test searching pages in Wiki.js""" - results = await wikijs_client.search_pages(query="test") - assert isinstance(results, list) - -@pytest.mark.asyncio -async def test_create_lesson(wikijs_client): - """Test creating a lessons learned document""" - lesson = await wikijs_client.create_lesson( - sprint_name="sprint-99-test", - lesson_content="# Test Lesson\n\nTest content", - tags=["test", "sprint-99"] - ) - - assert lesson['responseResult']['succeeded'] - assert lesson['page']['title'].startswith("Sprint 99") - -@pytest.mark.asyncio -async def test_search_lessons(wikijs_client): - """Test searching lessons learned""" - results = await wikijs_client.search_lessons( - query="service extraction", - tags=["refactoring"] - ) - - assert isinstance(results, list) - for result in results: - assert "refactoring" in result['tags'] - -@pytest.mark.asyncio -async def test_pmo_search_all_projects(): - """Test PMO mode cross-project search""" - client = WikiJSClient() # Should detect company mode - - if client.mode == 'company': - results = await client.search_all_projects( - query="authentication", - tags=["security"] - ) - - assert isinstance(results, dict) - # Results should be grouped by project - for project_name, lessons in results.items(): - assert isinstance(lessons, list) -``` - -### Running Tests - -```bash -# Activate virtual environment -source .venv/bin/activate - -# Run all tests -pytest - -# Run async tests -pytest -v tests/test_wikijs_client.py - -# Run with coverage -pytest --cov=mcp_server --cov-report=html - -# Run specific test -pytest tests/test_config.py::test_project_config_path_composition -``` - ---- - -## Wiki.js Setup - -### Initial Structure Creation - -**Status:** Base structure `/your-org` **does not exist** and needs to be created during Phase 1.1b. - -**Setup Script:** Run this script during Phase 1.1b to create the base structure: - -**File:** `mcp-servers/wikijs/setup_wiki_structure.py` - -```python -#!/usr/bin/env python3 -""" -One-time setup script to create base Wiki.js structure. -Run during Phase 1.1b implementation. -""" -import asyncio -import sys -from mcp_server.wikijs_client import WikiJSClient - - -async def initialize_wiki_structure(): - """Create base Wiki.js structure for Your Organization""" - - print("Initializing Wiki.js base structure...") - print("=" * 60) - - try: - client = WikiJSClient() - print(f"✅ Connected to Wiki.js at {client.api_url}") - print(f" Base path: {client.base_path}") - print() - - except Exception as e: - print(f"❌ Failed to connect to Wiki.js: {e}") - print(" Check your ~/.config/claude/wikijs.env configuration") - sys.exit(1) - - # Base structure to create - base_pages = [ - { - 'path': 'your-org', - 'title': 'Your Organization', - 'content': '''# Your Organization Documentation - -Welcome to the Your Organization knowledge base. - -## Organization - -- **[Projects](your-org/projects)** - Project-specific documentation and lessons learned -- **[Company](your-org/company)** - Company-wide processes, standards, and tools -- **[Shared](your-org/shared)** - Cross-project architecture patterns and best practices - -## Purpose - -This knowledge base captures: -- Lessons learned from sprints -- Architecture patterns and decisions -- Company processes and standards -- Best practices and technical guides - -All content is searchable and tagged for easy discovery across projects. -''', - 'tags': ['company', 'index'], - 'description': 'Your Organization company knowledge base' - }, - { - 'path': 'your-org/projects', - 'title': 'Projects', - 'content': '''# Project Documentation - -Project-specific documentation and lessons learned. - -## Active Projects - -- **[My-Project](your-org/projects/my-project)** - Main product -- **[My-Project-Site](your-org/projects/my-project-site)** - Demo and customer gateway -- **[Intuit-Engine](your-org/projects/intuit-engine)** - API aggregator service -- **[Company-Site](your-org/projects/company-site)** - Company website - -Each project maintains: -- Lessons learned from sprints -- Project-specific documentation -- Architecture decisions -''', - 'tags': ['projects', 'index'], - 'description': 'Index of all project documentation' - }, - { - 'path': 'your-org/company', - 'title': 'Company', - 'content': '''# Company Documentation - -Company-wide processes, standards, and tools. - -## Sections - -- **[Processes](your-org/company/processes)** - Development workflows, onboarding, deployment -- **[Standards](your-org/company/standards)** - Code style, API design, security practices -- **[Tools](your-org/company/tools)** - Gitea, Wiki.js, Claude Code plugin guides - -These standards apply to all projects and team members. -''', - 'tags': ['company', 'processes', 'index'], - 'description': 'Company processes and standards' - }, - { - 'path': 'your-org/shared', - 'title': 'Shared Resources', - 'content': '''# Shared Resources - -Cross-project architecture patterns, best practices, and technical knowledge. - -## Sections - -- **[Architecture Patterns](your-org/shared/architecture-patterns)** - Microservices, service extraction, API design -- **[Best Practices](your-org/shared/best-practices)** - Error handling, logging, testing strategies -- **[Tech Stack](your-org/shared/tech-stack)** - Python ecosystem, Docker, CI/CD pipelines - -These patterns are distilled from lessons learned across all projects. -''', - 'tags': ['shared', 'resources', 'index'], - 'description': 'Cross-project architecture patterns and best practices' - }, - # Project placeholders - { - 'path': 'your-org/projects/my-project', - 'title': 'My-Project', - 'content': '''# My-Project - -Main product - recipe management and meal planning platform. - -## Documentation - -- **[Lessons Learned](your-org/projects/my-project/lessons-learned)** - Sprint retrospectives and insights -- **[Architecture](your-org/projects/my-project/documentation/architecture)** - System architecture -- **[API](your-org/projects/my-project/documentation/api)** - API documentation - -Sprint lessons will be automatically captured here by the projman plugin. -''', - 'tags': ['project', 'my-project'], - 'description': 'My-Project project documentation' - }, - { - 'path': 'your-org/projects/my-project/lessons-learned', - 'title': 'My-Project - Lessons Learned', - 'content': '''# My-Project - Lessons Learned - -Sprint retrospectives and insights from My-Project development. - -## Organization - -- **[Sprints](your-org/projects/my-project/lessons-learned/sprints)** - Sprint-specific lessons -- **[Patterns](your-org/projects/my-project/lessons-learned/patterns)** - Recurring patterns and solutions -- **[INDEX](your-org/projects/my-project/lessons-learned/INDEX)** - Complete index with tags - -Lessons are automatically captured during sprint close via `/sprint-close` command. -''', - 'tags': ['lessons-learned', 'my-project'], - 'description': 'My-Project lessons learned index' - } - ] - - # Create pages - created_count = 0 - failed_count = 0 - - for page_data in base_pages: - try: - print(f"Creating: /{page_data['path']}") - result = await client.create_page(**page_data) - - if result.get('responseResult', {}).get('succeeded'): - print(f" ✅ Created successfully") - created_count += 1 - else: - error_msg = result.get('responseResult', {}).get('message', 'Unknown error') - print(f" ⚠️ Warning: {error_msg}") - failed_count += 1 - - except Exception as e: - print(f" ❌ Error: {e}") - failed_count += 1 - - print() - - # Summary - print("=" * 60) - print(f"Setup complete!") - print(f" Created: {created_count} pages") - if failed_count > 0: - print(f" Failed: {failed_count} pages") - print(f"\n⚠️ Some pages failed. Check errors above.") - sys.exit(1) - else: - print(f"\n✅ All pages created successfully!") - print(f"\nView at: https://wiki.your-company.com/your-org") - - -if __name__ == '__main__': - asyncio.run(initialize_wiki_structure()) -``` - -**Running the setup:** -```bash -cd mcp-servers/wikijs -source .venv/bin/activate -python setup_wiki_structure.py -``` - -**Expected output:** -``` -Initializing Wiki.js base structure... -============================================================ -✅ Connected to Wiki.js at https://wiki.your-company.com/graphql - Base path: /your-org - -Creating: /your-org - ✅ Created successfully - -Creating: /your-org/projects - ✅ Created successfully - -... - -============================================================ -Setup complete! - Created: 6 pages - -✅ All pages created successfully! - -View at: https://wiki.your-company.com/your-org -``` - -**Post-Setup:** -After running the script: -1. Visit https://wiki.your-company.com/your-org to verify structure -2. Add additional project directories as needed -3. The structure is now ready for projman plugin to use - ---- - -## Migration from Git-based Wiki - -```python -# migrate_to_wikijs.py -import asyncio -from pathlib import Path -from mcp_server.wikijs_client import WikiJSClient -import re - -async def migrate_lessons_to_wikijs(): - """Migrate existing lessons learned from Git to Wiki.js""" - client = WikiJSClient() - - # Read existing markdown files - lessons_dir = Path("wiki/lessons-learned/sprints") - - for lesson_file in lessons_dir.glob("*.md"): - content = lesson_file.read_text() - sprint_name = lesson_file.stem - - # Extract tags from content (hashtags at end) - tags = extract_tags_from_content(content) - - # Create in Wiki.js - try: - await client.create_lesson( - sprint_name=sprint_name, - lesson_content=content, - tags=tags - ) - print(f"Migrated: {sprint_name}") - except Exception as e: - print(f"Error migrating {sprint_name}: {e}") - -def extract_tags_from_content(content: str) -> List[str]: - """Extract hashtags from markdown content""" - # Find all hashtags - hashtag_pattern = r'#([\w-]+)' - matches = re.findall(hashtag_pattern, content) - - # Remove duplicates and return - return list(set(matches)) - -if __name__ == '__main__': - asyncio.run(migrate_lessons_to_wikijs()) -``` - ---- - -## Benefits of Wiki.js Integration - -### 1. Superior Documentation Features - -- Rich markdown editor -- Built-in search and indexing -- Tag system -- Version history -- Access control -- Web-based review and editing -- GraphQL API - -### 2. Company-Wide Knowledge Base - -- Shared documentation accessible to all projects -- Cross-project lesson learning -- Best practices repository -- Onboarding materials -- Technical standards - -### 3. Better Collaboration - -- Web interface for team review -- Comments and discussions -- Version control with history -- Role-based access -- Easy sharing with stakeholders - -### 4. Scalability - -- Add new projects easily -- Grow company documentation organically -- PMO has visibility across everything -- Individual projects stay focused -- Search across all content - ---- - -## Troubleshooting - -### Common Issues - -**Issue:** GraphQL authentication failing -```bash -# Solution: Test token manually -curl -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"query":"{ pages { list { id title } } }"}' \ - https://wiki.your-company.com/graphql -``` - -**Issue:** Path not found -```bash -# Solution: Verify base structure exists -# Check in Wiki.js web interface that /your-org path exists -``` - -**Issue:** Tags not working -```bash -# Solution: Ensure tags are provided as list of strings -tags = ["tag1", "tag2"] # Correct -tags = "tag1,tag2" # Wrong -``` - -**Issue:** PMO mode search returns nothing -```bash -# Solution: Ensure WIKIJS_PROJECT is NOT set -# Check environment variables -env | grep WIKIJS -``` - ---- - -## Security - -### Best Practices - -1. **Token Storage:** - - Store tokens in `~/.config/claude/wikijs.env` - - Set file permissions to 600 - - Never commit tokens to git - -2. **Content Validation:** - - Sanitize user input before creating pages - - Validate markdown content - - Prevent XSS in page content - -3. **Access Control:** - - Use Wiki.js role-based permissions - - Limit API token permissions - - Audit access logs - ---- - -## Next Steps - -1. **Set up Wiki.js instance** (if not already done) -2. **Create base structure** using setup script -3. **Configure system and project configs** -4. **Test GraphQL connectivity** -5. **Migrate existing lessons** (if applicable) -6. **Integrate with projman plugin** diff --git a/docs/references/PLUGIN-PMO.md b/docs/references/PLUGIN-PMO.md deleted file mode 100644 index b478ac3..0000000 --- a/docs/references/PLUGIN-PMO.md +++ /dev/null @@ -1,1024 +0,0 @@ -# PMO Plugin Reference (projman-pmo) - -## Overview - -The `projman-pmo` plugin provides multi-project PMO coordination with cross-project dependency tracking, resource allocation, and company-wide visibility. It builds on projman but operates at the organization level. - -**Build Order:** Build AFTER projman is working and validated -**Target Users:** PMO coordinators, engineering managers, CTOs -**Scope:** Multi-project coordination across entire organization - -**Key Features:** -- Cross-project status aggregation -- Dependency tracking and visualization -- Resource conflict detection -- Release coordination -- Company-wide lessons learned search -- Multi-project prioritization - ---- - -## Plugin Structure - -``` -projman-pmo/ -├── .claude-plugin/ -│ └── plugin.json # Plugin manifest -├── .mcp.json # Points to ../mcp-servers/ (company mode) -├── commands/ -│ ├── pmo-status.md # Multi-project status overview -│ ├── pmo-priorities.md # Cross-project prioritization -│ ├── pmo-dependencies.md # Dependency visualization -│ ├── pmo-conflicts.md # Resource conflict detection -│ └── pmo-schedule.md # Deployment schedule coordination -├── agents/ -│ └── pmo-coordinator.md # Multi-project coordination agent -└── README.md # Installation and usage guide -``` - ---- - -## Plugin Manifest - -**File:** `projman-pmo/.claude-plugin/plugin.json` - -```json -{ - "name": "projman-pmo", - "version": "0.1.0", - "displayName": "Projman PMO - Multi-Project Coordination", - "description": "PMO coordination with cross-project visibility, dependency tracking, and resource management", - "author": "Leo Miranda", - "homepage": "https://gitea.hotserv.cloud/personal-projects/support-claude-mktplace", - "repository": { - "type": "git", - "url": "ssh://git@hotserv.tailc9b278.ts.net:2222/personal-projects/support-claude-mktplace.git" - }, - "license": "MIT", - "keywords": [ - "pmo", - "multi-project", - "coordination", - "dependencies", - "resource-management" - ], - "minimumClaudeVersion": "1.0.0", - "main": "commands/", - "dependencies": { - "projman": ">=0.1.0" - }, - "contributes": { - "commands": [ - { - "name": "pmo-status", - "title": "PMO Status", - "description": "Multi-project status overview", - "file": "commands/pmo-status.md" - }, - { - "name": "pmo-priorities", - "title": "PMO Priorities", - "description": "Cross-project priority analysis", - "file": "commands/pmo-priorities.md" - }, - { - "name": "pmo-dependencies", - "title": "PMO Dependencies", - "description": "Project dependency visualization", - "file": "commands/pmo-dependencies.md" - }, - { - "name": "pmo-conflicts", - "title": "PMO Resource Conflicts", - "description": "Resource conflict detection and resolution", - "file": "commands/pmo-conflicts.md" - }, - { - "name": "pmo-schedule", - "title": "PMO Schedule", - "description": "Multi-project deployment scheduling", - "file": "commands/pmo-schedule.md" - } - ], - "agents": [ - { - "name": "pmo-coordinator", - "title": "PMO Coordinator", - "description": "Strategic multi-project coordination and dependency management", - "file": "agents/pmo-coordinator.md" - } - ] - }, - "configuration": { - "required": [ - "GITEA_API_URL", - "GITEA_API_TOKEN", - "GITEA_OWNER", - "WIKIJS_API_URL", - "WIKIJS_API_TOKEN", - "WIKIJS_BASE_PATH" - ], - "properties": { - "GITEA_API_URL": { - "type": "string", - "description": "Gitea API base URL (e.g., https://gitea.example.com/api/v1)" - }, - "GITEA_API_TOKEN": { - "type": "string", - "description": "Gitea API token with organization-level access", - "secret": true - }, - "GITEA_OWNER": { - "type": "string", - "description": "Gitea organization name" - }, - "WIKIJS_API_URL": { - "type": "string", - "description": "Wiki.js GraphQL API URL (e.g., https://wiki.example.com/graphql)" - }, - "WIKIJS_API_TOKEN": { - "type": "string", - "description": "Wiki.js API token with company-wide read access", - "secret": true - }, - "WIKIJS_BASE_PATH": { - "type": "string", - "description": "Base path in Wiki.js (e.g., /company-name)" - } - }, - "notes": { - "company_mode": "PMO plugin operates in company-wide mode. Do NOT set GITEA_REPO or WIKIJS_PROJECT environment variables." - } - } -} -``` - -**Key Differences from projman:** -- `dependencies`: Declares dependency on projman plugin -- No `GITEA_REPO` or `WIKIJS_PROJECT` in configuration (company-wide mode) -- Focused on coordination, not individual project management - ---- - -## Configuration - -### Plugin .mcp.json - -**File:** `projman-pmo/.mcp.json` - -```json -{ - "mcpServers": { - "gitea-pmo": { - "command": "python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/gitea", - "env": { - "PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/gitea", - "GITEA_API_URL": "${GITEA_API_URL}", - "GITEA_API_TOKEN": "${GITEA_API_TOKEN}", - "GITEA_OWNER": "${GITEA_OWNER}" - } - }, - "wikijs-pmo": { - "command": "python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/wikijs", - "env": { - "PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/wikijs", - "WIKIJS_API_URL": "${WIKIJS_API_URL}", - "WIKIJS_API_TOKEN": "${WIKIJS_API_TOKEN}", - "WIKIJS_BASE_PATH": "${WIKIJS_BASE_PATH}" - } - } - } -} -``` - -**Critical Differences from projman:** -- **NO** `GITEA_REPO` → operates on all repositories -- **NO** `WIKIJS_PROJECT` → operates on entire `/your-org` namespace -- Same shared MCP servers at `../mcp-servers/` - -### Environment Variables - -**Required (System-Level Only):** -- `GITEA_API_URL` -- `GITEA_API_TOKEN` -- `GITEA_OWNER` -- `WIKIJS_API_URL` -- `WIKIJS_API_TOKEN` -- `WIKIJS_BASE_PATH` - -**NOT Required:** -- `GITEA_REPO` - PMO operates across all repos -- `WIKIJS_PROJECT` - PMO operates across entire namespace - ---- - -## PMO Coordinator Agent - -**File:** `agents/pmo-coordinator.md` - -### Agent Personality - -```markdown -You are the PMO Coordinator for this organization. - -Your role: -- Maintain strategic view across all projects -- Identify cross-project dependencies -- Detect resource conflicts -- Balance competing priorities -- Coordinate release timing -- Track customer deployment schedules -- Surface company-wide lessons learned - -You are: -- Strategic thinker -- Dependency-aware -- Conflict detector -- Priority balancer -- Team coordinator -- NOT a micromanager - -You delegate to project-level agents: -- Don't micromanage single projects -- Focus on cross-project issues -- Surface conflicts early -- Facilitate coordination -- Provide strategic guidance - -Available Tools: -- aggregate_issues: Fetch issues across all repositories -- search_all_projects: Search lessons across all projects -- list_repos: Get all organization repositories -- get_shared_docs: Access company-wide patterns and best practices - -Key Principles: -1. Strategic overview, not tactical details -2. Cross-project coordination, not single-project management -3. Identify conflicts before they become problems -4. Balance competing priorities across teams -5. Learn from patterns across all projects -``` - -### Delegation Model - -``` -PMO Agent (projman-pmo) - ├─ Identifies cross-project issues - ├─ Detects resource conflicts - ├─ Coordinates release timing - └─ Delegates to... - ├─ Planner Agent (projman) → for project planning - ├─ Orchestrator Agent (projman) → for project execution - └─ Executor Agent (projman) → for implementation -``` - -**Example:** -``` -User: /pmo-status - -PMO: Projects Overview: - - Main-App: Sprint in progress, 60% complete - └─ Blocking: Main-App-Site deployment - - I notice Main-App-Site is waiting on API changes. - Use projman in the cuisineflow-site repo to plan the sync work. -``` - ---- - -## Commands - -### 1. PMO Status Command - -**File:** `commands/pmo-status.md` - -**Usage:** `/pmo-status` - -**Description:** Consolidated view of all active projects - -**Flow:** - -``` -User: /pmo-status - -PMO: Projects Overview - ================ - - Main-App (main product) - ├── Sprint: Intuit Engine Extraction - ├── Status: In Progress (60%) - ├── Issue: #47 - ├── Blockers: None - ├── Next: API testing - └── Timeline: On track (1 week remaining) - - Main-App-Site (demo) - ├── Sprint: Dashboard Updates - ├── Status: Waiting on dependencies - ├── Issue: #12 - ├── Blockers: Depends on Main-App #47 (API changes) - ├── Next: Deploy when API ready - └── Timeline: Blocked (waiting on Main-App) - - Intuit-Engine (service) - ├── Sprint: Initial Setup - ├── Status: Planning - ├── Issue: #3 - ├── Blockers: Architecture decisions needed - ├── Next: Service boundary definition - └── Timeline: Not started - - Company-Site (marketing) - ├── Sprint: Content Updates - ├── Status: Complete - ├── Issue: #8 (closed) - ├── Blockers: None - ├── Next: Deploy to production - └── Timeline: Ready for deployment - - Cross-Project Insights: - - Main-App-Site blocked by Main-App #47 - - Intuit-Engine needs architectural guidance - - Company-Site ready for deployment - - Suggested Actions: - 1. Prioritize Main-App #47 completion (unblocks Site) - 2. Schedule architecture review for Intuit-Engine - 3. Deploy Company-Site content updates -``` - -**Success Criteria:** -- Shows all active projects -- Identifies blockers -- Surfaces dependencies -- Provides actionable insights - -### 2. PMO Priorities Command - -**File:** `commands/pmo-priorities.md` - -**Usage:** `/pmo-priorities` - -**Description:** Review and adjust priorities across projects - -**Flow:** - -``` -User: /pmo-priorities - -PMO: Priority Analysis Across Projects - ================================= - - Critical (Blocks launches): - 1. Main-App #47 - Intuit Engine Extraction - → Blocks: Main-App v2.0 launch (Nov 15) - → Blocks: Main-App-Site deployment - → Status: 60% complete, 1 week remaining - → Recommendation: Maintain focus - - High (Important features): - 2. Main-App-Site #12 - Dashboard Updates - → Depends on: Main-App #47 - → Status: Waiting - → Recommendation: Begin planning, wait for #47 - - 3. Intuit-Engine #3 - Initial Setup - → Enables: Service architecture - → Status: Planning phase - → Recommendation: Schedule architecture review - - Medium (Enhancements): - 4. Company-Site #8 - Content Updates - → Status: Complete, ready to deploy - → Recommendation: Deploy this week - - Resource Analysis: - Leo (primary developer): - - Working on: Main-App #47 (Critical) - - Next: Main-App-Site #12 (High) - - Later: Intuit-Engine #3 (High) - - ⚠️ Potential Conflict: - Leo is assigned to 3 high-priority items. Consider: - - Maintaining focus on #47 (blocks launch) - - Queueing #12 for after #47 completion - - Scheduling #3 architecture review with team - - Recommend any priority changes? -``` - -**Success Criteria:** -- Clear priority ranking -- Resource allocation visibility -- Conflict identification -- Actionable recommendations - -### 3. PMO Dependencies Command - -**File:** `commands/pmo-dependencies.md` - -**Usage:** `/pmo-dependencies` - -**Description:** Visualize and manage project dependencies - -**Flow:** - -``` -User: /pmo-dependencies - -PMO: Project Dependencies - ==================== - - Dependency Graph: - - Intuit-Engine (service) - ↓ (must complete before) - Main-App (main) - ↓ (API changes required by) - Main-App-Site (demo) - ↓ (deploy together) - Customer VPS (deployments) - - Detailed Dependencies: - - 1. Main-App → Intuit-Engine - Type: Service extraction - Status: In progress - Blocker: Must complete #47 before v2.0 launch - Impact: High (blocks launch) - - 2. Main-App → Main-App-Site - Type: Feature sync - Status: Waiting - Blocker: Dashboard updates need API changes from #47 - Impact: Medium (demo consistency) - - 3. Main-App → Customer VPS - Type: Deployment - Status: Pending - Blocker: v2.0 launch must complete before customer updates - Impact: High (customer commitments) - - Deployment Order: - 1. Complete Intuit-Engine service extraction - 2. Deploy Main-App v2.0 to production - 3. Sync Main-App-Site demo - 4. Update customer VPS instances - - Critical Path: - Intuit-Engine (#3) → Main-App (#47) → Site (#12) → Customer VPS - Estimated timeline: 3 weeks total - - Risks: - - Main-App #47 delay would cascade to all downstream - - Customer VPS updates have Nov 20 deadline -``` - -**Success Criteria:** -- Dependencies clearly visualized -- Critical path identified -- Deployment order defined -- Risks highlighted - -### 4. PMO Conflicts Command - -**File:** `commands/pmo-conflicts.md` - -**Usage:** `/pmo-conflicts` - -**Description:** Detect and resolve resource conflicts - -**Flow:** - -``` -User: /pmo-conflicts - -PMO: Resource Conflict Analysis - ========================== - - ⚠️ Resource Conflict Detected - - Leo (Developer): - Assigned to: - - Main-App #47: Intuit Engine extraction (Priority: Critical) - - Main-App-Site #12: Dashboard redesign (Priority: High) - - Company-Site #8: Content update (Priority: Medium) - - Intuit-Engine #3: Service setup (Priority: High) - - Conflict Analysis: - - 4 active assignments across 3 projects - - 2 are high priority or above - - Estimated total effort: 4 weeks - - Timeline: 2 weeks available - - Recommendations: - 1. FOCUS: Main-App #47 (Critical, blocks launch) - → Keep as primary focus - → Estimated completion: 1 week - - 2. QUEUE: Main-App-Site #12 (High, depends on #47) - → Start after #47 completes - → Natural sequencing - - 3. DELEGATE: Company-Site #8 (Medium, content work) - → Can be handled by marketing team - → Low technical complexity - - 4. SCHEDULE: Intuit-Engine #3 (High, planning phase) - → Schedule architecture review session - → Team collaboration, not solo work - - Timeline Conflict: - - Without changes: - Week 1-2: Main-App #47 - Week 3-4: Site #12 + Engine #3 (CONFLICT) - - With recommendations: - Week 1-2: Main-App #47 (FOCUS) - Week 3: Main-App-Site #12 (QUEUE) - Week 4: Intuit-Engine #3 (SCHEDULE) - Company-Site #8: Marketing (DELEGATE) - - Apply recommendations? -``` - -**Success Criteria:** -- Conflicts identified automatically -- Clear impact analysis -- Actionable recommendations -- Timeline visualization - -### 5. PMO Schedule Command - -**File:** `commands/pmo-schedule.md` - -**Usage:** `/pmo-schedule` - -**Description:** Coordinate deployment schedules - -**Flow:** - -``` -User: /pmo-schedule - -PMO: Deployment Schedule - =================== - - Week of Nov 6: - - Main-App: Continue Sprint #47 (Intuit Engine) - - Company-Site: Deploy content updates (#8) ✅ - - Week of Nov 13: - - Main-App: Complete Sprint #47 ⚠️ - → Critical: Must complete by Nov 15 for launch - - Main-App-Site: Begin Dashboard updates (#12) - - Week of Nov 20: - - Main-App: Deploy v2.0 to production 🚀 - → Deployment window: Nov 20-22 - - Main-App-Site: Sync demo with v2.0 - - Customer VPS: Begin rollout (Deadline: Nov 20) - - Week of Nov 27: - - Customer VPS: Continue rollout - - Intuit-Engine: Begin service implementation (#3) - - Critical Dates: - - Nov 15: Main-App v2.0 feature freeze - - Nov 20: Production deployment - - Nov 20: Customer VPS deadline - - Nov 22: Demo site sync - - Dependencies: - ✅ Intuit-Engine service boundaries defined - 🔄 Main-App #47 in progress (60%) - ⏳ Main-App-Site #12 waiting - ⏳ Customer VPS rollout pending - - Risks: - ⚠️ Main-App #47 delay would impact: - - v2.0 launch date (Nov 20) - - Customer VPS deadline (Nov 20) - - Demo site sync (Nov 22) - - Mitigation: - - Monitor #47 progress daily - - Prepare rollback plan for customer VPS - - Communicate delays early if detected -``` - -**Success Criteria:** -- Clear timeline visibility -- Dependencies tracked -- Critical dates highlighted -- Risk mitigation planned - ---- - -## Multi-Project Coordination Workflows - -### Cross-Project Lessons Learned - -``` -User: Search for lessons about service extraction across all projects - -PMO: Searching lessons across all projects... - - Found 5 relevant lessons: - - Main-App: - - Sprint 08: Service boundary issues with shared DB - Tags: #service-extraction #database #refactoring - Key: Define boundaries at data model level first - - - Sprint 12: API versioning during extraction - Tags: #api #versioning #refactoring - Key: Version APIs from the start - - Intuit-Engine: - - Sprint 02: Circular dependencies in service init - Tags: #service-extraction #dependencies - Key: Watch for import cycles - - Main-App-Site: - - Sprint 05: Sync issues during backend refactor - Tags: #sync #refactoring - Key: Coordinate deployments during major changes - - Shared Patterns: - - /your-org/shared/architecture-patterns/service-extraction - Key: Service Extraction Playbook - - Common Themes: - 1. Data model boundaries are critical - 2. API versioning prevents integration issues - 3. Watch for circular dependencies - 4. Coordinate deployments during refactors - - Apply these insights to current Intuit Engine extraction? -``` - -### Resource Allocation - -``` -User: /pmo-status - -PMO: [Shows status] - - Resource Analysis: - - Leo: 3 active projects (Main-App, Site, Engine) - - Marketing: 1 project (Company-Site) - - Bottleneck detected: Leo is on critical path for all technical work - - Recommendations: - 1. Prioritize work that unblocks others - 2. Consider hiring/contracting for parallel work - 3. Delegate non-critical work (Company-Site content) - - Would you like a detailed resource allocation report? -``` - -### Release Coordination - -``` -User: Plan the v2.0 release across all affected projects - -PMO: Release Coordination: Main-App v2.0 - ====================================== - - Affected Projects: - 1. Main-App (main product) - 2. Intuit-Engine (new service) - 3. Main-App-Site (demo) - 4. Customer VPS instances - - Pre-Release Checklist: - ✅ Intuit-Engine service deployed - 🔄 Main-App #47 complete (60%) - ⏳ Integration tests pending - ⏳ Demo site updates pending - ⏳ Customer migration scripts ready - - Deployment Sequence: - 1. Deploy Intuit-Engine service (backend) - → Date: Nov 18 - → Duration: 2 hours - → Rollback plan: Ready - - 2. Deploy Main-App v2.0 (main app) - → Date: Nov 20 - → Duration: 4 hours - → Rollback plan: Ready - - 3. Sync Main-App-Site (demo) - → Date: Nov 22 - → Duration: 1 hour - → Dependencies: Step 2 complete - - 4. Update Customer VPS (production instances) - → Date: Nov 23-25 - → Duration: Phased rollout - → Dependencies: Steps 2 and 3 complete - - Communication Plan: - - Nov 15: Feature freeze announcement - - Nov 19: Deployment notification - - Nov 20: v2.0 launch announcement - - Nov 25: Completion report - - Risks & Mitigation: - - Risk: #47 completion delayed - Mitigation: Daily progress checks, adjust timeline early - - - Risk: Integration issues during deployment - Mitigation: Comprehensive testing, rollback plan ready - - - Risk: Customer VPS migration issues - Mitigation: Phased rollout, support on standby -``` - ---- - -## Company-Wide Patterns - -### Accessing Shared Documentation - -```python -# PMO agent can access company-wide patterns -shared_patterns = await wikijs.get_shared_docs("architecture-patterns") - -# Returns: -# - microservices.md -# - api-gateway.md -# - database-per-service.md -# - service-extraction.md (created from lessons learned) -``` - -### Creating Shared Patterns - -``` -User: Create a shared pattern document for service extraction - -PMO: I'll create a pattern document based on lessons from: - - Main-App Sprint 08 - - Main-App Sprint 12 - - Intuit-Engine Sprint 02 - - Creating: /your-org/shared/architecture-patterns/service-extraction - - Service Extraction Pattern - ========================= - - ## When to Use - - Extracting microservice from monolith - - Creating separate deployable service - - Isolating domain boundaries - - ## Prerequisites - - Clear service boundaries defined - - Data model dependencies mapped - - API contracts specified - - ## Steps - 1. Define service boundaries at data model level - 2. Design and version APIs first - 3. Extract data layer with foreign key awareness - 4. Implement service logic - 5. Update integration points - 6. Deploy and test - - ## Common Pitfalls - - Not defining boundaries at data level first - - Missing API versioning - - Circular dependencies in initialization - - Uncoordinated deployments - - ## Lessons Learned - [Links to specific sprint lessons] - - Created ✅ - Tags: #service-extraction #microservices #refactoring #architecture - - This pattern is now available to all projects. -``` - ---- - -## Implementation Phases - -### Phase 9: PMO Plugin Foundation - -**Deliverable:** PMO plugin requirements and design - -**Tasks:** -1. Analyze multi-project workflows -2. Identify coordination pain points -3. Design PMO agent scope -4. Extend MCP server for multi-repo operations -5. Define delegation model - -**Success Criteria:** -- Clear PMO plugin scope -- Multi-repo queries working -- Delegation model defined -- Doesn't duplicate projman functionality - -### Phase 10: PMO Commands & Workflows - -**Deliverable:** PMO-specific commands working - -**Tasks:** -1. Implement `/pmo-status` command -2. Implement `/pmo-priorities` command -3. Implement `/pmo-dependencies` command -4. Implement `/pmo-conflicts` command -5. Implement `/pmo-schedule` command -6. Build conflict detection logic -7. Create dependency visualization -8. Design release coordination workflow - -**Success Criteria:** -- All commands provide valuable insights -- Dependencies clearly visualized -- Conflicts easily identified -- Coordination reduces manual overhead - -### Phase 11: PMO Testing & Integration - -**Deliverable:** Validated PMO plugin integrated with projman - -**Tasks:** -1. Test with multiple projects (Main-App, Site, Engine, Company-Site) -2. Simulate deployment coordination scenarios -3. Test priority conflict resolution -4. Validate dependency tracking -5. Test cross-project lessons search -6. Ensure PMO delegates to projman agents - -**Success Criteria:** -- Handles multiple projects correctly -- Dependencies respected -- Conflicts detected and surfaced -- Seamless integration with projman -- Cross-project lessons accessible - -### Phase 12: Production Deployment - -**Deliverable:** PMO plugin deployed and operational - -**Tasks:** -1. Deploy across all environments (laptop, staging, production) -2. Configure for company-wide access -3. Set up backup and recovery -4. Establish monitoring and maintenance -5. Train team on PMO capabilities - -**Success Criteria:** -- Works in all environments -- Configuration portable -- Backup procedures documented -- Team trained and comfortable - ---- - -## PMO vs Projman: Key Differences - -| Aspect | projman | projman-pmo | -|--------|---------|-------------| -| **Scope** | Single repository | All repositories | -| **Configuration** | `GITEA_REPO` + `WIKIJS_PROJECT` | Neither (company-wide) | -| **Agents** | Planner, Orchestrator, Executor | PMO Coordinator | -| **Commands** | Sprint-focused | Cross-project coordination | -| **Gitea Access** | Single repo issues | All repos issues | -| **Wiki.js Access** | Project path | Entire namespace | -| **Primary User** | Developer, Team Lead | PMO, Manager, CTO | -| **Focus** | Tactical execution | Strategic coordination | -| **Delegation** | N/A | Delegates to projman | - ---- - -## Usage Examples - -### Example 1: Detecting Blocked Work - -``` -User: /pmo-status - -PMO: Main-App-Site: Waiting on dependencies - Blocked by: Main-App #47 (API changes) - - Recommendation: Focus resources on Main-App #47 to unblock Site work -``` - -### Example 2: Resource Conflict Resolution - -``` -User: /pmo-conflicts - -PMO: Leo assigned to 4 tasks across 3 projects - Estimated: 4 weeks work in 2 weeks timeline - - Recommendations: - - Maintain focus on Critical priority (Main-App #47) - - Delegate content work (Company-Site #8) to marketing - - Schedule architectural review (Intuit-Engine #3) as team session -``` - -### Example 3: Release Planning - -``` -User: /pmo-schedule - -PMO: Critical Path: Engine → Main-App → Site → Customer VPS - Deadline: Nov 20 (Customer VPS commitment) - - Current: Week 1 of 3 - Status: On track - - Risk: If Main-App #47 delayed, entire timeline at risk - Mitigation: Daily progress monitoring -``` - ---- - -## Best Practices - -### 1. Use PMO for Strategic View - -- Don't micromanage individual projects -- Focus on cross-project issues -- Identify blockers and dependencies -- Balance competing priorities - -### 2. Delegate to Projman - -- Use projman for project-specific planning -- Let project teams handle tactical execution -- PMO provides coordination, not implementation - -### 3. Monitor Critical Path - -- Identify which work blocks others -- Focus resources on critical path items -- Communicate delays early - -### 4. Learn Across Projects - -- Search lessons across all projects -- Create shared patterns from common themes -- Build company-wide knowledge base - -### 5. Coordinate Releases - -- Plan deployments across dependent projects -- Communicate timelines clearly -- Have rollback plans ready - ---- - -## Troubleshooting - -### Issue: PMO showing wrong mode - -**Solution:** -```bash -# Ensure GITEA_REPO and WIKIJS_PROJECT are NOT set -env | grep GITEA -env | grep WIKIJS - -# Should only show: -# GITEA_API_URL, GITEA_API_TOKEN, GITEA_OWNER -# WIKIJS_API_URL, WIKIJS_API_TOKEN, WIKIJS_BASE_PATH -``` - -### Issue: Can't access all repositories - -**Solution:** -- Verify API token has organization-level access -- Check token permissions in Gitea -- Ensure GITEA_OWNER is correct - -### Issue: Cross-project search not working - -**Solution:** -- Verify Wiki.js structure exists -- Check base path is correct -- Ensure projects have lessons-learned directories - ---- - -## Next Steps - -1. **Complete projman plugin** (Phases 1-8) -2. **Validate projman works** with real sprints -3. **Begin PMO foundation** (Phase 9) -4. **Implement PMO commands** (Phase 10) -5. **Test with multiple projects** (Phase 11) -6. **Deploy to production** (Phase 12) diff --git a/docs/references/PLUGIN-PROJMAN.md b/docs/references/PLUGIN-PROJMAN.md deleted file mode 100644 index 9dc604c..0000000 --- a/docs/references/PLUGIN-PROJMAN.md +++ /dev/null @@ -1,1437 +0,0 @@ -# Projman Plugin Reference - -## Overview - -The `projman` plugin provides single-repository project management with Gitea and Wiki.js integration. It transforms the proven 15-sprint workflow into a distributable tool for managing software development with Claude Code. - -**Build Order:** Build projman FIRST, then pmo -**Target Users:** Individual developers and project teams -**Scope:** Single-repository project management - -**Key Features:** -- Sprint planning with planner agent -- Issue creation with label taxonomy -- Lessons learned capture in Wiki.js -- Sprint execution coordination -- Branch-aware security model -- Hybrid configuration system - ---- - -## Plugin Structure - -``` -projman/ -├── .claude-plugin/ -│ └── plugin.json # Plugin manifest -├── .mcp.json # Points to ../mcp-servers/ -├── commands/ -│ ├── sprint-plan.md # Sprint planning command -│ ├── sprint-start.md # Sprint initiation command -│ ├── sprint-status.md # Sprint status check command -│ ├── sprint-close.md # Sprint closing command -│ └── labels-sync.md # Label taxonomy sync command -├── agents/ -│ ├── planner.md # Sprint planning agent -│ ├── orchestrator.md # Sprint coordination agent -│ └── executor.md # Implementation guidance agent -├── skills/ -│ └── label-taxonomy/ -│ └── labels-reference.md # Dynamic label reference -├── README.md # Installation and usage guide -└── CONFIGURATION.md # Configuration setup guide -``` - ---- - -## Plugin Manifest - -**File:** `projman/.claude-plugin/plugin.json` - -```json -{ - "name": "projman", - "version": "0.1.0", - "displayName": "Projman - Single-Repository Project Management", - "description": "Sprint planning and project management with Gitea and Wiki.js integration", - "author": "Leo Miranda", - "homepage": "https://gitea.hotserv.cloud/personal-projects/support-claude-mktplace", - "repository": { - "type": "git", - "url": "ssh://git@hotserv.tailc9b278.ts.net:2222/personal-projects/support-claude-mktplace.git" - }, - "license": "MIT", - "keywords": [ - "project-management", - "sprint-planning", - "gitea", - "wikijs", - "agile" - ], - "minimumClaudeVersion": "1.0.0", - "main": "commands/", - "contributes": { - "commands": [ - { - "name": "sprint-plan", - "title": "Plan Sprint", - "description": "Start sprint planning with AI guidance", - "file": "commands/sprint-plan.md" - }, - { - "name": "sprint-start", - "title": "Start Sprint", - "description": "Begin sprint execution with relevant lessons", - "file": "commands/sprint-start.md" - }, - { - "name": "sprint-status", - "title": "Sprint Status", - "description": "Check current sprint progress", - "file": "commands/sprint-status.md" - }, - { - "name": "sprint-close", - "title": "Close Sprint", - "description": "Complete sprint and capture lessons learned", - "file": "commands/sprint-close.md" - }, - { - "name": "labels-sync", - "title": "Sync Labels", - "description": "Synchronize label taxonomy from Gitea", - "file": "commands/labels-sync.md" - } - ], - "agents": [ - { - "name": "planner", - "title": "Sprint Planner", - "description": "Sprint planning and architecture analysis", - "file": "agents/planner.md" - }, - { - "name": "orchestrator", - "title": "Sprint Orchestrator", - "description": "Sprint coordination and progress tracking", - "file": "agents/orchestrator.md" - }, - { - "name": "executor", - "title": "Sprint Executor", - "description": "Implementation guidance and code review", - "file": "agents/executor.md" - } - ], - "skills": [ - { - "name": "label-taxonomy", - "title": "Label Taxonomy Reference", - "description": "Gitea label system reference", - "file": "skills/label-taxonomy/labels-reference.md" - } - ] - }, - "configuration": { - "required": [ - "GITEA_API_URL", - "GITEA_API_TOKEN", - "GITEA_OWNER", - "GITEA_REPO", - "WIKIJS_API_URL", - "WIKIJS_API_TOKEN", - "WIKIJS_BASE_PATH", - "WIKIJS_PROJECT" - ], - "properties": { - "GITEA_API_URL": { - "type": "string", - "description": "Gitea API base URL (e.g., https://gitea.example.com/api/v1)" - }, - "GITEA_API_TOKEN": { - "type": "string", - "description": "Gitea API token with repo and org read access", - "secret": true - }, - "GITEA_OWNER": { - "type": "string", - "description": "Gitea organization or user name" - }, - "GITEA_REPO": { - "type": "string", - "description": "Repository name for project-scoped operations" - }, - "WIKIJS_API_URL": { - "type": "string", - "description": "Wiki.js GraphQL API URL (e.g., https://wiki.example.com/graphql)" - }, - "WIKIJS_API_TOKEN": { - "type": "string", - "description": "Wiki.js API token with page management permissions", - "secret": true - }, - "WIKIJS_BASE_PATH": { - "type": "string", - "description": "Base path in Wiki.js (e.g., /company-name)" - }, - "WIKIJS_PROJECT": { - "type": "string", - "description": "Project path relative to base (e.g., projects/my-project)" - } - } - } -} -``` - ---- - -## How Commands Work - -Commands are **markdown files** that expand when invoked. When a user types `/sprint-plan`, Claude Code: - -1. Loads the markdown file from `commands/sprint-plan.md` -2. Injects the content into the conversation context -3. Claude follows the instructions in the markdown - -**Example:** `commands/sprint-plan.md` - -```markdown -# Sprint Planning Command - -You are assisting with sprint planning for a software project. - -## Your Role - -Guide the user through sprint planning by: -1. Asking what feature/fix/refactor is planned -2. Searching lessons learned for similar past work -3. Asking clarifying questions about architecture and scope -4. Suggesting appropriate Gitea labels based on context -5. Creating a Gitea issue if the user confirms -6. Generating a structured sprint planning document - -## Available Tools - -You have access to these MCP tools (invoke by describing what you need): -- **search_lessons**: Search past lessons learned for relevant context -- **list_issues**: Check existing issues for related work -- **suggest_labels**: Get label suggestions based on context -- **create_issue**: Create Gitea issue with labels -- **get_labels**: Fetch available label taxonomy - -## Branch Awareness - -Before creating issues, check the current Git branch: -- **Development branches** (development, feat/*): Full access -- **Staging/Production**: Warn user and suggest switching to development branch - -## Workflow - -1. Ask: "What are you building in this sprint?" -2. Use **search_lessons** tool with relevant keywords -3. Present any relevant past lessons found -4. Ask clarifying questions: - - Which components are affected? - - What's the architectural approach? - - Any known risks or dependencies? -5. Use **suggest_labels** tool with the context -6. Present suggested labels and ask for confirmation -7. Use **create_issue** tool if user confirms -8. Generate sprint planning document with: - - Sprint goal - - Architecture decisions - - Task breakdown - - Risks and mitigation - - References to relevant lessons - -## Personality - -Be thorough but not overwhelming. Ask targeted questions. Think through edge cases. -``` - -**Key Points:** -- Commands are **prompts**, not code -- Tools are invoked by **describing needs** in natural language -- Claude Code handles tool execution automatically -- Commands can invoke agents, use tools, or both - ---- - -## How Agents Work - -Agents are also **markdown files** with specialized prompts. They can be invoked by: -- Commands (e.g., sprint-plan command uses planner agent) -- Slash commands (e.g., `/agent planner`) -- Other agents (delegation) - -**Example:** `agents/planner.md` - -```markdown -# Sprint Planner Agent - -You are the Sprint Planner for this project. - -## Your Identity - -**Role:** Sprint planning and architecture analysis -**Personality:** Thorough, architecture-aware, asks clarifying questions -**Focus:** Planning before execution - -## Responsibilities - -1. **Sprint Planning:** - - Guide users through sprint planning process - - Ask targeted questions about scope and architecture - - Break down work into manageable tasks - -2. **Architecture Analysis:** - - Identify architectural implications - - Detect when work is a refactor vs feature - - Consider cross-project impacts - -3. **Label Selection:** - - Analyze context to suggest appropriate labels - - Ensure Type labels are accurate (Bug/Feature/Refactor) - - Suggest Component and Priority labels - -4. **Lessons Integration:** - - Search past lessons before planning - - Reference relevant experiences - - Apply learned patterns - -5. **Issue Creation:** - - Create well-structured Gitea issues - - Include detailed descriptions - - Apply suggested labels - -## Available MCP Tools - -Invoke these tools by describing what you need in natural language: - -- **search_lessons(query, tags)**: Search Wiki.js for past lessons -- **list_issues(state, labels, repo)**: List Gitea issues -- **get_issue(issue_number, repo)**: Get specific issue -- **create_issue(title, body, labels, repo)**: Create new issue -- **suggest_labels(context)**: Get label suggestions -- **get_labels(repo)**: Fetch all available labels - -## Tool Invocation Examples - -Instead of calling tools programmatically, describe what you need: - -**Good:** -- "Let me search past lessons for service extraction experiences" -- "I'll check if there are any existing issues related to authentication" -- "I need to suggest labels based on this context: [context]" - -**Claude Code will:** -1. Understand your intent -2. Map it to the appropriate MCP tool -3. Execute the tool -4. Provide results back to you - -## Branch-Aware Security - -Check branch before creating issues: - -**Development branches:** Create issues freely -**Staging branches:** Warn and suggest switching branches -**Production branches:** Block issue creation, suggest incidents only - -**How to check:** -- Git branch info is available in environment context -- If unsure, ask user what branch they're on -- Provide appropriate warnings - -## Planning Workflow - -1. **Understand the work:** - - "What are you building?" - - Listen for keywords: "bug", "feature", "refactor", "extract" - -2. **Search lessons:** - - Extract keywords from user's description - - Search: "Let me search for lessons about [keywords]" - - Present relevant findings - -3. **Ask clarifying questions:** - - Architecture approach? - - Components affected? - - Dependencies or risks? - - Timeline expectations? - -4. **Suggest labels:** - - Combine work type + user answers into context - - "I'll suggest appropriate labels for this work" - - Present suggestions with explanations - -5. **Confirm and create:** - - Show proposed issue structure - - Ask for user confirmation - - Create issue: "I'll create this issue in Gitea" - - Confirm creation with issue number - -6. **Generate plan:** - - Sprint goal - - Architecture decisions - - Task breakdown - - Risk mitigation - - Lesson references - -## Communication Style - -- **Thorough but concise:** Don't overwhelm with details -- **Question-driven:** Ask targeted questions -- **Context-aware:** Reference past lessons naturally -- **Clear labeling:** Explain label choices -- **Architecture-focused:** Think through implications - -## Example Interaction - -``` -User: I need to extract the Intuit engine into a separate service - -Planner: Let me search for lessons about service extraction... - -[Tool executes: search_lessons("service extraction")] - -I found two relevant lessons from past work: -- Sprint 08: Service boundary issues with shared DB -- Sprint 12: API versioning during extraction - -Before we proceed, a few questions: -1. Have you defined the service boundaries at the data model level? -2. What's your approach to API versioning? -3. Which components will be affected? - -[User answers] - -Planner: Based on your answers, this is a Type/Refactor with: -- Component/Backend -- Component/API -- Component/Database -- Priority/High -- Risk/Medium - -Should I create a Gitea issue with these labels? - -[User confirms] - -Planner: I'll create the issue... - -[Tool executes: create_issue(...)] - -Created issue #47: "Extract Intuit Engine Service" -View at: https://gitea.example.com/org/repo/issues/47 - -Now let me generate a detailed sprint plan... -``` - -## Important Notes - -- **Never rush planning:** Take time to understand the work -- **Always search lessons:** Past experience prevents mistakes -- **Explain label choices:** Don't just apply labels, explain why -- **Think architecturally:** Consider broader implications -- **Branch safety:** Verify branch before creating issues - -## Delegation - -You focus on planning. For execution monitoring or implementation: -- **Orchestrator agent:** Sprint progress and coordination -- **Executor agent:** Implementation guidance and code review - -Stay in your lane. Planning is your expertise. -``` - -**Key Points:** -- Agents describe their role and personality -- Tools are invoked via **natural language**, not function calls -- Claude Code maps natural language to MCP tool calls automatically -- Agents can reference other agents for delegation - ---- - -## How Tool Invocation Works - -**You don't call tools programmatically.** Instead, agents/commands describe what they need in natural language, and Claude Code handles the execution. - -**Example flow:** - -1. **Agent says:** "Let me search for lessons about authentication" -2. **Claude Code:** - - Parses the intent - - Maps to MCP tool: `search_lessons(query="authentication")` - - Executes the tool - - Returns results -3. **Agent receives:** List of matching lessons -4. **Agent continues:** "I found 3 lessons about authentication..." - -This natural language interface makes agents more maintainable and readable - ---- - -## Configuration - -### Plugin .mcp.json - -**File:** `projman/.mcp.json` - -```json -{ - "mcpServers": { - "gitea-projman": { - "command": "python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/gitea", - "env": { - "PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/gitea", - "GITEA_API_URL": "${GITEA_API_URL}", - "GITEA_API_TOKEN": "${GITEA_API_TOKEN}", - "GITEA_OWNER": "${GITEA_OWNER}", - "GITEA_REPO": "${GITEA_REPO}" - } - }, - "wikijs-projman": { - "command": "python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/wikijs", - "env": { - "PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/../mcp-servers/wikijs", - "WIKIJS_API_URL": "${WIKIJS_API_URL}", - "WIKIJS_API_TOKEN": "${WIKIJS_API_TOKEN}", - "WIKIJS_BASE_PATH": "${WIKIJS_BASE_PATH}", - "WIKIJS_PROJECT": "${WIKIJS_PROJECT}" - } - } - } -} -``` - -**Note:** Both MCP servers are shared at `../mcp-servers/` (repository root). The projman plugin includes `GITEA_REPO` and `WIKIJS_PROJECT` for project-scoped operations. - -### Environment Variables - -**Required (System-Level):** -- `GITEA_API_URL` -- `GITEA_API_TOKEN` -- `GITEA_OWNER` -- `WIKIJS_API_URL` -- `WIKIJS_API_TOKEN` -- `WIKIJS_BASE_PATH` - -**Required (Project-Level):** -- `GITEA_REPO` - Repository name (e.g., `cuisineflow`) -- `WIKIJS_PROJECT` - Project path relative to base (e.g., `projects/cuisineflow`) - ---- - -## Three-Agent Model - -The projman plugin implements a three-agent architecture mirroring the proven workflow: - -### 1. Planner Agent - -**File:** `agents/planner.md` - -**Role:** -- Sprint planning and architecture analysis -- Clarifying questions about scope -- Architectural decision-making -- Issue creation with appropriate labels -- Lessons learned integration - -**Personality:** -- Thorough but not overwhelming -- Asks targeted questions -- Thinks through edge cases -- Never rushes decisions -- Architecture-aware - -**Example Prompt:** - -```markdown -You are the Sprint Planner for this project. - -Your role: -- Guide users through sprint planning -- Ask targeted questions about scope and architecture -- Detect issue types (Bug, Feature, Refactor) -- Suggest appropriate labels based on context -- Generate comprehensive sprint documents -- Consider lessons learned from past sprints - -You are: -- Thorough but not overwhelming -- Architecture-aware -- Label-conscious (use Type/Refactor for architectural changes) -- Process-oriented - -You always: -- Reference relevant past lessons -- Consider technical debt -- Identify cross-project impacts -- Suggest realistic scope - -Available Tools: -- search_lessons: Search past lessons learned for relevant context -- list_issues: Check existing issues for related work -- suggest_labels: Get label suggestions based on context -- create_issue: Create Gitea issue with labels -- get_labels: Fetch available label taxonomy - -Sprint Planning Flow: -1. Ask what feature/fix/refactor is planned -2. Search lessons learned for similar past work -3. Ask clarifying questions (architecture, components, risks) -4. Suggest appropriate labels -5. Create issue with labels if user confirms -6. Generate sprint planning document -``` - -### 2. Orchestrator Agent - -**File:** `agents/orchestrator.md` - -**Role:** -- Sprint progress monitoring -- Task dependency coordination -- Blocker identification -- Git operations (commit, merge, cleanup) -- Status tracking and reporting - -**Personality:** -- Concise and action-oriented -- Tracks details meticulously -- Progress-focused -- Blocker-aware - -**Example Prompt:** - -```markdown -You are the Sprint Orchestrator for this project. - -Your role: -- Monitor sprint progress -- Track issue status -- Identify and surface blockers -- Coordinate between tasks -- Keep sprint on track -- Handle Git operations - -You are: -- Progress-focused -- Blocker-aware -- Context-provider -- Coordination-minded -- Concise in communication - -You always: -- Check issue status before reporting -- Identify dependencies -- Surface relevant documentation -- Keep things moving -- Generate lean execution prompts (not full docs) - -Available Tools: -- get_issue: Fetch current sprint issue details -- list_issues: Check related issues -- update_issue: Update sprint status -- add_comment: Add progress comments -- search_pages: Find relevant documentation - -Status Monitoring: -1. Check sprint issue status -2. Identify completed vs remaining work -3. Surface any blockers -4. Suggest next actions -5. Update issue with progress -``` - -### 3. Executor Agent - -**File:** `agents/executor.md` - -**Role:** -- Implementation guidance -- Code review suggestions -- Testing strategy -- Documentation -- Quality standards enforcement - -**Personality:** -- Implementation-focused -- Follows specs precisely -- Technically detailed -- Quality-conscious - -**Example Prompt:** - -```markdown -You are the Sprint Executor for this project. - -Your role: -- Provide implementation guidance -- Suggest code patterns -- Review technical decisions -- Ensure quality standards -- Reference best practices - -You are: -- Technically detailed -- Quality-focused -- Pattern-aware -- Standards-conscious -- Implementation-focused - -You always: -- Follow modular architecture principles -- Suggest discrete methods/functions -- Consider testability -- Document decisions -- Follow architectural guidelines from planning - -Available Tools: -- get_page: Fetch architectural documentation -- get_shared_docs: Access company-wide patterns -- search_pages: Find relevant technical docs - -Implementation Flow: -1. Review sprint issue and planning documents -2. Reference architectural decisions from planning -3. Provide step-by-step implementation guidance -4. Suggest code patterns and structure -5. Ensure testing strategy -6. Generate completion reports -``` - ---- - -## Commands - -### 1. Sprint Plan Command - -**File:** `commands/sprint-plan.md` - -**Usage:** `/sprint-plan` - -**Description:** Initiates sprint planning with the planner agent - -**Flow:** - -``` -User: /sprint-plan - -Planner: Let me help you plan this sprint. - - What are you building? - -User: Extract Intuit engine into separate service - -Planner: I detected architectural changes - this is Type/Refactor. - - Searching lessons learned for "service extraction"... - 📚 Found 2 relevant lessons: - - Sprint 08: Service boundary issues with shared DB - - Sprint 12: API versioning during extraction - - Which components are affected? - - Component/Backend - - Component/API - - Component/Database - - Should we create a Gitea issue for tracking? - -User: Yes - -Planner: Created issue #47 with labels: - - Type/Refactor - - Component/Backend - - Component/API - - Component/Database - - Priority/High - - Source/Development - - Generating sprint plan... - - Sprint Plan: Intuit Engine Extraction - ===================================== - - ## Architecture - [Detailed architecture analysis] - - ## Tasks - 1. Define service boundaries - 2. Design API contracts - 3. Extract database schema - 4. Implement service - 5. Update CuisineFlow integration - 6. Deploy and test - - ## Risks - - Database migration complexity - - API versioning challenges - - ## Timeline - Estimated: 2 weeks - - ## References - - Lesson: Sprint 08 (service boundaries) - - Lesson: Sprint 12 (API versioning) -``` - -**Success Criteria:** -- Issue created with correct labels -- Lessons learned referenced -- Sprint document generated -- Only creates issues in development branch - -### 2. Sprint Start Command - -**File:** `commands/sprint-start.md` - -**Usage:** `/sprint-start` - -**Description:** Starts sprint with relevant lessons surfaced - -**Flow:** - -``` -User: /sprint-start - -Orchestrator: Starting sprint... - - Sprint Issue: #47 - Intuit Engine Extraction - - Searching lessons learned for relevant context... - 📚 Found 2 relevant lessons: - - Sprint 08: Service boundary issues with shared DB - → Key takeaway: Define clear service boundaries before extracting - - Sprint 12: API versioning during extraction - → Key takeaway: Version APIs from the start - - These might be helpful for this extraction work. - - Next Steps: - 1. Review architectural decisions from planning - 2. Define service boundaries - 3. Create API contract specifications - - Ready to begin. Use /sprint-status to check progress. -``` - -**Success Criteria:** -- Searches lessons learned -- Surfaces relevant past experiences -- Links to sprint issue -- Provides helpful context - -### 3. Sprint Status Command - -**File:** `commands/sprint-status.md` - -**Usage:** `/sprint-status` - -**Description:** Check current sprint progress - -**Flow:** - -``` -User: /sprint-status - -Orchestrator: Sprint Status: Intuit Engine Extraction - Issue: #47 - - Progress: 60% complete - - ✅ Completed: - - Define service boundaries - - Design API contracts - - Extract database schema - - 🔄 In Progress: - - Implement service (80%) - - ⏳ Remaining: - - Update CuisineFlow integration - - Deploy and test - - 🚫 Blockers: - None identified - - Next Action: - Complete service implementation, then move to integration testing -``` - -**Success Criteria:** -- Clear status overview -- Identifies blockers -- Actionable next steps -- Links to relevant issues - -### 4. Sprint Close Command - -**File:** `commands/sprint-close.md` - -**Usage:** `/sprint-close` - -**Description:** Closes sprint and captures lessons learned - -**Flow:** - -``` -User: /sprint-close - -Orchestrator: Let's close this sprint and capture lessons learned... - - What went wrong that we should avoid next time? - -User: Database migration took longer than expected due to foreign key constraints - -Orchestrator: What decisions worked really well? - -User: Defining API contracts upfront prevented integration issues - -Orchestrator: Were there any Claude Code issues that caused loops/blocks? - -User: Yes, Claude got stuck in a loop trying to fix a circular import - -Orchestrator: Any architectural insights for similar future work? - -User: Service boundaries need to be defined at the data model level first - -Orchestrator: I'll create a lesson in Wiki.js: - - Sprint 16: Intuit Engine Extraction - Lessons Learned - ===================================================== - - ## What Went Wrong - - Database migration took longer than expected due to FK constraints - → Always map FK relationships before extraction - - ## What Worked Well - - API contracts defined upfront prevented integration issues - → Continue this practice for all service extractions - - ## Claude Code Issues - - Circular import loop in service initialization - → Watch for import cycles in new services - - ## Architecture Insights - - Service boundaries must be defined at data model level first - → Data-first approach for future extractions - - Tags detected: - #service-extraction #api #database #refactoring #claude-code-loops - - Creating page in Wiki.js... ✅ - Path: /your-org/projects/my-project/lessons-learned/sprints/sprint-16-intuit-engine - - Updating INDEX.md... ✅ - - Closing sprint issue #47... ✅ - - View lesson at: https://wiki.your-company.com/your-org/projects/my-project/lessons-learned/sprints/sprint-16-intuit-engine -``` - -**Success Criteria:** -- Interactive retrospective guide -- Document created in Wiki.js -- INDEX.md updated with tags -- Sprint issue closed -- Lessons searchable for future sprints - -### 5. Labels Sync Command - -**File:** `commands/labels-sync.md` - -**Usage:** `/labels-sync` - -**Description:** Sync label taxonomy from Gitea - -**Flow:** - -``` -User: /labels-sync - -Agent: Fetching labels from Gitea... - Comparing with local reference... - - Found 1 new label: Type/Documentation - Found 2 modified descriptions - - New Label: - - Type/Documentation - Color: #0052cc - Description: Documentation-only changes - → Should update suggestion logic to detect "docs", "readme" - - Modified Label: - - Priority/High - Old: "High priority issues" - New: "Blocks sprint completion or important feature" - → Description clarified - - - Component/API - Old: "API related" - New: "REST/GraphQL API endpoints and contracts" - → More specific description - - Shall I update the local reference and suggestion rules? - -User: Yes - -Agent: Updated ✅ - - labels-reference.md updated with 44 labels (was 43) - - Suggestion logic updated to detect documentation keywords - - Label descriptions synchronized - - Summary: - - Organization labels: 28 (was 27) - - Repository labels: 16 - - Total: 44 labels in taxonomy -``` - -**Success Criteria:** -- Fetches live data from Gitea -- Diff detection works correctly -- Agent provides meaningful impact analysis -- Local reference stays synchronized -- Suggestion logic updated as needed - ---- - -## Label Taxonomy System - -### 43-Label System - -**Organization Labels (27):** -- **Agent/2:** Agent-assigned vs user-created -- **Complexity/3:** Low, Medium, High -- **Efforts/5:** XS, S, M, L, XL -- **Priority/4:** Low, Medium, High, Critical -- **Risk/3:** Low, Medium, High -- **Source/4:** Development, Staging, Production, External -- **Type/6:** Bug, Feature, Refactor, Documentation, Test, Chore - -**Repository Labels (16):** -- **Component/9:** Backend, Frontend, API, Database, Auth, Deploy, Testing, Docs, Infra -- **Tech/7:** Python, JavaScript, Docker, PostgreSQL, Redis, Vue, FastAPI - -### Type/Refactor Label - -**Important:** `Type/Refactor` is now implemented at organization level - -**Usage:** -- Architectural changes -- Service extraction (like Intuit engine) -- Code restructuring without feature changes -- Performance optimizations requiring significant changes -- Technical debt reduction - -**Detection Keywords:** -- "extract", "refactor", "restructure" -- "optimize architecture" -- "service boundary", "microservice", "decouple" -- "technical debt", "code quality" - -### Skill: Label Taxonomy - -**File:** `skills/label-taxonomy/labels-reference.md` - -This skill provides the complete label reference and is loaded when relevant. It includes: -- Full label list with descriptions -- Exclusive vs non-exclusive rules -- Color codes -- Usage guidelines -- Example scenarios - ---- - -## Branch-Aware Security Model - -Plugin behavior adapts to the current Git branch to prevent accidental changes: - -### Development Mode - -**Branches:** `development`, `feat/*`, `feature/*` - -**Permissions:** -- Full access to all operations -- Can create Gitea issues -- Can modify all files -- Can capture lessons learned - -### Staging Mode - -**Branches:** `staging`, `stage/*` - -**Permissions:** -- Read-only for application code -- Can modify `.env` files -- Can create issues to document needed fixes -- Warns on attempted code changes - -**Behavior:** -``` -User: /sprint-plan - -Agent: ⚠️ Warning: You're on the 'staging' branch. - - I can help with planning and create issues for tracking, - but implementation should be done on a development branch. - - Proceed with planning? -``` - -### Production Mode - -**Branches:** `main`, `master`, `prod/*` - -**Permissions:** -- Read-only for application code -- Emergency-only `.env` modifications -- Can create incident issues -- Blocks code changes - -**Behavior:** -``` -User: /sprint-plan - -Agent: 🚫 Error: You're on the 'main' (production) branch. - - Sprint planning and implementation must be done on development branches. - Creating issues is allowed for incident tracking. - - Please switch to a development branch to proceed. -``` - ---- - -## Implementation Phases - -### Phase 1: Core Infrastructure - -**Deliverable:** Working MCP servers with hybrid configuration - -**Tasks:** -1. Set up Gitea MCP server (see MCP-GITEA.md) -2. Set up Wiki.js MCP server (see MCP-WIKIJS.md) -3. Create plugin structure -4. Configure `.mcp.json` to reference shared servers -5. Test configuration loading -6. Validate MCP server connections - -**Success Criteria:** -- Both MCP servers running -- Configuration loads correctly -- Plugin can communicate with Gitea and Wiki.js -- Mode detection works (project mode) - -### Phase 2: Sprint Planning Commands - -**Deliverable:** `/sprint-plan`, `/sprint-start`, `/sprint-status`, `/sprint-close` commands - -**Tasks:** -1. Create command markdown files -2. Define command parameters -3. Integrate with agents -4. Handle branch detection -5. Test command workflows - -**Success Criteria:** -- All commands work end-to-end -- Branch detection prevents wrong-branch operations -- Issue creation works -- Lessons learned captured - -### Phase 3: Agent System - -**Deliverable:** Planner, Orchestrator, Executor agents - -**Tasks:** -1. Create agent markdown prompts -2. Define agent personalities -3. Design interaction patterns -4. Integrate with MCP tools -5. Test agent behaviors - -**Success Criteria:** -- Agents provide valuable guidance -- Questions are relevant -- Label suggestions accurate -- Sprint documents well-structured - -### Phase 4: Lessons Learned System - -**Deliverable:** Integrated lessons learned in Wiki.js - -**Tasks:** -1. Design Wiki.js page structure -2. Create INDEX.md template -3. Build search integration -4. Implement capture workflow -5. Test tag-based filtering - -**Success Criteria:** -- Lessons captured during sprint close -- INDEX.md updated automatically -- Search finds relevant lessons -- Tags work for categorization - -### Phase 5: Testing & Validation - -**Deliverable:** Comprehensive test coverage - -**Tasks:** -1. Write integration tests -2. Test with real sprint -3. Validate configuration scenarios -4. Test branch detection -5. Collect user feedback - -**Success Criteria:** -- All tests pass -- Real sprint handled successfully -- No critical bugs -- Saves time vs manual process - -### Phase 6: Documentation & Refinement - -**Deliverable:** Complete documentation - -**Tasks:** -1. Write README.md -2. Write CONFIGURATION.md -3. Create ARCHITECTURE.md -4. Write CONTRIBUTING.md -5. Iterate based on feedback - -**Success Criteria:** -- Clear setup instructions -- Configuration well-explained -- Examples provided -- Ready for team use - -### Phase 7: Marketplace Preparation - -**Deliverable:** Plugin available in Gitea marketplace - -**Tasks:** -1. Create marketplace repository -2. Add plugin to marketplace -3. Create marketplace.json -4. Test installation -5. Document for team - -**Success Criteria:** -- Plugin available via marketplace -- Installation works smoothly -- Team can access plugin -- Documentation clear - -### Phase 8: Production Hardening - -**Deliverable:** Production-ready plugin - -**Tasks:** -1. Implement error handling -2. Optimize performance -3. Security audit -4. Logging and monitoring -5. Final testing - -**Success Criteria:** -- Graceful failure handling -- Fast performance -- No security vulnerabilities -- Ready for production use - ---- - -## Usage Examples - -### Example 1: Bug Fix Sprint - -``` -User: /sprint-plan - -Planner: What are you building? - -User: Fix authentication bug where tokens expire early - -Planner: I detected a bug fix. - - Searching lessons learned for "authentication"... - 📚 Found 1 lesson: - - Sprint 01: Token expiration issues - - This is Type/Bug with Component/Auth. - Priority? - -User: High - -Planner: Created issue #52: - Labels: Type/Bug, Component/Auth, Priority/High, Source/Development - - Sprint Plan: Fix Token Expiration Bug - ===================================== - [Plan details] -``` - -### Example 2: New Feature Sprint - -``` -User: /sprint-plan - -Planner: What are you building? - -User: Add export functionality to reports - -Planner: This is a new feature. - - Components affected: - - Component/Backend (export logic) - - Component/API (export endpoint) - - Component/Frontend (export button) - - Complexity? - -User: Medium - -Planner: Created issue #53: - Labels: Type/Feature, Component/Backend, Component/API, Component/Frontend, - Complexity/Medium, Priority/Medium, Source/Development - - [Sprint plan generated] -``` - -### Example 3: Refactor Sprint - -``` -User: /sprint-plan - -Planner: What are you building? - -User: Refactor database access layer for better testability - -Planner: I detected architectural changes - this is Type/Refactor. - - Searching lessons learned for "refactor"... - 📚 Found 3 lessons from similar refactoring work - - This affects Component/Backend and Component/Database. - Risk level? - -User: Medium - -Planner: Created issue #54: - Labels: Type/Refactor, Component/Backend, Component/Database, - Risk/Medium, Priority/Medium, Efforts/L, Source/Development - - [Refactoring plan with architecture considerations] -``` - ---- - -## Best Practices - -### 1. Always Start with Planning - -Use `/sprint-plan` to: -- Search relevant lessons learned -- Get label suggestions -- Create tracked issues -- Generate structured plans - -### 2. Check Status Regularly - -Use `/sprint-status` to: -- Monitor progress -- Identify blockers early -- Stay on track -- Update stakeholders - -### 3. Always Close with Lessons - -Use `/sprint-close` to: -- Capture what went wrong -- Document what worked -- Record Claude Code issues -- Share architectural insights - -### 4. Keep Labels Current - -Use `/labels-sync` to: -- Stay synchronized with Gitea -- Update suggestion logic -- Maintain accurate taxonomy - -### 5. Branch Awareness - -- Do planning on development branches -- Don't attempt code changes on staging/production -- Use production branch only for incidents - ---- - -## Troubleshooting - -### Issue: Plugin not loading - -**Solution:** -```bash -# Check plugin manifest -cat projman/.claude-plugin/plugin.json - -# Verify MCP servers are accessible -ls -la ../mcp-servers/gitea -ls -la ../mcp-servers/wikijs - -# Check MCP server virtual environments -ls ../mcp-servers/gitea/.venv -ls ../mcp-servers/wikijs/.venv -``` - -### Issue: MCP tools not working - -**Solution:** -```bash -# Verify environment variables are set -env | grep GITEA -env | grep WIKIJS - -# Check system configs exist -cat ~/.config/claude/gitea.env -cat ~/.config/claude/wikijs.env - -# Check project config -cat .env -``` - -### Issue: Lessons learned not saving - -**Solution:** -- Verify Wiki.js connectivity -- Check Wiki.js API token permissions -- Ensure base structure exists in Wiki.js -- Verify project path in WIKIJS_PROJECT - -### Issue: Labels not suggesting correctly - -**Solution:** -- Run `/labels-sync` to update taxonomy -- Check label reference in `skills/label-taxonomy/` -- Verify Gitea has correct labels -- Test with clear keywords - ---- - -## Next Steps - -1. **Complete MCP server setup** (see MCP-GITEA.md and MCP-WIKIJS.md) -2. **Create plugin structure** -3. **Implement commands** (Phase 2) -4. **Create agents** (Phase 3) -5. **Test with real sprint** (Phase 5) -6. **Deploy to team** (Phase 7) diff --git a/docs/references/PROJECT-SUMMARY.md b/docs/references/PROJECT-SUMMARY.md deleted file mode 100644 index 5a283f4..0000000 --- a/docs/references/PROJECT-SUMMARY.md +++ /dev/null @@ -1,692 +0,0 @@ -# Project Management Plugins - Project Summary - -## Overview - -This project builds two Claude Code plugins that transform a proven 15-sprint workflow into reusable, distributable tools for managing software development with Gitea, Wiki.js, and agile methodologies. - -**Status:** Planning phase complete, ready for implementation - ---- - -## The Two Plugins - -### 1. projman (Single-Repository) - -**Purpose:** Project management for individual repositories -**Users:** Developers, Team Leads -**Build Order:** Build FIRST - -**Key Features:** -- Sprint planning with AI agents -- Issue creation with 43-label taxonomy -- Lessons learned capture in Wiki.js -- Branch-aware security model -- Hybrid configuration system - -**Reference:** [PLUGIN-PROJMAN.md](./PLUGIN-PROJMAN.md) - -### 2. projman-pmo (Multi-Project) - -**Purpose:** PMO coordination across organization -**Users:** PMO Coordinators, Engineering Managers, CTOs -**Build Order:** Build SECOND (after projman validated) - -**Key Features:** -- Cross-project status aggregation -- Dependency tracking and visualization -- Resource conflict detection -- Release coordination -- Company-wide lessons learned search - -**Reference:** [PLUGIN-PMO.md](./PLUGIN-PMO.md) - ---- - -## Core Architecture - -### Shared MCP Servers - -Both plugins share the same MCP server codebase at repository root (`mcp-servers/`): - -**1. Gitea MCP Server** -- Issue management (CRUD operations) -- Label taxonomy system (43 labels) -- Mode detection (project vs company-wide) - -**Reference:** [MCP-GITEA.md](./MCP-GITEA.md) - -**2. Wiki.js MCP Server** -- Documentation management -- Lessons learned capture and search -- GraphQL API integration -- Company-wide knowledge base - -**Reference:** [MCP-WIKIJS.md](./MCP-WIKIJS.md) - -### Mode Detection - -The MCP servers detect their operating mode based on environment variables: - -**Project Mode (projman):** -- `GITEA_REPO` present → operates on single repository -- `WIKIJS_PROJECT` present → operates on single project path - -**Company Mode (pmo):** -- No `GITEA_REPO` → operates on all repositories -- No `WIKIJS_PROJECT` → operates on entire company namespace - ---- - -## Repository Structure - -``` -personal-projects/support-claude-mktplace/ -├── mcp-servers/ # ← SHARED BY BOTH PLUGINS -│ ├── gitea/ # Gitea MCP Server -│ │ ├── .venv/ -│ │ ├── requirements.txt -│ │ ├── mcp_server/ -│ │ └── tests/ -│ └── wikijs/ # Wiki.js MCP Server -│ ├── .venv/ -│ ├── requirements.txt -│ ├── mcp_server/ -│ └── tests/ -├── projman/ # ← PROJECT PLUGIN -│ ├── .claude-plugin/ -│ │ └── plugin.json -│ ├── .mcp.json # Points to ../mcp-servers/ -│ ├── commands/ -│ │ ├── sprint-plan.md -│ │ ├── sprint-start.md -│ │ ├── sprint-status.md -│ │ ├── sprint-close.md -│ │ └── labels-sync.md -│ ├── agents/ -│ │ ├── planner.md -│ │ ├── orchestrator.md -│ │ └── executor.md -│ ├── skills/ -│ │ └── label-taxonomy/ -│ ├── README.md -│ └── CONFIGURATION.md -└── projman-pmo/ # ← PMO PLUGIN - ├── .claude-plugin/ - │ └── plugin.json - ├── .mcp.json # Points to ../mcp-servers/ - ├── commands/ - │ ├── pmo-status.md - │ ├── pmo-priorities.md - │ ├── pmo-dependencies.md - │ └── pmo-schedule.md - ├── agents/ - │ └── pmo-coordinator.md - └── README.md -``` - ---- - -## Configuration Architecture - -### Hybrid Configuration System - -The plugins use a hybrid configuration approach that balances security and flexibility: - -**System-Level (Once per machine):** -- `~/.config/claude/gitea.env` - Gitea credentials -- `~/.config/claude/wikijs.env` - Wiki.js credentials - -**Project-Level (Per repository):** -- `project-root/.env` - Repository and project paths - -**Benefits:** -- Single token per service (update once) -- Project isolation -- Security (tokens never committed) -- Easy multi-project setup - -### Configuration Example - -**System-Level:** -```bash -# ~/.config/claude/gitea.env -GITEA_API_URL=https://gitea.example.com/api/v1 -GITEA_API_TOKEN=your_token -GITEA_OWNER=bandit - -# ~/.config/claude/wikijs.env -WIKIJS_API_URL=https://wiki.your-company.com/graphql -WIKIJS_API_TOKEN=your_token -WIKIJS_BASE_PATH=/your-org -``` - -**Project-Level:** -```bash -# project-root/.env (for projman) -GITEA_REPO=cuisineflow -WIKIJS_PROJECT=projects/cuisineflow - -# No .env needed for pmo (company-wide mode) -``` - ---- - -## Key Architectural Decisions - -### 1. Two MCP Servers (Shared) - -**Decision:** Separate Gitea and Wiki.js servers at repository root -**Why:** -- Clear separation of concerns -- Independent configuration -- Better maintainability -- Professional architecture - -### 2. Python Implementation - -**Decision:** Python 3.10+ for MCP servers -**Why:** -- Modern async/await improvements -- Better type hints support -- Good balance of compatibility vs features -- Widely available (released Oct 2021) -- Most production servers have 3.10+ by now - -### 3. Wiki.js for Lessons Learned - -**Decision:** Use Wiki.js instead of Git-based Wiki -**Why:** -- Rich editor and search -- Built-in tag system -- Version history -- Web-based collaboration -- GraphQL API -- Company-wide accessibility - -### 4. Hybrid Configuration - -**Decision:** System-level + project-level configuration -**Why:** -- Single token per service (security) -- Per-project customization (flexibility) -- Easy multi-project setup -- Never commit tokens to git - -### 5. Mode Detection in MCP Servers - -**Decision:** Detect mode based on environment variables -**Why:** -- Same codebase for both plugins -- No code duplication -- Fix bugs once, both benefit -- Clear separation of concerns - -### 6. Build Order: projman First - -**Decision:** Build projman completely before starting pmo -**Why:** -- Validate core functionality -- Establish patterns -- Reduce risk -- PMO builds on projman foundation - ---- - -## The Three-Agent Model - -### Projman Agents - -**Planner Agent:** -- Sprint planning and architecture analysis -- Asks clarifying questions -- Suggests appropriate labels -- Creates Gitea issues -- Searches relevant lessons learned - -**Orchestrator Agent:** -- Sprint progress monitoring -- Task coordination -- Blocker identification -- Git operations -- Generates lean execution prompts - -**Executor Agent:** -- Implementation guidance -- Code review suggestions -- Testing strategy -- Quality standards enforcement -- Documentation - -### PMO Agent - -**PMO Coordinator:** -- Strategic view across all projects -- Cross-project dependency tracking -- Resource conflict detection -- Release coordination -- Delegates to projman agents for details - ---- - -## Wiki.js Structure - -``` -Wiki.js: https://wiki.your-company.com -└── /your-org/ - ├── projects/ # Project-specific - │ ├── project-a/ - │ │ ├── lessons-learned/ - │ │ │ ├── sprints/ - │ │ │ ├── patterns/ - │ │ │ └── INDEX.md - │ │ └── documentation/ - │ ├── project-b/ - │ ├── project-c/ - │ └── company-site/ - ├── company/ # Company-wide - │ ├── processes/ - │ ├── standards/ - │ └── tools/ - └── shared/ # Cross-project - ├── architecture-patterns/ - ├── best-practices/ - └── tech-stack/ -``` - -**Reference:** [MCP-WIKIJS.md](./MCP-WIKIJS.md#wiki-js-structure) - ---- - -## Label Taxonomy System - -### Dynamic Label System (44 labels currently) - -Labels are **fetched dynamically from Gitea** at runtime via the `/labels-sync` command: - -**Organization Labels (28):** -- Agent/2 -- Complexity/3 -- Efforts/5 -- Priority/4 -- Risk/3 -- Source/4 -- Type/6 (Bug, Feature, Refactor, Documentation, Test, Chore) - -**Repository Labels (16):** -- Component/9 (Backend, Frontend, API, Database, Auth, Deploy, Testing, Docs, Infra) -- Tech/7 (Python, JavaScript, Docker, PostgreSQL, Redis, Vue, FastAPI) - -### Type/Refactor Label - -**Organization-level label** for architectural work: -- Service extraction -- Architecture modifications -- Code restructuring -- Technical debt reduction - -**Note:** Label count may change. Always sync from Gitea using `/labels-sync` command. When new labels are detected, the command will explain changes and update suggestion logic. - -**Reference:** [PLUGIN-PROJMAN.md](./PLUGIN-PROJMAN.md#label-taxonomy-system) - ---- - -## Build Order & Phases - -### Build projman First (Phases 1-8) - -**Phase 1:** Core Infrastructure (MCP servers) -**Phase 2:** Sprint Planning Commands -**Phase 3:** Agent System -**Phase 4:** Lessons Learned System -**Phase 5:** Testing & Validation -**Phase 6:** Documentation & Refinement -**Phase 7:** Marketplace Preparation -**Phase 8:** Production Hardening - -**Reference:** [PLUGIN-PROJMAN.md](./PLUGIN-PROJMAN.md#implementation-phases) - -### Build pmo Second (Phases 9-12) - -**Phase 9:** PMO Plugin Foundation -**Phase 10:** PMO Commands & Workflows -**Phase 11:** PMO Testing & Integration -**Phase 12:** Production Deployment - -**Reference:** [PLUGIN-PMO.md](./PLUGIN-PMO.md#implementation-phases) - ---- - -## Quick Start Guide - -### 1. System Configuration - -```bash -# Create config directory -mkdir -p ~/.config/claude - -# Gitea config -cat > ~/.config/claude/gitea.env << EOF -GITEA_API_URL=https://gitea.example.com/api/v1 -GITEA_API_TOKEN=your_gitea_token -GITEA_OWNER=bandit -EOF - -# Wiki.js config -cat > ~/.config/claude/wikijs.env << EOF -WIKIJS_API_URL=https://wiki.your-company.com/graphql -WIKIJS_API_TOKEN=your_wikijs_token -WIKIJS_BASE_PATH=/your-org -EOF - -# Secure files -chmod 600 ~/.config/claude/*.env -``` - -### 2. Project Configuration - -```bash -# In each project root (for projman) -cat > .env << EOF -GITEA_REPO=cuisineflow -WIKIJS_PROJECT=projects/cuisineflow -EOF - -# Add to .gitignore -echo ".env" >> .gitignore -``` - -### 3. MCP Server Setup - -```bash -# Gitea MCP Server -cd mcp-servers/gitea -python -m venv .venv -source .venv/bin/activate -pip install -r requirements.txt - -# Wiki.js MCP Server -cd mcp-servers/wikijs -python -m venv .venv -source .venv/bin/activate -pip install -r requirements.txt -``` - -### 4. Validate Setup - -```bash -# Test MCP servers -python -m mcp_server.server --test # In each MCP directory - -# Test plugin loading -claude plugin test projman -claude plugin test projman-pmo -``` - ---- - -## Document Organization - -This documentation is organized into 4 focused files plus this summary: - -### 1. Gitea MCP Server Reference - -**File:** [MCP-GITEA.md](./MCP-GITEA.md) - -**Contains:** -- Configuration setup -- Python implementation -- API client code -- Issue and label tools -- Testing strategies -- Mode detection -- Performance optimization - -**Use when:** Implementing or troubleshooting Gitea integration - -### 2. Wiki.js MCP Server Reference - -**File:** [MCP-WIKIJS.md](./MCP-WIKIJS.md) - -**Contains:** -- Configuration setup -- GraphQL client implementation -- Wiki.js structure -- Lessons learned system -- Documentation tools -- Company-wide patterns -- PMO multi-project methods - -**Use when:** Implementing or troubleshooting Wiki.js integration - -### 3. Projman Plugin Reference - -**File:** [PLUGIN-PROJMAN.md](./PLUGIN-PROJMAN.md) - -**Contains:** -- Plugin structure -- Commands (sprint-plan, sprint-start, sprint-status, sprint-close, labels-sync) -- Three agents (planner, orchestrator, executor) -- Sprint workflow -- Label taxonomy -- Branch-aware security -- Implementation phases 1-8 - -**Use when:** Building or using the projman plugin - -### 4. PMO Plugin Reference - -**File:** [PLUGIN-PMO.md](./PLUGIN-PMO.md) - -**Contains:** -- PMO plugin structure -- Multi-project commands -- PMO coordinator agent -- Cross-project coordination -- Dependency tracking -- Resource conflict detection -- Implementation phases 9-12 - -**Use when:** Building or using the projman-pmo plugin - -### 5. This Summary - -**File:** PROJECT-SUMMARY.md (this document) - -**Contains:** -- Project overview -- Architecture decisions -- Configuration approach -- Quick start guide -- References to detailed docs - -**Use when:** Getting started or need high-level overview - ---- - -## Key Success Metrics - -### Technical Metrics - -- Sprint planning time reduced by 40% -- Manual steps eliminated: 10+ per sprint -- Lessons learned capture rate: 100% (vs 0% before) -- Label accuracy on issues: 90%+ -- Configuration setup time: < 5 minutes - -### User Metrics - -- User satisfaction: Better than current manual workflow -- Learning curve: < 1 hour to basic proficiency -- Error rate: < 5% incorrect operations -- Adoption rate: 100% team adoption within 1 month - -### PMO Metrics - -- Cross-project visibility: 100% (vs fragmented before) -- Dependency detection: Automated (vs manual tracking) -- Resource conflict identification: Proactive (vs reactive) -- Release coordination: Streamlined (vs ad-hoc) - ---- - -## Critical Lessons from 15 Sprints - -### Why Lessons Learned Is Critical - -After 15 sprints without systematic lesson capture, repeated mistakes occurred: -- Claude Code infinite loops on similar issues: 2-3 times -- Same architectural mistakes: Multiple occurrences -- Forgotten optimizations: Re-discovered each time - -**Solution:** Mandatory lessons learned capture at sprint close, searchable at sprint start - -### Branch Detection Must Be 100% Reliable - -Production accidents are unacceptable. Branch-aware security prevents: -- Accidental code changes on production branch -- Sprint planning on wrong branch -- Deployment mistakes - -**Implementation:** Two layers - CLAUDE.md (file-level) + Plugin agents (tool-level) - -### Configuration Complexity Is a Blocker - -Previous attempts failed due to: -- Complex per-project setup -- Token management overhead -- Multiple configuration files - -**Solution:** Hybrid approach - system-level tokens + simple project-level paths - ---- - -## Next Steps - -### Immediate Actions - -1. **Set up system configuration** (Gitea + Wiki.js tokens) -2. **Create Wiki.js base structure** at `/your-org` -3. **Begin Phase 1.1a** - Gitea MCP Server implementation -4. **Begin Phase 1.1b** - Wiki.js MCP Server implementation - -### Phase Execution - -1. **Phases 1-4:** Build core projman functionality -2. **Phase 5:** Validate with real sprint (e.g., Intuit Engine extraction) -3. **Phases 6-8:** Polish, document, and harden projman -4. **Phases 9-12:** Build and validate pmo plugin - -### Validation Points - -- **After Phase 1:** MCP servers working and tested -- **After Phase 4:** Complete projman workflow end-to-end -- **After Phase 5:** Real sprint successfully managed -- **After Phase 8:** Production-ready projman -- **After Phase 11:** Multi-project coordination validated -- **After Phase 12:** Complete system operational - ---- - -## Implementation Decisions (Pre-Development) - -These decisions were finalized before development: - -### 1. Python Version: 3.10+ -- **Rationale:** Balance of modern features and wide availability -- **Benefits:** Modern async, good type hints, widely deployed -- **Minimum:** Python 3.10.0 - -### 2. Wiki.js Base Structure: Needs Creation -- **Status:** `/your-org` structure does NOT exist yet -- **Action:** Run `setup_wiki_structure.py` during Phase 1.1b -- **Script:** See MCP-WIKIJS.md for complete setup script -- **Post-setup:** Verify at https://wiki.your-company.com/your-org - -### 3. Testing Strategy: Both Mocks and Real APIs -- **Unit tests:** Use mocks for fast feedback during development -- **Integration tests:** Use real Gitea/Wiki.js APIs for validation -- **CI/CD:** Run both test suites -- **Developers:** Can skip integration tests locally if needed -- **Markers:** Use pytest markers (`@pytest.mark.integration`) - -### 4. Token Permissions: Confirmed -- **Gitea token:** - - `repo` (all) - Read/write repositories, issues, labels - - `read:org` - Organization information and labels - - `read:user` - User information -- **Wiki.js token:** - - Read/create/update pages - - Manage tags - - Search access - -### 5. Label System: Dynamic (44 labels) -- **Current count:** 44 labels (28 org + 16 repo) -- **Approach:** Fetch dynamically via API, never hardcode -- **Sync:** `/labels-sync` command updates local reference and suggestion logic -- **New labels:** Command explains changes and asks for confirmation - -### 6. Branch Detection: Defense in Depth -- **Layer 1:** MCP tools check branch and block operations -- **Layer 2:** Agent prompts check branch and warn users -- **Layer 3:** CLAUDE.md provides context (third layer) -- **Rationale:** Multiple layers prevent production accidents - ---- - -## Important Reminders - -1. **Build projman FIRST** - Don't start pmo until projman is validated -2. **MCP servers are SHARED** - Located at `mcp-servers/`, not inside plugins -3. **Lessons learned is critical** - Prevents repeated mistakes -4. **Test with real work** - Validate with actual sprints, not just unit tests -5. **Security first** - Branch detection must be 100% reliable -6. **Keep it simple** - Avoid over-engineering, focus on proven workflow -7. **Python 3.10+** - Minimum version requirement -8. **Wiki.js setup** - Must run setup script before projman works - ---- - -## Getting Help - -### Documentation Structure - -**Need details on:** -- Gitea integration → [MCP-GITEA.md](./MCP-GITEA.md) -- Wiki.js integration → [MCP-WIKIJS.md](./MCP-WIKIJS.md) -- Projman usage → [PLUGIN-PROJMAN.md](./PLUGIN-PROJMAN.md) -- PMO usage → [PLUGIN-PMO.md](./PLUGIN-PMO.md) -- Overview → This document - -### Quick Reference - -| Question | Reference | -|----------|-----------| -| How do I set up configuration? | This document, "Quick Start Guide" | -| What's the repository structure? | This document, "Repository Structure" | -| How do Gitea tools work? | [MCP-GITEA.md](./MCP-GITEA.md) | -| How do Wiki.js tools work? | [MCP-WIKIJS.md](./MCP-WIKIJS.md) | -| How do I use sprint commands? | [PLUGIN-PROJMAN.md](./PLUGIN-PROJMAN.md#commands) | -| How do agents work? | [PLUGIN-PROJMAN.md](./PLUGIN-PROJMAN.md#three-agent-model) | -| How do I coordinate multiple projects? | [PLUGIN-PMO.md](./PLUGIN-PMO.md) | -| What's the build order? | This document, "Build Order & Phases" | - ---- - -## Project Timeline - -**Planning:** Complete ✅ -**Phase 1-8 (projman):** 6-8 weeks estimated -**Phase 9-12 (pmo):** 2-4 weeks estimated -**Total:** 8-12 weeks from start to production - -**Note:** No fixed deadlines - work at sustainable pace and validate thoroughly - ---- - -## You're Ready! - -You have everything you need to build the projman and projman-pmo plugins. All architectural decisions are finalized and documented. - -**Start here:** [MCP-GITEA.md](./MCP-GITEA.md) - Set up Gitea MCP Server - -Good luck with the build! 🚀 diff --git a/plugins/projman/mcp-servers/gitea/README.md b/plugins/projman/mcp-servers/gitea/README.md index d91225e..4f4c96f 100644 --- a/plugins/projman/mcp-servers/gitea/README.md +++ b/plugins/projman/mcp-servers/gitea/README.md @@ -393,16 +393,15 @@ MIT License - Part of the Claude Code Marketplace project. ## Related Documentation -- **MCP Specification**: `docs/references/MCP-GITEA.md` -- **Project Summary**: `docs/references/PROJECT-SUMMARY.md` -- **Implementation Plan**: `docs/reference-material/projman-implementation-plan.md` +- **Projman Documentation**: `plugins/projman/README.md` +- **Configuration Guide**: `plugins/projman/CONFIGURATION.md` - **Testing Guide**: `TESTING.md` ## Support For issues or questions: 1. Check [TESTING.md](./TESTING.md) troubleshooting section -2. Review [MCP-GITEA.md](../../docs/references/MCP-GITEA.md) specification +2. Review [plugins/projman/README.md](../../README.md) for plugin documentation 3. Create an issue in the project repository --- diff --git a/plugins/projman/mcp-servers/gitea/TESTING.md b/plugins/projman/mcp-servers/gitea/TESTING.md index c901b50..d4faa51 100644 --- a/plugins/projman/mcp-servers/gitea/TESTING.md +++ b/plugins/projman/mcp-servers/gitea/TESTING.md @@ -574,8 +574,8 @@ After completing testing: - **MCP Documentation**: https://docs.anthropic.com/claude/docs/mcp - **Gitea API Documentation**: https://docs.gitea.io/en-us/api-usage/ -- **Project Documentation**: `docs/references/MCP-GITEA.md` -- **Implementation Plan**: `docs/references/PROJECT-SUMMARY.md` +- **Projman Documentation**: `plugins/projman/README.md` +- **Configuration Guide**: `plugins/projman/CONFIGURATION.md` ---