9.2 KiB
9.2 KiB
| description |
|---|
| Sync OpenProject work packages with current feature specs and tasks — creates milestones, phases, and child tasks as needed. |
User Input
$ARGUMENTS
You MUST consider the user input before proceeding (if not empty).
Outline
-
Setup:
- Resolve remote URL: Run
git remote get-url originto get the remote URL. All commit references in this skill MUST use<remote-url>/commit/<hash>format. Never use bare hashes. - Run
.specify/scripts/powershell/check-prerequisites.ps1 -Jsonfrom repo root and parse FEATURE_DIR, BRANCH, and AVAILABLE_DOCS list. All paths must be absolute. For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'''m Groot' (or double-quote if possible: "I'm Groot"). - If the script fails (no feature branch, no specs directory, or prerequisites not met): proceed to step 2a (ad-hoc mode).
- Resolve remote URL: Run
-
Determine development stage: Check which design artifacts exist in FEATURE_DIR:
spec.mdexists → at least "specify" stageplan.mdexists → at least "plan" stagetasks.mdexists → at least "tasks" stage- Tasks with
[X]checkboxes → "implement" stage (in progress) - No artifacts at all → "none" stage (proceed to step 2a)
2a. Ad-hoc mode (no SpecKit artifacts available):
- This handles cases where:
- The branch is not a SpecKit feature branch (e.g.,
main,fix/something,hotfix/urgent) - No
specs/directory exists for this branch - The user wants to log work to an existing WP without full SpecKit setup
- The branch is not a SpecKit feature branch (e.g.,
- Ask the user: "No SpecKit feature detected for this branch. Which OpenProject work package should I update?"
- Accept one of:
- A WP ID (e.g.,
#10423or10423) - A search term to find the WP (use
mcp__openproject__list_work_packageswith project ID 229 and present matching results) - "new" to create a new work package
- "skip" to abort the OP update
- A WP ID (e.g.,
- If the user provides a WP ID or selects from search results:
- Get the commits to be logged:
git log --oneline origin/HEAD..HEAD(or from user input) - Add a comment to the selected WP with commit links (
<remote-url>/commit/<hash>) and summary - Report what was logged and skip steps 3–8
- Get the commits to be logged:
- If the user says "new" or no search results match:
- Ask for a subject (suggest one based on the branch name or recent commit messages)
- Ask for a type (Task, Feature, Bug, etc.) — list available types via
mcp__openproject__list_typesif needed - Optionally ask for description, priority, and assignee
- Create the WP via
mcp__openproject__create_work_packagewith project ID 229 - Then log commits to the newly created WP (same as WP ID flow above)
- Report the new WP ID and what was logged, skip steps 3–8
- If the user says "skip": abort and return without error
-
Load context:
- Read
spec.mdto extract feature title and user stories - If
tasks.mdexists: Read it to extract phases, task counts, OP WP IDs (from— OP #NNNNNin phase headers), and task details - Read
CLAUDE.mdfor the OpenProject Work Package IDs table and existing mappings
- Read
-
Find or create the Milestone work package:
- Extract the feature number and name from the branch name (e.g.,
001-ai-etl-platform) - Search OpenProject for an existing Milestone WP matching this feature:
- Use
mcp__openproject__list_work_packageswith project ID 229 and filter by type "Milestone" - Look for a WP whose subject contains the feature number or name
- Use
- If found: Display the milestone WP (ID, subject, status) and confirm with user
- If NOT found: Offer to create one:
- Propose title:
{feature-number} - {Feature Name from spec.md}(e.g., "001 - Core ETL + Visual Designer (V1)") - Propose description from spec.md summary
- Ask user for confirmation before creating via
mcp__openproject__create_work_package
- Propose title:
- Store the milestone WP ID for subsequent steps
- Extract the feature number and name from the branch name (e.g.,
-
Stage: "tasks" — Sync Phases as Work Packages:
- Skip this step if
tasks.mddoes not exist - Parse all phase headers from tasks.md:
## Phase N: Description — OP #NNNNN - For each phase:
- If OP WP ID is present in the header: Verify the WP exists via
mcp__openproject__get_work_package- If it exists: Compare the subject and update if the description has changed (use
mcp__openproject__update_work_package) - If it does NOT exist (stale ID): Flag it and offer to create a new WP
- If it exists: Compare the subject and update if the description has changed (use
- If NO OP WP ID in the header: Create a new Phase WP:
- Type: "Phase" (or "Task" if Phase type unavailable — check
mcp__openproject__list_typesfirst) - Subject:
Phase N: Description(e.g., "Phase 3: US-1 — Manage Users and Roles") - Description: Include the phase purpose, task count, checkpoint criteria, and user story goal
- After creation, update the tasks.md phase header to include
— OP #NewID
- Type: "Phase" (or "Task" if Phase type unavailable — check
- If OP WP ID is present in the header: Verify the WP exists via
- Create milestone relations: For each phase WP, create a
requiresrelation from the phase to the milestone (if not already linked):- Use
mcp__openproject__list_relationson the phase WP to check existing relations - If no
requiresrelation to the milestone exists, create one viamcp__openproject__create_relation
- Use
- Create inter-phase dependencies: Parse the dependency graph from tasks.md (look for "Depends on: Phase N" notes and the dependency graph section):
- For each dependency, create a
followsrelation (phase X follows phase Y) - Check existing relations first to avoid duplicates
- For each dependency, create a
- Report summary: phases found, created, updated, relations created
- Skip this step if
-
Stage: "implement" — Sync Tasks as Child Work Packages:
- Skip this step if NOT in "implement" stage (no
[X]tasks) unless the user explicitly requests task sync - For each phase in tasks.md:
- Get the phase WP ID from the header
- Use
mcp__openproject__list_work_packagesto find existing child WPs under this phase (filter by parent if supported, or list all project WPs and filter by subject prefix) - Parse all tasks in the phase:
- [ ] T### [P?] [US?] Description - For each task:
- If a matching child WP exists (match by task ID in subject, e.g., "T042"):
- Compare status: if task is
[X]in tasks.md but WP is not closed → update WP status - Compare subject: if description changed → update WP subject
- Compare status: if task is
- If NO matching child WP exists: Create one:
- Type: "Task"
- Subject:
T### — Description(e.g., "T042 — Implement refresh token denylist in backend/etl/.../TokenDenylistService.java") - Set parent to the phase WP ID (use direct API PATCH with
_links.parent.hrefsince MCP update_work_package does not support parent — see CLAUDE.md constraints)
- Batch creation: Process tasks in batches to avoid rate limiting. Create up to 10 WPs at a time, then pause briefly.
- If a matching child WP exists (match by task ID in subject, e.g., "T042"):
- Update task completion status:
- For tasks marked
[X]in tasks.md: Update the corresponding WP status to "Closed" (or appropriate status) - For tasks marked
[ ]: Ensure WP is in "New" or "In progress" status
- For tasks marked
- Report summary: tasks found, created, updated, status synced
- Skip this step if NOT in "implement" stage (no
-
Update CLAUDE.md (if new WP IDs were created):
- Update the OpenProject Work Package IDs table in CLAUDE.md with any new phase WP IDs
- Update task counts if they changed
- Add any new relation IDs
-
Update tasks.md (if new phase WP IDs were assigned):
- Update phase headers with newly assigned OP WP IDs:
## Phase N: Description — OP #NewID
- Update phase headers with newly assigned OP WP IDs:
-
Report: Output a summary table:
| Action | Count | Details | |--------------|-------|----------------------------------| | Milestone | 1 | #XXXXX (found/created) | | Phases | N | M created, K updated, J existing | | Tasks | N | M created, K updated | | Relations | N | M requires, K follows | | Files Updated| N | tasks.md, CLAUDE.md |- List any errors or items that need manual attention
- Suggest next steps (e.g., "Run /speckit.implement to start implementation")
Operating Rules
- Never delete work packages — only create or update. If a WP seems orphaned, flag it for manual review.
- Always check before creating — search for existing WPs before creating new ones to avoid duplicates.
- Preserve existing OP WP IDs — if a phase header already has an OP ID, trust it unless the WP doesn't exist.
- Respect MCP limitations:
- Relations are CRD only (no update) — to change a relation type, delete and recreate
- Parent-child cannot be set via
update_work_package— use direct API PATCH with_links.parent.href - Milestones cannot have children — use
requiresrelations instead
- Batch operations — when creating many WPs, process in batches of 10 to avoid overwhelming the API.
- Confirm destructive-ish actions — ask user before bulk-creating WPs (e.g., "About to create 23 phase WPs. Proceed?").
- Log activity — after creating or updating WPs, add a comment with context (e.g., "Synced from tasks.md phase header").