Manage VFX team issues on GitHub Projects - timeline scheduling, status updates, member commit checks, bulk assign. Use when managing VFX team project board, adding issues to timeline, checking member progress, or bulk-updating issue fields.
Role: VFX Team Project Board Automation Scope: GitHub Projects V2 management for VFX team Platform: Windows + gh CLI + GraphQL API Repository: sipherxyz/s2 Project: #5 (S2 Huli Nine Tails Vengance)
node claude-agents/vfx-dashboard/refresh-vfx-dashboard.js
start "" "claude-agents/vfx-dashboard/vfx-dashboard-v5.html"
Automate repetitive GitHub Projects operations for the VFX team: scheduling issues on timeline, bulk status changes, member progress checks, and issue assignment. Replaces manual GraphQL mutations with a single skill.
gh CLI authenticated: gh auth statusreferences/vfx-project-ids.md{CWD} = Current Working Directory
{RepoOwner} = sipherxyz
{RepoName} = s2
{ProjectNum} = 5
{ProjectId} = PVT_kwDOBR2Dpc4Azdrn
{TempDir} = C:\Users\{user}\AppData\Local\Temp
Load all field IDs and member handles from references/vfx-project-ids.md.
/github-workflow:vfx-project-manager # FULL SYNC: all members → update timeline → refresh dashboard
/github-workflow:vfx-project-manager timeline <member> # Single member timeline sync
/github-workflow:vfx-project-manager check <member> # Check commits vs tasks for member
/github-workflow:vfx-project-manager assign <issue-numbers> <member>
/github-workflow:vfx-project-manager status <issue-numbers> <status>
Purpose: Find all open issues assigned to a member that are missing timeline dates, then add them to the Project #5 timeline.
gh issue list -R sipherxyz/s2 --assignee {member} --state open --limit 100 --json number,title,labels,state
For each issue, query Project #5 field values using GraphQL. Batch up to 15 issues per query using aliases:
query {
i0: repository(owner:"sipherxyz", name:"s2") {
issue(number:{N}) {
id number title
projectItems(first:5) {
nodes {
id project { number }
fieldValues(first:20) {
nodes {
... on ProjectV2ItemFieldDateValue {
date field { ... on ProjectV2Field { name } }
}
... on ProjectV2ItemFieldSingleSelectValue {
name field { ... on ProjectV2Field { name } }
}
}
}
}
}
}
}
i1: ...
}
Write query to temp file, execute via:
gh api graphql -f query="$(cat /c/Users/{user}/AppData/Local/Temp/{file}.txt)"
Filter for issues where:
For issues not yet in Project #5:
gh project item-add 5 --owner sipherxyz --url https://github.com/sipherxyz/s2/issues/{number}
Query the newly-added items to get their project item IDs (needed for field mutations).
CRITICAL: Before scheduling dates, check if the member already has commits related to each issue.
git log --author="{member}" --since="1 week ago" --oneline --format="%h %ad %s" --date=short
Cross-reference commit messages with issue titles/keywords. If commits exist:
NEVER set future dates. If no matching commits → leave dates empty (user will schedule manually).
After cross-referencing commits with issues, identify orphan commits — commits that don't match any open or closed issue.
Group orphan commits by topic using commit message tags/keywords:
[Lighting] SH360, Desert SH070, Trailer C100 → 1 issue about lighting work
[VFX] Trailer Shot 050 060 090 → 1 issue about trailer VFX
For each orphan group, create a new issue:
gh issue create --repo sipherxyz/s2 \
--title "task_S02_VFX_{topic_slug}" \
--body "Auto-created from orphan commits for {member}.\n\nCommits:\n- {hash} {date} {message}\n- ..." \
--assignee {member} \
--label vfx
Then:
gh project item-add 5 --owner sipherxyz --url {issue_url}Title format: task_S02_VFX_{area}_{short_description} using lowercase + underscores. Derive from commit message tags:
[Lighting] Trailer C100 → task_S02_VFX_lighting_trailer_c100[VFX] Shot 290 300 Trailer → task_S02_VFX_cine_trailer_shot_290_300For issues with commits (already worked on):
Start date = date of first related commit
End date = date of last related commit
Status = Done or Fixed
For issues without commits (no work yet):
DO NOT set any dates — leave Start date and End date empty.
Status = To Do
The user will manually schedule future work on the GitHub Projects timeline.
Use aliases for batch mutations:
s0:, s1: ... for status = To Dod0s:, d0e:, d1s:, d1e: ... for start/end datesKeep under 20 mutations per API call to avoid rate limits.
Ensure all issues have vfx label:
gh issue edit {number} --add-label vfx --repo sipherxyz/s2
Present a summary table:
Added to timeline: {count} issues for {member}
| # | Title | Status | Timeline |
|---|-------|--------|----------|
| #123 | task name | To Do | Feb 16 - Feb 20 |
| #456 | task name | To Do | Feb 23 - Feb 27 |
ALWAYS refresh and open the dashboard after timeline changes:
node claude-agents/vfx-dashboard/refresh-vfx-dashboard.js
start "" "claude-agents/vfx-dashboard/vfx-dashboard-v5.html"
Purpose: Compare a member's git commits against their assigned tasks to find gaps (orphan commits without tasks, or stale open issues).
git log --author="{member}" --since="1 week ago" --oneline --format="%h %ad %s" --date=short
Also try common name variations (e.g., "TyVo" → also search "Ty Vo", "ty.vo").
gh issue list -R sipherxyz/s2 --assignee {member} --state open --limit 50 --json number,title,labels,state,createdAt
gh issue list -R sipherxyz/s2 --assignee {member} --state closed --limit 50 --json number,title,labels,state,closedAt
Query open issues for their Project #5 status and dates (same as timeline Step 2).
Group commits by work area (from commit message tags like [VFX], [Lighting], [Tool]).
Cross-reference with issues:
If orphan commits are found (commits with no matching issue), automatically create issues following the same logic as timeline Step 5.6:
task_S02_VFX_{topic} titlevfx labelMember: {member}
Commits (last week): {count}
Open issues: {count}
Closed issues: {count}
Work Areas:
| Area | Period | Commits | Covered by Issue |
|------|--------|---------|------------------|
| Baiwuchang cutscene | Feb 3-10 | 12 | #19685 |
| Tiger OPN | Jan 22-Feb 2 | 15 | #18671 (closed) |
| Lighting SH360 | Feb 11 | 2 | ⚡ NEW #19800 (auto-created) |
Issues:
| # | Title | Project | Status | Dates | Flag |
|---|-------|---------|--------|-------|------|
| #19685 | bwc cutscene | Yes | Done | Feb 3-8 | OPEN but Done - should close? |
| #18327 | tiger lighting | No | - | - | NOT on timeline |
| #19800 | lighting_sh360 | Yes | Fixed | Feb 11 | ⚡ AUTO-CREATED |
Purpose: Bulk assign issues to a member with labels and add to Project #5.
/github-workflow:vfx-project-manager assign 19620,19625,19588 TienDang-VFX
gh issue edit {number} --add-assignee {member} --add-label vfx --repo sipherxyz/s2
gh project item-add 5 --owner sipherxyz --url https://github.com/sipherxyz/s2/issues/{number}
Query issue node ID, then set Issue Type = Task via GraphQL updateIssue mutation.
Assigned {count} issues to @{member}:
- #{n1}: {title}
- #{n2}: {title}
All added to Project #5 with label: vfx
Purpose: Bulk update status for multiple issues on Project #5.
/github-workflow:vfx-project-manager status 19620,19625 todo
/github-workflow:vfx-project-manager status 19620,19625 fixed
Status values: todo → f75ad846, fixed → 7177aeee
Query each issue's project item ID via GraphQL.
Build mutation with aliases:
mutation {
s0: updateProjectV2ItemFieldValue(input: {
projectId: "PVT_kwDOBR2Dpc4Azdrn",
itemId: "{ITEM_ID}",
fieldId: "PVTSSF_lADOBR2Dpc4AzdrnzgpQGXw",
value: { singleSelectOptionId: "{STATUS_ID}" }
}) { projectV2Item { id } }
...
}
Updated {count} issues to status: {status}
- #{n1}: {title}
- #{n2}: {title}
Purpose: Run the complete workflow for ALL VFX members: check commits, sync timeline, fix missing data, then refresh and open dashboard.
Load member list from references/vfx-project-ids.md:
TienDang-VFX, TyVo-VFX, HoaNguyen-VFX, TuanDangVFXAther, QuangTranLightingArtAther, VuDuong-CREATIVE
For each member, run timeline action (Steps 1-9 from the timeline section above):
vfx labelAfter processing all members, show combined report:
═══════════════════════════════════════
VFX PROJECT SYNC COMPLETE
═══════════════════════════════════════
| Member | Open | Synced | Added | Already OK |
|--------|------|--------|-------|------------|
| TienDang-VFX | 40 | 40 | 2 new | 38 |
| TyVo-VFX | 6 | 6 | 3 new | 3 |
| HoaNguyen-VFX | 3 | 3 | 1 new | 2 |
| TuanDangVFXAther | 5 | 5 | 0 | 5 |
| QuangTranLightingArtAther | 2 | 2 | 0 | 2 |
| VuDuong-CREATIVE | 1 | 1 | 0 | 1 |
Total: {N} issues synced, {M} newly added to timeline
ALWAYS run these two commands at the end — do NOT skip:
node claude-agents/vfx-dashboard/refresh-vfx-dashboard.js
Then open in browser:
start "" "claude-agents/vfx-dashboard/vfx-dashboard-v5.html"
Dashboard refreshed and opened!
File: claude-agents/vfx-dashboard/vfx-dashboard-v5.html
Split batch mutations into smaller chunks (max 15-18 mutations per call). Wait 2 seconds between calls.
If an issue is not in Project #5 when trying to set fields:
gh project item-add 5 --owner sipherxyz --url {url}Never pass GraphQL queries as inline strings in bash. Always:
gh api graphql -f query="$(cat /c/Users/{user}/AppData/Local/Temp/{file}.txt)"If gh issue edit --add-label fails because label doesn't exist, log warning and continue. Don't block the workflow.
timeline: Finds issues without dates, schedules across weekstimeline: Adds missing issues to Project #5timeline: Sets status=To Do and start/end dates via batch GraphQLtimeline: Adds vfx label to all issuescheck: Fetches commits and issues for a membercheck: Identifies orphan commits, stale issues, timeline gapsassign: Bulk assigns with labels and project membershipassign: Sets Issue Type = Taskstatus: Bulk updates status via batch GraphQLoverview: Shows team-wide summarygh commands target --repo sipherxyz/s2 explicitly| GitHub Handle | Git Author(s) |
|---|---|
| TienDang-VFX | TienDang-VFX, Cinematic, miinhtien, DANG MINH TIEN |
| TyVo-VFX | Ty Vo |
| HoaNguyen-VFX | HoaNguyen-VFX |
| TuanDangVFXAther | TuanDang |
| QuangTranLightingArtAther | Tran Duy Quang |
| VuDuong-CREATIVE | yuduong |