fix(ssh): validate Linear issue row fields

This commit is contained in:
Brennan Benson
2026-08-27 02:52:59 -07:00
parent 0ace8be9fb
commit 53eea013b4
2 changed files with 72 additions and 0 deletions
@@ -96,4 +96,38 @@ describe('formatRemoteCli', () => {
stderr: ''
})
})
it('falls back to JSON for malformed Linear issue row fields', () => {
const response: RpcResponse = {
id: 'rpc-1',
ok: true,
_meta: meta,
result: {
issues: [
{
id: 'issue-1',
identifier: 'ENG-1',
title: 'Broken state',
url: 'https://linear.app/acme/issue/ENG-1',
labels: [],
state: { name: 42 },
workspace: { id: 'workspace-1', name: 'Acme' }
}
],
meta: {
limit: null,
returned: 1,
hasMore: false,
orderBy: 'updatedAt',
partial: false,
workspaceErrors: []
}
}
}
expect(formatRemoteCli(response)).toEqual({
stdout: `${JSON.stringify(response.result)}\n`,
stderr: ''
})
})
})
@@ -47,10 +47,48 @@ function isLinearMcpIssue(issue: unknown): boolean {
typeof issue.title === 'string' &&
typeof issue.url === 'string' &&
Array.isArray(issue.labels) &&
issue.labels.every(isLinearNamedEntity) &&
isOptionalLinearNamedEntity(issue.state) &&
isOptionalLinearNamedEntity(issue.team) &&
isOptionalLinearNamedEntity(issue.project) &&
isOptionalLinearNamedEntity(issue.cycle) &&
isOptionalLinearUser(issue.assignee) &&
(issue.priority === undefined ||
issue.priority === null ||
typeof issue.priority === 'number') &&
isLinearWorkspaceCandidate(issue.workspace)
)
}
function isOptionalLinearNamedEntity(value: unknown): boolean {
return value === undefined || value === null || isLinearNamedEntity(value)
}
function isLinearNamedEntity(value: unknown): boolean {
return (
isRecord(value) &&
(value.id === undefined || value.id === null || typeof value.id === 'string') &&
(value.name === undefined || value.name === null || typeof value.name === 'string') &&
(value.color === undefined || value.color === null || typeof value.color === 'string') &&
(value.type === undefined || value.type === null || typeof value.type === 'string')
)
}
function isOptionalLinearUser(value: unknown): boolean {
return (
value === undefined ||
value === null ||
(isRecord(value) &&
(value.id === undefined || value.id === null || typeof value.id === 'string') &&
(value.displayName === undefined ||
value.displayName === null ||
typeof value.displayName === 'string') &&
(value.avatarUrl === undefined ||
value.avatarUrl === null ||
typeof value.avatarUrl === 'string'))
)
}
function isLinearWorkspaceCandidate(workspace: unknown): boolean {
return (
isRecord(workspace) && typeof workspace.id === 'string' && typeof workspace.name === 'string'