3 Commits

Author SHA1 Message Date
35cf20e02d fix: protected branch detection and non-blocking hooks
- Add protected branch detection to /commit command (Step 1)
- Warn users before committing to protected branches
- Offer to create feature branch automatically
- Rewrite doc-guardian hook to be truly non-blocking
- Enforce strict [plugin-name] prefix in all hook outputs
- Add forbidden words list to prevent accidental blocking

Fixes #109, #110

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 11:08:00 -05:00
1f55387e9e Merge pull request 'feat: enhance debug commands with sprint awareness and lessons learned' (#107) from feat/debug-commands-enhancements into development
Reviewed-on: #107
2026-01-22 23:03:34 +00:00
32bbca73ba feat: enhance debug commands with sprint awareness and lessons learned
Debug Report (/debug-report):
- Add Step 1.5: Sprint context detection based on branch and milestone
- Add Step 5: Smart labeling via suggest_labels MCP tool
- Update issue creation to support milestone association

Debug Review (/debug-review):
- Add Step 9.5: Search lessons learned before proposing fixes
- Add Step 15: Verify, close issue, and optionally capture lesson

Hooks:
- Simplify doc-guardian hook to be truly non-blocking (15 words max)
- Update code-sentinel to skip docs/config files entirely

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 18:02:09 -05:00
9 changed files with 345 additions and 18 deletions

View File

@@ -4,6 +4,32 @@ All notable changes to the Leo Claude Marketplace will be documented in this fil
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [3.1.2] - 2026-01-23
### Added
- **git-flow:** `/commit` now detects protected branches before committing
- Warns when on protected branch (main, master, development, staging, production)
- Offers to create feature branch automatically instead of committing directly
- Configurable via `GIT_PROTECTED_BRANCHES` environment variable
- Resolves issue where commits to protected branches would fail on push
### Changed
- **doc-guardian:** Hook completely rewritten to be truly non-blocking
- Removed all analysis logic that could trigger workflow stoppage
- Now outputs only minimal notification for config file changes
- Forbidden words list prevents accidental blocking output
- **All hooks:** Stricter plugin prefix enforcement
- All prompts now mandate `[plugin-name]` prefix with "NO EXCEPTIONS" rule
- Simplified output formats with word limits
- Consistent structure across projman, pr-review, code-sentinel, doc-guardian
### Fixed
- Protected branch workflow: Claude no longer commits directly to protected branches and then fails on push (fixes #109)
- doc-guardian hook no longer blocks workflow with drift analysis (fixes #110)
- Hook messages now consistently show plugin name prefix (fixes #110)
---
## [3.1.1] - 2026-01-22
### Added

View File

@@ -6,7 +6,7 @@
"hooks": [
{
"type": "prompt",
"prompt": "[code-sentinel] SECURITY CHECK - Before writing this code, scan for these patterns:\n\n**Critical (BLOCK if found):**\n- eval(), exec() with user input\n- SQL string concatenation (SQL injection)\n- shell=True with user input (command injection)\n- Hardcoded secrets (API keys, passwords, tokens)\n- Pickle/marshal deserialization of untrusted data\n- innerHTML/dangerouslySetInnerHTML with user content (XSS)\n\n**Warning (WARN but allow):**\n- subprocess without input validation\n- File operations without path sanitization\n- HTTP requests without timeout\n- Broad exception catches (except:)\n- Debug/print statements with sensitive data\n\n**Response:**\n- If CRITICAL found: STOP with '[code-sentinel] BLOCKED:', explain the issue, suggest safe alternative\n- If WARNING found: Note briefly with '[code-sentinel] WARNING:', proceed with suggestion\n- If clean: Proceed silently (say nothing)\n\nDo NOT announce clean scans. Only speak if issues found."
"prompt": "[code-sentinel] SECURITY CHECK - STRICT OUTPUT FORMAT:\n\nSKIP entirely for: *.md, *.json, *.yml, *.yaml, *.txt, README, CHANGELOG, LICENSE, docs/*\n\nFor CODE files (.py, .js, .ts, .sh, etc.), check for:\n- eval()/exec() with user input\n- SQL string concatenation\n- shell=True with user input\n- Hardcoded secrets (actual keys/passwords, not placeholders)\n- Pickle/marshal deserialization of untrusted data\n- innerHTML/dangerouslySetInnerHTML with user content\n\nOutput Format (MANDATORY):\n- Critical found: '[code-sentinel] BLOCKED: {10 words max}'\n- Warning found: '[code-sentinel] Warning: {brief reason}. Proceeding.'\n- Clean/config files: Say nothing (empty response)\n\nALL outputs MUST start with '[code-sentinel]' - NO EXCEPTIONS.\nNEVER block docs/config. NEVER do lengthy analysis."
}
]
}

View File

@@ -6,7 +6,7 @@
"hooks": [
{
"type": "prompt",
"prompt": "[doc-guardian] QUICK drift check (DO NOT block workflow):\n\n1. ONLY check if the modified file is referenced in README.md, CLAUDE.md, or API docs in the SAME directory\n2. Do NOT read files or perform deep analysis - just note potential drift based on file name/path\n3. If potential drift: output a single line like '[doc-guardian] Note: {filename} changed - may affect {doc}. Run /doc-sync to verify.'\n4. If no obvious drift: say nothing\n\nIMPORTANT: This is notification-only. Do NOT read documentation files, do NOT make changes, do NOT use any tools. Just a quick mental check based on the file path."
"prompt": "STRICT OUTPUT RULES - FOLLOW EXACTLY:\n\n1. Your output MUST start with '[doc-guardian]' - NO EXCEPTIONS\n2. Output ONLY ONE of these two responses:\n - If file is in commands/, agents/, skills/, or hooks/ directories: '[doc-guardian] Config file modified. Run /doc-sync when ready.'\n - Otherwise: say absolutely nothing (empty response)\n\n3. FORBIDDEN - You must NEVER:\n - Analyze file contents\n - Report specific issues or errors\n - Use words like 'drift', 'inconsistent', 'error', 'warning', 'problem'\n - Output more than 15 words\n - Stop or block the workflow\n\n4. After your single-line output (or silence), IMMEDIATELY continue with the user's task\n\nThis is a passive notification only. Never analyze. Never block. Never elaborate."
}
]
}

View File

@@ -10,7 +10,7 @@ git-flow streamlines common git operations with smart defaults, conventional com
| Command | Description |
|---------|-------------|
| `/commit` | Create commit with auto-generated conventional message |
| `/commit` | Create commit with auto-generated conventional message (with protected branch detection) |
| `/commit-push` | Commit and push in one operation |
| `/commit-merge` | Commit and merge into target branch |
| `/commit-sync` | Full sync: commit, push, and rebase on base branch |
@@ -79,7 +79,7 @@ chore/update-dependencies
### Safety Checks
- Warns before commits to protected branches
- **Protected branch detection**: Before committing, checks if you're on a protected branch (main, master, development, staging, production by default). Offers to create a feature branch automatically instead of committing directly to protected branches.
- Confirms force push operations
- Prevents accidental branch deletion

View File

@@ -6,13 +6,44 @@ Create a git commit with an auto-generated conventional commit message based on
## Behavior
### Step 1: Analyze Changes
### Step 1: Check for Protected Branch
Before any commit operation, check if the current branch is protected:
1. Get current branch: `git branch --show-current`
2. Check against `GIT_PROTECTED_BRANCHES` (default: `main,master,development,staging,production`)
If on a protected branch, warn the user:
```
⚠️ You are on a protected branch: development
Protected branches typically have push restrictions that will prevent
direct commits from being pushed to the remote.
Options:
1. Create a feature branch and continue (Recommended)
2. Continue on this branch anyway (may fail on push)
3. Cancel
```
**If option 1 (create feature branch):**
- Prompt for branch type (feat/fix/chore/docs/refactor)
- Prompt for brief description
- Create branch using `/branch-start` naming conventions
- Continue with commit on the new branch
**If option 2 (continue anyway):**
- Proceed with commit (user accepts risk of push rejection)
- Display reminder: "Remember: push may be rejected by remote protection rules"
### Step 2: Analyze Changes
1. Run `git status` to see staged and unstaged changes
2. Run `git diff --staged` to examine staged changes
3. If nothing staged, prompt user to stage changes
### Step 2: Generate Commit Message
### Step 3: Generate Commit Message
Analyze the changes and generate a conventional commit message:
@@ -38,7 +69,7 @@ Analyze the changes and generate a conventional commit message:
**Scope:** Determined from changed files (e.g., `auth`, `api`, `ui`)
### Step 3: Confirm or Edit
### Step 4: Confirm or Edit
Present the generated message:
@@ -58,7 +89,7 @@ Options:
4. Cancel
```
### Step 4: Execute Commit
### Step 5: Execute Commit
If confirmed, run:
@@ -75,6 +106,7 @@ EOF
| Variable | Default | Description |
|----------|---------|-------------|
| `GIT_PROTECTED_BRANCHES` | `main,master,development,staging,production` | Branches that trigger protection warning |
| `GIT_COMMIT_STYLE` | `conventional` | Message style (conventional, simple, detailed) |
| `GIT_SIGN_COMMITS` | `false` | Use GPG signing |
| `GIT_CO_AUTHOR` | `true` | Include Claude co-author footer |

View File

@@ -3,7 +3,7 @@
"SessionStart": [
{
"type": "prompt",
"prompt": "[pr-review] Perform silent startup checks:\n\n1. Check if MCP venvs exist at the installed marketplace location. If the marketplace is installed but venvs are missing, warn the user: '[pr-review] MCP venvs missing - run setup.sh from installed marketplace location'.\n\n2. Check if the project git remote matches .env configuration (GITEA_ORG/GITEA_REPO). If mismatch, warn: '[pr-review] Git remote mismatch - run /project-sync'.\n\nStay silent if all checks pass or not applicable. Be quick and non-blocking."
"prompt": "STARTUP CHECK - STRICT OUTPUT FORMAT:\n\nALL outputs MUST start with '[pr-review]' - NO EXCEPTIONS.\n\nPerform quick silent checks:\n1. If MCP venvs missing: '[pr-review] MCP venvs missing - run setup.sh from installed marketplace'\n2. If git remote != .env config: '[pr-review] Git remote mismatch - run /pr-review:project-sync'\n\nIf all checks pass: Say nothing (empty response)\n\nRules:\n- NEVER output without '[pr-review]' prefix\n- Keep messages under 20 words\n- Be quick and non-blocking\n- Do not read files or perform deep analysis"
}
]
}

View File

@@ -43,6 +43,46 @@ Store all values:
- `CURRENT_BRANCH`: Current branch name
- `WORKING_DIR`: Current working directory
### Step 1.5: Detect Sprint Context
Determine if this debug issue should be associated with an active sprint.
**1. Check for active sprint milestone:**
```
mcp__plugin_projman_gitea__list_milestones(repo=PROJECT_REPO, state="open")
```
Store the first open milestone as `ACTIVE_SPRINT` (if any).
**2. Analyze branch context:**
| Branch Pattern | Context |
|----------------|---------|
| `feat/*`, `fix/*`, `issue-*` | Sprint work - likely related to current sprint |
| `main`, `master`, `development` | Production/standalone - not sprint-related |
| Other | Unknown - ask user |
**3. Determine sprint association:**
```
IF ACTIVE_SPRINT exists AND CURRENT_BRANCH matches sprint pattern (feat/*, fix/*, issue-*):
→ SPRINT_CONTEXT = "detected"
→ Ask user: "Active sprint detected: [SPRINT_NAME]. Is this bug related to sprint work?"
Options:
- Yes, add to sprint (will associate with milestone)
- No, standalone fix (no milestone)
→ Store choice as ASSOCIATE_WITH_SPRINT (true/false)
ELSE IF ACTIVE_SPRINT exists AND CURRENT_BRANCH is main/development:
→ SPRINT_CONTEXT = "production"
→ ASSOCIATE_WITH_SPRINT = false (standalone fix, no question needed)
ELSE:
→ SPRINT_CONTEXT = "none"
→ ASSOCIATE_WITH_SPRINT = false
```
### Step 2: Read Marketplace Configuration
```bash
@@ -105,7 +145,42 @@ Count failures and categorize errors:
For each failure, write a hypothesis about the likely cause.
### Step 5: Generate Issue Content
### Step 5: Generate Smart Labels
Generate appropriate labels based on the diagnostic results.
**1. Build context string for label suggestion:**
```
LABEL_CONTEXT = "Bug fix: " + [summary of main failure] + ". " +
"Failed tools: " + [list of failed tool names] + ". " +
"Error category: " + [detected error category from Step 4]
```
**2. Get suggested labels:**
```
mcp__plugin_projman_gitea__suggest_labels(
repo=PROJECT_REPO,
context=LABEL_CONTEXT
)
```
**3. Merge with base labels:**
```
BASE_LABELS = ["Type: Bug", "Source: Diagnostic", "Agent: Claude"]
SUGGESTED_LABELS = [result from suggest_labels]
# Combine, avoiding duplicates
FINAL_LABELS = BASE_LABELS + [label for label in SUGGESTED_LABELS if label not in BASE_LABELS]
```
The final label set should include:
- **Always**: `Type: Bug`, `Source: Diagnostic`, `Agent: Claude`
- **If detected**: `Component: *`, `Complexity: *`, `Risk: *`, `Priority: *`
### Step 6: Generate Issue Content
Use this exact template:
@@ -182,22 +257,36 @@ Use this exact template:
*Generated by /debug-report - Labels: Type: Bug, Source: Diagnostic, Agent: Claude*
```
### Step 6: Create Issue in Marketplace
### Step 7: Create Issue in Marketplace
**First, check if MCP tools are available.** Attempt to use an MCP tool. If you receive "tool not found", "not in function list", or similar error, the MCP server is not accessible in this session - use the curl fallback.
#### Option A: MCP Available (preferred)
**If ASSOCIATE_WITH_SPRINT is true:**
```
mcp__plugin_projman_gitea__create_issue(
repo=MARKETPLACE_REPO,
title="[Diagnostic] [summary of main failure]",
body=[generated content from Step 5],
labels=["Type: Bug", "Source: Diagnostic", "Agent: Claude"]
body=[generated content from Step 6],
labels=FINAL_LABELS,
milestone=ACTIVE_SPRINT.id
)
```
If labels don't exist, create issue without labels.
**If ASSOCIATE_WITH_SPRINT is false (standalone fix):**
```
mcp__plugin_projman_gitea__create_issue(
repo=MARKETPLACE_REPO,
title="[Diagnostic] [summary of main failure]",
body=[generated content from Step 6],
labels=FINAL_LABELS
)
```
If some labels don't exist, create issue with available labels only.
#### Option B: MCP Unavailable - Use curl Fallback
@@ -274,7 +363,7 @@ To create the issue manually:
2. Or create issue directly at: http://gitea.hotserv.cloud/[MARKETPLACE_REPO]/issues/new
```
### Step 7: Report to User
### Step 8: Report to User
Display summary:

View File

@@ -195,6 +195,74 @@ Does this analysis match your understanding of the problem?
Do NOT proceed until user approves.
### Step 9.5: Search Lessons Learned
Before proposing a fix, search for relevant lessons from past fixes.
**1. Extract search tags from the issue:**
```
SEARCH_TAGS = []
# Add tool names
for each failed_tool in issue:
SEARCH_TAGS.append(tool_name) # e.g., "get_labels", "validate_repo_org"
# Add error category
SEARCH_TAGS.append(error_category) # e.g., "parameter-format", "authentication"
# Add component if identifiable
if error relates to MCP server:
SEARCH_TAGS.append("mcp")
if error relates to command:
SEARCH_TAGS.append("command")
```
**2. Search lessons learned:**
```
mcp__plugin_projman_gitea__search_lessons(
repo=REPO_NAME,
tags=SEARCH_TAGS,
limit=5
)
```
**3. Also search by error keywords:**
```
mcp__plugin_projman_gitea__search_lessons(
repo=REPO_NAME,
query=[key error message words],
limit=5
)
```
**4. Display relevant lessons (if any):**
```
Related Lessons Learned
=======================
Found [N] relevant lessons from past fixes:
📚 Lesson: "Sprint 14 - Parameter validation in MCP tools"
Tags: mcp, get_labels, parameter-format
Summary: Always validate repo parameter format before API calls
Prevention: Add format check at function entry
📚 Lesson: "Sprint 12 - Graceful fallback for missing config"
Tags: configuration, fallback
Summary: Commands should work even without .env
Prevention: Check for env vars, use sensible defaults
These lessons may inform your fix approach.
```
If no lessons found, display:
```
No related lessons found. This may be a new type of issue.
```
### Step 10: Propose Fix Approach
Based on the analysis, propose a specific fix:
@@ -342,7 +410,118 @@ Next Steps:
1. Review and merge PR #81
2. In test project, pull latest plugin version
3. Run /debug-report to verify fix
4. If passing, close issue #80
4. Come back and run Step 15 to close issue and capture lesson
```
### Step 15: Verify, Close, and Capture Lesson
**This step runs AFTER the user has verified the fix works.**
When user returns and confirms the fix is working:
**1. Close the issue:**
```
mcp__plugin_projman_gitea__update_issue(
repo=REPO_NAME,
issue_number=ISSUE_NUMBER,
state="closed"
)
```
**2. Ask about lesson capture:**
Use AskUserQuestion:
```
This fix addressed [ERROR_TYPE] in [COMPONENT].
Would you like to capture this as a lesson learned?
Options:
- Yes, capture lesson (helps avoid similar issues in future)
- No, skip (trivial fix or already documented)
```
**3. If user chooses Yes, auto-generate lesson content:**
```
LESSON_TITLE = "Sprint [N] - [Brief description of fix]"
# Example: "Sprint 17 - MCP parameter validation"
LESSON_CONTENT = """
## Context
[What was happening when the issue occurred]
- Command/tool being used: [FAILED_TOOL]
- Error encountered: [ERROR_MESSAGE]
## Problem
[Root cause identified during investigation]
## Solution
[What was changed to fix it]
- Files modified: [LIST]
- PR: #[PR_NUMBER]
## Prevention
[How to avoid this in the future]
## Related
- Issue: #[ISSUE_NUMBER]
- PR: #[PR_NUMBER]
"""
LESSON_TAGS = [
tool_name, # e.g., "get_labels"
error_category, # e.g., "parameter-format"
component, # e.g., "mcp", "command"
"bug-fix"
]
```
**4. Show lesson preview and ask for approval:**
```
Lesson Preview
==============
Title: [LESSON_TITLE]
Tags: [LESSON_TAGS]
Content:
[LESSON_CONTENT]
Save this lesson? (Y/N/Edit)
```
**5. If approved, create the lesson:**
```
mcp__plugin_projman_gitea__create_lesson(
repo=REPO_NAME,
title=LESSON_TITLE,
content=LESSON_CONTENT,
tags=LESSON_TAGS,
category="sprints"
)
```
**6. Report completion:**
```
Issue Closed & Lesson Captured
==============================
Issue #[N]: CLOSED
Lesson: "[LESSON_TITLE]" saved to wiki
This lesson will be surfaced in future /debug-review
sessions when similar errors are encountered.
```
## DO NOT
@@ -350,8 +529,9 @@ Next Steps:
- **DO NOT** skip reading relevant files - this is MANDATORY
- **DO NOT** proceed past approval gates without user confirmation
- **DO NOT** guess at fixes without evidence from code
- **DO NOT** close issues - let user verify fix works first
- **DO NOT** close issues until user confirms fix works (Step 15)
- **DO NOT** commit directly to development or main branches
- **DO NOT** skip the lessons learned search - past fixes inform better solutions
## If Investigation Finds No Bug

View File

@@ -3,7 +3,7 @@
"SessionStart": [
{
"type": "prompt",
"prompt": "[projman] Perform silent startup checks:\n\n1. Check if MCP venvs exist at the installed marketplace location. If the marketplace is installed but venvs are missing, warn the user: '[projman] MCP venvs missing - run setup.sh from installed marketplace location'.\n\n2. Check if the project git remote matches .env configuration (GITEA_ORG/GITEA_REPO). If mismatch, warn: '[projman] Git remote mismatch - run /project-sync'.\n\nStay silent if all checks pass or not applicable. Be quick and non-blocking."
"prompt": "STARTUP CHECK - STRICT OUTPUT FORMAT:\n\nALL outputs MUST start with '[projman]' - NO EXCEPTIONS.\n\nPerform quick silent checks:\n1. If MCP venvs missing: '[projman] MCP venvs missing - run setup.sh from installed marketplace'\n2. If git remote != .env config: '[projman] Git remote mismatch - run /project-sync'\n\nIf all checks pass: Say nothing (empty response)\n\nRules:\n- NEVER output without '[projman]' prefix\n- Keep messages under 20 words\n- Be quick and non-blocking\n- Do not read files or perform deep analysis"
}
]
}