Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 1, 2025

Closes: #1510

Enhances the issue_graph tool to be the primary tool for project status queries. This PR adds intelligent focus shifting, cross-repo relationship discovery, and status extraction to provide comprehensive project overviews in a single API call.

Changes

New Features

  • focus parameter - Automatically shifts focus to parent epic or batch

    • focus="epic" - Finds and focuses on the nearest epic in the hierarchy
    • focus="batch" - Finds and focuses on the nearest batch/parent issue
    • Falls back gracefully with helpful suggestions if no match found
  • Cross-repo support - Uses GraphQL to discover relationships across repositories

    • Parent issues can be in different repos than their sub-issues
    • Sub-issues are fetched with their actual owner/repo (not assumed same-repo)
    • Full GitHub URL parsing (https://github.com/owner/repo/issues/123)
  • Status extraction - Lightweight "if lucky" status detection

    • Parses milestone due dates (overdue/due in X days)
    • Scans issue body for status keywords (on-track, delayed, blocked, ETA, etc.)
    • Checks 3 most recent comments for status updates (epics/batches only)
  • State reason - Shows why issues/PRs are in their current state

    • Issues: completed, not_planned, duplicate, reopened
    • PRs: merged state detection
  • Project info - Fetches project name and status for the focus node

  • Issue Types recognition - Detects GitHub's native "Epic" issue type for classification

Tool Description Updates

  • Enhanced issue_graph description to emphasize it as the primary tool for status queries
  • Updated issue_read description to defer to issue_graph for status/progress questions
  • Updated server instructions with comprehensive guidance on when to use issue_graph

Example Output

GRAPH SUMMARY
=============
Focus: github/copilot-agent-services#871 (batch) "[Batch] Support scope challenge"
State: open
Focus shifted: from github/github-mcp-server-remote#461 via cross-reference
Hierarchy: #201 (epic) → #871 (batch)
Direct children: 6
Projects: Agent Services Team Dashboard [In Progress]

NODES (5 total)
===============
github/github-mcp-server-remote#461|pr|merged|Implement initial scope challenge
  Preview: Only do a scope challenge for org list tool...
#871|batch|open|[Batch] Support scope challenge in remote MCP [FOCUS]
  Preview: Build out scope challenge...
  Status: Target: 2:00pm PT today (Thursday)

What an LLM Gets From This Data

From a single tool call, an LLM can understand:

  1. Work Context: The focus item and its position in the work hierarchy
  2. Hierarchy: Full epic → batch → task → PR chain across repositories
  3. Node Classification: Epics, batches, tasks, PRs with GitHub Issue Types support
  4. Status Updates: Milestone due dates, status keywords, recent updates
  5. State Details: Open/closed with reason (completed, not_planned, duplicate, merged)
  6. Project Info: Which projects the issue is in and its status
  7. Cross-repo Relationships: Parent/child links that span different repositories

Testing

  • Added tests for cross-repo ancestor traversal via cross-references
  • Added tests for findBestFocus with cross-repo relationships
  • Added test cases for GitHub URL parsing
  • Added test case for Issue Types (Epic) classification
  • All existing tests pass

Checklist

  • script/lint passes
  • script/test passes
  • Toolsnaps updated
  • README.md updated via script/generate-docs

Copilot AI and others added 3 commits December 1, 2025 10:59
Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
Copilot AI changed the title [WIP] Add issue_graph tool to visualize issue and PR relationships Add issue_graph tool to visualize issue/PR relationships and hierarchy Dec 1, 2025
Copilot AI requested a review from SamMorrowDrums December 1, 2025 11:10
Copilot finished work on behalf of SamMorrowDrums December 1, 2025 11:10
…tput

- Refactor fetchNode to return raw issue data along with node, avoiding
  second API call in crawl loop
- Add 30 second timeout to prevent runaway crawling
- Include parent edges in output by reversing direction for display
- Move cross-tool info from description to instructions.go (was already there)
- Shorter tool description focusing on core functionality
@SamMorrowDrums SamMorrowDrums force-pushed the copilot/add-issue-graph-tool branch from 76f4dbc to 4dcc5b6 Compare December 1, 2025 11:20
Use ListIssueTimeline API to find issues that have 'cross-referenced'
events, which indicates they were mentioned in another issue. This
captures relationships like 'mentioned in #815' that aren't visible
in the issue body or sub-issues.

The timeline crawling:
- Fetches up to 100 timeline events per issue
- Filters for 'cross-referenced' event types
- Extracts the source issue from cross-reference events
- Adds edges with RelationTypeRelated
- Queues referenced issues for further crawling
The text format already provides all necessary information for LLMs
to understand the issue graph. The redundant JSON output was adding
significant token overhead without providing additional value.

The text format includes:
- Graph summary with focus node info and hierarchy
- All nodes with type, state, title, and body preview
- Parent/child relationships
- Related issue connections
- Add legend explaining node types (epic, batch, task, pr)
- Rename 'EDGES' to 'SUB-ISSUES' with explicit parent→child label
- Rename 'RELATED' to 'CROSS-REFERENCES' with mentioned/referenced label
- Use ↔ symbol for bidirectional cross-references
- Show '(none)' for empty sections instead of blank
- Remove redundant JSON output to reduce token usage
…/PR relationships

This prompt provides a guided workflow for:
1. Running issue_graph to see current state
2. Searching for related issues/PRs that should be connected
3. Identifying orphaned or missing relationships
4. Proposing and adding connections with user approval
5. Verifying connections via issue_graph

Parameters:
- owner/repo/issue_number: The issue/PR to analyze
- additional_repos: Cross-repo search (e.g., epic in planning repo)
- known_links: User-provided issue URLs that should be connected
@github github deleted a comment from Copilot AI Dec 1, 2025
…s extraction

- Add 'focus' parameter to shift focus to parent epic/batch
- Support cross-repo sub-issues and parent lookup via GraphQL
- Extract status updates from issue body, comments, and milestones
- Add state reason (completed, not_planned, duplicate, merged)
- Fetch project info for focus node
- Parse full GitHub URLs for cross-repo references
- Recognize GitHub Issue Types (Epic) for node classification
- Enhanced tool description to emphasize using issue_graph first
- Update issue_read description to defer to issue_graph for status
- Update server instructions with comprehensive issue_graph guidance
// Matches owner/repo#123 style references (cross-repo)
crossRepoRefRegex = regexp.MustCompile(`([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+)#(\d+)`)
// Matches full GitHub URLs like https://github.com/owner/repo/issues/123 or /pull/123
githubURLRefRegex = regexp.MustCompile(`https?://(?:www\.)?github\.com/([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+)/(?:issues|pull)/(\d+)`)

Check failure

Code scanning / CodeQL

Missing regular expression anchor High

When this is used as a regular expression on a URL, it may match anywhere, and arbitrary hosts may come before or after it.

Copilot Autofix

AI 4 days ago

To fix the problem, we should add a ^ anchor at the start of the regular expression and possibly a $ anchor at the end if we expect the entire string to be just a GitHub URL (often not the case for extraction in free text). In most extraction scenarios, we use functions like FindAllStringSubmatch to extract all matches from a larger string, and each match is checked against the regex from the start; so using ^ in each match ensures that random substrings are not matched. The minimal required fix is to update line 114 in file pkg/github/issue_graph.go by adding ^ at the beginning of the regex, i.e., change

https?://(?:www\.)?github\.com/...

to

^https?://(?:www\.)?github\.com/...

No new imports or additional methods are needed; just a change in the regex definition. This change ensures that the extraction finds only URLs that start at the match, preventing invalid or embedded matches.

Suggested changeset 1
pkg/github/issue_graph.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/pkg/github/issue_graph.go b/pkg/github/issue_graph.go
--- a/pkg/github/issue_graph.go
+++ b/pkg/github/issue_graph.go
@@ -111,7 +111,7 @@
 	// Matches owner/repo#123 style references (cross-repo)
 	crossRepoRefRegex = regexp.MustCompile(`([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+)#(\d+)`)
 	// Matches full GitHub URLs like https://github.com/owner/repo/issues/123 or /pull/123
-	githubURLRefRegex = regexp.MustCompile(`https?://(?:www\.)?github\.com/([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+)/(?:issues|pull)/(\d+)`)
+	githubURLRefRegex = regexp.MustCompile(`^https?://(?:www\.)?github\.com/([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+)/(?:issues|pull)/(\d+)`)
 	// Matches "closes #123", "fixes #123", "resolves #123" patterns (PR linking to issue)
 	closesRefRegex = regexp.MustCompile(`(?i)(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+(?:(?:([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+))?#(\d+))`)
 	// URL pattern to remove
EOF
@@ -111,7 +111,7 @@
// Matches owner/repo#123 style references (cross-repo)
crossRepoRefRegex = regexp.MustCompile(`([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+)#(\d+)`)
// Matches full GitHub URLs like https://github.com/owner/repo/issues/123 or /pull/123
githubURLRefRegex = regexp.MustCompile(`https?://(?:www\.)?github\.com/([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+)/(?:issues|pull)/(\d+)`)
githubURLRefRegex = regexp.MustCompile(`^https?://(?:www\.)?github\.com/([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+)/(?:issues|pull)/(\d+)`)
// Matches "closes #123", "fixes #123", "resolves #123" patterns (PR linking to issue)
closesRefRegex = regexp.MustCompile(`(?i)(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+(?:(?:([a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?)/([a-zA-Z0-9._-]+))?#(\d+))`)
// URL pattern to remove
Copilot is powered by AI and may make mistakes. Always verify output.
@SamMorrowDrums SamMorrowDrums changed the title Add issue_graph tool to visualize issue/PR relationships and hierarchy feat(issue_graph): Add focus parameter, cross-repo support, and status extraction Dec 1, 2025
@SamMorrowDrums SamMorrowDrums marked this pull request as ready for review December 1, 2025 15:52
@SamMorrowDrums SamMorrowDrums requested a review from a team as a code owner December 1, 2025 15:52
Copilot AI review requested due to automatic review settings December 1, 2025 15:52
Copilot finished reviewing on behalf of SamMorrowDrums December 1, 2025 15:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a comprehensive issue_graph tool to provide a unified view of issue/PR relationships and project status in a single API call, reducing the need for multiple separate queries.

Key Changes:

  • New issue_graph tool with focus parameter for automatic parent epic/batch discovery
  • Cross-repository relationship support via GraphQL for parent/sub-issue traversal
  • Status extraction from milestones, issue bodies, and recent comments
  • Enhanced tool descriptions and server instructions to guide LLMs toward using issue_graph for status queries

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
pkg/github/issue_graph.go Core implementation of the graph crawler with BFS traversal, GraphQL queries, and cross-repo support (1647 lines)
pkg/github/issue_graph_test.go Comprehensive unit tests covering reference extraction, node classification, graph formatting, and cross-repo scenarios
pkg/github/issue_graph_prompts.go ConnectIssueGraph prompt for guided workflow to find and connect missing relationships
pkg/github/tools.go Registers the new issue_graph tool and ConnectIssueGraph prompt in the issues toolset
pkg/github/issues.go Updates issue_read description to defer to issue_graph for status/progress questions
pkg/github/instructions.go Adds detailed guidance on when to use issue_graph as the primary tool for status queries
pkg/github/toolsnaps/issue_graph.snap Tool schema snapshot for the new issue_graph tool
pkg/github/toolsnaps/issue_read.snap Updated snapshot reflecting the modified issue_read description
README.md Documents the new issue_graph tool with its parameters
work-plan.md Unrelated OAuth scopes work documentation (should be removed from this PR)
e2e-repos-to-delete.txt Unrelated e2e test cleanup file (should be removed from this PR)
docs/remote-server.md Unrelated change from "Default" to "all" toolset name

| Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) |
|----------------|--------------------------------------------------|-------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Default | ["Default" toolset](../README.md#default-toolset) | https://api.githubcopilot.com/mcp/ | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2F%22%7D) | [read-only](https://api.githubcopilot.com/mcp/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Freadonly%22%7D) |
| all | All available GitHub MCP tools | https://api.githubcopilot.com/mcp/ | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2F%22%7D) | [read-only](https://api.githubcopilot.com/mcp/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Freadonly%22%7D) |
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change from "Default" to "all" appears to be unrelated to the issue_graph feature. If this is an intentional change, it should be in a separate PR or explained in the PR description.

Suggested change
| all | All available GitHub MCP tools | https://api.githubcopilot.com/mcp/ | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2F%22%7D) | [read-only](https://api.githubcopilot.com/mcp/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Freadonly%22%7D) |
| Default | All available GitHub MCP tools | https://api.githubcopilot.com/mcp/ | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2F%22%7D) | [read-only](https://api.githubcopilot.com/mcp/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Freadonly%22%7D) |

Copilot uses AI. Check for mistakes.
vars := map[string]interface{}{
"owner": githubv4.String(owner),
"repo": githubv4.String(repo),
"number": githubv4.Int(int32(number)), //nolint:gosec // issue numbers are always small positive integers
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same int32 overflow issue as line 1416. The gosec suppression should acknowledge the theoretical limitation or use a safer conversion pattern.

Copilot uses AI. Check for mistakes.
}

// Add timeout to prevent runaway crawling
crawlCtx, cancel := context.WithTimeout(ctx, 7*time.Second)
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout of 7 seconds is a magic number without explanation. Consider extracting this to a named constant at the package level (e.g., MaxGraphCrawlTimeout) with a comment explaining why 7 seconds was chosen. This makes it easier to tune performance and understand the trade-offs.

Copilot uses AI. Check for mistakes.
"number": githubv4.Int(int32(number)), //nolint:gosec // issue numbers are always small positive integers
}

queryCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another magic number timeout (2 seconds). Consider extracting to a named constant for consistency with the other timeout suggestions.

Copilot uses AI. Check for mistakes.
Comment on lines +66 to +96
**CRITICAL: For ANY question about issue/PR/epic status, updates, or progress - ALWAYS call 'issue_graph' FIRST before any other tool.**
'issue_graph' is the FASTEST PATH to project status - one call returns the entire work hierarchy (epic → batches → tasks → PRs) instead of multiple separate API calls.
Trigger phrases that REQUIRE 'issue_graph' as the FIRST tool call:
- "update on..." / "status of..." / "progress on..." / "tell me about..."
- "what's happening with..." / "how is... going" / "state of..."
- "project status" / "how is the project going" / "overall progress"
- "epic" / "parent issue" / "sub-issues" / "blocking" / "depends on"
- ANY issue/PR number reference when asking for status or updates
Example: User asks "give me an update on issue #123" → Call issue_graph(owner, repo, 123) FIRST.
Example: User asks "what's the status of the project" → Call issue_graph with the epic/tracking issue number.
The 'issue_graph' tool returns in ONE call:
- Full hierarchy: epic → batch → task → PR relationships across the entire project
- All sub-issues and "closes/fixes" references
- Status updates extracted from issue bodies/comments
- Cross-references and related work
- Open/closed state of all related items
Use focus="epic" to automatically find and focus on the parent epic of any issue.
ONLY AFTER calling 'issue_graph', use other tools:
- 'issue_read' for full details of specific issues identified in the graph
- 'search_issues' to find related issues not in the graph
For creating/modifying issues:
- Check 'list_issue_types' first for organizations to use proper issue types
- Use 'search_issues' before creating new issues to avoid duplicates
- Always set 'state_reason' when closing issues`
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The instructions include many emphatic phrases like "CRITICAL", "ALWAYS", "MUST", "FIRST", etc. While these emphasize importance, they may be overly forceful. Consider whether a more balanced tone would be clearer and easier for LLMs to parse, while still conveying priority. The repetition of these strong directives across multiple sentences could potentially confuse rather than clarify.

Copilot uses AI. Check for mistakes.
// Regular expressions for extracting issue references
var (
// Matches #123 style references (same repo)
sameRepoRefRegex = regexp.MustCompile(`(?:^|[^\w])#(\d+)`)
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern for same-repo references uses (?:^|[^\w])#(\d+) which will match #123 in the middle of words. This could potentially extract false positives from hex color codes (e.g., #ffffff123), commit SHAs, or other contexts where # followed by digits doesn't represent an issue. Consider adding a word boundary check or being more specific about the preceding character to avoid these false matches.

Suggested change
sameRepoRefRegex = regexp.MustCompile(`(?:^|[^\w])#(\d+)`)
sameRepoRefRegex = regexp.MustCompile(`(?:^|[^\w])#(\d+)\b`)

Copilot uses AI. Check for mistakes.
Comment on lines +233 to +241
mcp.WithDescription(t("TOOL_ISSUE_READ_DESCRIPTION", `Get detailed information about a single issue: full body, comments, sub-issues, or labels.
**USE issue_graph INSTEAD when user asks about:**
- Status, updates, or progress on issues/PRs/epics
- Project overview or how work is going
- Parent issues, sub-issues, or work hierarchy
- Related or blocking issues
issue_read is for: reading the full issue body, fetching comments, listing sub-issues of a known parent, or getting label details - AFTER you already know which specific issue you need.`)),
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The description update is very verbose and includes bold formatting (**USE issue_graph INSTEAD when user asks about:**). While this emphasizes the importance, consider if this level of detail is appropriate for a tool description field, or if it would be better served in documentation or server instructions. The description is quite long for an API tool definition.

Suggested change
mcp.WithDescription(t("TOOL_ISSUE_READ_DESCRIPTION", `Get detailed information about a single issue: full body, comments, sub-issues, or labels.
**USE issue_graph INSTEAD when user asks about:**
- Status, updates, or progress on issues/PRs/epics
- Project overview or how work is going
- Parent issues, sub-issues, or work hierarchy
- Related or blocking issues
issue_read is for: reading the full issue body, fetching comments, listing sub-issues of a known parent, or getting label details - AFTER you already know which specific issue you need.`)),
mcp.WithDescription(t("TOOL_ISSUE_READ_DESCRIPTION", `Get detailed information about a single issue, including its body, comments, sub-issues, and labels.`)),

Copilot uses AI. Check for mistakes.
Comment on lines +450 to +473
requestCount := 0
mockedHTTPClient := mock.NewMockedHTTPClient(
mock.WithRequestMatchHandler(
mock.GetReposIssuesByOwnerByRepoByIssueNumber,
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Determine which issue is being requested based on URL
path := r.URL.Path
var issue *github.Issue
switch {
case strings.Contains(path, "/101"):
issue = subIssue1
case strings.Contains(path, "/102"):
issue = subIssue2
default:
issue = parentIssue
}
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(issue)
}),
),
mock.WithRequestMatchHandler(
mock.GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber,
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requestCount++
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable requestCount is incremented but never checked in the test. If this is intended for debugging or future assertions, consider either using it in an assertion or removing it to keep the test code clean.

Copilot uses AI. Check for mistakes.
Comment on lines +806 to +808
timelineEvents, timelineResp, err := gc.client.Issues.ListIssueTimeline(ctx, current.owner, current.repo, current.number, &github.ListOptions{
PerPage: 100,
})
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeline events API call uses PerPage: 100 without pagination. For issues with many cross-references, this could miss events beyond the first 100. Consider either adding pagination or documenting this limitation as a known trade-off for performance.

Copilot uses AI. Check for mistakes.
Comment on lines +1413 to +1416
vars := map[string]interface{}{
"owner": githubv4.String(owner),
"repo": githubv4.String(repo),
"number": githubv4.Int(int32(number)), //nolint:gosec // issue numbers are always small positive integers
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gosec lint suppression comment references "issue numbers are always small positive integers", but the conversion to int32 could theoretically overflow for issue numbers above 2,147,483,647. While extremely unlikely in practice, GitHub's API uses int for issue numbers, not int32. Consider using a safer conversion or updating the comment to acknowledge this theoretical limitation.

Suggested change
vars := map[string]interface{}{
"owner": githubv4.String(owner),
"repo": githubv4.String(repo),
"number": githubv4.Int(int32(number)), //nolint:gosec // issue numbers are always small positive integers
// Issue numbers must fit in int32 for githubv4.Int; GitHub API currently uses int, but issue numbers above 2,147,483,647 will overflow.
if number < 1 || number > int32(^uint32(0)>>1) {
// Return nil or handle error gracefully if issue number is out of int32 range
return nil
}
vars := map[string]interface{}{
"owner": githubv4.String(owner),
"repo": githubv4.String(repo),
"number": githubv4.Int(int32(number)), //nolint:gosec // issue numbers are always small positive integers; conversion will fail for numbers above int32 max

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add issue_graph tool to visualize issue/PR relationships and hierarchy

2 participants