Files
orca/src/cli/handlers/worktree-gitlab-link-context.ts
T
c1d403a47b feat(cli): link GitHub and GitLab items on worktree create and set
Expose and validate the existing workspace link fields, preserving omitted values and provider identity checks.

Related: https://github.com/stablyai/orca/pull/22609

Co-authored-by: marco song <marco.song@mvlchain.io>
Co-authored-by: SongMarco <20613630+SongMarco@users.noreply.github.com>
Co-authored-by: Luca Critelli <lucacri@gmail.com>
Co-authored-by: Neil <neil@stably.ai>
2026-10-03 00:51:19 -07:00

54 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { parseRemoteProjectRefCandidate } from '../../main/gitlab/project-ref-parser'
import type { Repo } from '../../shared/repo-types'
import type { RuntimeWorktreeRecord } from '../../shared/runtime-types'
import { parseGitLabIssueOrMRLink, type ProjectSlug } from '../../shared/new-workspace/gitlab-links'
import { RuntimeClientError, type RuntimeClient } from '../runtime-client'
export async function assertGitLabLinkFlagProjectsMatch(
flags: Map<string, string | boolean>,
client: RuntimeClient,
target: { repo: string } | { worktree: string }
): Promise<void> {
const projects = ['gitlab-issue', 'gitlab-mr'].flatMap((name) => {
const value = flags.get(name)
const link =
typeof value === 'string' && /^https?:\/\//i.test(value.trim())
? parseGitLabIssueOrMRLink(value)
: null
return link ? [link.slug] : []
})
if (projects.length === 0) {
return
}
let project: ProjectSlug | null = null
let repo: string
if ('worktree' in target) {
const result = await client.call<{ worktree: RuntimeWorktreeRecord }>('worktree.show', target)
const context = result.result.worktree.linkedTaskSourceContext
const identity = context?.providerIdentity
if (context?.provider === 'gitlab' && identity?.provider === 'gitlab' && identity.webUrl) {
project = parseRemoteProjectRefCandidate(identity.webUrl)
}
repo = `id:${result.result.worktree.repoId}`
} else {
repo = target.repo
}
if (!project) {
const result = await client.call<{ repo: Repo }>('repo.show', { repo })
const remoteUrl = result.result.repo.gitRemoteIdentity?.remoteUrl
project = remoteUrl ? parseRemoteProjectRefCandidate(remoteUrl) : null
}
// Numeric slots cannot retain a pasted URL's foreign host or project.
if (
!project ||
projects.some((link) => link.host !== project.host || link.path !== project.path)
) {
throw new RuntimeClientError(
'invalid_argument',
'The GitLab URL must match the workspace source project or the repository’s stored remote. Use a number for an item in that project; URLs cannot choose a different project.'
)
}
}