import { type ProjectCacheEntry, type StoredCredentials } from "./config.js"; import { ShipFlowClient } from "./client.js"; export interface RepoCoord { owner: string; repo: string; } export declare function parseGitRemote(url: string): RepoCoord | null; export declare function getCwdRepoRoot(): string | null; export declare function getCwdRemote(): RepoCoord | null; /** `owner/repo` for the cwd's origin remote, or null when there is no git repo * or origin is not a github.com URL. Local only — never touches the network. */ export declare function cwdRepoFullName(): string | null; export interface ResolvedProject extends ProjectCacheEntry { repoFullName: string; } /** Resolves the ShipFlow project for the cwd repo. Prompts on ambiguity. Caches * the choice. Throws when the API can't be reached — for the commands that * genuinely need a projectId (signals, feature map, claims). * * A thin wrapper over {@link resolveProjectDegradable} so there is exactly ONE * resolution path: the strict and degradable forms differ only in what they do * with an unreachable server, and a second copy of the cache/remote/prompt * logic is how the two would drift apart. */ export declare function resolveProject(client: ShipFlowClient, creds: StoredCredentials): Promise; /** The one dependency name a degraded resolution reports (machine-readable, so * `--json` consumers can branch on it rather than parse the warning text). */ export declare const SHIPFLOW_API_DEP = "shipflow-api"; /** Whether a rejected API call means the dependency was UNAVAILABLE — that it * never answered — as opposed to answering with a refusal. * * This is the distinction issue #447 turns on, and getting it wrong is * symmetrical: `degraded` must describe the DEPENDENCY'S HEALTH, not whether * the probe happened to throw. Catch everything and a server that answers 404 * is reported "unavailable", sending an operator to hunt an outage that is not * happening. Catch nothing and the outage the issue exists for still aborts. * * No `ApiError` means no HTTP response reached us at all (ECONNREFUSED, DNS, * TLS, or a body that would not parse) — nothing was answered, so: unavailable. * * 5xx counts as unavailable deliberately. A real outage behind a proxy shows up * as 502/503/504 far more often than as a refused connection, so treating "the * server answered, with 'I am broken'" as a hard error would leave #447's own * failure mode uncured for every gateway-fronted deployment. The server has * told us nothing about the repo either way. */ export declare function isDependencyUnavailable(e: unknown): boolean; /** Collapse a failure message to ONE line, for the single-line warning * contract. `ApiError.message` embeds the raw response body verbatim, which is * routinely multi-line — pretty-printed JSON, or a proxy's HTML error page — * and a WARNING that spans twenty lines is a wall an operator scrolls past. * Capped as well as flattened: a 40 KB gateway page on one line is no more * readable than on twenty. */ export declare function flattenCause(e: unknown, max?: number): string; /** A project resolution that survives a ShipFlow API outage (issue #447). * * `repoFullName` is ALWAYS present: it is derived from the git remote, five * lines before the server is ever consulted. `project` is null when only the * remote could be read — the caller then has everything a GitHub-only command * needs (the repo) and nothing that requires the API (projectId / feature map * / signals), which is exactly the distinction the outage exposed. */ export interface DegradableProject { repoFullName: string; project: ResolvedProject | null; /** Dependencies that were unavailable — `[]` on a healthy resolution. */ degraded: string[]; /** The ONE operator-facing warning line, or null when nothing degraded. */ warning: string | null; /** The underlying failure message, so the strict {@link resolveProject} can * re-throw the ORIGINAL error text rather than a paraphrase of it. */ cause?: string; } /** {@link resolveProject}, but a ShipFlow API failure degrades instead of * throwing: the repo comes from the git remote and the caller is told, loudly, * which check did not run. * * Only an UNAVAILABLE API degrades — see {@link isDependencyUnavailable}. A * missing git repo, a non-GitHub remote, and "this repo is in no ShipFlow * project" are still hard errors, and so is any status the server ANSWERS * with: 401 (not you), 403 (not allowed), 404 REPO_NOT_FOUND (not in your * tenant). Those are misconfiguration a human must fix, not an outage to ride * out, and papering over them would let a command run against a repo the * caller has no access to. */ export declare function resolveProjectDegradable(client: ShipFlowClient, creds: StoredCredentials): Promise; /** The single degraded-resolution warning line. Modelled on `issue next`'s * claims-API warning: name the dependency, say the check did NOT run, and name * the dependent steps being skipped — a degraded gate that says nothing is the * #407-class failure this issue exists to stop. Pure + testable. */ export declare function degradedProjectWarning(repoFullName: string, cause: string): string; /** The line `pr packet` prints when the per-feature evidence-coverage check did * NOT run. Same contract as {@link degradedProjectWarning} — one line, name the * dependency, name the check that was skipped, carry the cause. * * This exists because a WARM project cache reaches the feature map with the API * already dead: resolution short-circuits on the cache (so it degrades nothing * and warns nothing), the fetch then fails, and the old bare `catch {}` dropped * the coverage check in total silence — which is issue #447's own title. */ export declare function featureMapSkippedWarning(cause: string): string; /** GitHub's REST API (what `gh pr diff` runs on) — named separately from * {@link SHIPFLOW_API_DEP} because the two fail independently and a `--json` * consumer must be able to tell WHICH gate went dark. Losing the ShipFlow * feature map costs a nice-to-have; losing GitHub's own view of the PR costs * the security scan's *input*, which is an approve precondition. * * Deliberately NOT the key for the acceptance-brief fetch: `gh issue view * --json` runs on GraphQL, so a brief-read failure degrades * {@link GITHUB_GRAPHQL_DEP} — naming REST there sent an operator to the wrong * API status page for a GraphQL outage (PR #482 round-5 review). One key per * transport that can actually fail. */ export declare const GITHUB_REST_DEP = "github-rest"; /** The stderr half of a changed-file census that did not answer. The * machine-readable half is `degraded: ["github-rest"]` in the command's * `--json`, and the human half in the review body — a piped consumer never * sees stderr, so the fact has to travel in the artifact too. * * Says NOT DETERMINED, never "0": an undetermined expected-count is exactly the * input the attestation gate must refuse to treat as agreement. */ export declare function changedFilesUnavailableWarning(cause: string): string; /** The line `pr packet` prints when the coverage check was **not applicable** — * `--repo` targets a repo outside this checkout's ShipFlow project, so * `loadGhCtx` deliberately skipped resolution (`projectNotApplicable`) and * there is no map that could describe the target. * * Deliberately carries NO `⚠️`, no `WARNING`, never the word "unavailable", and * does not NAME a dependency — naming one is the degradation convention, and * the finding here was a healthy dependency being named as the culprit. * Nothing failed. {@link featureMapSkippedWarning} was being reused for this * case, so a supported cross-repo override rendered an outage that never * happened — and, since the loop-reviewer contract blocks approve on a * degradation marker, made every cross-repo packet permanently unapprovable on * a healthy system (PR #482 review). A false RED costs the same trust as the * false green this slice removes: the marker only means something while it is * reserved for a real failure. One line, like its siblings. */ export declare function featureMapNotApplicableNote(target: string): string; /** GitHub's GraphQL API — the dependency the review-thread query runs on. * * Named SEPARATELY from {@link SHIPFLOW_API_DEP} because the two fail * independently and a `--json` consumer must be able to tell them apart: a * ShipFlow outage costs the feature map (a nice-to-have), while a GraphQL blip * costs the unresolved-thread count — which is the loop reviewer's §0 approve * PRECONDITION. Collapsing both into one key would hide which gate went dark. */ export declare const GITHUB_GRAPHQL_DEP = "github-graphql"; /** The stderr half of an unavailable review-thread fetch. The in-artifact half * is `packet.REVIEW_THREADS_UNAVAILABLE_MARKER` — a piped packet never sees * stderr, which is why the marker must ALSO be in the markdown body. */ export declare function reviewThreadsUnavailableWarning(cause: string): string; /** The stderr half of a linked-issue fetch that did not answer. The in-artifact * half is `packet.specUnavailableMarker` — same two-channel contract as * {@link reviewThreadsUnavailableWarning}. * * Names {@link GITHUB_GRAPHQL_DEP}: the brief fetch is `gh issue view --json`, * which gh serves over GraphQL — the same transport as the review-thread * query, and the entire basis for classifying its failure from its own error * rather than probing REST. Naming `github-rest` here reported one GraphQL * outage as two different dependencies and pointed the operator at the wrong * status page (PR #482 round-5 review). Losing the brief is still a DIFFERENT * finding from losing the thread count — the warnings and `--json` fields stay * separate — but the dependency key tells the truth about the transport. * * A bare `catch {}` here rendered "No linked issue/brief found", which is the * packet's wording for a PR that genuinely links nothing: a GitHub blip became * an accusation against the author, and sent the reviewer to judge a diff with * no spec while its own output reported nothing missing (PR #482 review). An * input that could not be READ is never an input that is ABSENT. */ export declare function specUnavailableWarning(issueNumber: number, cause: string): string; /** The counterpart to {@link specUnavailableWarning} for a linked number GitHub * ANSWERED about but that is not a readable issue here — a deleted/transferred * number, or a `Part of #N` that names a PR (`gh issue view` refuses those, * while the REST issues endpoint resolves them). * * Deliberately carries NO `⚠️`, no `WARNING`, never the word "unavailable", and * does not NAME a dependency — exactly the contract * {@link featureMapNotApplicableNote} follows, and for the same reason. GitHub * answering proves there is no outage, so this is a plain finding about the * link, not a degradation. Reusing the degradation wording pushed * {@link GITHUB_REST_DEP} on a 404, and the loop-reviewer rule blocks approve on * any `degraded[]` entry — which made a PR with a stale link permanently * unapprovable on a healthy GitHub (PR #482 round-3 review). One line, like its * siblings. */ export declare function specNotReadableIssueNote(issueNumber: number, repo: string): string; /** The in-artifact marker `issue work` / `issue next` print on stdout when the * ShipFlow triage did not load. The intake gate runs on the issue body alone * then — it must not report the same shape as an issue that genuinely has no * triage. Kept verbatim (no cause appended) so the human-readable render stays * one stable line; the cause travels on the stderr warning below. */ export declare const TRIAGE_UNAVAILABLE_MARKER = "\u26A0\uFE0F triage unavailable \u2014 ShipFlow context and relatedFiles NOT loaded"; /** The stderr half of a failed triage fetch — one line, names the dependency, * names what did not load, carries the cause. */ export declare function triageUnavailableWarning(cause: string): string; //# sourceMappingURL=project.d.ts.map