import type { Command } from "commander"; import type { ShipFlowClient, TriageView } from "../client.js"; import { type DuplicateCandidate } from "../issue-similarity.js"; import type { DependencyRef } from "../issue-order.js"; /** Load an issue's ShipFlow triage, distinguishing "no triage exists" from * "the triage did NOT load" (issue #447 slice B). * * The `.catch(() => null)` this replaces collapsed both into `null`, and * `printIssueContext` renders `null` as silence — so the intake gate ran on * the issue body alone while reporting the same shape as a fully-loaded issue. * A genuinely triage-less issue answers 200 (cli_handler.go HandleGetTriage); * ANY rejection means the input did not arrive, which is what the flag records * — and it is loud on stderr as well, one line, carrying the cause. */ export declare function loadTriage(ctx: { client: Pick; creds: { org: string; }; project: { projectId: string; }; }, repo: string, number: number): Promise<{ triage: TriageView | null; unavailable: boolean; }>; /** Exit code for "an open issue already says this — nothing was created" * (issue #580). * * **12, not 5.** `CONTRIBUTING.md` rule 3 makes exit codes a **repository-wide** * API ("exit codes `3/4/5/6/7/10/11` … stay byte-compatible"), not a per-command * namespace, and `5` is already **automerge not ready** (`commands/pr.ts:864`). * The first cut of this PR reused 5 and shipped a test asserting it was free — * the test only checked the `issue` family, so it certified the collision. * Every code below 12 is taken repo-wide: 1 usage/validation · 2 prose lint · * 3 claim taken · 4 no work · 5 automerge not ready · 6 rebase conflict · * 7 open threads · 8 conflict-check dirty (`pr.ts:1087`) · 9 `SCAN_EXIT` * (`pr.ts:335`) · 10 unexpected (`helpers.ts:273`) · 11 evidence delivery. * 12 is the first free one, so a caller can tell "you filed a duplicate" from * "an automerge gate is closed" without parsing prose. */ export declare const EXIT_DUPLICATE_ISSUE = 12; /** * Pre-flight duplicate guard for `issue create` (issue #580). Exits * `EXIT_DUPLICATE_ISSUE` — creating nothing — when an open issue already says * what the caller is about to file. * * Two properties are load-bearing: * * 1. **It fetches the FULL open set** (`DUPLICATE_SCAN_LIMIT`, not * `ghIssueList`'s default 30). The 30-issue newest-first window is exactly * what hid #427 behind 118 newer issues while the loop's instruction-only * dedupe reported "no duplicates". * 2. **A fetch failure degrades OPEN.** A GitHub outage must never stop a bug * from being filed — the guard warns loudly and returns, and the issue is * created. Blocking here would turn a read outage into a write outage. * * Returns the candidates it found (empty when clean, or the ones * `--allow-duplicate` overrode); it does not return when it blocks. */ export declare function duplicatePreflight(repo: string, title: string, opts: { allowDuplicate?: boolean; json?: boolean; yaml?: boolean; }): DuplicateCandidate[]; /** The guard and the write, inseparable: every `issue create` reaches * `ghIssueCreate` through here, so the dedupe check cannot be routed around. * Exported for the regression tests, which assert `gh issue create` is never * executed on a blocked title. */ export declare function createIssueGuarded(args: { repo: string; title: string; body: string; labels: string[]; assignees?: string[]; assigneesAuto?: boolean; }, opts: { allowDuplicate?: boolean; json?: boolean; yaml?: boolean; }, { skipPreflight }?: { skipPreflight?: boolean; }): void; /** Assignees for a new issue (issue #673). Under `pickup-scope=assigned` (the * default) assignment IS the queueing gesture (#600): an issue filed with no * assignee is invisible to `issue next` — a dead letter until a human assigns * it by hand, which is exactly what happened to every bug-sweep filing. So * `issue create` auto-assigns the resolved login by default — the SAME rule * pickup filters on, not a new one. * * An explicit `--assignee` always wins (`@me` resolves fail-closed through * `resolveMeLogin`, #652 — the caller named a person; silently filing * unassigned would not be that person). The AUTO path degrades instead of * failing: an issue report must never be blocked (#196's rule), so an * unresolvable login files UNASSIGNED with a loud warning naming the * consequence. `pickup-scope=all` keeps today's behavior — no auto-assign. * * `--no-assign` is the PER-INVOCATION opt-out (PR #674 review): every filing * surface funnels through this command, `/shipflow-new-issue` included, so * without it a human filing a backlog item on the shared account silently * hands it to the loop's pickup queue — and the only escape would be flipping * the GLOBAL `pickup-scope`. It is mutually exclusive with `--assignee`: * "assign nobody" and "assign this person" cannot both be honoured, and * picking one silently would drop an instruction the caller typed. * * `auto` in the return says WHOSE decision the assignees are, which is what * decides whether a `gh` rejection of the SEPARATE assignment step is fatal * (see `attachAssignees`). Either way the issue is already filed by then. */ export declare function resolveCreateAssignees(explicit: string[] | undefined, noAssign?: boolean): { assignees: string[]; auto: boolean; }; /** The `issue next` waiting-on re-admit body: notice + the loop marker. * Pure and exported so the test invokes the REAL assembly (issue #626). * * Ends with the loop marker: without it, UnblockNeedsHuman treats this * comment as a human reply and silently strips needs-human. */ export declare function renderReadmitBody(dep: DependencyRef): string; export declare function registerIssueCommand(program: Command): void; //# sourceMappingURL=issue.d.ts.map