{"version":3,"sources":["../src/contribute.ts"],"sourcesContent":["// Contribute — stream a save (PR or direct commit) from app code\n// (UI_AS_APPS_SPEC §5.1, CONTRIBUTE_SPEC). The host runs the *existing*\n// contribution orchestrator and streams its stages back; this is the typed\n// front door over `protocolStream`.\n//\n// The OAuth token never reaches here — it stays on the host. The app passes a\n// commit message + save mode and watches stages go by; the host owns the token,\n// the GitHub API calls, and the user-facing consent.\nimport { protocolStream } from './protocolStream';\nimport { PROTOCOL_CONTRIBUTE } from './generated/protocol';\n\n/** The save strategy. `direct` requires the first-party `contribute:direct`\n *  capability and a scarier consent line — a `contribute:any` app asking for it\n *  is REJECTED (`forbidden`), never silently downgraded to a PR (threat T11). */\nexport type ContributeMode = 'pr' | 'direct';\n\n/** The recovery a recoverable save error offers (CONTRIBUTE_SPEC §12), so an app\n *  renders the specified action instead of a generic \"try again\". Mirrors the\n *  host orchestrator's `RecoveryAction`.\n *  - `retry` — the failed step is idempotent; re-running the save is safe.\n *  - `use-different-name` — a branch with that name exists and is not this\n *    session's lineage; renaming (or, for a caller-supplied name, the §8.8 gated\n *    force-update) is the only way on.\n *  - `open-pr` — the branch was pushed but opening the PR failed; resume with the\n *    event's `openPR` context (CT-6), never re-push.\n *  - `switch-to-pr` — a direct commit was rejected as a non-fast-forward; offer a\n *    new branch + PR instead (CT-3). */\nexport type RecoveryAction = 'retry' | 'use-different-name' | 'open-pr' | 'switch-to-pr';\n\n/** Identifiers for the `open-pr` resume: the branch already exists on the push\n *  repo (the upstream or the user's fork) and only the PR is missing. `head` is\n *  the PR head ref (`branch` or `forkOwner:branch`). Minted by the host; an app\n *  passes it back unchanged in {@link ContributeOptions.resume}. */\nexport interface OpenPRResumeContext {\n  pushOwner: string;\n  repository: string;\n  branchName: string;\n  base: string;\n  head: string;\n}\n\n/** A stage emitted as the contribution runs. Mirrors the host orchestrator's\n *  event union; carries progress metadata only — never the token or file blobs. */\nexport type ContributionEvent =\n  | { stage: 'auth-check' }\n  | { stage: 'diff-compute' }\n  | { stage: 'permission-check' }\n  | { stage: 'install-required'; targetOwner: string; targetRepo: string; installUrl: string }\n  | { stage: 'conflict-check' }\n  | { stage: 'fork-prepare'; forkOwner: string; alreadyExists: boolean }\n  | { stage: 'upload-blob'; path: string; index: number; total: number }\n  | { stage: 'create-tree' }\n  | { stage: 'create-commit' }\n  | { stage: 'create-branch'; branchName: string }\n  | { stage: 'create-pr' }\n  | { stage: 'pr-updated'; prNumber: number; prUrl: string; commitSha: string }\n  | { stage: 'commit-pushed'; ref: string; commitSha: string }\n  | { stage: 'switch-branch'; provider: 'github'; pushOwner: string; repository: string; branchName: string }\n  | { stage: 'done'; prUrl?: string; prNumber?: number; commitSha: string }\n  | { stage: 'warning'; message: string; details?: unknown }\n  | {\n      stage: 'error';\n      message: string;\n      recoverable: boolean;\n      /** The specific recovery to offer. Absent ⇒ the generic recoverable surface. */\n      recovery?: RecoveryAction;\n      /** Present only with `recovery === 'open-pr'`: the existing branch to open a PR for. */\n      openPR?: OpenPRResumeContext;\n    };\n\n/** The settled outcome (the stream's return value). */\nexport interface ContributionResult {\n  prUrl?: string;\n  prNumber?: number;\n  commitSha: string;\n  treeSha: string;\n  branchName: string;\n  mode: 'direct-commit' | 'new-branch-pr' | 'extend-existing';\n}\n\n/** Options for a contribution: the commit message, save {@link ContributeMode},\n *  (PR mode) an optional branch name, and the transcript request hint. */\nexport interface ContributeOptions {\n  /** The commit message / PR title. */\n  commitMessage: string;\n  /** `'pr'` (default) opens a PR; `'direct'` commits to the branch and needs\n   *  the first-party `contribute:direct` capability. */\n  mode?: ContributeMode;\n  /** Override the generated branch name (PR mode). */\n  branchName?: string;\n  /** CONTRIBUTE_TRANSCRIPT_SPEC §4 R-CT-5: the \"Commit session transcript\"\n   *  checkbox's sole effect — a boolean request HINT, never bytes/path/render\n   *  (R-CT-6). The host's disclosure review remains the consent (R-CT-7) and\n   *  the hint is spent per contribution (R-CT-8). */\n  transcriptRequested?: boolean;\n  /** CONTRIBUTE_SPEC §8.8: update a caller-supplied branch that already exists.\n   *  Offer it only after a `use-different-name` error on a name the user typed;\n   *  the host's lineage gate (CT-4) still decides whether the update is allowed. */\n  forceUpdateBranch?: boolean;\n  /** Resume instead of a fresh save. `open-pr` opens the PR for the branch a\n   *  failed attempt already pushed (CT-6), using the error event's `openPR`\n   *  context unchanged; the host refuses a context it did not mint for this app. */\n  resume?: { kind: 'open-pr'; context: OpenPRResumeContext };\n}\n\n/**\n * Save the current working tree, streaming each stage.\n *\n * ```ts\n * for await (const ev of contribute({ commitMessage: 'Edit post' })) {\n *   if (ev.stage === 'done') console.log(ev.prUrl);\n * }\n * ```\n *\n * Yields {@link ContributionEvent}s and returns a {@link ContributionResult}.\n * Throws a `StreamError` (`.code`) if the host rejects the request — notably\n * `forbidden` when a `contribute:any` app asks for `mode: 'direct'` (T11).\n */\nexport function contribute(opts: ContributeOptions): AsyncGenerator<ContributionEvent, ContributionResult, void> {\n  return protocolStream<ContributionEvent, ContributionResult>(PROTOCOL_CONTRIBUTE, 'run', [opts]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,4BAA+B;AAC/B,sBAAoC;AA6G7B,SAAS,WAAW,MAAsF;AAC/G,aAAO,sCAAsD,qCAAqB,OAAO,CAAC,IAAI,CAAC;AACjG;","names":[]}