mirror of
https://github.com/stablyai/orca.git
synced 2026-11-03 18:47:40 +00:00
* [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>
85 lines
2.4 KiB
TypeScript
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
|
|
}
|
|
}
|