6 Commits

Author SHA1 Message Date
36e6ac2dd0 Merge pull request 'development' (#283) from development into main
Reviewed-on: #283
2026-01-28 21:48:57 +00:00
d27c440631 Merge pull request 'fix(gitea-mcp): address MCP tool issues from Sprint 6' (#282) from fix/281-mcp-tool-issues into development
Reviewed-on: #282
2026-01-28 21:48:07 +00:00
e56d685a68 fix(gitea-mcp): address MCP tool issues from Sprint 6
Fixes #281 - Multiple MCP tool issues discovered during sprint execution

## Changes

1. **list_issues Token Overflow** (Issue 1)
   - Added `milestone` parameter to filter issues server-side
   - Reduces response size by filtering at API level instead of client-side

2. **Type Coercion for MCP Serialization** (Issues 2 & 4)
   - Added `_coerce_types()` helper function in server.py
   - Handles integers passed as strings (milestone_id, issue_number, etc.)
   - Handles arrays passed as JSON strings (labels, tags, etc.)
   - Applied to all tool calls automatically

3. **Sprint Approval Check Clarification** (Issue 3)
   - Updated sprint-start.md to clarify approval is RECOMMENDED, not enforced
   - Changed STOP/block language to WARN/suggest language
   - Added note explaining this is workflow guidance, not code-enforced

## Files Changed
- mcp-servers/gitea/mcp_server/gitea_client.py: Added milestone param
- mcp-servers/gitea/mcp_server/tools/issues.py: Pass milestone param
- mcp-servers/gitea/mcp_server/server.py: Type coercion + milestone schema
- plugins/projman/commands/sprint-start.md: Clarified approval check

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 15:57:42 -05:00
3e0e779803 Merge pull request 'development' (#280) from development into main
Reviewed-on: #280
2026-01-28 20:37:52 +00:00
5638891d01 Merge pull request 'fix(projman): add new command verification step to sprint-close' (#279) from fix/sprint-close-new-command-verification into development
Reviewed-on: #279
2026-01-28 20:37:23 +00:00
611b50b150 fix(projman): add new command verification step to sprint-close
Addresses issue #278 - sprint-diagram command not discoverable after Sprint 4.

Root cause: Claude Code discovers skills at session start. Commands added
during a session are NOT discoverable until restart.

Prevention: Added step 7 "New Command Verification" to sprint-close workflow:
- Reminds about session restart requirement
- Creates follow-up verification task
- Explains why this happens

Lesson learned created: lessons/patterns/sprint-4---new-commands-not-discoverable-until-session-restart

Closes #278

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 15:36:11 -05:00
5 changed files with 89 additions and 26 deletions

View File

@@ -53,6 +53,7 @@ class GiteaClient:
self, self,
state: str = 'open', state: str = 'open',
labels: Optional[List[str]] = None, labels: Optional[List[str]] = None,
milestone: Optional[str] = None,
repo: Optional[str] = None repo: Optional[str] = None
) -> List[Dict]: ) -> List[Dict]:
""" """
@@ -61,6 +62,7 @@ class GiteaClient:
Args: Args:
state: Issue state (open, closed, all) state: Issue state (open, closed, all)
labels: Filter by labels labels: Filter by labels
milestone: Filter by milestone title (exact match)
repo: Repository in 'owner/repo' format repo: Repository in 'owner/repo' format
Returns: Returns:
@@ -71,6 +73,8 @@ class GiteaClient:
params = {'state': state} params = {'state': state}
if labels: if labels:
params['labels'] = ','.join(labels) params['labels'] = ','.join(labels)
if milestone:
params['milestones'] = milestone
logger.info(f"Listing issues from {owner}/{target_repo} with state={state}") logger.info(f"Listing issues from {owner}/{target_repo} with state={state}")
response = self.session.get(url, params=params) response = self.session.get(url, params=params)
response.raise_for_status() response.raise_for_status()

View File

@@ -26,6 +26,44 @@ logging.getLogger("mcp").setLevel(logging.ERROR)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def _coerce_types(arguments: dict) -> dict:
"""
Coerce argument types to handle MCP serialization quirks.
MCP sometimes passes integers as strings and arrays as JSON strings.
This function normalizes them to the expected Python types.
"""
coerced = {}
for key, value in arguments.items():
if value is None:
coerced[key] = value
continue
# Coerce integer fields
int_fields = {'issue_number', 'milestone_id', 'pr_number', 'depends_on', 'milestone', 'limit'}
if key in int_fields and isinstance(value, str):
try:
coerced[key] = int(value)
continue
except ValueError:
pass
# Coerce array fields that might be JSON strings
array_fields = {'labels', 'tags', 'issue_numbers', 'comments'}
if key in array_fields and isinstance(value, str):
try:
parsed = json.loads(value)
if isinstance(parsed, list):
coerced[key] = parsed
continue
except json.JSONDecodeError:
pass
coerced[key] = value
return coerced
class GiteaMCPServer: class GiteaMCPServer:
"""MCP Server for Gitea integration""" """MCP Server for Gitea integration"""
@@ -88,6 +126,10 @@ class GiteaMCPServer:
"items": {"type": "string"}, "items": {"type": "string"},
"description": "Filter by labels" "description": "Filter by labels"
}, },
"milestone": {
"type": "string",
"description": "Filter by milestone title (exact match)"
},
"repo": { "repo": {
"type": "string", "type": "string",
"description": "Repository name (for PMO mode)" "description": "Repository name (for PMO mode)"
@@ -899,6 +941,9 @@ class GiteaMCPServer:
List of TextContent with results List of TextContent with results
""" """
try: try:
# Coerce types to handle MCP serialization quirks
arguments = _coerce_types(arguments)
# Route to appropriate tool handler # Route to appropriate tool handler
if name == "list_issues": if name == "list_issues":
result = await self.issue_tools.list_issues(**arguments) result = await self.issue_tools.list_issues(**arguments)

View File

@@ -98,6 +98,7 @@ class IssueTools:
self, self,
state: str = 'open', state: str = 'open',
labels: Optional[List[str]] = None, labels: Optional[List[str]] = None,
milestone: Optional[str] = None,
repo: Optional[str] = None repo: Optional[str] = None
) -> List[Dict]: ) -> List[Dict]:
""" """
@@ -106,6 +107,7 @@ class IssueTools:
Args: Args:
state: Issue state (open, closed, all) state: Issue state (open, closed, all)
labels: Filter by labels labels: Filter by labels
milestone: Filter by milestone title (exact match)
repo: Override configured repo (for PMO multi-repo) repo: Override configured repo (for PMO multi-repo)
Returns: Returns:
@@ -124,7 +126,7 @@ class IssueTools:
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
return await loop.run_in_executor( return await loop.run_in_executor(
None, None,
lambda: self.gitea.list_issues(state, labels, repo) lambda: self.gitea.list_issues(state, labels, milestone, repo)
) )
async def get_issue( async def get_issue(

View File

@@ -54,23 +54,32 @@ The orchestrator agent will guide you through:
- If partial: Keep status as "In Progress", note completed implementations - If partial: Keep status as "In Progress", note completed implementations
- Add summary of what was accomplished - Add summary of what was accomplished
7. **Update CHANGELOG** (MANDATORY) 7. **New Command Verification** (if applicable)
- Check if this sprint added new commands or skills
- **IMPORTANT:** New commands are NOT discoverable until session restart
- If new commands were added:
- List them in sprint close notes
- Remind user: "New commands require session restart to test"
- Create verification task in next sprint or backlog
- **WHY:** Claude Code discovers skills at session start; commands added during a session won't work until restart
8. **Update CHANGELOG** (MANDATORY)
- Add all sprint changes to `[Unreleased]` section in CHANGELOG.md - Add all sprint changes to `[Unreleased]` section in CHANGELOG.md
- Categorize: Added, Changed, Fixed, Removed, Deprecated - Categorize: Added, Changed, Fixed, Removed, Deprecated
- Include plugin prefix (e.g., `- **projman:** New feature`) - Include plugin prefix (e.g., `- **projman:** New feature`)
8. **Version Check** 9. **Version Check**
- Run `/suggest-version` to analyze changes and recommend version bump - Run `/suggest-version` to analyze changes and recommend version bump
- If release warranted: run `./scripts/release.sh X.Y.Z` - If release warranted: run `./scripts/release.sh X.Y.Z`
- Ensures version numbers stay in sync across files - Ensures version numbers stay in sync across files
9. **Git Operations** 10. **Git Operations**
- Commit any remaining work (including CHANGELOG updates) - Commit any remaining work (including CHANGELOG updates)
- Merge feature branches if needed - Merge feature branches if needed
- Clean up merged branches - Clean up merged branches
- Tag sprint completion (if release created) - Tag sprint completion (if release created)
10. **Close Milestone** 11. **Close Milestone**
- Use `update_milestone` to close the sprint milestone - Use `update_milestone` to close the sprint milestone
- Document final completion status - Document final completion status

View File

@@ -6,9 +6,13 @@ description: Begin sprint execution with relevant lessons learned from previous
You are initiating sprint execution. The orchestrator agent will coordinate the work, analyze dependencies for parallel execution, search for relevant lessons learned, and guide you through the implementation process. You are initiating sprint execution. The orchestrator agent will coordinate the work, analyze dependencies for parallel execution, search for relevant lessons learned, and guide you through the implementation process.
## Sprint Approval Verification ## Sprint Approval Verification (Recommended)
**CRITICAL: Sprint must be approved before execution.** **RECOMMENDED: Sprint should be approved before execution.**
> **Note:** This is a recommended workflow practice, not code-enforced. The orchestrator
> SHOULD check for approval, but execution will proceed if approval is missing. For
> critical projects, consider making approval mandatory in your workflow.
The orchestrator checks for approval in the milestone description: The orchestrator checks for approval in the milestone description:
@@ -19,16 +23,15 @@ get_milestone(milestone_id=17)
**If Approval Missing:** **If Approval Missing:**
``` ```
⚠️ SPRINT NOT APPROVED ⚠️ SPRINT APPROVAL NOT FOUND (Warning)
Sprint 17 has not been approved for execution. Sprint 17 milestone does not contain an approval record.
The milestone description does not contain an approval record.
Please run /sprint-plan to: Recommended: Run /sprint-plan first to:
1. Review the sprint scope 1. Review the sprint scope
2. Approve the execution plan 2. Document the approved execution plan
Then run /sprint-start again. Proceeding anyway - consider adding approval for audit trail.
``` ```
**If Approval Found:** **If Approval Found:**
@@ -42,10 +45,10 @@ Then run /sprint-start again.
Proceeding with execution within approved scope... Proceeding with execution within approved scope...
``` ```
**Scope Enforcement:** **Scope Enforcement (when approval exists):**
- Agents can ONLY create branches matching approved patterns - Agents SHOULD only create branches matching approved patterns
- Agents can ONLY modify files within approved paths - Agents SHOULD only modify files within approved paths
- Operations outside scope require re-approval via `/sprint-plan` - Operations outside scope should trigger re-approval via `/sprint-plan`
## Branch Detection ## Branch Detection
@@ -66,11 +69,11 @@ If you are on a production or staging branch, you MUST stop and ask the user to
The orchestrator agent will: The orchestrator agent will:
1. **Verify Sprint Approval** 1. **Verify Sprint Approval** (Recommended)
- Check milestone description for `## Sprint Approval` section - Check milestone description for `## Sprint Approval` section
- If no approval found, STOP and direct user to `/sprint-plan` - If no approval found, WARN user and suggest `/sprint-plan` first
- If approval found, extract scope (branches, files) - If approval found, extract scope (branches, files)
- Agents operate ONLY within approved scope - Agents SHOULD operate within approved scope when available
2. **Detect Checkpoints (Resume Support)** 2. **Detect Checkpoints (Resume Support)**
- Check each open issue for `## Checkpoint` comments - Check each open issue for `## Checkpoint` comments