/** * Build the id → issue map the planner reconciles against. * * One `gh issue list` invocation over the discovery label. Three details are load-bearing * and all three were wrong in the first draft: * * - **`--limit` must be explicit.** `gh issue list` defaults to 30 results. A single call * without a limit therefore returns at most 30 issues on a repo that has more, and every * item missing from the map plans a `create` — producing exactly the duplicate issues the * whole design exists to prevent, on every run, undetectably. * - **Truncation must be a refusal, not a shrug.** A response of N issues is otherwise * indistinguishable from "N is all there are". So the requested limit travels with the * result and `count === limit` refuses before anything can plan a create. * - **`labels` are objects.** `gh issue list --json labels` returns * `{id,name,description,color}`, not strings. Treating them as strings makes every * comparison against `aidlc:` fail, so every item plans `update-labels` on every * run and the projection never converges. They are flattened to names here, at the * boundary, once. * * Requirements: roadmap-issue-projection/AC-11, roadmap-issue-projection/AC-12, * roadmap-issue-projection/AC-13 * * @module */ import { type GhRunner } from './gh.js'; import type { RemoteMilestone } from './milestone-projection.js'; import type { RemoteIssue } from './types.js'; /** * How many issues one map may hold. * * `gh` pages internally up to `--limit`, so this is one paginated sequence rather than a * cap on a single page. A repo that reaches it gets a named refusal; that is a better * outcome than a partial map, and better than reimplementing cursors against an interface * (`gh issue list`) that exposes none. */ export declare const ISSUE_LIST_LIMIT = 1000; export type DiscoverResult = { kind: 'ok'; issues: readonly RemoteIssue[]; } | { kind: 'truncated'; count: number; limit: number; } | { kind: 'failed'; error: string; }; export interface DiscoverOpts { repo: string | null; label: string; limit?: number; /** * Ask for each issue's milestone. Only while milestones are on, so a repo without a * milestones file makes the same call as before (github-milestones/AC-15). */ withMilestone?: boolean; } /** Read every labelled issue, open and closed. */ export declare function buildIssueMap(gh: GhRunner, opts: DiscoverOpts): DiscoverResult; /** The message for a truncated map. */ export declare function truncatedMessage(count: number, limit: number): string; export type MilestoneListResult = { kind: 'ok'; milestones: readonly RemoteMilestone[]; } | { kind: 'failed'; error: string; }; /** * Every milestone on the repository, open and closed (github-milestones/AC-1..AC-3). * * `gh` has no milestone subcommand, so this is the REST list through `gh api`. `{owner}/{repo}` * is `gh`'s own placeholder for the current repository, matching how the issue calls resolve * it when `roadmap.sync.repo` is unset. `--jq '.[]'` turns every page into one object per * line, which parses the same however `--paginate` joins the pages. */ export declare function listMilestones(gh: GhRunner, repo: string | null): MilestoneListResult; //# sourceMappingURL=discover.d.ts.map