| name | scope |
| description | Scope a refined GitHub issue for implementation. Reads the codebase to build a file-level implementation plan, checks for file overlap conflicts with in-flight work, and promotes refined -> todo when clear. Trigger when the user says "scope", "scope this issue", "scope #123", "/scope 170", or "implementation plan for issue".
|
/scope -- Scope a refined issue for implementation
Scope a GitHub issue from the donovan-yohan/relay-ide repository for implementation. Read the codebase, write a file-level implementation plan into the issue body, check for conflicts with in-flight work, and promote the issue from refined to todo if the path is clear.
ARGUMENTS: The user provides an issue number (e.g., /scope 170 or /scope #170).
Step 1: Parse and validate
Extract the issue number from the arguments (strip any # prefix).
gh issue view <NUMBER> --repo donovan-yohan/relay-ide --json number,title,body,labels,state
Validate:
- The issue must be open
- The issue must have the
refined label
- If the issue already has
todo or in-progress, stop and tell the user it's already been promoted
- If the issue has
backlog but not refined, stop and tell the user it needs to be refined first
Read and understand the issue title and body. These are your requirements.
Step 2: Explore the codebase
Explore the codebase thoroughly to identify which files need to change:
- Search for modules, components, routes, stores, types, and tests related to the issue requirements
- Check
docs/ARCHITECTURE.md, docs/FRONTEND.md, and docs/DESIGN.md for relevant patterns
- Identify both the files that need modification AND the test files that need updating
- Note any shared types, utilities, or configuration that might be affected
Do NOT guess. Read the actual code. Verify every file path exists using Glob or Read before including it in the plan. The plan must be grounded in the current state of the repo.
Step 3: Draft the implementation plan
Write a structured implementation plan. Use this exact format so that conflict detection can parse the file list:
## Implementation Plan
> Generated by /scope on YYYY-MM-DD
### Files to Change
\`\`\`files
server/example.ts -- reason for change
src/components/Example.tsx -- reason for change
src/stores/exampleStore.ts -- NEW: new store for feature
test/example.test.ts -- add tests for new behavior
\`\`\`
### Approach
1. First step...
2. Second step...
3. ...
### Acceptance Criteria
- [ ] Criterion derived from the issue requirements
- [ ] ...
### Risk Notes
- Any PTY, WebSocket, auth, or session state concerns
- Any cross-module dependencies to watch
Rules for the plan:
- Every file path must be relative to the repo root
- Every file must have a brief rationale after
-- (the first occurrence of -- separates path from rationale)
- Prefix new files with
NEW: in the rationale (e.g., src/stores/foo.ts -- NEW: state for feature)
- Verify every file exists before listing it (except files marked
NEW:)
- Include test files explicitly
- The approach should be concrete steps, not vague descriptions
- Acceptance criteria should be verifiable (testable or observable)
- Risk notes are optional -- only include if the change touches PTY, WebSocket, auth, session state, or other high-risk areas
- Use today's date in YYYY-MM-DD format for the "Generated by" line
Step 4: Conflict detection
Check all open issues labeled todo or in-progress for file overlap.
gh api "repos/donovan-yohan/relay-ide/issues?state=open&per_page=100" \
| jq '[.[] | select(.labels | map(.name) | (contains(["todo"]) or contains(["in-progress"])))]'
For each issue found, fetch its body and look for a ```files block.
Parsing the files block:
- Each line inside the block is one entry
- Split on the first
-- to get the file path (left side) and rationale (right side)
- Trim whitespace from the path
- If an issue has no
files block, skip it (it was created before /scope existed)
Compare extracted file paths with your plan's file list.
Overlap rules:
- Exact file match = conflict (same file in both plans)
- Same directory with related concerns = potential conflict (flag but don't block)
- Different modules entirely = no conflict
If you find conflicts, collect the conflicting issue numbers and file paths.
Step 5: Act on results
Path A: No conflicts
- Update the issue body by appending the implementation plan. Use the Write tool or printf to construct the full body content (current body + separator + plan), write it to a temp file, then apply:
gh issue edit <NUMBER> --repo donovan-yohan/relay-ide --body-file /tmp/scope-issue-body.md
Important: Preserve the entire existing issue body. Append a --- separator, then the implementation plan.
- Promote the labels:
gh issue edit <NUMBER> --repo donovan-yohan/relay-ide --remove-label "refined" --add-label "todo"
- Report success:
- Issue number and title
- Files in the plan
- "Promoted to todo -- ready to claim"
Path B: Conflicts found
-
Still append the implementation plan to the issue body (same as Path A step 1), so the plan is preserved.
-
Add a comment noting the conflicts:
gh issue comment <NUMBER> --repo donovan-yohan/relay-ide --body-file /tmp/scope-conflict-comment.md
Write the comment body to the temp file first. Format:
## Scope Conflict Detected
This issue has file overlap with in-flight work:
| Conflicting Issue | Overlapping Files |
| ----------------- | ----------------- |
| #X -- title | `path/to/file.ts` |
Holding in `refined` until conflicts resolve. Will need re-scoping after the blocking issues land.
- Wire up blocking relationships via GraphQL:
gh api graphql -f query='query { repository(owner: "donovan-yohan", name: "relay-ide") {
blocked: issue(number: <THIS_ISSUE>) { id }
blocker: issue(number: <CONFLICTING_ISSUE>) { id }
} }'
gh api graphql -f query='mutation {
addBlockedBy(input: {
issueId: "<THIS_ISSUE_NODE_ID>",
blockingIssueId: "<BLOCKER_NODE_ID>"
}) { issue { title } blockingIssue { title } }
}'
-
Do NOT remove the refined label. Do NOT add todo.
-
Report the situation:
- Issue number and title
- Files in the plan
- Conflicts found (issue numbers + overlapping files)
- "Held in refined -- blocked by #X, #Y"
Path C: Only potential conflicts (same directory, different files)
- Append the plan to the issue body
- Add a comment noting the potential overlap (informational, not blocking)
- Promote to
todo (same as Path A)
- Report with a note: "Potential overlap with #X in
server/ -- monitor for merge conflicts"
Pitfalls and lessons learned
- Always use
--body-file for issue body/comment writes. Never --body with heredoc in command substitution -- parentheses in markdown break shell interpolation.
- Write temp files with the Write tool or printf, not with single-quoted heredocs when you need to interpolate variable content. Single-quoted heredoc delimiters (
<<'BODY') prevent variable expansion.
- GraphQL requires node IDs -- issue numbers don't work. Always fetch with
gh api graphql query first. Batch multiple issues in one query.
addBlockedBy semantics -- issueId is the blocked issue, blockingIssueId is the blocker. Easy to mix up.
- Don't guess file paths -- always verify files exist with Glob or Read before including them in the plan. The only exception is files marked
NEW:.
- Preserve the existing issue body -- append the plan, don't replace the body.
- Parse
files blocks on first -- only -- the rationale text may contain -- as well.
- Skip issues without
files blocks -- older issues created before /scope won't have them.