@shipfox/api-integration-linear 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +89 -0
- package/LICENSE +21 -0
- package/README.md +88 -0
- package/dist/api/client.d.ts +29 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +189 -0
- package/dist/api/client.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-tools-provider.d.ts +32 -0
- package/dist/core/agent-tools-provider.d.ts.map +1 -0
- package/dist/core/agent-tools-provider.js +63 -0
- package/dist/core/agent-tools-provider.js.map +1 -0
- package/dist/core/agent-tools.d.ts +10 -0
- package/dist/core/agent-tools.d.ts.map +1 -0
- package/dist/core/agent-tools.js +920 -0
- package/dist/core/agent-tools.js.map +1 -0
- package/dist/core/disconnect.d.ts +18 -0
- package/dist/core/disconnect.d.ts.map +1 -0
- package/dist/core/disconnect.js +23 -0
- package/dist/core/disconnect.js.map +1 -0
- package/dist/core/errors.d.ts +35 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +59 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/install.d.ts +47 -0
- package/dist/core/install.d.ts.map +1 -0
- package/dist/core/install.js +102 -0
- package/dist/core/install.js.map +1 -0
- package/dist/core/scopes.d.ts +4 -0
- package/dist/core/scopes.d.ts.map +1 -0
- package/dist/core/scopes.js +17 -0
- package/dist/core/scopes.js.map +1 -0
- package/dist/core/state.d.ts +12 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +54 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/tokens.d.ts +39 -0
- package/dist/core/tokens.d.ts.map +1 -0
- package/dist/core/tokens.js +117 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/core/webhook.d.ts +16 -0
- package/dist/core/webhook.d.ts.map +1 -0
- package/dist/core/webhook.js +105 -0
- package/dist/core/webhook.js.map +1 -0
- package/dist/db/db.d.ts +369 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +18 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/installations.d.ts +53 -0
- package/dist/db/installations.d.ts.map +1 -0
- package/dist/db/installations.js +125 -0
- package/dist/db/installations.js.map +1 -0
- package/dist/db/migrations.d.ts +2 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +5 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/installations.d.ts +186 -0
- package/dist/db/schema/installations.d.ts.map +1 -0
- package/dist/db/schema/installations.js +40 -0
- package/dist/db/schema/installations.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/presentation/dto/integrations.d.ts +17 -0
- package/dist/presentation/dto/integrations.d.ts.map +1 -0
- package/dist/presentation/dto/integrations.js +6 -0
- package/dist/presentation/dto/integrations.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-connection.d.ts +16 -0
- package/dist/presentation/e2eRoutes/create-connection.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-connection.js +64 -0
- package/dist/presentation/e2eRoutes/create-connection.js.map +1 -0
- package/dist/presentation/e2eRoutes/index.d.ts +5 -0
- package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/index.js +11 -0
- package/dist/presentation/e2eRoutes/index.js.map +1 -0
- package/dist/presentation/routes/errors.d.ts +2 -0
- package/dist/presentation/routes/errors.d.ts.map +1 -0
- package/dist/presentation/routes/errors.js +65 -0
- package/dist/presentation/routes/errors.js.map +1 -0
- package/dist/presentation/routes/install.d.ts +19 -0
- package/dist/presentation/routes/install.d.ts.map +1 -0
- package/dist/presentation/routes/install.js +100 -0
- package/dist/presentation/routes/install.js.map +1 -0
- package/dist/presentation/routes/webhooks.d.ts +11 -0
- package/dist/presentation/routes/webhooks.d.ts.map +1 -0
- package/dist/presentation/routes/webhooks.js +136 -0
- package/dist/presentation/routes/webhooks.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_initial.sql +15 -0
- package/drizzle/meta/0000_snapshot.json +126 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +7 -0
- package/package.json +72 -0
- package/src/api/client.test.ts +366 -0
- package/src/api/client.ts +281 -0
- package/src/config.test.ts +34 -0
- package/src/config.ts +22 -0
- package/src/connection-external-url.test.ts +64 -0
- package/src/core/agent-tools-provider.test.ts +245 -0
- package/src/core/agent-tools-provider.ts +106 -0
- package/src/core/agent-tools.ts +918 -0
- package/src/core/disconnect.test.ts +45 -0
- package/src/core/disconnect.ts +27 -0
- package/src/core/errors.ts +71 -0
- package/src/core/install.ts +162 -0
- package/src/core/scopes.ts +18 -0
- package/src/core/state.test.ts +51 -0
- package/src/core/state.ts +85 -0
- package/src/core/tokens.test.ts +281 -0
- package/src/core/tokens.ts +219 -0
- package/src/core/webhook.test.ts +318 -0
- package/src/core/webhook.ts +146 -0
- package/src/db/db.ts +18 -0
- package/src/db/installations.test.ts +182 -0
- package/src/db/installations.ts +215 -0
- package/src/db/migrations.ts +4 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/installations.ts +42 -0
- package/src/index.test.ts +20 -0
- package/src/index.ts +153 -0
- package/src/presentation/dto/integrations.ts +9 -0
- package/src/presentation/e2eRoutes/create-connection.ts +85 -0
- package/src/presentation/e2eRoutes/index.test.ts +193 -0
- package/src/presentation/e2eRoutes/index.ts +14 -0
- package/src/presentation/routes/errors.ts +60 -0
- package/src/presentation/routes/install.test.ts +460 -0
- package/src/presentation/routes/install.ts +132 -0
- package/src/presentation/routes/webhooks.test.ts +407 -0
- package/src/presentation/routes/webhooks.ts +154 -0
- package/test/api-secrets.d.ts +28 -0
- package/test/env.ts +13 -0
- package/test/factories/index.ts +1 -0
- package/test/globalSetup.ts +23 -0
- package/test/index.ts +1 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +9 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,918 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AgentToolCatalogEntry,
|
|
3
|
+
AgentToolJsonSchema,
|
|
4
|
+
AgentToolSelectionCatalog,
|
|
5
|
+
AgentToolSelector,
|
|
6
|
+
} from '@shipfox/api-integration-core-dto';
|
|
7
|
+
|
|
8
|
+
export type LinearAgentToolRequiredScope = 'read' | 'write';
|
|
9
|
+
|
|
10
|
+
export type LinearAgentToolCategory =
|
|
11
|
+
| 'issues'
|
|
12
|
+
| 'comments'
|
|
13
|
+
| 'projects'
|
|
14
|
+
| 'documents'
|
|
15
|
+
| 'workspace'
|
|
16
|
+
| 'cycles'
|
|
17
|
+
| 'releases'
|
|
18
|
+
| 'release_notes'
|
|
19
|
+
| 'agents'
|
|
20
|
+
| 'diffs'
|
|
21
|
+
| 'attachments'
|
|
22
|
+
| 'documentation';
|
|
23
|
+
|
|
24
|
+
export interface LinearAgentToolCatalogEntry
|
|
25
|
+
extends AgentToolCatalogEntry<LinearAgentToolRequiredScope> {
|
|
26
|
+
category: LinearAgentToolCategory;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface LinearAgentToolCatalogInput {
|
|
30
|
+
id: string;
|
|
31
|
+
category: LinearAgentToolCategory;
|
|
32
|
+
description: string;
|
|
33
|
+
sensitivity: 'read' | 'write';
|
|
34
|
+
sensitive: boolean;
|
|
35
|
+
requiredScope: LinearAgentToolRequiredScope;
|
|
36
|
+
inputSchema: AgentToolJsonSchema;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const orderBySchema = enumSchema(['createdAt', 'updatedAt'], 'Sort order');
|
|
40
|
+
const cursorSchema = stringSchema('Next page cursor');
|
|
41
|
+
const limitSchema = numberSchema('Maximum number of results to return');
|
|
42
|
+
const dateFilterSchema = stringSchema('ISO-8601 date or duration filter');
|
|
43
|
+
const prioritySchema = numberSchema('0=None, 1=Urgent, 2=High, 3=Medium, 4=Low');
|
|
44
|
+
const nullableStringSchema = nullableSchema(stringSchema());
|
|
45
|
+
|
|
46
|
+
const pageProperties = {
|
|
47
|
+
cursor: cursorSchema,
|
|
48
|
+
limit: limitSchema,
|
|
49
|
+
orderBy: orderBySchema,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const timelineFilterProperties = {
|
|
53
|
+
createdAt: dateFilterSchema,
|
|
54
|
+
updatedAt: dateFilterSchema,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const linearAgentToolCatalog = [
|
|
58
|
+
tool({
|
|
59
|
+
id: 'get_attachment',
|
|
60
|
+
category: 'attachments',
|
|
61
|
+
description: 'Retrieve a Linear attachment by ID.',
|
|
62
|
+
sensitivity: 'read',
|
|
63
|
+
sensitive: false,
|
|
64
|
+
requiredScope: 'read',
|
|
65
|
+
inputSchema: objectSchema({id: stringSchema('Attachment ID')}, ['id']),
|
|
66
|
+
}),
|
|
67
|
+
tool({
|
|
68
|
+
id: 'get_agent_skill',
|
|
69
|
+
category: 'agents',
|
|
70
|
+
description: 'Retrieve a Linear Agent skill by ID, including its full markdown instructions.',
|
|
71
|
+
sensitivity: 'read',
|
|
72
|
+
sensitive: false,
|
|
73
|
+
requiredScope: 'read',
|
|
74
|
+
inputSchema: objectSchema({id: stringSchema('Agent skill ID')}, ['id']),
|
|
75
|
+
}),
|
|
76
|
+
tool({
|
|
77
|
+
id: 'get_diff',
|
|
78
|
+
category: 'diffs',
|
|
79
|
+
description: 'Look up a Linear diff by review URL, GitHub PR URL, identifier, UUID, or slug.',
|
|
80
|
+
sensitivity: 'read',
|
|
81
|
+
sensitive: false,
|
|
82
|
+
requiredScope: 'read',
|
|
83
|
+
inputSchema: objectSchema(
|
|
84
|
+
{
|
|
85
|
+
urlOrId: stringSchema(
|
|
86
|
+
'Linear review URL, diff slug, pull request ID, Linear identifier, or GitHub PR URL',
|
|
87
|
+
),
|
|
88
|
+
},
|
|
89
|
+
['urlOrId'],
|
|
90
|
+
),
|
|
91
|
+
}),
|
|
92
|
+
tool({
|
|
93
|
+
id: 'get_diff_threads',
|
|
94
|
+
category: 'diffs',
|
|
95
|
+
description:
|
|
96
|
+
'Look up Linear diff threads by review URL, GitHub PR URL, identifier, UUID, or slug.',
|
|
97
|
+
sensitivity: 'read',
|
|
98
|
+
sensitive: false,
|
|
99
|
+
requiredScope: 'read',
|
|
100
|
+
inputSchema: objectSchema(
|
|
101
|
+
{
|
|
102
|
+
orderBy: orderBySchema,
|
|
103
|
+
resolved: booleanSchema('Filter returned threads by resolved state'),
|
|
104
|
+
threadId: stringSchema('Top-level thread or comment ID to return'),
|
|
105
|
+
urlOrId: stringSchema(
|
|
106
|
+
'Linear review URL, diff slug, pull request ID, Linear identifier, or GitHub PR URL',
|
|
107
|
+
),
|
|
108
|
+
},
|
|
109
|
+
['urlOrId'],
|
|
110
|
+
),
|
|
111
|
+
}),
|
|
112
|
+
tool({
|
|
113
|
+
id: 'get_document',
|
|
114
|
+
category: 'documents',
|
|
115
|
+
description: 'Retrieve a Linear document by ID or slug.',
|
|
116
|
+
sensitivity: 'read',
|
|
117
|
+
sensitive: false,
|
|
118
|
+
requiredScope: 'read',
|
|
119
|
+
inputSchema: objectSchema({id: stringSchema('Document ID or slug')}, ['id']),
|
|
120
|
+
}),
|
|
121
|
+
tool({
|
|
122
|
+
id: 'get_issue',
|
|
123
|
+
category: 'issues',
|
|
124
|
+
description: 'Retrieve detailed information about a Linear issue.',
|
|
125
|
+
sensitivity: 'read',
|
|
126
|
+
sensitive: false,
|
|
127
|
+
requiredScope: 'read',
|
|
128
|
+
inputSchema: objectSchema(
|
|
129
|
+
{
|
|
130
|
+
id: stringSchema('Issue ID or identifier'),
|
|
131
|
+
includeCustomerNeeds: booleanSchema('Include associated customer needs'),
|
|
132
|
+
includeRelations: booleanSchema('Include blocking, related, and duplicate relations'),
|
|
133
|
+
includeReleases: booleanSchema('Include associated releases'),
|
|
134
|
+
},
|
|
135
|
+
['id'],
|
|
136
|
+
),
|
|
137
|
+
}),
|
|
138
|
+
tool({
|
|
139
|
+
id: 'list_issues',
|
|
140
|
+
category: 'issues',
|
|
141
|
+
description: 'List Linear issues visible to the authenticated connection.',
|
|
142
|
+
sensitivity: 'read',
|
|
143
|
+
sensitive: false,
|
|
144
|
+
requiredScope: 'read',
|
|
145
|
+
inputSchema: objectSchema({
|
|
146
|
+
...pageProperties,
|
|
147
|
+
...timelineFilterProperties,
|
|
148
|
+
assignee: nullableStringSchema,
|
|
149
|
+
cycle: stringSchema('Cycle name, number, or ID'),
|
|
150
|
+
delegate: stringSchema('Agent name or ID'),
|
|
151
|
+
includeArchived: booleanSchema('Include archived issues'),
|
|
152
|
+
label: stringSchema('Label name or ID'),
|
|
153
|
+
parentId: stringSchema('Parent issue ID or identifier'),
|
|
154
|
+
priority: prioritySchema,
|
|
155
|
+
project: stringSchema('Project name, ID, or slug'),
|
|
156
|
+
query: stringSchema('Search issue title or description'),
|
|
157
|
+
release: stringSchema('Release ID or slug'),
|
|
158
|
+
state: stringSchema('State type, name, or ID'),
|
|
159
|
+
team: stringSchema('Team name or ID'),
|
|
160
|
+
}),
|
|
161
|
+
}),
|
|
162
|
+
tool({
|
|
163
|
+
id: 'list_comments',
|
|
164
|
+
category: 'comments',
|
|
165
|
+
description: 'List comments on a Linear issue, project, initiative, document, or milestone.',
|
|
166
|
+
sensitivity: 'read',
|
|
167
|
+
sensitive: false,
|
|
168
|
+
requiredScope: 'read',
|
|
169
|
+
inputSchema: objectSchema({
|
|
170
|
+
...pageProperties,
|
|
171
|
+
documentId: stringSchema('Document ID or slug'),
|
|
172
|
+
initiativeId: stringSchema('Initiative name or ID'),
|
|
173
|
+
issueId: stringSchema('Issue ID or identifier'),
|
|
174
|
+
milestoneId: stringSchema('Milestone UUID'),
|
|
175
|
+
projectId: stringSchema('Project name, ID, or slug'),
|
|
176
|
+
}),
|
|
177
|
+
}),
|
|
178
|
+
tool({
|
|
179
|
+
id: 'list_issue_labels',
|
|
180
|
+
category: 'issues',
|
|
181
|
+
description: 'List issue labels in a Linear workspace or team.',
|
|
182
|
+
sensitivity: 'read',
|
|
183
|
+
sensitive: false,
|
|
184
|
+
requiredScope: 'read',
|
|
185
|
+
inputSchema: objectSchema({
|
|
186
|
+
...pageProperties,
|
|
187
|
+
name: stringSchema('Filter by label name'),
|
|
188
|
+
team: stringSchema('Team name or ID'),
|
|
189
|
+
}),
|
|
190
|
+
}),
|
|
191
|
+
tool({
|
|
192
|
+
id: 'list_issue_statuses',
|
|
193
|
+
category: 'issues',
|
|
194
|
+
description: 'List available issue statuses in a Linear team.',
|
|
195
|
+
sensitivity: 'read',
|
|
196
|
+
sensitive: false,
|
|
197
|
+
requiredScope: 'read',
|
|
198
|
+
inputSchema: objectSchema({team: stringSchema('Team name or ID')}, ['team']),
|
|
199
|
+
}),
|
|
200
|
+
tool({
|
|
201
|
+
id: 'get_issue_status',
|
|
202
|
+
category: 'issues',
|
|
203
|
+
description: 'Retrieve detailed information about an issue status by name or ID.',
|
|
204
|
+
sensitivity: 'read',
|
|
205
|
+
sensitive: false,
|
|
206
|
+
requiredScope: 'read',
|
|
207
|
+
inputSchema: objectSchema(
|
|
208
|
+
{
|
|
209
|
+
id: stringSchema('Status ID'),
|
|
210
|
+
name: stringSchema('Status name'),
|
|
211
|
+
team: stringSchema('Team name or ID'),
|
|
212
|
+
},
|
|
213
|
+
['id', 'name', 'team'],
|
|
214
|
+
),
|
|
215
|
+
}),
|
|
216
|
+
tool({
|
|
217
|
+
id: 'list_teams',
|
|
218
|
+
category: 'workspace',
|
|
219
|
+
description: 'List teams in the Linear workspace.',
|
|
220
|
+
sensitivity: 'read',
|
|
221
|
+
sensitive: false,
|
|
222
|
+
requiredScope: 'read',
|
|
223
|
+
inputSchema: objectSchema({
|
|
224
|
+
...pageProperties,
|
|
225
|
+
...timelineFilterProperties,
|
|
226
|
+
includeArchived: booleanSchema('Include archived teams'),
|
|
227
|
+
query: stringSchema('Search query'),
|
|
228
|
+
}),
|
|
229
|
+
}),
|
|
230
|
+
tool({
|
|
231
|
+
id: 'get_team',
|
|
232
|
+
category: 'workspace',
|
|
233
|
+
description: 'Retrieve detailed information about a Linear team.',
|
|
234
|
+
sensitivity: 'read',
|
|
235
|
+
sensitive: false,
|
|
236
|
+
requiredScope: 'read',
|
|
237
|
+
inputSchema: objectSchema({query: stringSchema('Team UUID, key, or name')}, ['query']),
|
|
238
|
+
}),
|
|
239
|
+
tool({
|
|
240
|
+
id: 'list_users',
|
|
241
|
+
category: 'workspace',
|
|
242
|
+
description: 'Retrieve users in the Linear workspace.',
|
|
243
|
+
sensitivity: 'read',
|
|
244
|
+
sensitive: false,
|
|
245
|
+
requiredScope: 'read',
|
|
246
|
+
inputSchema: objectSchema({
|
|
247
|
+
...pageProperties,
|
|
248
|
+
query: stringSchema('Filter by name or email'),
|
|
249
|
+
team: stringSchema('Team name or ID'),
|
|
250
|
+
}),
|
|
251
|
+
}),
|
|
252
|
+
tool({
|
|
253
|
+
id: 'list_projects',
|
|
254
|
+
category: 'projects',
|
|
255
|
+
description: 'List projects in the Linear workspace.',
|
|
256
|
+
sensitivity: 'read',
|
|
257
|
+
sensitive: false,
|
|
258
|
+
requiredScope: 'read',
|
|
259
|
+
inputSchema: objectSchema({
|
|
260
|
+
...pageProperties,
|
|
261
|
+
...timelineFilterProperties,
|
|
262
|
+
includeArchived: booleanSchema('Include archived projects'),
|
|
263
|
+
includeMembers: booleanSchema('Include project members'),
|
|
264
|
+
includeMilestones: booleanSchema('Include milestones'),
|
|
265
|
+
initiative: stringSchema('Initiative name or ID'),
|
|
266
|
+
label: stringSchema('Label name or ID'),
|
|
267
|
+
member: stringSchema('User ID, name, email, or "me"'),
|
|
268
|
+
query: stringSchema('Search project name'),
|
|
269
|
+
state: stringSchema('State type, name, or ID'),
|
|
270
|
+
team: stringSchema('Team name or ID'),
|
|
271
|
+
}),
|
|
272
|
+
}),
|
|
273
|
+
tool({
|
|
274
|
+
id: 'get_project',
|
|
275
|
+
category: 'projects',
|
|
276
|
+
description: 'Retrieve details of a specific Linear project.',
|
|
277
|
+
sensitivity: 'read',
|
|
278
|
+
sensitive: false,
|
|
279
|
+
requiredScope: 'read',
|
|
280
|
+
inputSchema: objectSchema(
|
|
281
|
+
{
|
|
282
|
+
includeMembers: booleanSchema('Include project members'),
|
|
283
|
+
includeMilestones: booleanSchema('Include milestones'),
|
|
284
|
+
includeResources: booleanSchema('Include documents, links, and attachments'),
|
|
285
|
+
query: stringSchema('Project name, ID, or slug'),
|
|
286
|
+
},
|
|
287
|
+
['query'],
|
|
288
|
+
),
|
|
289
|
+
}),
|
|
290
|
+
tool({
|
|
291
|
+
id: 'list_project_labels',
|
|
292
|
+
category: 'projects',
|
|
293
|
+
description: 'List project labels in the Linear workspace.',
|
|
294
|
+
sensitivity: 'read',
|
|
295
|
+
sensitive: false,
|
|
296
|
+
requiredScope: 'read',
|
|
297
|
+
inputSchema: objectSchema({
|
|
298
|
+
...pageProperties,
|
|
299
|
+
name: stringSchema('Filter by label name'),
|
|
300
|
+
}),
|
|
301
|
+
}),
|
|
302
|
+
tool({
|
|
303
|
+
id: 'list_milestones',
|
|
304
|
+
category: 'projects',
|
|
305
|
+
description: 'List milestones in a Linear project.',
|
|
306
|
+
sensitivity: 'read',
|
|
307
|
+
sensitive: false,
|
|
308
|
+
requiredScope: 'read',
|
|
309
|
+
inputSchema: objectSchema({project: stringSchema('Project name, ID, or slug')}, ['project']),
|
|
310
|
+
}),
|
|
311
|
+
tool({
|
|
312
|
+
id: 'get_milestone',
|
|
313
|
+
category: 'projects',
|
|
314
|
+
description: 'Retrieve details of a Linear milestone by ID or name.',
|
|
315
|
+
sensitivity: 'read',
|
|
316
|
+
sensitive: false,
|
|
317
|
+
requiredScope: 'read',
|
|
318
|
+
inputSchema: objectSchema(
|
|
319
|
+
{
|
|
320
|
+
project: stringSchema('Project name, ID, or slug'),
|
|
321
|
+
query: stringSchema('Milestone name or ID'),
|
|
322
|
+
},
|
|
323
|
+
['project', 'query'],
|
|
324
|
+
),
|
|
325
|
+
}),
|
|
326
|
+
tool({
|
|
327
|
+
id: 'get_release',
|
|
328
|
+
category: 'releases',
|
|
329
|
+
description: 'Retrieve details of a Linear release by ID or slug.',
|
|
330
|
+
sensitivity: 'read',
|
|
331
|
+
sensitive: false,
|
|
332
|
+
requiredScope: 'read',
|
|
333
|
+
inputSchema: objectSchema(
|
|
334
|
+
{
|
|
335
|
+
id: stringSchema('Release ID or slug'),
|
|
336
|
+
includeReleaseNotes: booleanSchema('Include associated release notes'),
|
|
337
|
+
},
|
|
338
|
+
['id'],
|
|
339
|
+
),
|
|
340
|
+
}),
|
|
341
|
+
tool({
|
|
342
|
+
id: 'get_release_note',
|
|
343
|
+
category: 'release_notes',
|
|
344
|
+
description: 'Retrieve Linear release notes by ID or slug, including markdown content.',
|
|
345
|
+
sensitivity: 'read',
|
|
346
|
+
sensitive: false,
|
|
347
|
+
requiredScope: 'read',
|
|
348
|
+
inputSchema: objectSchema(
|
|
349
|
+
{
|
|
350
|
+
id: stringSchema('Release notes ID or slug'),
|
|
351
|
+
includeReleases: booleanSchema('Include associated releases'),
|
|
352
|
+
},
|
|
353
|
+
['id'],
|
|
354
|
+
),
|
|
355
|
+
}),
|
|
356
|
+
tool({
|
|
357
|
+
id: 'list_cycles',
|
|
358
|
+
category: 'cycles',
|
|
359
|
+
description: 'Retrieve cycles for a specific Linear team.',
|
|
360
|
+
sensitivity: 'read',
|
|
361
|
+
sensitive: false,
|
|
362
|
+
requiredScope: 'read',
|
|
363
|
+
inputSchema: objectSchema(
|
|
364
|
+
{
|
|
365
|
+
teamId: stringSchema('Team ID'),
|
|
366
|
+
type: enumSchema(['current', 'previous', 'next'], 'Cycle filter'),
|
|
367
|
+
},
|
|
368
|
+
['teamId'],
|
|
369
|
+
),
|
|
370
|
+
}),
|
|
371
|
+
tool({
|
|
372
|
+
id: 'list_documents',
|
|
373
|
+
category: 'documents',
|
|
374
|
+
description: 'List documents in the Linear workspace.',
|
|
375
|
+
sensitivity: 'read',
|
|
376
|
+
sensitive: false,
|
|
377
|
+
requiredScope: 'read',
|
|
378
|
+
inputSchema: objectSchema({
|
|
379
|
+
...pageProperties,
|
|
380
|
+
...timelineFilterProperties,
|
|
381
|
+
creatorId: stringSchema('Creator ID'),
|
|
382
|
+
includeArchived: booleanSchema('Include archived documents'),
|
|
383
|
+
initiativeId: stringSchema('Initiative ID'),
|
|
384
|
+
projectId: stringSchema('Project ID'),
|
|
385
|
+
query: stringSchema('Search query'),
|
|
386
|
+
teamId: stringSchema('Team ID'),
|
|
387
|
+
}),
|
|
388
|
+
}),
|
|
389
|
+
tool({
|
|
390
|
+
id: 'get_status_updates',
|
|
391
|
+
category: 'projects',
|
|
392
|
+
description: 'List or retrieve project or initiative status updates.',
|
|
393
|
+
sensitivity: 'read',
|
|
394
|
+
sensitive: false,
|
|
395
|
+
requiredScope: 'read',
|
|
396
|
+
inputSchema: objectSchema(
|
|
397
|
+
{
|
|
398
|
+
...pageProperties,
|
|
399
|
+
...timelineFilterProperties,
|
|
400
|
+
id: stringSchema('Status update ID'),
|
|
401
|
+
includeArchived: booleanSchema('Include archived updates'),
|
|
402
|
+
initiative: stringSchema('Initiative name or ID'),
|
|
403
|
+
project: stringSchema('Project name, ID, or slug'),
|
|
404
|
+
type: enumSchema(['project', 'initiative'], 'Status update type'),
|
|
405
|
+
user: stringSchema('User ID, name, email, or "me"'),
|
|
406
|
+
},
|
|
407
|
+
['type'],
|
|
408
|
+
),
|
|
409
|
+
}),
|
|
410
|
+
tool({
|
|
411
|
+
id: 'list_release_notes',
|
|
412
|
+
category: 'release_notes',
|
|
413
|
+
description: 'List release notes in the workspace, optionally filtered by pipeline or release.',
|
|
414
|
+
sensitivity: 'read',
|
|
415
|
+
sensitive: false,
|
|
416
|
+
requiredScope: 'read',
|
|
417
|
+
inputSchema: objectSchema({
|
|
418
|
+
...pageProperties,
|
|
419
|
+
...timelineFilterProperties,
|
|
420
|
+
includeArchived: booleanSchema('Include archived release notes'),
|
|
421
|
+
includeContent: booleanSchema('Include markdown release notes content'),
|
|
422
|
+
includeReleases: booleanSchema('Include associated releases'),
|
|
423
|
+
pipeline: stringSchema('Release pipeline ID, slug, or exact name'),
|
|
424
|
+
query: stringSchema('Search release notes title'),
|
|
425
|
+
release: stringSchema('Release ID or slug'),
|
|
426
|
+
}),
|
|
427
|
+
}),
|
|
428
|
+
tool({
|
|
429
|
+
id: 'list_release_pipelines',
|
|
430
|
+
category: 'releases',
|
|
431
|
+
description: 'List release pipelines in the Linear workspace.',
|
|
432
|
+
sensitivity: 'read',
|
|
433
|
+
sensitive: false,
|
|
434
|
+
requiredScope: 'read',
|
|
435
|
+
inputSchema: objectSchema({
|
|
436
|
+
...pageProperties,
|
|
437
|
+
...timelineFilterProperties,
|
|
438
|
+
includeArchived: booleanSchema('Include archived release pipelines'),
|
|
439
|
+
includeStages: booleanSchema('Include each pipeline stages'),
|
|
440
|
+
includeTeams: booleanSchema('Include each pipeline teams'),
|
|
441
|
+
isProduction: booleanSchema('Filter by production pipeline flag'),
|
|
442
|
+
query: stringSchema('Search pipeline name'),
|
|
443
|
+
team: stringSchema('Team name or ID'),
|
|
444
|
+
type: enumSchema(['continuous', 'scheduled'], 'Pipeline type'),
|
|
445
|
+
}),
|
|
446
|
+
}),
|
|
447
|
+
tool({
|
|
448
|
+
id: 'list_releases',
|
|
449
|
+
category: 'releases',
|
|
450
|
+
description:
|
|
451
|
+
'List releases in the workspace, with optional filtering by pipeline, stage, version, and text.',
|
|
452
|
+
sensitivity: 'read',
|
|
453
|
+
sensitive: false,
|
|
454
|
+
requiredScope: 'read',
|
|
455
|
+
inputSchema: objectSchema({
|
|
456
|
+
...pageProperties,
|
|
457
|
+
...timelineFilterProperties,
|
|
458
|
+
hasReleaseNotes: booleanSchema('Filter to releases that do or do not have release notes'),
|
|
459
|
+
includeArchived: booleanSchema('Include archived releases'),
|
|
460
|
+
includeReleaseNotes: booleanSchema('Include associated release notes'),
|
|
461
|
+
pipeline: stringSchema('Release pipeline ID, slug, or exact name'),
|
|
462
|
+
query: stringSchema('Search release name or version'),
|
|
463
|
+
stage: stringSchema('Release stage ID or exact name'),
|
|
464
|
+
stageType: enumSchema(
|
|
465
|
+
['planned', 'started', 'completed', 'canceled'],
|
|
466
|
+
'Stage lifecycle type',
|
|
467
|
+
),
|
|
468
|
+
version: stringSchema('Exact version match'),
|
|
469
|
+
}),
|
|
470
|
+
}),
|
|
471
|
+
tool({
|
|
472
|
+
id: 'list_agent_skills',
|
|
473
|
+
category: 'agents',
|
|
474
|
+
description: 'List Linear Agent skills available to the authenticated user.',
|
|
475
|
+
sensitivity: 'read',
|
|
476
|
+
sensitive: false,
|
|
477
|
+
requiredScope: 'read',
|
|
478
|
+
inputSchema: objectSchema(pageProperties),
|
|
479
|
+
}),
|
|
480
|
+
tool({
|
|
481
|
+
id: 'get_user',
|
|
482
|
+
category: 'workspace',
|
|
483
|
+
description: 'Retrieve details of a specific Linear user.',
|
|
484
|
+
sensitivity: 'read',
|
|
485
|
+
sensitive: false,
|
|
486
|
+
requiredScope: 'read',
|
|
487
|
+
inputSchema: objectSchema({query: stringSchema('User ID, name, email, or "me"')}, ['query']),
|
|
488
|
+
}),
|
|
489
|
+
tool({
|
|
490
|
+
id: 'list_diffs',
|
|
491
|
+
category: 'diffs',
|
|
492
|
+
description: 'List Linear diff pull requests visible to the authenticated user.',
|
|
493
|
+
sensitivity: 'read',
|
|
494
|
+
sensitive: false,
|
|
495
|
+
requiredScope: 'read',
|
|
496
|
+
inputSchema: objectSchema({
|
|
497
|
+
...pageProperties,
|
|
498
|
+
owner: stringSchema('Repository owner'),
|
|
499
|
+
query: stringSchema('Search by title, branch, PR number, or bare slug'),
|
|
500
|
+
repo: stringSchema('Repository name'),
|
|
501
|
+
status: stringSchema('Pull request status'),
|
|
502
|
+
}),
|
|
503
|
+
}),
|
|
504
|
+
tool({
|
|
505
|
+
id: 'extract_images',
|
|
506
|
+
category: 'attachments',
|
|
507
|
+
description: 'Extract and fetch images from markdown content.',
|
|
508
|
+
sensitivity: 'read',
|
|
509
|
+
sensitive: false,
|
|
510
|
+
requiredScope: 'read',
|
|
511
|
+
inputSchema: objectSchema(
|
|
512
|
+
{markdown: stringSchema('Markdown content containing image references')},
|
|
513
|
+
['markdown'],
|
|
514
|
+
),
|
|
515
|
+
}),
|
|
516
|
+
tool({
|
|
517
|
+
id: 'search_documentation',
|
|
518
|
+
category: 'documentation',
|
|
519
|
+
description: "Search Linear's documentation to learn about features and usage.",
|
|
520
|
+
sensitivity: 'read',
|
|
521
|
+
sensitive: false,
|
|
522
|
+
requiredScope: 'read',
|
|
523
|
+
inputSchema: objectSchema(
|
|
524
|
+
{
|
|
525
|
+
page: numberSchema('Page number'),
|
|
526
|
+
query: stringSchema('Search query'),
|
|
527
|
+
},
|
|
528
|
+
['query'],
|
|
529
|
+
),
|
|
530
|
+
}),
|
|
531
|
+
tool({
|
|
532
|
+
id: 'create_attachment',
|
|
533
|
+
category: 'attachments',
|
|
534
|
+
description: 'Upload a tiny file through the MCP worker and attach it to a Linear issue.',
|
|
535
|
+
sensitivity: 'write',
|
|
536
|
+
sensitive: true,
|
|
537
|
+
requiredScope: 'write',
|
|
538
|
+
inputSchema: objectSchema(
|
|
539
|
+
{
|
|
540
|
+
base64Content: stringSchema('Deprecated base64-encoded file content to upload'),
|
|
541
|
+
contentType: stringSchema('MIME type for the upload'),
|
|
542
|
+
filename: stringSchema('Filename for the upload'),
|
|
543
|
+
issue: stringSchema('Issue ID or identifier'),
|
|
544
|
+
sha256: stringSchema('Expected SHA-256 hex digest of the decoded file bytes'),
|
|
545
|
+
size: numberSchema('Expected decoded file size in bytes'),
|
|
546
|
+
subtitle: stringSchema('Attachment subtitle'),
|
|
547
|
+
title: stringSchema('Attachment title'),
|
|
548
|
+
},
|
|
549
|
+
['base64Content', 'contentType', 'filename', 'issue', 'sha256'],
|
|
550
|
+
),
|
|
551
|
+
}),
|
|
552
|
+
tool({
|
|
553
|
+
id: 'create_attachment_from_upload',
|
|
554
|
+
category: 'attachments',
|
|
555
|
+
description: 'Link an already-uploaded Linear asset URL to an existing issue as an attachment.',
|
|
556
|
+
sensitivity: 'write',
|
|
557
|
+
sensitive: true,
|
|
558
|
+
requiredScope: 'write',
|
|
559
|
+
inputSchema: objectSchema(
|
|
560
|
+
{
|
|
561
|
+
assetUrl: stringSchema('Linear upload asset URL returned by prepare_attachment_upload'),
|
|
562
|
+
issue: stringSchema('Issue ID or identifier'),
|
|
563
|
+
subtitle: stringSchema('Attachment subtitle'),
|
|
564
|
+
title: stringSchema('Attachment title'),
|
|
565
|
+
},
|
|
566
|
+
['assetUrl', 'issue'],
|
|
567
|
+
),
|
|
568
|
+
}),
|
|
569
|
+
tool({
|
|
570
|
+
id: 'prepare_attachment_upload',
|
|
571
|
+
category: 'attachments',
|
|
572
|
+
description: 'Prepare a direct Linear file upload for an existing issue.',
|
|
573
|
+
sensitivity: 'write',
|
|
574
|
+
sensitive: true,
|
|
575
|
+
requiredScope: 'write',
|
|
576
|
+
inputSchema: objectSchema(
|
|
577
|
+
{
|
|
578
|
+
contentType: stringSchema('MIME type for the upload'),
|
|
579
|
+
filename: stringSchema('Filename for the upload'),
|
|
580
|
+
issue: stringSchema('Issue ID or identifier'),
|
|
581
|
+
size: numberSchema('Exact file size in bytes'),
|
|
582
|
+
subtitle: stringSchema('Suggested attachment subtitle for the finalize step'),
|
|
583
|
+
title: stringSchema('Suggested attachment title for the finalize step'),
|
|
584
|
+
},
|
|
585
|
+
['contentType', 'filename', 'issue', 'size'],
|
|
586
|
+
),
|
|
587
|
+
}),
|
|
588
|
+
tool({
|
|
589
|
+
id: 'save_issue',
|
|
590
|
+
category: 'issues',
|
|
591
|
+
description: 'Create or update a Linear issue.',
|
|
592
|
+
sensitivity: 'write',
|
|
593
|
+
sensitive: false,
|
|
594
|
+
requiredScope: 'write',
|
|
595
|
+
inputSchema: objectSchema(
|
|
596
|
+
{
|
|
597
|
+
addReleases: arraySchema(stringSchema('Release ID or slug')),
|
|
598
|
+
assignee: nullableStringSchema,
|
|
599
|
+
blockedBy: arraySchema(stringSchema('Blocking issue ID or identifier')),
|
|
600
|
+
blocks: arraySchema(stringSchema('Blocked issue ID or identifier')),
|
|
601
|
+
cycle: nullableStringSchema,
|
|
602
|
+
delegate: nullableStringSchema,
|
|
603
|
+
description: stringSchema('Issue description as Markdown'),
|
|
604
|
+
dueDate: stringSchema('Due date in ISO format'),
|
|
605
|
+
duplicateOf: nullableStringSchema,
|
|
606
|
+
estimate: nullableSchema(numberSchema('Issue estimate value')),
|
|
607
|
+
id: stringSchema('Issue ID or identifier'),
|
|
608
|
+
labels: arraySchema(stringSchema('Label name or ID')),
|
|
609
|
+
links: arraySchema(
|
|
610
|
+
objectSchema(
|
|
611
|
+
{
|
|
612
|
+
title: stringSchema('Attachment title'),
|
|
613
|
+
url: stringSchema('Attachment URL'),
|
|
614
|
+
},
|
|
615
|
+
['title', 'url'],
|
|
616
|
+
),
|
|
617
|
+
),
|
|
618
|
+
milestone: stringSchema('Milestone name or ID'),
|
|
619
|
+
parentId: nullableStringSchema,
|
|
620
|
+
priority: prioritySchema,
|
|
621
|
+
project: nullableStringSchema,
|
|
622
|
+
relatedTo: arraySchema(stringSchema('Related issue ID or identifier')),
|
|
623
|
+
removeBlockedBy: arraySchema(stringSchema('Blocking issue ID or identifier to remove')),
|
|
624
|
+
removeBlocks: arraySchema(stringSchema('Blocked issue ID or identifier to remove')),
|
|
625
|
+
removeRelatedTo: arraySchema(stringSchema('Related issue ID or identifier to remove')),
|
|
626
|
+
removeReleases: arraySchema(stringSchema('Release ID or slug to remove')),
|
|
627
|
+
setReleases: arraySchema(stringSchema('Release ID or slug')),
|
|
628
|
+
state: stringSchema('State type, name, or ID'),
|
|
629
|
+
team: stringSchema('Team name or ID'),
|
|
630
|
+
title: stringSchema('Issue title'),
|
|
631
|
+
},
|
|
632
|
+
[],
|
|
633
|
+
),
|
|
634
|
+
}),
|
|
635
|
+
tool({
|
|
636
|
+
id: 'save_comment',
|
|
637
|
+
category: 'comments',
|
|
638
|
+
description:
|
|
639
|
+
'Create or update a comment on a Linear issue, project, initiative, document, or milestone.',
|
|
640
|
+
sensitivity: 'write',
|
|
641
|
+
sensitive: false,
|
|
642
|
+
requiredScope: 'write',
|
|
643
|
+
inputSchema: objectSchema(
|
|
644
|
+
{
|
|
645
|
+
body: stringSchema('Comment body as Markdown'),
|
|
646
|
+
documentId: stringSchema('Document ID or slug'),
|
|
647
|
+
id: stringSchema('Comment ID'),
|
|
648
|
+
initiativeId: stringSchema('Initiative name or ID'),
|
|
649
|
+
issueId: stringSchema('Issue ID or identifier'),
|
|
650
|
+
milestoneId: stringSchema('Milestone UUID'),
|
|
651
|
+
parentId: stringSchema('Parent comment ID'),
|
|
652
|
+
projectId: stringSchema('Project name, ID, or slug'),
|
|
653
|
+
},
|
|
654
|
+
['body'],
|
|
655
|
+
),
|
|
656
|
+
}),
|
|
657
|
+
tool({
|
|
658
|
+
id: 'save_project',
|
|
659
|
+
category: 'projects',
|
|
660
|
+
description: 'Create or update a Linear project.',
|
|
661
|
+
sensitivity: 'write',
|
|
662
|
+
sensitive: true,
|
|
663
|
+
requiredScope: 'write',
|
|
664
|
+
inputSchema: objectSchema(
|
|
665
|
+
{
|
|
666
|
+
addInitiatives: arraySchema(stringSchema('Initiative name or ID')),
|
|
667
|
+
addTeams: arraySchema(stringSchema('Team name or ID')),
|
|
668
|
+
color: stringSchema('Hex color'),
|
|
669
|
+
description: stringSchema('Project description as Markdown'),
|
|
670
|
+
icon: stringSchema('Icon name or emoji code'),
|
|
671
|
+
id: stringSchema('Project ID'),
|
|
672
|
+
labels: arraySchema(stringSchema('Label name or ID')),
|
|
673
|
+
lead: nullableStringSchema,
|
|
674
|
+
name: stringSchema('Project name'),
|
|
675
|
+
priority: prioritySchema,
|
|
676
|
+
removeInitiatives: arraySchema(stringSchema('Initiative name or ID')),
|
|
677
|
+
removeTeams: arraySchema(stringSchema('Team name or ID')),
|
|
678
|
+
setInitiatives: arraySchema(stringSchema('Initiative name or ID')),
|
|
679
|
+
setTeams: arraySchema(stringSchema('Team name or ID')),
|
|
680
|
+
startDate: stringSchema('Start date in ISO format'),
|
|
681
|
+
startDateResolution: enumSchema(
|
|
682
|
+
['halfYear', 'month', 'quarter', 'year'],
|
|
683
|
+
'Start date resolution',
|
|
684
|
+
),
|
|
685
|
+
state: stringSchema('Project state'),
|
|
686
|
+
summary: stringSchema('Short summary'),
|
|
687
|
+
targetDate: stringSchema('Target date in ISO format'),
|
|
688
|
+
targetDateResolution: enumSchema(
|
|
689
|
+
['halfYear', 'month', 'quarter', 'year'],
|
|
690
|
+
'Target date resolution',
|
|
691
|
+
),
|
|
692
|
+
},
|
|
693
|
+
[],
|
|
694
|
+
),
|
|
695
|
+
}),
|
|
696
|
+
tool({
|
|
697
|
+
id: 'save_document',
|
|
698
|
+
category: 'documents',
|
|
699
|
+
description: 'Create or update a Linear document.',
|
|
700
|
+
sensitivity: 'write',
|
|
701
|
+
sensitive: true,
|
|
702
|
+
requiredScope: 'write',
|
|
703
|
+
inputSchema: objectSchema(
|
|
704
|
+
{
|
|
705
|
+
color: stringSchema('Hex color'),
|
|
706
|
+
content: stringSchema('Document content as Markdown'),
|
|
707
|
+
cycle: stringSchema('Cycle name, number, or ID'),
|
|
708
|
+
icon: stringSchema('Icon name or emoji code'),
|
|
709
|
+
id: stringSchema('Document ID or slug'),
|
|
710
|
+
initiative: stringSchema('Initiative name or ID'),
|
|
711
|
+
issue: stringSchema('Issue ID or identifier'),
|
|
712
|
+
project: stringSchema('Project name, ID, or slug'),
|
|
713
|
+
team: stringSchema('Team name or ID'),
|
|
714
|
+
title: stringSchema('Document title'),
|
|
715
|
+
},
|
|
716
|
+
[],
|
|
717
|
+
),
|
|
718
|
+
}),
|
|
719
|
+
tool({
|
|
720
|
+
id: 'save_milestone',
|
|
721
|
+
category: 'projects',
|
|
722
|
+
description: 'Create or update a Linear milestone in a project.',
|
|
723
|
+
sensitivity: 'write',
|
|
724
|
+
sensitive: true,
|
|
725
|
+
requiredScope: 'write',
|
|
726
|
+
inputSchema: objectSchema(
|
|
727
|
+
{
|
|
728
|
+
description: stringSchema('Milestone description'),
|
|
729
|
+
id: stringSchema('Milestone name or ID'),
|
|
730
|
+
name: stringSchema('Milestone name'),
|
|
731
|
+
project: stringSchema('Project name, ID, or slug'),
|
|
732
|
+
targetDate: nullableStringSchema,
|
|
733
|
+
},
|
|
734
|
+
['project'],
|
|
735
|
+
),
|
|
736
|
+
}),
|
|
737
|
+
tool({
|
|
738
|
+
id: 'save_release',
|
|
739
|
+
category: 'releases',
|
|
740
|
+
description: 'Create or update a Linear release.',
|
|
741
|
+
sensitivity: 'write',
|
|
742
|
+
sensitive: true,
|
|
743
|
+
requiredScope: 'write',
|
|
744
|
+
inputSchema: objectSchema(
|
|
745
|
+
{
|
|
746
|
+
commitSha: stringSchema('Commit SHA associated with the release'),
|
|
747
|
+
completedAt: nullableSchema(stringSchema('Completed timestamp in ISO DateTime format')),
|
|
748
|
+
createdAt: stringSchema('Import or create timestamp in ISO DateTime format'),
|
|
749
|
+
description: stringSchema('Release description'),
|
|
750
|
+
id: stringSchema('Release ID or slug to update'),
|
|
751
|
+
name: stringSchema('Release name'),
|
|
752
|
+
pipeline: stringSchema('Release pipeline ID, slug, or exact name'),
|
|
753
|
+
stage: stringSchema('Release stage ID, exact name, or lifecycle type within the pipeline'),
|
|
754
|
+
startDate: nullableSchema(stringSchema('Estimated start date in ISO YYYY-MM-DD format')),
|
|
755
|
+
startedAt: nullableSchema(stringSchema('Started timestamp in ISO DateTime format')),
|
|
756
|
+
targetDate: nullableSchema(
|
|
757
|
+
stringSchema('Estimated completion date in ISO YYYY-MM-DD format'),
|
|
758
|
+
),
|
|
759
|
+
version: stringSchema('Version identifier'),
|
|
760
|
+
},
|
|
761
|
+
[],
|
|
762
|
+
),
|
|
763
|
+
}),
|
|
764
|
+
tool({
|
|
765
|
+
id: 'save_release_note',
|
|
766
|
+
category: 'release_notes',
|
|
767
|
+
description: 'Create or update Linear release notes.',
|
|
768
|
+
sensitivity: 'write',
|
|
769
|
+
sensitive: true,
|
|
770
|
+
requiredScope: 'write',
|
|
771
|
+
inputSchema: objectSchema(
|
|
772
|
+
{
|
|
773
|
+
content: stringSchema('Release notes content as Markdown'),
|
|
774
|
+
id: stringSchema('Release notes ID or slug to update'),
|
|
775
|
+
pipeline: stringSchema('Release pipeline ID, slug, or exact name'),
|
|
776
|
+
rangeFromRelease: stringSchema('Oldest release ID or slug in the note range'),
|
|
777
|
+
rangeToRelease: stringSchema('Newest release ID or slug in the note range'),
|
|
778
|
+
releases: arraySchema(stringSchema('Release ID or slug')),
|
|
779
|
+
title: stringSchema('Release notes title'),
|
|
780
|
+
},
|
|
781
|
+
[],
|
|
782
|
+
),
|
|
783
|
+
}),
|
|
784
|
+
tool({
|
|
785
|
+
id: 'save_status_update',
|
|
786
|
+
category: 'projects',
|
|
787
|
+
description: 'Create or update a project or initiative status update.',
|
|
788
|
+
sensitivity: 'write',
|
|
789
|
+
sensitive: true,
|
|
790
|
+
requiredScope: 'write',
|
|
791
|
+
inputSchema: objectSchema(
|
|
792
|
+
{
|
|
793
|
+
body: stringSchema('Status update body as Markdown'),
|
|
794
|
+
health: enumSchema(['onTrack', 'atRisk', 'offTrack'], 'Status update health'),
|
|
795
|
+
id: stringSchema('Status update ID'),
|
|
796
|
+
initiative: stringSchema('Initiative name or ID'),
|
|
797
|
+
isDiffHidden: booleanSchema('Hide diff with previous update'),
|
|
798
|
+
project: stringSchema('Project name, ID, or slug'),
|
|
799
|
+
type: enumSchema(['project', 'initiative'], 'Status update type'),
|
|
800
|
+
},
|
|
801
|
+
['type'],
|
|
802
|
+
),
|
|
803
|
+
}),
|
|
804
|
+
tool({
|
|
805
|
+
id: 'create_issue_label',
|
|
806
|
+
category: 'issues',
|
|
807
|
+
description: 'Create a new Linear issue label.',
|
|
808
|
+
sensitivity: 'write',
|
|
809
|
+
sensitive: true,
|
|
810
|
+
requiredScope: 'write',
|
|
811
|
+
inputSchema: objectSchema(
|
|
812
|
+
{
|
|
813
|
+
color: stringSchema('Hex color code'),
|
|
814
|
+
description: stringSchema('Label description'),
|
|
815
|
+
isGroup: booleanSchema('Is label group'),
|
|
816
|
+
name: stringSchema('Label name'),
|
|
817
|
+
parent: stringSchema('Parent label group name'),
|
|
818
|
+
teamId: stringSchema('Team UUID'),
|
|
819
|
+
},
|
|
820
|
+
['name'],
|
|
821
|
+
),
|
|
822
|
+
}),
|
|
823
|
+
tool({
|
|
824
|
+
id: 'delete_comment',
|
|
825
|
+
category: 'comments',
|
|
826
|
+
description: 'Delete a Linear comment.',
|
|
827
|
+
sensitivity: 'write',
|
|
828
|
+
sensitive: true,
|
|
829
|
+
requiredScope: 'write',
|
|
830
|
+
inputSchema: objectSchema({id: stringSchema('Comment ID')}, ['id']),
|
|
831
|
+
}),
|
|
832
|
+
tool({
|
|
833
|
+
id: 'delete_status_update',
|
|
834
|
+
category: 'projects',
|
|
835
|
+
description: 'Delete or archive a Linear project or initiative status update.',
|
|
836
|
+
sensitivity: 'write',
|
|
837
|
+
sensitive: true,
|
|
838
|
+
requiredScope: 'write',
|
|
839
|
+
inputSchema: objectSchema(
|
|
840
|
+
{
|
|
841
|
+
id: stringSchema('Status update ID'),
|
|
842
|
+
type: enumSchema(['project', 'initiative'], 'Status update type'),
|
|
843
|
+
},
|
|
844
|
+
['id', 'type'],
|
|
845
|
+
),
|
|
846
|
+
}),
|
|
847
|
+
tool({
|
|
848
|
+
id: 'delete_attachment',
|
|
849
|
+
category: 'attachments',
|
|
850
|
+
description: 'Delete a Linear attachment.',
|
|
851
|
+
sensitivity: 'write',
|
|
852
|
+
sensitive: true,
|
|
853
|
+
requiredScope: 'write',
|
|
854
|
+
inputSchema: objectSchema({id: stringSchema('Attachment ID')}, ['id']),
|
|
855
|
+
}),
|
|
856
|
+
] as const satisfies readonly LinearAgentToolCatalogEntry[];
|
|
857
|
+
|
|
858
|
+
export type LinearAgentToolId = (typeof linearAgentToolCatalog)[number]['id'];
|
|
859
|
+
|
|
860
|
+
export const linearAgentToolSelectionCatalog =
|
|
861
|
+
buildLinearAgentToolSelectionCatalog(linearAgentToolCatalog);
|
|
862
|
+
|
|
863
|
+
function buildLinearAgentToolSelectionCatalog(
|
|
864
|
+
catalog: readonly LinearAgentToolCatalogEntry[],
|
|
865
|
+
): AgentToolSelectionCatalog {
|
|
866
|
+
return {
|
|
867
|
+
selectors: catalog.map(
|
|
868
|
+
(entry): AgentToolSelector => ({
|
|
869
|
+
token: entry.id,
|
|
870
|
+
kind: 'standalone',
|
|
871
|
+
sensitivity: entry.sensitivity,
|
|
872
|
+
sensitive: entry.sensitive,
|
|
873
|
+
}),
|
|
874
|
+
),
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
function tool(input: LinearAgentToolCatalogInput): LinearAgentToolCatalogEntry {
|
|
879
|
+
return input;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
function objectSchema(
|
|
883
|
+
properties: Record<string, AgentToolJsonSchema>,
|
|
884
|
+
required: string[] = [],
|
|
885
|
+
extraSchema: Partial<AgentToolJsonSchema> = {},
|
|
886
|
+
): AgentToolJsonSchema {
|
|
887
|
+
return {
|
|
888
|
+
type: 'object',
|
|
889
|
+
additionalProperties: false,
|
|
890
|
+
properties,
|
|
891
|
+
...(required.length > 0 ? {required} : {}),
|
|
892
|
+
...extraSchema,
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
function stringSchema(description?: string): AgentToolJsonSchema {
|
|
897
|
+
return {type: 'string', ...(description ? {description} : {})};
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
function numberSchema(description?: string): AgentToolJsonSchema {
|
|
901
|
+
return {type: 'number', ...(description ? {description} : {})};
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
function booleanSchema(description: string): AgentToolJsonSchema {
|
|
905
|
+
return {type: 'boolean', description};
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function enumSchema(values: string[], description: string): AgentToolJsonSchema {
|
|
909
|
+
return {type: 'string', description, enum: values};
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
function arraySchema(items: AgentToolJsonSchema): AgentToolJsonSchema {
|
|
913
|
+
return {type: 'array', items};
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
function nullableSchema(schema: AgentToolJsonSchema): AgentToolJsonSchema {
|
|
917
|
+
return {anyOf: [schema, {type: 'null'}]};
|
|
918
|
+
}
|