Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions apps/docs/integrations/linear.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ previews.

The Brain keeps one durable page per visible Linear issue, including its current
workflow state, team, project, priority, labels, assignee, description, and a
bounded set of recent comments. Collection uses the same workspace connection
configured above; it does not require another Linear token.
bounded set of recent comments. When available, issue pages also include cycle,
estimate, start date, parent, and related-issue context. Collection uses the same
workspace connection configured above; it does not require another Linear token.

Roomote refreshes changed issues incrementally and periodically checks the full
visible issue set. Archived issues remain available as historical context. If an
Expand Down
53 changes: 51 additions & 2 deletions packages/linear/src/__tests__/linear-client-brain.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 58 additions & 1 deletion packages/linear/src/linear-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,30 @@ export class LinearClient {
url
priority
priorityLabel
estimate
createdAt
updatedAt
startedAt
completedAt
canceledAt
archivedAt
dueDate
state { name type }
team { key name }
project { name }
cycle { name number }
parent { id identifier title }
creator { name }
assignee { name }
labels { nodes { name } }
relations(first: 20) {
nodes { type relatedIssue { id identifier title } }
pageInfo { hasNextPage }
}
inverseRelations(first: 20) {
nodes { type issue { id identifier title } }
pageInfo { hasNextPage }
}
comments(last: 20, orderBy: createdAt) {
nodes {
id
Expand Down Expand Up @@ -143,18 +155,40 @@ export class LinearClient {
url: string;
priority?: number | null;
priorityLabel?: string | null;
estimate?: number | null;
createdAt: string;
updatedAt: string;
startedAt?: string | null;
completedAt?: string | null;
canceledAt?: string | null;
archivedAt?: string | null;
dueDate?: string | null;
state?: { name: string; type: string } | null;
team?: { key: string; name: string } | null;
project?: { name: string } | null;
cycle?: { name?: string | null; number: number } | null;
parent?: {
id: string;
identifier: string;
title: string;
} | null;
creator?: { name: string } | null;
assignee?: { name: string } | null;
labels?: { nodes?: Array<{ name: string }> };
relations?: {
nodes?: Array<{
type: string;
relatedIssue: { id: string; identifier: string; title: string };
}>;
pageInfo?: { hasNextPage?: boolean };
};
inverseRelations?: {
nodes?: Array<{
type: string;
issue: { id: string; identifier: string; title: string };
}>;
pageInfo?: { hasNextPage?: boolean };
};
comments?: {
nodes?: Array<{
id: string;
Expand All @@ -181,18 +215,41 @@ export class LinearClient {
url: issue.url,
priority: issue.priority ?? null,
priorityLabel: issue.priorityLabel ?? null,
estimate: issue.estimate ?? null,
createdAt: issue.createdAt,
updatedAt: issue.updatedAt,
startedAt: issue.startedAt ?? null,
completedAt: issue.completedAt ?? null,
canceledAt: issue.canceledAt ?? null,
archivedAt: issue.archivedAt ?? null,
dueDate: issue.dueDate ?? null,
state: issue.state ?? null,
team: issue.team ?? null,
project: issue.project ?? null,
cycle: issue.cycle
? { name: issue.cycle.name ?? null, number: issue.cycle.number }
: null,
parent: issue.parent ?? null,
creator: issue.creator ?? null,
assignee: issue.assignee ?? null,
labels: (issue.labels?.nodes ?? []).map((label) => label.name),
labels: (issue.labels?.nodes ?? [])
.map((label) => label.name)
.sort((a, b) => a.localeCompare(b)),
relationships: [
...(issue.relations?.nodes ?? []).map((relation) => ({
type: relation.type,
direction: 'outbound' as const,
issue: relation.relatedIssue,
})),
...(issue.inverseRelations?.nodes ?? []).map((relation) => ({
type: relation.type,
direction: 'inbound' as const,
issue: relation.issue,
})),
],
relationshipsTruncated:
issue.relations?.pageInfo?.hasNextPage === true ||
issue.inverseRelations?.pageInfo?.hasNextPage === true,
comments: (issue.comments?.nodes ?? []).map((comment) => ({
id: comment.id,
body: comment.body,
Expand Down
10 changes: 10 additions & 0 deletions packages/linear/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,18 +271,28 @@ export interface LinearBrainIssue {
url: string;
priority: number | null;
priorityLabel: string | null;
estimate: number | null;
createdAt: string;
updatedAt: string;
startedAt: string | null;
completedAt: string | null;
canceledAt: string | null;
archivedAt: string | null;
dueDate: string | null;
state: { name: string; type: string } | null;
team: { key: string; name: string } | null;
project: { name: string } | null;
cycle: { name: string | null; number: number } | null;
parent: { id: string; identifier: string; title: string } | null;
creator: { name: string } | null;
assignee: { name: string } | null;
labels: string[];
relationships: Array<{
type: string;
direction: 'outbound' | 'inbound';
issue: { id: string; identifier: string; title: string };
}>;
relationshipsTruncated: boolean;
comments: Array<{
id: string;
body: string;
Expand Down
72 changes: 67 additions & 5 deletions packages/sdk/src/server/lib/__tests__/brain-linear.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading