9 Commits

Author SHA1 Message Date
d2b6560fba Merge pull request 'development' (#318) from development into main
Reviewed-on: #318
2026-01-29 17:00:15 +00:00
7c3a2ac31c Merge pull request 'fix(projman): remove automatic cache clearing from session start hook' (#317) from fix/remove-auto-cache-clear into development
Reviewed-on: #317
2026-01-29 16:59:53 +00:00
e0ab4c2ddf fix(projman): remove automatic cache clearing from session start hook
The startup-check.sh hook was clearing ~/.claude/plugins/cache/ at every
session start, which was aggressive and potentially disruptive. Cache
clearing is now a manual operation via the new /clear-cache command.

Changes:
- Remove automatic cache clearing from startup-check.sh
- Add /clear-cache command for manual cache clearing when needed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 11:58:31 -05:00
4b1c561bb6 Merge pull request 'development' (#316) from development into main
Reviewed-on: #316
2026-01-29 03:20:50 +00:00
5f82f8ebbd Merge pull request 'fix(gitea-mcp): accept string or integer for numeric params' (#315) from fix/mcp-integer-type-coercion into development
Reviewed-on: #315
2026-01-29 03:20:10 +00:00
b492a13702 fix(gitea-mcp): accept string or integer for numeric params
MCP library validates schema BEFORE call_tool handler runs, so
our _coerce_types function never gets a chance to convert strings.

Changed all integer fields to accept both types:
- issue_number, milestone_id, pr_number, depends_on, milestone, limit, position

This fixes: "Input validation error: '312' is not of type 'integer'"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 22:17:19 -05:00
786d3c0013 Merge pull request 'development' (#314) from development into main
Reviewed-on: #314
2026-01-29 03:13:15 +00:00
5aaab4cb9a Merge pull request 'fix(doc-guardian): make hook silent by default' (#313) from fix/312-doc-guardian-silent-hook into development
Reviewed-on: #313
2026-01-29 03:12:40 +00:00
3c3b3b4575 fix(doc-guardian): make hook silent by default
- Remove all output by default to prevent workflow interruption
- Queue changes silently to .doc-guardian-queue
- Add file+type deduplication (same file won't be queued twice)
- Add DOC_GUARDIAN_VERBOSE=1 env var for opt-in notifications
- Users run /doc-sync or /doc-audit to process queue

Fixes #312 (partial - addresses issues 1, 2, 3)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 22:12:09 -05:00
4 changed files with 64 additions and 66 deletions

View File

@@ -144,7 +144,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Issue number" "description": "Issue number"
}, },
"repo": { "repo": {
@@ -189,7 +189,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Issue number" "description": "Issue number"
}, },
"title": { "title": {
@@ -211,7 +211,7 @@ class GiteaMCPServer:
"description": "New labels" "description": "New labels"
}, },
"milestone": { "milestone": {
"type": "integer", "type": ["integer", "string"],
"description": "Milestone ID to assign" "description": "Milestone ID to assign"
}, },
"repo": { "repo": {
@@ -229,7 +229,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Issue number" "description": "Issue number"
}, },
"comment": { "comment": {
@@ -424,7 +424,7 @@ class GiteaMCPServer:
"description": "Tags to filter by (optional)" "description": "Tags to filter by (optional)"
}, },
"limit": { "limit": {
"type": "integer", "type": ["integer", "string"],
"default": 20, "default": 20,
"description": "Maximum results" "description": "Maximum results"
}, },
@@ -462,7 +462,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"milestone_id": { "milestone_id": {
"type": "integer", "type": ["integer", "string"],
"description": "Milestone ID" "description": "Milestone ID"
}, },
"repo": { "repo": {
@@ -506,7 +506,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"milestone_id": { "milestone_id": {
"type": "integer", "type": ["integer", "string"],
"description": "Milestone ID" "description": "Milestone ID"
}, },
"title": { "title": {
@@ -541,7 +541,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"milestone_id": { "milestone_id": {
"type": "integer", "type": ["integer", "string"],
"description": "Milestone ID" "description": "Milestone ID"
}, },
"repo": { "repo": {
@@ -560,7 +560,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Issue number" "description": "Issue number"
}, },
"repo": { "repo": {
@@ -578,11 +578,11 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Issue that will depend on another" "description": "Issue that will depend on another"
}, },
"depends_on": { "depends_on": {
"type": "integer", "type": ["integer", "string"],
"description": "Issue that blocks issue_number" "description": "Issue that blocks issue_number"
}, },
"repo": { "repo": {
@@ -600,11 +600,11 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"issue_number": { "issue_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Issue that depends on another" "description": "Issue that depends on another"
}, },
"depends_on": { "depends_on": {
"type": "integer", "type": ["integer", "string"],
"description": "Issue being depended on" "description": "Issue being depended on"
}, },
"repo": { "repo": {
@@ -782,7 +782,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"pr_number": { "pr_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Pull request number" "description": "Pull request number"
}, },
"repo": { "repo": {
@@ -800,7 +800,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"pr_number": { "pr_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Pull request number" "description": "Pull request number"
}, },
"repo": { "repo": {
@@ -818,7 +818,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"pr_number": { "pr_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Pull request number" "description": "Pull request number"
}, },
"repo": { "repo": {
@@ -836,7 +836,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"pr_number": { "pr_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Pull request number" "description": "Pull request number"
}, },
"body": { "body": {
@@ -855,7 +855,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"path": {"type": "string"}, "path": {"type": "string"},
"position": {"type": "integer"}, "position": {"type": ["integer", "string"]},
"body": {"type": "string"} "body": {"type": "string"}
} }
}, },
@@ -876,7 +876,7 @@ class GiteaMCPServer:
"type": "object", "type": "object",
"properties": { "properties": {
"pr_number": { "pr_number": {
"type": "integer", "type": ["integer", "string"],
"description": "Pull request number" "description": "Pull request number"
}, },
"body": { "body": {

View File

@@ -1,11 +1,12 @@
#!/bin/bash #!/bin/bash
# doc-guardian notification hook # doc-guardian notification hook
# Tracks documentation dependencies and queues updates # Tracks documentation dependencies and queues updates
# This is a command hook - guaranteed not to block workflow
# #
# IMPORTANT: Output is purely informational - uses passive language # SILENT BY DEFAULT - No output to avoid interrupting Claude's workflow.
# to avoid triggering Claude to seek user confirmation. # Changes are queued to .doc-guardian-queue for later processing.
# Run /doc-sync to process the queue when ready. # Run /doc-sync or /doc-audit to see and process pending updates.
#
# Set DOC_GUARDIAN_VERBOSE=1 to enable notification output.
# Read tool input from stdin (JSON with file_path) # Read tool input from stdin (JSON with file_path)
INPUT=$(cat) INPUT=$(cat)
@@ -48,40 +49,26 @@ DEPENDENT_DOCS="${DOC_DEPS[$MODIFIED_TYPE]}"
# Queue file for tracking pending updates # Queue file for tracking pending updates
QUEUE_FILE="${CLAUDE_PROJECT_ROOT:-.}/.doc-guardian-queue" QUEUE_FILE="${CLAUDE_PROJECT_ROOT:-.}/.doc-guardian-queue"
# Debounce: skip notification if same type was logged in last 5 seconds # Add to queue (always, for deduplication we check file+type combo)
# This prevents 4+ rapid notifications during batch edits # Format: timestamp | type | file_path | dependent_docs
DEBOUNCE_SECONDS=5 QUEUE_ENTRY="$(date +%Y-%m-%dT%H:%M:%S) | $MODIFIED_TYPE | $FILE_PATH | $DEPENDENT_DOCS"
# Check if this exact file+type combo already exists in queue (dedup)
if [ -f "$QUEUE_FILE" ]; then if [ -f "$QUEUE_FILE" ]; then
LAST_ENTRY=$(tail -1 "$QUEUE_FILE" 2>/dev/null || true) if grep -qF "| $MODIFIED_TYPE | $FILE_PATH |" "$QUEUE_FILE" 2>/dev/null; then
LAST_TYPE=$(echo "$LAST_ENTRY" | cut -d'|' -f2 | tr -d ' ') # Already queued, skip silently
LAST_TIME=$(echo "$LAST_ENTRY" | cut -d'|' -f1 | tr -d ' ') exit 0
if [ "$LAST_TYPE" = "$MODIFIED_TYPE" ] && [ -n "$LAST_TIME" ]; then
# Convert timestamps to seconds for comparison
LAST_EPOCH=$(date -d "$LAST_TIME" +%s 2>/dev/null || echo "0")
NOW_EPOCH=$(date +%s)
DIFF=$((NOW_EPOCH - LAST_EPOCH))
if [ "$DIFF" -lt "$DEBOUNCE_SECONDS" ]; then
# Still add to queue, but skip notification
{
echo "$(date +%Y-%m-%dT%H:%M:%S) | $MODIFIED_TYPE | $FILE_PATH | $DEPENDENT_DOCS"
} >> "$QUEUE_FILE" 2>/dev/null || true
exit 0
fi
fi fi
fi fi
# Add to queue (create if doesn't exist, append if does) # Add to queue
{ echo "$QUEUE_ENTRY" >> "$QUEUE_FILE" 2>/dev/null || true
echo "$(date +%Y-%m-%dT%H:%M:%S) | $MODIFIED_TYPE | $FILE_PATH | $DEPENDENT_DOCS"
} >> "$QUEUE_FILE" 2>/dev/null || true
# Count pending updates # SILENT by default - only output if DOC_GUARDIAN_VERBOSE is set
PENDING_COUNT=$(wc -l < "$QUEUE_FILE" 2>/dev/null | tr -d ' ' || echo "1") # This prevents Claude from stopping to ask about documentation updates
if [ "${DOC_GUARDIAN_VERBOSE:-0}" = "1" ]; then
# Output passive notification (no action implied) PENDING_COUNT=$(wc -l < "$QUEUE_FILE" 2>/dev/null | tr -d ' ' || echo "1")
# Uses "queued" instead of "update needed" to avoid triggering Claude to ask about it echo "[doc-guardian] queued: $MODIFIED_TYPE ($PENDING_COUNT pending)"
echo "[doc-guardian] drift queued: $MODIFIED_TYPE$DEPENDENT_DOCS ($PENDING_COUNT total)" fi
exit 0 exit 0

View File

@@ -0,0 +1,24 @@
# /clear-cache
Clear plugin cache to force fresh configuration reload. Run this after marketplace updates.
## When to Use
- After updating the marketplace (`git pull` or reinstall)
- When MCP servers show stale configuration
- When plugin changes don't take effect
## What It Does
1. Clears `~/.claude/plugins/cache/leo-claude-mktplace/`
2. Forces Claude Code to re-read `.mcp.json` files on next session
## Instructions
Run this command, then **restart your Claude Code session** for changes to take effect.
```bash
rm -rf ~/.claude/plugins/cache/leo-claude-mktplace/
```
After clearing, inform the user: "Cache cleared. Restart Claude Code for changes to take effect."

View File

@@ -10,19 +10,6 @@ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "$(realpath "$0")")")}"
# Marketplace root is 2 levels up from plugin root (plugins/projman -> .) # Marketplace root is 2 levels up from plugin root (plugins/projman -> .)
MARKETPLACE_ROOT="$(dirname "$(dirname "$PLUGIN_ROOT")")" MARKETPLACE_ROOT="$(dirname "$(dirname "$PLUGIN_ROOT")")"
VENV_REPAIR_SCRIPT="$MARKETPLACE_ROOT/scripts/venv-repair.sh" VENV_REPAIR_SCRIPT="$MARKETPLACE_ROOT/scripts/venv-repair.sh"
PLUGIN_CACHE="$HOME/.claude/plugins/cache/leo-claude-mktplace"
# ============================================================================
# Clear stale plugin cache (MUST run before MCP servers load)
# ============================================================================
# The cache at ~/.claude/plugins/cache/ holds versioned .mcp.json files.
# After marketplace updates, cached configs may point to old paths.
# Clearing forces Claude to read fresh configs from installed marketplace.
if [[ -d "$PLUGIN_CACHE" ]]; then
rm -rf "$PLUGIN_CACHE"
# Don't output anything - this should be silent and automatic
fi
# ============================================================================ # ============================================================================
# Auto-repair MCP venvs (runs before other checks) # Auto-repair MCP venvs (runs before other checks)