@alasano/pi-linear 0.1.1 → 0.3.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/README.md +16 -2
- package/assets/linear_list_issues.png +0 -0
- package/assets/screenshot.png +0 -0
- package/extensions/params.ts +40 -1
- package/extensions/renderers/comments.ts +323 -0
- package/extensions/renderers/common.ts +305 -0
- package/extensions/renderers/documents.ts +326 -0
- package/extensions/renderers/initiatives.ts +344 -0
- package/extensions/renderers/issue-labels.ts +294 -0
- package/extensions/renderers/issue-relations.ts +318 -0
- package/extensions/renderers/issue-statuses.ts +199 -0
- package/extensions/renderers/issues.ts +373 -0
- package/extensions/renderers/milestones.ts +294 -0
- package/extensions/renderers/project-labels.ts +279 -0
- package/extensions/renderers/project-relations.ts +344 -0
- package/extensions/renderers/projects.ts +437 -0
- package/extensions/renderers/state.ts +35 -0
- package/extensions/renderers/teams.ts +246 -0
- package/extensions/renderers/users.ts +242 -0
- package/extensions/renderers/workspaces.ts +44 -0
- package/extensions/selections.ts +10 -3
- package/extensions/settings.ts +40 -7
- package/extensions/tools/comments.ts +30 -11
- package/extensions/tools/documents.ts +42 -11
- package/extensions/tools/initiatives.ts +43 -11
- package/extensions/tools/issue-labels.ts +36 -11
- package/extensions/tools/issue-relations.ts +32 -13
- package/extensions/tools/issue-statuses.ts +19 -11
- package/extensions/tools/issues.ts +53 -19
- package/extensions/tools/milestones.ts +31 -11
- package/extensions/tools/project-labels.ts +30 -11
- package/extensions/tools/project-relations.ts +32 -13
- package/extensions/tools/projects.ts +48 -16
- package/extensions/tools/teams.ts +23 -11
- package/extensions/tools/users.ts +23 -11
- package/extensions/tools/workspaces.ts +6 -0
- package/extensions/types.ts +12 -0
- package/package.json +1 -1
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
import { defineTool } from '@mariozechner/pi-coding-agent';
|
|
2
2
|
import { Type } from '@sinclair/typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import {
|
|
5
|
+
PaginationParams,
|
|
6
|
+
paginationVariables,
|
|
7
|
+
FilterParam,
|
|
8
|
+
SortParam,
|
|
9
|
+
RawInputParam,
|
|
10
|
+
} from '../params';
|
|
11
|
+
import { PROJECT_DETAIL_SELECTION, PROJECT_LIST_SELECTION } from '../selections';
|
|
12
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
13
|
import { compactObject, asObject, asObjectArray, asString } from '../util';
|
|
14
|
+
import {
|
|
15
|
+
renderLinearArchiveProjectCall,
|
|
16
|
+
renderLinearDeleteProjectCall,
|
|
17
|
+
renderLinearGetProjectCall,
|
|
18
|
+
renderLinearProjectListCall,
|
|
19
|
+
renderLinearProjectListResult,
|
|
20
|
+
renderLinearProjectResult,
|
|
21
|
+
renderLinearProjectSuccessResult,
|
|
22
|
+
renderLinearSaveProjectCall,
|
|
23
|
+
renderLinearSaveProjectResult,
|
|
24
|
+
renderLinearUnarchiveProjectCall,
|
|
25
|
+
} from '../renderers/projects';
|
|
8
26
|
|
|
9
27
|
export function projectTools() {
|
|
10
28
|
return [
|
|
@@ -17,21 +35,17 @@ export function projectTools() {
|
|
|
17
35
|
...FilterParam,
|
|
18
36
|
...SortParam,
|
|
19
37
|
}),
|
|
38
|
+
renderCall: renderLinearProjectListCall,
|
|
20
39
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
21
40
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
22
41
|
const variables = compactObject({
|
|
23
|
-
|
|
24
|
-
before: params.before,
|
|
42
|
+
...paginationVariables(params, 20),
|
|
25
43
|
filter: asObject(params.filter),
|
|
26
|
-
first: params.first ?? 20,
|
|
27
|
-
includeArchived: params.includeArchived,
|
|
28
|
-
last: params.last,
|
|
29
|
-
orderBy: params.orderBy,
|
|
30
44
|
sort: asObjectArray(params.sort),
|
|
31
45
|
});
|
|
32
46
|
|
|
33
47
|
const data = await linearGraphQL<{
|
|
34
|
-
projects:
|
|
48
|
+
projects: LinearConnection<JsonObject>;
|
|
35
49
|
}>(
|
|
36
50
|
apiKey,
|
|
37
51
|
`query ListProjects(
|
|
@@ -55,7 +69,13 @@ export function projectTools() {
|
|
|
55
69
|
sort: $sort
|
|
56
70
|
) {
|
|
57
71
|
nodes {
|
|
58
|
-
${
|
|
72
|
+
${PROJECT_LIST_SELECTION}
|
|
73
|
+
}
|
|
74
|
+
pageInfo {
|
|
75
|
+
hasNextPage
|
|
76
|
+
hasPreviousPage
|
|
77
|
+
startCursor
|
|
78
|
+
endCursor
|
|
59
79
|
}
|
|
60
80
|
}
|
|
61
81
|
}`,
|
|
@@ -64,12 +84,14 @@ export function projectTools() {
|
|
|
64
84
|
);
|
|
65
85
|
|
|
66
86
|
const projects = data.projects.nodes;
|
|
87
|
+
const pageInfo = data.projects.pageInfo;
|
|
67
88
|
return {
|
|
68
|
-
content: [{ type: 'text', text: JSON.stringify({ projects }, null, 2) }],
|
|
69
|
-
details: { projects },
|
|
89
|
+
content: [{ type: 'text', text: JSON.stringify({ projects, pageInfo }, null, 2) }],
|
|
90
|
+
details: { projects, pageInfo },
|
|
70
91
|
};
|
|
71
92
|
});
|
|
72
93
|
},
|
|
94
|
+
renderResult: renderLinearProjectListResult,
|
|
73
95
|
}),
|
|
74
96
|
defineTool({
|
|
75
97
|
name: 'linear_get_project',
|
|
@@ -78,13 +100,14 @@ export function projectTools() {
|
|
|
78
100
|
parameters: Type.Object({
|
|
79
101
|
projectId: Type.String({ description: 'Project id.' }),
|
|
80
102
|
}),
|
|
103
|
+
renderCall: renderLinearGetProjectCall,
|
|
81
104
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
82
105
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
83
106
|
const data = await linearGraphQL<{ project: JsonObject | null }>(
|
|
84
107
|
apiKey,
|
|
85
108
|
`query GetProject($id: String!) {
|
|
86
109
|
project(id: $id) {
|
|
87
|
-
${
|
|
110
|
+
${PROJECT_DETAIL_SELECTION}
|
|
88
111
|
}
|
|
89
112
|
}`,
|
|
90
113
|
{ id: params.projectId },
|
|
@@ -100,6 +123,7 @@ export function projectTools() {
|
|
|
100
123
|
};
|
|
101
124
|
});
|
|
102
125
|
},
|
|
126
|
+
renderResult: renderLinearProjectResult('Project'),
|
|
103
127
|
}),
|
|
104
128
|
defineTool({
|
|
105
129
|
name: 'linear_save_project',
|
|
@@ -145,6 +169,7 @@ export function projectTools() {
|
|
|
145
169
|
slackChannelName: Type.Optional(Type.String()),
|
|
146
170
|
...RawInputParam,
|
|
147
171
|
}),
|
|
172
|
+
renderCall: renderLinearSaveProjectCall,
|
|
148
173
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
149
174
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
150
175
|
const rawInput = asObject(params.input) || {};
|
|
@@ -203,7 +228,7 @@ export function projectTools() {
|
|
|
203
228
|
projectUpdate(id: $id, input: $input) {
|
|
204
229
|
success
|
|
205
230
|
project {
|
|
206
|
-
${
|
|
231
|
+
${PROJECT_DETAIL_SELECTION}
|
|
207
232
|
}
|
|
208
233
|
}
|
|
209
234
|
}`,
|
|
@@ -238,7 +263,7 @@ export function projectTools() {
|
|
|
238
263
|
projectCreate(input: $input, slackChannelName: $slackChannelName) {
|
|
239
264
|
success
|
|
240
265
|
project {
|
|
241
|
-
${
|
|
266
|
+
${PROJECT_DETAIL_SELECTION}
|
|
242
267
|
}
|
|
243
268
|
}
|
|
244
269
|
}`,
|
|
@@ -260,6 +285,7 @@ export function projectTools() {
|
|
|
260
285
|
};
|
|
261
286
|
});
|
|
262
287
|
},
|
|
288
|
+
renderResult: renderLinearSaveProjectResult,
|
|
263
289
|
}),
|
|
264
290
|
defineTool({
|
|
265
291
|
name: 'linear_delete_project',
|
|
@@ -268,6 +294,7 @@ export function projectTools() {
|
|
|
268
294
|
parameters: Type.Object({
|
|
269
295
|
projectId: Type.String(),
|
|
270
296
|
}),
|
|
297
|
+
renderCall: renderLinearDeleteProjectCall,
|
|
271
298
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
272
299
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
273
300
|
const data = await linearGraphQL<{
|
|
@@ -293,6 +320,7 @@ export function projectTools() {
|
|
|
293
320
|
};
|
|
294
321
|
});
|
|
295
322
|
},
|
|
323
|
+
renderResult: renderLinearProjectSuccessResult('Deleted'),
|
|
296
324
|
}),
|
|
297
325
|
defineTool({
|
|
298
326
|
name: 'linear_archive_project',
|
|
@@ -302,6 +330,7 @@ export function projectTools() {
|
|
|
302
330
|
projectId: Type.String(),
|
|
303
331
|
trash: Type.Optional(Type.Boolean()),
|
|
304
332
|
}),
|
|
333
|
+
renderCall: renderLinearArchiveProjectCall,
|
|
305
334
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
306
335
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
307
336
|
const data = await linearGraphQL<{
|
|
@@ -327,6 +356,7 @@ export function projectTools() {
|
|
|
327
356
|
};
|
|
328
357
|
});
|
|
329
358
|
},
|
|
359
|
+
renderResult: renderLinearProjectSuccessResult('Archived'),
|
|
330
360
|
}),
|
|
331
361
|
defineTool({
|
|
332
362
|
name: 'linear_unarchive_project',
|
|
@@ -335,6 +365,7 @@ export function projectTools() {
|
|
|
335
365
|
parameters: Type.Object({
|
|
336
366
|
projectId: Type.String(),
|
|
337
367
|
}),
|
|
368
|
+
renderCall: renderLinearUnarchiveProjectCall,
|
|
338
369
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
339
370
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
340
371
|
const data = await linearGraphQL<{
|
|
@@ -360,6 +391,7 @@ export function projectTools() {
|
|
|
360
391
|
};
|
|
361
392
|
});
|
|
362
393
|
},
|
|
394
|
+
renderResult: renderLinearProjectSuccessResult('Unarchived'),
|
|
363
395
|
}),
|
|
364
396
|
];
|
|
365
397
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { defineTool } from '@mariozechner/pi-coding-agent';
|
|
2
2
|
import { Type } from '@sinclair/typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
|
-
import { PaginationParams, FilterParam } from '../params';
|
|
4
|
+
import { PaginationParams, paginationVariables, FilterParam } from '../params';
|
|
5
5
|
import { TEAM_SELECTION } from '../selections';
|
|
6
|
-
import type { LinearTeam, JsonObject } from '../types';
|
|
6
|
+
import type { LinearTeam, JsonObject, LinearConnection } from '../types';
|
|
7
7
|
import { compactObject, asObject } from '../util';
|
|
8
|
+
import {
|
|
9
|
+
renderLinearGetTeamCall,
|
|
10
|
+
renderLinearTeamListCall,
|
|
11
|
+
renderLinearTeamListResult,
|
|
12
|
+
renderLinearTeamResult,
|
|
13
|
+
} from '../renderers/teams';
|
|
8
14
|
|
|
9
15
|
export function teamTools() {
|
|
10
16
|
return [
|
|
@@ -17,19 +23,15 @@ export function teamTools() {
|
|
|
17
23
|
...PaginationParams,
|
|
18
24
|
...FilterParam,
|
|
19
25
|
}),
|
|
26
|
+
renderCall: renderLinearTeamListCall,
|
|
20
27
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
21
28
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
22
29
|
const variables = compactObject({
|
|
23
|
-
|
|
24
|
-
before: params.before,
|
|
30
|
+
...paginationVariables(params, 50),
|
|
25
31
|
filter: asObject(params.filter),
|
|
26
|
-
first: params.first,
|
|
27
|
-
includeArchived: params.includeArchived,
|
|
28
|
-
last: params.last,
|
|
29
|
-
orderBy: params.orderBy,
|
|
30
32
|
});
|
|
31
33
|
|
|
32
|
-
const data = await linearGraphQL<{ teams:
|
|
34
|
+
const data = await linearGraphQL<{ teams: LinearConnection<LinearTeam> }>(
|
|
33
35
|
apiKey,
|
|
34
36
|
`query ListTeams(
|
|
35
37
|
$after: String
|
|
@@ -59,6 +61,12 @@ export function teamTools() {
|
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
}
|
|
64
|
+
pageInfo {
|
|
65
|
+
hasNextPage
|
|
66
|
+
hasPreviousPage
|
|
67
|
+
startCursor
|
|
68
|
+
endCursor
|
|
69
|
+
}
|
|
62
70
|
}
|
|
63
71
|
}`,
|
|
64
72
|
variables,
|
|
@@ -66,12 +74,14 @@ export function teamTools() {
|
|
|
66
74
|
);
|
|
67
75
|
|
|
68
76
|
const teams = data.teams.nodes;
|
|
77
|
+
const pageInfo = data.teams.pageInfo;
|
|
69
78
|
return {
|
|
70
|
-
content: [{ type: 'text', text: JSON.stringify({ teams }, null, 2) }],
|
|
71
|
-
details: { teams },
|
|
79
|
+
content: [{ type: 'text', text: JSON.stringify({ teams, pageInfo }, null, 2) }],
|
|
80
|
+
details: { teams, pageInfo },
|
|
72
81
|
};
|
|
73
82
|
});
|
|
74
83
|
},
|
|
84
|
+
renderResult: renderLinearTeamListResult,
|
|
75
85
|
}),
|
|
76
86
|
defineTool({
|
|
77
87
|
name: 'linear_get_team',
|
|
@@ -80,6 +90,7 @@ export function teamTools() {
|
|
|
80
90
|
parameters: Type.Object({
|
|
81
91
|
teamId: Type.String(),
|
|
82
92
|
}),
|
|
93
|
+
renderCall: renderLinearGetTeamCall,
|
|
83
94
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
84
95
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
85
96
|
const data = await linearGraphQL<{ team: JsonObject | null }>(
|
|
@@ -100,6 +111,7 @@ export function teamTools() {
|
|
|
100
111
|
};
|
|
101
112
|
});
|
|
102
113
|
},
|
|
114
|
+
renderResult: renderLinearTeamResult('Team'),
|
|
103
115
|
}),
|
|
104
116
|
];
|
|
105
117
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { defineTool } from '@mariozechner/pi-coding-agent';
|
|
2
2
|
import { Type } from '@sinclair/typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL } from '../client';
|
|
4
|
-
import { PaginationParams, FilterParam, SortParam } from '../params';
|
|
4
|
+
import { PaginationParams, paginationVariables, FilterParam, SortParam } from '../params';
|
|
5
5
|
import { USER_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
6
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
7
|
import { compactObject, asObject, asObjectArray } from '../util';
|
|
8
|
+
import {
|
|
9
|
+
renderLinearGetUserCall,
|
|
10
|
+
renderLinearUserListCall,
|
|
11
|
+
renderLinearUserListResult,
|
|
12
|
+
renderLinearUserResult,
|
|
13
|
+
} from '../renderers/users';
|
|
8
14
|
|
|
9
15
|
export function userTools() {
|
|
10
16
|
return [
|
|
@@ -18,22 +24,18 @@ export function userTools() {
|
|
|
18
24
|
...SortParam,
|
|
19
25
|
includeDisabled: Type.Optional(Type.Boolean()),
|
|
20
26
|
}),
|
|
27
|
+
renderCall: renderLinearUserListCall,
|
|
21
28
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
22
29
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
23
30
|
const variables = compactObject({
|
|
24
|
-
|
|
25
|
-
before: params.before,
|
|
31
|
+
...paginationVariables(params, 50),
|
|
26
32
|
filter: asObject(params.filter),
|
|
27
|
-
first: params.first ?? 50,
|
|
28
|
-
includeArchived: params.includeArchived,
|
|
29
33
|
includeDisabled: params.includeDisabled,
|
|
30
|
-
last: params.last,
|
|
31
|
-
orderBy: params.orderBy,
|
|
32
34
|
sort: asObjectArray(params.sort),
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
const data = await linearGraphQL<{
|
|
36
|
-
users:
|
|
38
|
+
users: LinearConnection<JsonObject>;
|
|
37
39
|
}>(
|
|
38
40
|
apiKey,
|
|
39
41
|
`query ListUsers(
|
|
@@ -61,6 +63,12 @@ export function userTools() {
|
|
|
61
63
|
nodes {
|
|
62
64
|
${USER_SELECTION}
|
|
63
65
|
}
|
|
66
|
+
pageInfo {
|
|
67
|
+
hasNextPage
|
|
68
|
+
hasPreviousPage
|
|
69
|
+
startCursor
|
|
70
|
+
endCursor
|
|
71
|
+
}
|
|
64
72
|
}
|
|
65
73
|
}`,
|
|
66
74
|
variables,
|
|
@@ -68,12 +76,14 @@ export function userTools() {
|
|
|
68
76
|
);
|
|
69
77
|
|
|
70
78
|
const users = data.users.nodes;
|
|
79
|
+
const pageInfo = data.users.pageInfo;
|
|
71
80
|
return {
|
|
72
|
-
content: [{ type: 'text', text: JSON.stringify({ users }, null, 2) }],
|
|
73
|
-
details: { users },
|
|
81
|
+
content: [{ type: 'text', text: JSON.stringify({ users, pageInfo }, null, 2) }],
|
|
82
|
+
details: { users, pageInfo },
|
|
74
83
|
};
|
|
75
84
|
});
|
|
76
85
|
},
|
|
86
|
+
renderResult: renderLinearUserListResult,
|
|
77
87
|
}),
|
|
78
88
|
defineTool({
|
|
79
89
|
name: 'linear_get_user',
|
|
@@ -82,6 +92,7 @@ export function userTools() {
|
|
|
82
92
|
parameters: Type.Object({
|
|
83
93
|
userId: Type.String(),
|
|
84
94
|
}),
|
|
95
|
+
renderCall: renderLinearGetUserCall,
|
|
85
96
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
86
97
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
87
98
|
const data = await linearGraphQL<{ user: JsonObject | null }>(
|
|
@@ -102,6 +113,7 @@ export function userTools() {
|
|
|
102
113
|
};
|
|
103
114
|
});
|
|
104
115
|
},
|
|
116
|
+
renderResult: renderLinearUserResult,
|
|
105
117
|
}),
|
|
106
118
|
];
|
|
107
119
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { defineTool } from '@mariozechner/pi-coding-agent';
|
|
2
2
|
import { Type } from '@sinclair/typebox';
|
|
3
3
|
import { switchWorkspace, type WorkspaceCredentials } from '../client';
|
|
4
|
+
import {
|
|
5
|
+
renderLinearSwitchWorkspaceCall,
|
|
6
|
+
renderLinearSwitchWorkspaceResult,
|
|
7
|
+
} from '../renderers/workspaces';
|
|
4
8
|
|
|
5
9
|
export function workspaceTools(creds: WorkspaceCredentials) {
|
|
6
10
|
const names = Object.keys(creds.workspaces);
|
|
@@ -16,6 +20,7 @@ export function workspaceTools(creds: WorkspaceCredentials) {
|
|
|
16
20
|
description: `Workspace name to switch to. One of: ${names.join(', ')}`,
|
|
17
21
|
}),
|
|
18
22
|
}),
|
|
23
|
+
renderCall: renderLinearSwitchWorkspaceCall,
|
|
19
24
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
20
25
|
const updated = await switchWorkspace(params.name);
|
|
21
26
|
return {
|
|
@@ -28,6 +33,7 @@ export function workspaceTools(creds: WorkspaceCredentials) {
|
|
|
28
33
|
details: { active: updated.activeWorkspace },
|
|
29
34
|
};
|
|
30
35
|
},
|
|
36
|
+
renderResult: renderLinearSwitchWorkspaceResult,
|
|
31
37
|
}),
|
|
32
38
|
];
|
|
33
39
|
}
|
package/extensions/types.ts
CHANGED
|
@@ -4,6 +4,18 @@ export type LinearGraphQLError = {
|
|
|
4
4
|
message: string;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
export type LinearPageInfo = {
|
|
8
|
+
hasNextPage: boolean;
|
|
9
|
+
hasPreviousPage: boolean;
|
|
10
|
+
startCursor?: string | null;
|
|
11
|
+
endCursor?: string | null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type LinearConnection<T> = {
|
|
15
|
+
nodes: T[];
|
|
16
|
+
pageInfo: LinearPageInfo;
|
|
17
|
+
};
|
|
18
|
+
|
|
7
19
|
export type LinearIssue = {
|
|
8
20
|
id: string;
|
|
9
21
|
identifier: string;
|