Files
orca/src/main/linear/issue-relation-mutation.ts
T
OrcaWinandOrcaWin 3286f3b259 [comment audit] Clean up IPC, host lifecycle and native-chat comments (#32966)
* [comment audit] Tighten watcher lifetime and file-write constraints [skip ci]

* [comment audit] Clarify IPC routing and notification comments [skip ci]

* [comment audit] Shorten watcher, preflight and PTY comments [skip ci]

* [comment audit] Clarify PTY delivery and restore ownership [skip ci]

* [comment audit] Tighten PTY environment and flow-control rationale [skip ci]

* [comment audit] Clarify IPC spawn and stable-pane guarantees [skip ci]

* [comment audit] Tighten PTY provider and filesystem ownership rationale [skip ci]

* [comment audit] Clarify clone ownership and remote runtime recovery [skip ci]

* [comment audit] Condense upload, settings and SSH lifecycle comments [skip ci]

* [comment audit] Shorten shutdown, preview and worktree watcher rationale [skip ci]

* [comment audit] Clarify worktree identity, remote ownership and copy limits [skip ci]

* [comment audit] Shorten worktree catalog, removal and WSL routing rationale [skip ci]

* [comment audit] Tighten Linear credential, pagination and export comments [skip ci]

* [comment audit] Condense managed-server activation, snapshot and launch rationale [skip ci]

* [comment audit] Trim runtime installation and managed-server lifecycle comments [skip ci]

* [comment audit] Simplify managed tunnel, memory and menu comments [skip ci]

* [comment audit] Condense integration, model catalog and attachment rationale [skip ci]

* [comment audit] Shorten journal persistence, replay and queue rationale [skip ci]

* [comment audit] Condense journal ordering and timeline lifecycle comments [skip ci]

* [comment audit] Trim timeline and subscriber delivery explanations [skip ci]

* [comment audit] Shorten Stop, child-exit and recovery contracts [skip ci]

* [comment audit] Simplify handover and host recovery comments [skip ci]

* [comment audit] Trim queue delivery and provider startup commentary [skip ci]

* [comment audit] Clarify restart and rewind safety comments [skip ci]

* [comment audit] Trim status, Stop and completion commentary [skip ci]

* [comment audit] Simplify transcript lookup and visual containment comments [skip ci]

* [comment audit] Trim transcript reader, watcher and WSL transport commentary [skip ci]

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-23 19:07:32 -07:00

85 lines
2.4 KiB
TypeScript

import type { LinearClient } from '@linear/sdk'
import type { RawRelationNode } from './issue-context/raw'
import { isAuthError } from './client'
import { classifyLinearWriteFailure, LinearWriteFailure } from './linear-issue-write-support'
type RelationMutationResponse = {
issueRelationCreate?: {
success?: boolean
issueRelation?: RawRelationNode | null
} | null
issueRelationDelete?: { success?: boolean } | null
}
const CREATE_RELATION_MUTATION = `
mutation OrcaLinearCreateIssueRelation($input: IssueRelationCreateInput!) {
issueRelationCreate(input: $input) {
success
issueRelation {
id
type
issue { id identifier title url }
relatedIssue { id identifier title url }
}
}
}
`
const DELETE_RELATION_MUTATION = `
mutation OrcaLinearDeleteIssueRelation($id: String!) {
issueRelationDelete(id: $id) { success }
}
`
export async function createLinearIssueRelation(
client: LinearClient,
input: { issueId: string; relatedIssueId: string; type: string }
): Promise<RawRelationNode> {
const raw = await runRelationMutation(() =>
client.client.rawRequest<RelationMutationResponse, Record<string, unknown>>(
CREATE_RELATION_MUTATION,
{ input }
)
)
const created = raw.data?.issueRelationCreate
if (created?.success !== true || !created.issueRelation) {
throw new LinearWriteFailure('failed', 'Linear relation creation failed')
}
return created.issueRelation
}
export async function deleteLinearIssueRelation(
client: LinearClient,
relationId: string
): Promise<void> {
const raw = await runRelationMutation(() =>
client.client.rawRequest<RelationMutationResponse, Record<string, unknown>>(
DELETE_RELATION_MUTATION,
{ id: relationId }
)
)
if (raw.data?.issueRelationDelete?.success !== true) {
throw new LinearWriteFailure('failed', 'Linear relation removal failed')
}
}
async function runRelationMutation<T>(mutation: () => Promise<T>): Promise<T> {
try {
return await mutation()
} catch (error) {
if (isAuthError(error)) {
throw error
}
const failure = classifyLinearWriteFailure(error)
if (failure.kind === 'duplicate_id') {
// Server-assigned relation IDs make duplicate errors ambiguous with concurrent creation.
throw new LinearWriteFailure(
'unconfirmed',
'Linear relation mutation could not be confirmed.',
error
)
}
throw failure
}
}