mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 02:17:31 +00:00
* fix(cli): worktree create sends the host --project/--host selected Codex review 6 #6: the CLI picked the right setup but sent only its repo id, so a repo id set up on two hosts failed as selector_ambiguous; and --project-host-setup ignored --host when setup ids repeated. worktree.create gains optional repoHostId (older hosts drop it and keep the old behaviour); the runtime narrows the repo selector to that host. * refactor(runtime): the repo selector carries its host through every lookup Review follow-up (Codex + Opus on #31066): a separate repoHostId was dropped by the startup-agent lookup, the CLI's GitLab link check and the create dedupe key. RuntimeRepoSelector now carries the host with the selector, so showRepo/resolveRepoSelector and startup-agent resolution keep it; the create dedupe key includes it; repo.show gains the same optional repoHostId; the CLI spreads one CliRepoTarget into every repo lookup. Handler-level tests cover worktree.create (plain, startupAgent, startupDraft), agent.launch, repo.show and the dedupe key. * test(runtime): drop a needless cast in the agent.launch host test; fold an import
55 lines
2.2 KiB
TypeScript
55 lines
2.2 KiB
TypeScript
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'
|
||
import type { CliRepoTarget } from '../worktree-project-target'
|
||
|
||
export async function assertGitLabLinkFlagProjectsMatch(
|
||
flags: Map<string, string | boolean>,
|
||
client: RuntimeClient,
|
||
target: CliRepoTarget | { 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 repoTarget: CliRepoTarget
|
||
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)
|
||
}
|
||
repoTarget = { repo: `id:${result.result.worktree.repoId}` }
|
||
} else {
|
||
repoTarget = target
|
||
}
|
||
if (!project) {
|
||
const result = await client.call<{ repo: Repo }>('repo.show', repoTarget)
|
||
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.'
|
||
)
|
||
}
|
||
}
|