mirror of
https://github.com/stablyai/orca.git
synced 2026-10-02 00:02:05 +00:00
* Add linked issue guidance and ELI5 sections to PR generation prompts Include linked GitHub issues in PR descriptions with Fixes/Refs guidance, and require ELI5 Problem and Solution sections before implementation details. Tests verify linked issue substitution and prompt structure enforcement. * Include linked issue details in PR description generation - Fetch the linked GitHub/GitLab issue title and body so generated PRs reference real issue context instead of just a number - Use provider-specific reference syntax (Fixes/Refs, Closes/Related to, AB#) and label the issue by the active provider - Feed issue title and description into the generation prompt while treating them as untrusted context, never as instructions - Fall back to a cached work-item title when the provider lookup fails, and skip cross-provider issue attachment
80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
import type { HostedReviewProvider } from '../../shared/hosted-review'
|
|
import type { PullRequestLinkedIssue } from '../../shared/pull-request-generation'
|
|
import { isLinkedIssueNumber } from '../../shared/source-control-ai-action-variables'
|
|
import type { WorkspaceLinkedItem } from '../../shared/types'
|
|
import { getIssue as getGitHubIssue } from '../github/issues'
|
|
import { getIssue as getGitLabIssue } from '../gitlab/issues'
|
|
|
|
export type PullRequestLinkedIssueMeta = {
|
|
linkedIssue?: number | null
|
|
linkedGitLabIssue?: number | null
|
|
linkedWorkItem?: WorkspaceLinkedItem | null
|
|
}
|
|
|
|
type LocalGitOptions = { wslDistro?: string }
|
|
|
|
function inferIssueProvider(
|
|
meta: PullRequestLinkedIssueMeta,
|
|
provider?: HostedReviewProvider | null
|
|
): 'github' | 'gitlab' | null {
|
|
if (provider === 'github' || provider === 'gitlab') {
|
|
return provider
|
|
}
|
|
if (provider) {
|
|
return null
|
|
}
|
|
if (meta.linkedWorkItem?.type === 'issue') {
|
|
if (meta.linkedWorkItem.provider === 'github' || meta.linkedWorkItem.provider === 'gitlab') {
|
|
return meta.linkedWorkItem.provider
|
|
}
|
|
}
|
|
const hasGitHub = isLinkedIssueNumber(meta.linkedIssue)
|
|
const hasGitLab = isLinkedIssueNumber(meta.linkedGitLabIssue)
|
|
return hasGitHub === hasGitLab ? null : hasGitHub ? 'github' : 'gitlab'
|
|
}
|
|
|
|
function fallbackTitle(
|
|
meta: PullRequestLinkedIssueMeta,
|
|
provider: 'github' | 'gitlab',
|
|
number: number
|
|
): string {
|
|
const item = meta.linkedWorkItem
|
|
return item?.provider === provider && item.type === 'issue' && item.number === number
|
|
? item.title
|
|
: '(title unavailable)'
|
|
}
|
|
|
|
export async function loadPullRequestLinkedIssue(args: {
|
|
meta: PullRequestLinkedIssueMeta | null | undefined
|
|
provider?: HostedReviewProvider | null
|
|
repoPath: string
|
|
connectionId?: string | null
|
|
localGitOptions?: LocalGitOptions
|
|
}): Promise<PullRequestLinkedIssue | null> {
|
|
if (!args.meta) {
|
|
return null
|
|
}
|
|
const provider = inferIssueProvider(args.meta, args.provider)
|
|
const number =
|
|
provider === 'github'
|
|
? args.meta.linkedIssue
|
|
: provider === 'gitlab'
|
|
? args.meta.linkedGitLabIssue
|
|
: null
|
|
if (!provider || !isLinkedIssueNumber(number)) {
|
|
return null
|
|
}
|
|
|
|
const issue =
|
|
provider === 'github'
|
|
? await getGitHubIssue(args.repoPath, number, args.connectionId, args.localGitOptions)
|
|
: await getGitLabIssue(args.repoPath, number, args.connectionId, args.localGitOptions)
|
|
|
|
return {
|
|
provider,
|
|
number,
|
|
title: issue?.title || fallbackTitle(args.meta, provider, number),
|
|
description: issue?.description ?? ''
|
|
}
|
|
}
|