Skip to content

Search GitHub issues and pull requests in the current repository #815

Description

@taras

Story

As an executable-document author, I want to search the current repository's issues and pull requests with GitHub's query syntax, so an XMD workflow can select the work it needs without invoking gh or learning a second filtering language.

Example outcome

A workflow running with the intended repository in context supplies the same kind of query a person uses on GitHub:

is:pr is:open label:bug created:>=2026-01-01
<GitHub.Search
  query="is:pr is:open"
  sort="created"
  order="desc"
  page={1}
  perPage={20}
  as="result"
/>

It can inspect one page of normalized results and pagination metadata, request result.nextPage when another accessible page exists, and pass a selected pull-request URL to the URL-addressed details and evidence reads owned by #816:

<PullRequest.Reviews url={pullRequest.url} as="reviews" />
<PullRequest.Comments url={pullRequest.url} as="comments" />
<PullRequest.Checks url={pullRequest.url} as="checks" />

<GitHub.Search> is the public component. The lasting outcome is that GitHub's query language controls matching within the current repository.

Current gap

The existing pull-request read components start from one already-known canonical pull-request URL. There is no executable-document component that searches the repository currently selected by the document and returns a bounded result.

As a result, .reviews/AnalyzeReviewFeedback.md invokes gh pr list and renders provider-specific output before it can analyze recent pull requests.

Package and Plugin boundary

#822 is a prerequisite. It extracts the existing repository, Git, issue, pull-request and GitHub provider surface into one bundled @executablemd/git Plugin, which remains active by default in the run/workflow profile. There is no separate git-host or GitHub package or Plugin.

<GitHub.Search> joins that bundled Plugin under the GitHub.* namespace. A bare run or workflow profile therefore has the declaration and provider available without another Plugin selector; --plugin git remains an idempotent reference to the already-active bundled value.

Loading the profile alone performs no GitHub configuration read, credential lookup or request. Those boundaries are crossed only when an invoked <GitHub.Search> operation selects the bundled GitHub adapter. Missing or unusable configuration refuses that operation before transport.

Search contract

The authored search expression uses GitHub’s issue-and-pull-request query syntax. Every query selects exactly one result kind with is:issue or is:pr. Searching both kinds requires two independent <GitHub.Search> invocations. XMD does not invent separate props or vocabulary for result kind, state, labels, authors, dates, or other matching qualifiers.

Search is scoped to the Repository selection already in context. An ordinary xmd run may supply its ambient repository; a document may select another through its existing repository composition. The search accepts no repository prop. Future stories may add other contextual search scopes without changing what this repository-scoped form means.

The repository context is the scope boundary, not part of the authored query. XMD applies the current repository's exact GitHub scope and refuses repository-, organization-, or user-scoping qualifiers in the query so authored text cannot widen or contradict that context.

The optional sort and order props use GitHub REST search values. order is accepted only when sort is present; omitting both uses GitHub’s best-match order. XMD preserves GitHub’s returned order.

page defaults to 1. perPage defaults to 20 and accepts integers from 1 through GitHub’s maximum of 100. One invocation returns exactly one GitHub page; the component does not silently combine pages.

The captured result contains items, page, perPage, totalCount, nextPage, and resultCeilingReached. nextPage is the next accessible page number or null, never GitHub’s raw Link URL. resultCeilingReached reports when GitHub’s 1,000-result search ceiling prevents access to every match. A page whose first item would lie beyond that ceiling is refused before search.

The retained request contains the exact query and every explicit or defaulted ordering and pagination input. Results preserve GitHub’s order. Fewer remaining matches than perPage is a complete shorter page. GitHub’s incomplete_results response or any other incomplete page is unavailable rather than a successful partial result.

Each item is one of two closed normalized shapes distinguished by kind. Both shapes contain url, number, title, state, author, labels, assignees, commentsCount, createdAt, updatedAt, and nullable closedAt. Pull-request items have kind: "pull-request" and boolean draft; issue items have kind: "issue" and draft: null. author is a login or null; labels contains label names and assignees contains logins.

Bodies, text-match fragments, provider IDs, relevance scores, refs, commits, and diffs are not search summaries. Provider tokens, API endpoints, raw pagination links, raw responses, and transport diagnostics do not enter document bindings, rendered output, or journals.

Host boundary

The trusted repository provider authenticates the current Repository selection and establishes its GitHub identity before a search credential is read or a request is sent. A missing repository context, a non-GitHub repository, or a repository outside the host's configured read ceiling refuses before search.

GitHub's search endpoint is the first and defining query adapter. An ordinary xmd run performs a fresh read. A workflow run retains and replays the normalized result through the existing pull-request read execution boundary.

Searching grants no access to another repository and no Git push, pull-request update, issue update, comment publication, check publication, merge, or other collaboration-state mutation permission.

Acceptance

  • An executable document searches the current repository’s issues or pull requests with GitHub query syntax and no shell command.
  • <GitHub.Search> is declared and implemented by the bundled default @executablemd/git Plugin alongside its provider-neutral repository surface.
  • Loading the bundled Plugin without invoking <GitHub.Search> performs no GitHub configuration read, credential lookup or transport; an invoked search with missing or unusable configuration refuses before transport.
  • Every query contains exactly one of is:issue or is:pr; a query containing both or neither refuses before search.
  • The repository comes only from the contextual Repository selection; the component accepts no repository prop.
  • An authored repository, organization, or user scope qualifier is refused before credential lookup or network access.
  • Results use one documented deterministic order and contain closed normalized items with kind, url, number, title, state, author, labels, assignees, commentsCount, createdAt, updatedAt, closedAt, and draft.
  • draft is boolean for pull-request items and null for issue items; author and closedAt are nullable.
  • page defaults to 1; perPage defaults to 20 and accepts integers from 1 through 100.
  • One invocation returns one page with normalized page, perPage, totalCount, nextPage, and resultCeilingReached metadata.
  • Explicit and defaulted query, ordering, and pagination inputs are retained as part of the request.
  • Fewer remaining items than perPage produces a complete shorter page.
  • A missing, unauthorized, or non-GitHub repository context refuses before search.
  • Missing authentication, rate limiting, malformed provider data, and incomplete_results cannot become an empty or shortened successful page.
  • A page beyond GitHub’s accessible 1,000-result window is refused, and an in-range page discloses when the search has more matches than GitHub makes accessible.
  • Provider credentials, endpoints, raw pagination links, and raw responses never cross the normalized read boundary.
  • Completed workflow replay performs no provider request; an ordinary run reads current data.
  • .reviews/AnalyzeReviewFeedback.md can replace its gh pr list collection with the delivered component.

Evidence

Focused tests cover repository-context selection, GitHub query forwarding, deterministic ordering, issue-only and pull-request-only searches, default and explicit page sizes, consecutive page requests, a final page shorter than perPage, incomplete_results, the provider result ceiling, credential ordering, both closed normalized item shapes, rejection of unexpected provider fields, ordinary execution, and durable replay.

Negative controls omit the repository context, select a non-GitHub repository, use an unauthorized selection, and place repository-, organization-, or user-scoping qualifiers in the query. Each refuses before search. Another returns an incomplete page and proves that no partial result is returned.

An integration document searches a controlled repository and passes returned pull-request URLs to existing pull-request evidence components. Plugin-profile coverage proves that bare run/workflow profiles contain the complete Git Plugin once, already expose <GitHub.Search>, and selecting --plugin git neither duplicates nor reconfigures it. Zero-effect coverage proves that loading that profile alone reaches no GitHub configuration, credential or transport boundary.

Related work

Out of scope

  • Searching outside the current repository, including organization-wide, user-wide, and global search.
  • Reading a pull request's complete body, refs, commits, changed files, or diff; Read a pull request and its changes from executable documents #816 owns those URL-addressed reads.
  • Creating, updating, closing, merging, or marking an issue or pull request ready.
  • Posting comments or publishing check results.
  • Replacing the existing reviews, comments, or checks components.
  • Exposing raw GitHub REST response shapes.
  • Adding an unbounded repository-history export.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentsExecutable documents, authored workflows, and reader-facing document behaviorenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions