Files
orca/mobile/src/source-control/mobile-hosted-review-create-intent-runner.ts
T
Jinjing 8a39450b18 refs/heads/handle-mobile-pull-request-issues (#6598)
* feat(mobile): add commit failure recovery panel with AI fix action

- Surfaces a "Commit failed" panel with a one-tap AI fix button when a
  git commit fails in the source control view or PR creation flow
- Detects commit failures specifically during the committing progress
  step and captures staged entries and commit message for context
- Extracts commit failure summary and prompt logic into
  `src/shared/source-control-commit-failure.ts` and PR checks prompt
  into `src/shared/pr-checks-fix-prompt.ts` so both desktop and mobile
  share the same implementations
- Adds auto-find of an available Metro port starting from 8081 and
  extracts expo CLI bootstrap into `mobile-expo-cli.mjs` shared by
  `start-emulator` and a new `start-expo.mjs` wrapper

* Share source-control AI prompts and simplify mobile PR actions

- Extract conflict, check-fixing, and commit-failure prompt builders
  to shared modules for reuse by both desktop and mobile.
- Configure Metro in the mobile package to watch and bundle modules
  from the repository-root shared directory.
- Remove the desktop-style merge method picker from the mobile PR
  actions panel, opting to use repository defaults automatically.
- Refactor mobile hosted review creation and git preparation logic
  into dedicated helper files.
2026-06-28 00:58:17 -07:00

97 lines
2.6 KiB
TypeScript

import type { RpcClient } from '../transport/rpc-client'
import type { MobileGitStatusResult } from './mobile-git-status'
import {
createMobilePr,
getMobilePrCreateBlockMessage,
getMobilePrCreateSuccessWarning,
shouldPushBeforeMobilePrCreate,
type MobilePrPrefill
} from './mobile-pr-create'
import {
prepareMobileHostedReviewCreateIntent,
type MobileHostedReviewCreateIntentProgress
} from './mobile-hosted-review-create-intent'
type RunInput = {
branch: string
title: string
status: MobileGitStatusResult | null
commitMessage?: string
onProgress?: (progress: MobileHostedReviewCreateIntentProgress) => void
}
export type MobileHostedReviewCreateIntentRunOutcome =
| {
ok: true
url: string
warning?: string
prefill: MobilePrPrefill
status: MobileGitStatusResult | null
committed: boolean
}
| {
ok: false
error: string
committed?: boolean
status?: MobileGitStatusResult | null
commitMessage?: string
}
export function isMobileHostedReviewCommitFailure(
outcome: MobileHostedReviewCreateIntentRunOutcome,
progress: MobileHostedReviewCreateIntentProgress | null
): outcome is Extract<MobileHostedReviewCreateIntentRunOutcome, { ok: false }> & {
committed: false
} {
return !outcome.ok && progress === 'committing' && outcome.committed === false
}
export async function runMobileHostedReviewCreateIntent(
client: Pick<RpcClient, 'sendRequest'>,
worktreeId: string,
input: RunInput
): Promise<MobileHostedReviewCreateIntentRunOutcome> {
const prepared = await prepareMobileHostedReviewCreateIntent(client, worktreeId, input)
if (!prepared.ok) {
return prepared
}
const blockedMessage = getMobilePrCreateBlockMessage(prepared.prefill)
if (blockedMessage) {
return {
ok: false,
error: blockedMessage,
committed: prepared.committed,
status: prepared.status
}
}
input.onProgress?.('creating_review')
const created = await createMobilePr(client, worktreeId, {
provider: prepared.prefill.provider,
base: prepared.prefill.base,
head: input.branch,
title: prepared.prefill.title,
body: prepared.prefill.body,
draft: false,
pushBeforeCreate: shouldPushBeforeMobilePrCreate(prepared.prefill)
})
if (!created.ok) {
return {
ok: false,
error: created.error,
committed: prepared.committed,
status: prepared.status
}
}
return {
ok: true,
url: created.url,
warning: getMobilePrCreateSuccessWarning(created, prepared.prefill.provider),
prefill: prepared.prefill,
status: prepared.status,
committed: prepared.committed
}
}