@alasano/pi-linear 0.2.0 → 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 +2 -0
- package/extensions/params.ts +40 -1
- package/extensions/renderers/projects.ts +7 -0
- package/extensions/selections.ts +10 -3
- package/extensions/tools/comments.ts +13 -11
- package/extensions/tools/documents.ts +19 -11
- package/extensions/tools/initiatives.ts +19 -11
- package/extensions/tools/issue-labels.ts +19 -11
- package/extensions/tools/issue-relations.ts +15 -13
- package/extensions/tools/issue-statuses.ts +13 -11
- package/extensions/tools/issues.ts +24 -19
- package/extensions/tools/milestones.ts +13 -11
- package/extensions/tools/project-labels.ts +13 -11
- package/extensions/tools/project-relations.ts +15 -13
- package/extensions/tools/projects.ts +24 -16
- package/extensions/tools/teams.ts +13 -11
- package/extensions/tools/users.ts +13 -11
- package/extensions/types.ts +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,6 +110,8 @@ Run `/linear-settings` to open an overlay where you can choose the default outpu
|
|
|
110
110
|
| `linear_archive_project` | Archive or trash a project |
|
|
111
111
|
| `linear_unarchive_project` | Restore an archived project |
|
|
112
112
|
|
|
113
|
+
List and search results include `pageInfo` in the JSON output for cursor pagination. Project list results use a bounded summary selection, and `linear_get_project` plus project save results include the project's markdown `content` body.
|
|
114
|
+
|
|
113
115
|
### Project Labels
|
|
114
116
|
|
|
115
117
|
| Tool | Description |
|
package/extensions/params.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Type } from '@sinclair/typebox';
|
|
2
|
-
import { GenericObjectSchema } from './util';
|
|
2
|
+
import { compactObject, GenericObjectSchema } from './util';
|
|
3
3
|
|
|
4
4
|
export const PaginationParams = {
|
|
5
5
|
after: Type.Optional(Type.String({ description: 'Pagination cursor.' })),
|
|
@@ -26,6 +26,45 @@ export const PaginationParams = {
|
|
|
26
26
|
),
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
type PaginationVariableParams = {
|
|
30
|
+
after?: string;
|
|
31
|
+
before?: string;
|
|
32
|
+
first?: number;
|
|
33
|
+
includeArchived?: boolean;
|
|
34
|
+
last?: number;
|
|
35
|
+
orderBy?: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export function paginationVariables(
|
|
39
|
+
params: PaginationVariableParams,
|
|
40
|
+
defaultPageSize: number,
|
|
41
|
+
): Partial<PaginationVariableParams> {
|
|
42
|
+
const hasForwardPagination = params.after !== undefined || params.first !== undefined;
|
|
43
|
+
const hasBackwardPagination = params.before !== undefined || params.last !== undefined;
|
|
44
|
+
|
|
45
|
+
if (hasForwardPagination && hasBackwardPagination) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
'Use either forward pagination (first/after) or backward pagination (last/before), not both.',
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (hasBackwardPagination) {
|
|
52
|
+
return compactObject({
|
|
53
|
+
before: params.before,
|
|
54
|
+
includeArchived: params.includeArchived,
|
|
55
|
+
last: params.last ?? defaultPageSize,
|
|
56
|
+
orderBy: params.orderBy,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return compactObject({
|
|
61
|
+
after: params.after,
|
|
62
|
+
first: params.first ?? defaultPageSize,
|
|
63
|
+
includeArchived: params.includeArchived,
|
|
64
|
+
orderBy: params.orderBy,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
29
68
|
export const SortParam = {
|
|
30
69
|
sort: Type.Optional(Type.Array(GenericObjectSchema, { description: 'Sort input array.' })),
|
|
31
70
|
};
|
|
@@ -39,6 +39,7 @@ type ProjectLike = {
|
|
|
39
39
|
id?: string;
|
|
40
40
|
name?: string | null;
|
|
41
41
|
description?: string | null;
|
|
42
|
+
content?: string | null;
|
|
42
43
|
state?: string | null;
|
|
43
44
|
status?: { id?: string; name?: string | null } | null;
|
|
44
45
|
priority?: number | null;
|
|
@@ -55,6 +56,12 @@ type ProjectLike = {
|
|
|
55
56
|
type ProjectResultDetails = {
|
|
56
57
|
project?: ProjectLike | null;
|
|
57
58
|
projects?: ProjectLike[];
|
|
59
|
+
pageInfo?: {
|
|
60
|
+
hasNextPage?: boolean;
|
|
61
|
+
hasPreviousPage?: boolean;
|
|
62
|
+
startCursor?: string | null;
|
|
63
|
+
endCursor?: string | null;
|
|
64
|
+
};
|
|
58
65
|
success?: boolean;
|
|
59
66
|
};
|
|
60
67
|
|
package/extensions/selections.ts
CHANGED
|
@@ -94,7 +94,7 @@ export const ISSUE_LABEL_SELECTION = `
|
|
|
94
94
|
}
|
|
95
95
|
`;
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
const PROJECT_BASE_SELECTION = `
|
|
98
98
|
id
|
|
99
99
|
name
|
|
100
100
|
description
|
|
@@ -116,7 +116,7 @@ export const PROJECT_SELECTION = `
|
|
|
116
116
|
createdAt
|
|
117
117
|
updatedAt
|
|
118
118
|
url
|
|
119
|
-
teams {
|
|
119
|
+
teams(first: 10) {
|
|
120
120
|
nodes {
|
|
121
121
|
id
|
|
122
122
|
key
|
|
@@ -128,7 +128,7 @@ export const PROJECT_SELECTION = `
|
|
|
128
128
|
name
|
|
129
129
|
email
|
|
130
130
|
}
|
|
131
|
-
members {
|
|
131
|
+
members(first: 10) {
|
|
132
132
|
nodes {
|
|
133
133
|
id
|
|
134
134
|
name
|
|
@@ -141,6 +141,13 @@ export const PROJECT_SELECTION = `
|
|
|
141
141
|
}
|
|
142
142
|
`;
|
|
143
143
|
|
|
144
|
+
export const PROJECT_LIST_SELECTION = PROJECT_BASE_SELECTION;
|
|
145
|
+
|
|
146
|
+
export const PROJECT_DETAIL_SELECTION = `
|
|
147
|
+
${PROJECT_BASE_SELECTION}
|
|
148
|
+
content
|
|
149
|
+
`;
|
|
150
|
+
|
|
144
151
|
export const PROJECT_LABEL_SELECTION = `
|
|
145
152
|
id
|
|
146
153
|
name
|
|
@@ -1,9 +1,9 @@
|
|
|
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, RawInputParam } from '../params';
|
|
4
|
+
import { PaginationParams, paginationVariables, FilterParam, RawInputParam } from '../params';
|
|
5
5
|
import { COMMENT_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
6
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
7
|
import { compactObject, asObject, asString, GenericObjectSchema } from '../util';
|
|
8
8
|
import {
|
|
9
9
|
renderLinearCommentListCall,
|
|
@@ -29,17 +29,12 @@ export function commentTools() {
|
|
|
29
29
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
30
30
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
31
31
|
const variables = compactObject({
|
|
32
|
-
|
|
33
|
-
before: params.before,
|
|
32
|
+
...paginationVariables(params, 20),
|
|
34
33
|
filter: asObject(params.filter),
|
|
35
|
-
first: params.first ?? 20,
|
|
36
|
-
includeArchived: params.includeArchived,
|
|
37
|
-
last: params.last,
|
|
38
|
-
orderBy: params.orderBy,
|
|
39
34
|
});
|
|
40
35
|
|
|
41
36
|
const data = await linearGraphQL<{
|
|
42
|
-
comments:
|
|
37
|
+
comments: LinearConnection<JsonObject>;
|
|
43
38
|
}>(
|
|
44
39
|
apiKey,
|
|
45
40
|
`query ListComments(
|
|
@@ -63,6 +58,12 @@ export function commentTools() {
|
|
|
63
58
|
nodes {
|
|
64
59
|
${COMMENT_SELECTION}
|
|
65
60
|
}
|
|
61
|
+
pageInfo {
|
|
62
|
+
hasNextPage
|
|
63
|
+
hasPreviousPage
|
|
64
|
+
startCursor
|
|
65
|
+
endCursor
|
|
66
|
+
}
|
|
66
67
|
}
|
|
67
68
|
}`,
|
|
68
69
|
variables,
|
|
@@ -70,9 +71,10 @@ export function commentTools() {
|
|
|
70
71
|
);
|
|
71
72
|
|
|
72
73
|
const comments = data.comments.nodes;
|
|
74
|
+
const pageInfo = data.comments.pageInfo;
|
|
73
75
|
return {
|
|
74
|
-
content: [{ type: 'text', text: JSON.stringify({ comments }, null, 2) }],
|
|
75
|
-
details: { comments },
|
|
76
|
+
content: [{ type: 'text', text: JSON.stringify({ comments, pageInfo }, null, 2) }],
|
|
77
|
+
details: { comments, pageInfo },
|
|
76
78
|
};
|
|
77
79
|
});
|
|
78
80
|
},
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { defineTool } from '@mariozechner/pi-coding-agent';
|
|
2
2
|
import { Type } from '@sinclair/typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL, resolveTeamId } from '../client';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
PaginationParams,
|
|
6
|
+
paginationVariables,
|
|
7
|
+
FilterParam,
|
|
8
|
+
RawInputParam,
|
|
9
|
+
TeamConvenienceParams,
|
|
10
|
+
} from '../params';
|
|
5
11
|
import { DOCUMENT_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
12
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
13
|
import { compactObject, asObject, asString } from '../util';
|
|
8
14
|
import {
|
|
9
15
|
renderLinearCreateDocumentCall,
|
|
@@ -31,17 +37,12 @@ export function documentTools() {
|
|
|
31
37
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
32
38
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
33
39
|
const variables = compactObject({
|
|
34
|
-
|
|
35
|
-
before: params.before,
|
|
40
|
+
...paginationVariables(params, 20),
|
|
36
41
|
filter: asObject(params.filter),
|
|
37
|
-
first: params.first ?? 20,
|
|
38
|
-
includeArchived: params.includeArchived,
|
|
39
|
-
last: params.last,
|
|
40
|
-
orderBy: params.orderBy,
|
|
41
42
|
});
|
|
42
43
|
|
|
43
44
|
const data = await linearGraphQL<{
|
|
44
|
-
documents:
|
|
45
|
+
documents: LinearConnection<JsonObject>;
|
|
45
46
|
}>(
|
|
46
47
|
apiKey,
|
|
47
48
|
`query ListDocuments(
|
|
@@ -65,6 +66,12 @@ export function documentTools() {
|
|
|
65
66
|
nodes {
|
|
66
67
|
${DOCUMENT_SELECTION}
|
|
67
68
|
}
|
|
69
|
+
pageInfo {
|
|
70
|
+
hasNextPage
|
|
71
|
+
hasPreviousPage
|
|
72
|
+
startCursor
|
|
73
|
+
endCursor
|
|
74
|
+
}
|
|
68
75
|
}
|
|
69
76
|
}`,
|
|
70
77
|
variables,
|
|
@@ -72,9 +79,10 @@ export function documentTools() {
|
|
|
72
79
|
);
|
|
73
80
|
|
|
74
81
|
const documents = data.documents.nodes;
|
|
82
|
+
const pageInfo = data.documents.pageInfo;
|
|
75
83
|
return {
|
|
76
|
-
content: [{ type: 'text', text: JSON.stringify({ documents }, null, 2) }],
|
|
77
|
-
details: { documents },
|
|
84
|
+
content: [{ type: 'text', text: JSON.stringify({ documents, pageInfo }, null, 2) }],
|
|
85
|
+
details: { documents, pageInfo },
|
|
78
86
|
};
|
|
79
87
|
});
|
|
80
88
|
},
|
|
@@ -1,9 +1,15 @@
|
|
|
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 {
|
|
4
|
+
import {
|
|
5
|
+
PaginationParams,
|
|
6
|
+
paginationVariables,
|
|
7
|
+
FilterParam,
|
|
8
|
+
SortParam,
|
|
9
|
+
RawInputParam,
|
|
10
|
+
} from '../params';
|
|
5
11
|
import { INITIATIVE_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
12
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
13
|
import { compactObject, asObject, asObjectArray, asString } from '../util';
|
|
8
14
|
import {
|
|
9
15
|
renderLinearArchiveInitiativeCall,
|
|
@@ -33,18 +39,13 @@ export function initiativeTools() {
|
|
|
33
39
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
34
40
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
35
41
|
const variables = compactObject({
|
|
36
|
-
|
|
37
|
-
before: params.before,
|
|
42
|
+
...paginationVariables(params, 20),
|
|
38
43
|
filter: asObject(params.filter),
|
|
39
|
-
first: params.first ?? 20,
|
|
40
|
-
includeArchived: params.includeArchived,
|
|
41
|
-
last: params.last,
|
|
42
|
-
orderBy: params.orderBy,
|
|
43
44
|
sort: asObjectArray(params.sort),
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
const data = await linearGraphQL<{
|
|
47
|
-
initiatives:
|
|
48
|
+
initiatives: LinearConnection<JsonObject>;
|
|
48
49
|
}>(
|
|
49
50
|
apiKey,
|
|
50
51
|
`query ListInitiatives(
|
|
@@ -70,6 +71,12 @@ export function initiativeTools() {
|
|
|
70
71
|
nodes {
|
|
71
72
|
${INITIATIVE_SELECTION}
|
|
72
73
|
}
|
|
74
|
+
pageInfo {
|
|
75
|
+
hasNextPage
|
|
76
|
+
hasPreviousPage
|
|
77
|
+
startCursor
|
|
78
|
+
endCursor
|
|
79
|
+
}
|
|
73
80
|
}
|
|
74
81
|
}`,
|
|
75
82
|
variables,
|
|
@@ -77,9 +84,10 @@ export function initiativeTools() {
|
|
|
77
84
|
);
|
|
78
85
|
|
|
79
86
|
const initiatives = data.initiatives.nodes;
|
|
87
|
+
const pageInfo = data.initiatives.pageInfo;
|
|
80
88
|
return {
|
|
81
|
-
content: [{ type: 'text', text: JSON.stringify({ initiatives }, null, 2) }],
|
|
82
|
-
details: { initiatives },
|
|
89
|
+
content: [{ type: 'text', text: JSON.stringify({ initiatives, pageInfo }, null, 2) }],
|
|
90
|
+
details: { initiatives, pageInfo },
|
|
83
91
|
};
|
|
84
92
|
});
|
|
85
93
|
},
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { defineTool } from '@mariozechner/pi-coding-agent';
|
|
2
2
|
import { Type } from '@sinclair/typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL, resolveTeamId } from '../client';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
PaginationParams,
|
|
6
|
+
paginationVariables,
|
|
7
|
+
FilterParam,
|
|
8
|
+
RawInputParam,
|
|
9
|
+
TeamConvenienceParams,
|
|
10
|
+
} from '../params';
|
|
5
11
|
import { ISSUE_LABEL_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
12
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
13
|
import { compactObject, asObject, asString, mergeFilters } from '../util';
|
|
8
14
|
import {
|
|
9
15
|
renderLinearCreateIssueLabelCall,
|
|
@@ -45,17 +51,12 @@ export function issueLabelTools() {
|
|
|
45
51
|
const filter = mergeFilters(asObject(params.filter), convenienceFilter);
|
|
46
52
|
|
|
47
53
|
const variables = compactObject({
|
|
48
|
-
|
|
49
|
-
before: params.before,
|
|
54
|
+
...paginationVariables(params, 50),
|
|
50
55
|
filter,
|
|
51
|
-
first: params.first ?? 50,
|
|
52
|
-
includeArchived: params.includeArchived,
|
|
53
|
-
last: params.last,
|
|
54
|
-
orderBy: params.orderBy,
|
|
55
56
|
});
|
|
56
57
|
|
|
57
58
|
const data = await linearGraphQL<{
|
|
58
|
-
issueLabels:
|
|
59
|
+
issueLabels: LinearConnection<JsonObject>;
|
|
59
60
|
}>(
|
|
60
61
|
apiKey,
|
|
61
62
|
`query ListIssueLabels(
|
|
@@ -79,6 +80,12 @@ export function issueLabelTools() {
|
|
|
79
80
|
nodes {
|
|
80
81
|
${ISSUE_LABEL_SELECTION}
|
|
81
82
|
}
|
|
83
|
+
pageInfo {
|
|
84
|
+
hasNextPage
|
|
85
|
+
hasPreviousPage
|
|
86
|
+
startCursor
|
|
87
|
+
endCursor
|
|
88
|
+
}
|
|
82
89
|
}
|
|
83
90
|
}`,
|
|
84
91
|
variables,
|
|
@@ -86,9 +93,10 @@ export function issueLabelTools() {
|
|
|
86
93
|
);
|
|
87
94
|
|
|
88
95
|
const labels = data.issueLabels.nodes;
|
|
96
|
+
const pageInfo = data.issueLabels.pageInfo;
|
|
89
97
|
return {
|
|
90
|
-
content: [{ type: 'text', text: JSON.stringify({ labels }, null, 2) }],
|
|
91
|
-
details: { labels },
|
|
98
|
+
content: [{ type: 'text', text: JSON.stringify({ labels, pageInfo }, null, 2) }],
|
|
99
|
+
details: { labels, pageInfo },
|
|
92
100
|
};
|
|
93
101
|
});
|
|
94
102
|
},
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { defineTool } from '@mariozechner/pi-coding-agent';
|
|
2
2
|
import { Type } from '@sinclair/typebox';
|
|
3
3
|
import { withLinearAuth, linearGraphQL, resolveIssueId } from '../client';
|
|
4
|
-
import { PaginationParams } from '../params';
|
|
4
|
+
import { PaginationParams, paginationVariables } from '../params';
|
|
5
5
|
import { ISSUE_RELATION_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
6
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
7
|
import { compactObject } from '../util';
|
|
8
8
|
import {
|
|
9
9
|
renderLinearCreateIssueRelationCall,
|
|
@@ -27,17 +27,10 @@ export function issueRelationTools() {
|
|
|
27
27
|
renderCall: renderLinearIssueRelationListCall,
|
|
28
28
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
29
29
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
30
|
-
const variables =
|
|
31
|
-
after: params.after,
|
|
32
|
-
before: params.before,
|
|
33
|
-
first: params.first ?? 20,
|
|
34
|
-
includeArchived: params.includeArchived,
|
|
35
|
-
last: params.last,
|
|
36
|
-
orderBy: params.orderBy,
|
|
37
|
-
});
|
|
30
|
+
const variables = paginationVariables(params, 20);
|
|
38
31
|
|
|
39
32
|
const data = await linearGraphQL<{
|
|
40
|
-
issueRelations:
|
|
33
|
+
issueRelations: LinearConnection<JsonObject>;
|
|
41
34
|
}>(
|
|
42
35
|
apiKey,
|
|
43
36
|
`query ListIssueRelations(
|
|
@@ -59,6 +52,12 @@ export function issueRelationTools() {
|
|
|
59
52
|
nodes {
|
|
60
53
|
${ISSUE_RELATION_SELECTION}
|
|
61
54
|
}
|
|
55
|
+
pageInfo {
|
|
56
|
+
hasNextPage
|
|
57
|
+
hasPreviousPage
|
|
58
|
+
startCursor
|
|
59
|
+
endCursor
|
|
60
|
+
}
|
|
62
61
|
}
|
|
63
62
|
}`,
|
|
64
63
|
variables,
|
|
@@ -66,9 +65,12 @@ export function issueRelationTools() {
|
|
|
66
65
|
);
|
|
67
66
|
|
|
68
67
|
const issueRelations = data.issueRelations.nodes;
|
|
68
|
+
const pageInfo = data.issueRelations.pageInfo;
|
|
69
69
|
return {
|
|
70
|
-
content: [
|
|
71
|
-
|
|
70
|
+
content: [
|
|
71
|
+
{ type: 'text', text: JSON.stringify({ issueRelations, pageInfo }, null, 2) },
|
|
72
|
+
],
|
|
73
|
+
details: { issueRelations, pageInfo },
|
|
72
74
|
};
|
|
73
75
|
});
|
|
74
76
|
},
|
|
@@ -1,9 +1,9 @@
|
|
|
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 { WORKFLOW_STATE_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
6
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
7
|
import { compactObject, asObject } from '../util';
|
|
8
8
|
import {
|
|
9
9
|
renderLinearIssueStatusListCall,
|
|
@@ -25,17 +25,12 @@ export function issueStatusTools() {
|
|
|
25
25
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
26
26
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
27
27
|
const variables = compactObject({
|
|
28
|
-
|
|
29
|
-
before: params.before,
|
|
28
|
+
...paginationVariables(params, 50),
|
|
30
29
|
filter: asObject(params.filter),
|
|
31
|
-
first: params.first ?? 50,
|
|
32
|
-
includeArchived: params.includeArchived,
|
|
33
|
-
last: params.last,
|
|
34
|
-
orderBy: params.orderBy,
|
|
35
30
|
});
|
|
36
31
|
|
|
37
32
|
const data = await linearGraphQL<{
|
|
38
|
-
workflowStates:
|
|
33
|
+
workflowStates: LinearConnection<JsonObject>;
|
|
39
34
|
}>(
|
|
40
35
|
apiKey,
|
|
41
36
|
`query ListIssueStatuses(
|
|
@@ -59,6 +54,12 @@ export function issueStatusTools() {
|
|
|
59
54
|
nodes {
|
|
60
55
|
${WORKFLOW_STATE_SELECTION}
|
|
61
56
|
}
|
|
57
|
+
pageInfo {
|
|
58
|
+
hasNextPage
|
|
59
|
+
hasPreviousPage
|
|
60
|
+
startCursor
|
|
61
|
+
endCursor
|
|
62
|
+
}
|
|
62
63
|
}
|
|
63
64
|
}`,
|
|
64
65
|
variables,
|
|
@@ -66,9 +67,10 @@ export function issueStatusTools() {
|
|
|
66
67
|
);
|
|
67
68
|
|
|
68
69
|
const states = data.workflowStates.nodes;
|
|
70
|
+
const pageInfo = data.workflowStates.pageInfo;
|
|
69
71
|
return {
|
|
70
|
-
content: [{ type: 'text', text: JSON.stringify({ states }, null, 2) }],
|
|
71
|
-
details: { states },
|
|
72
|
+
content: [{ type: 'text', text: JSON.stringify({ states, pageInfo }, null, 2) }],
|
|
73
|
+
details: { states, pageInfo },
|
|
72
74
|
};
|
|
73
75
|
});
|
|
74
76
|
},
|
|
@@ -9,13 +9,14 @@ import {
|
|
|
9
9
|
} from '../client';
|
|
10
10
|
import {
|
|
11
11
|
PaginationParams,
|
|
12
|
+
paginationVariables,
|
|
12
13
|
FilterParam,
|
|
13
14
|
SortParam,
|
|
14
15
|
TeamConvenienceParams,
|
|
15
16
|
RawInputParam,
|
|
16
17
|
} from '../params';
|
|
17
18
|
import { ISSUE_SELECTION } from '../selections';
|
|
18
|
-
import type { LinearIssue, JsonObject } from '../types';
|
|
19
|
+
import type { LinearIssue, JsonObject, LinearConnection } from '../types';
|
|
19
20
|
import { compactObject, asObject, asObjectArray, asString, mergeFilters } from '../util';
|
|
20
21
|
import {
|
|
21
22
|
renderLinearArchiveIssueCall,
|
|
@@ -79,17 +80,12 @@ export function issueTools() {
|
|
|
79
80
|
);
|
|
80
81
|
|
|
81
82
|
const variables = compactObject({
|
|
82
|
-
|
|
83
|
-
before: params.before,
|
|
83
|
+
...paginationVariables(params, 20),
|
|
84
84
|
filter,
|
|
85
|
-
first: params.first ?? 20,
|
|
86
|
-
includeArchived: params.includeArchived,
|
|
87
|
-
last: params.last,
|
|
88
|
-
orderBy: params.orderBy,
|
|
89
85
|
sort: asObjectArray(params.sort),
|
|
90
86
|
});
|
|
91
87
|
|
|
92
|
-
const data = await linearGraphQL<{ issues:
|
|
88
|
+
const data = await linearGraphQL<{ issues: LinearConnection<LinearIssue> }>(
|
|
93
89
|
apiKey,
|
|
94
90
|
`query ListIssues(
|
|
95
91
|
$after: String
|
|
@@ -114,6 +110,12 @@ export function issueTools() {
|
|
|
114
110
|
nodes {
|
|
115
111
|
${ISSUE_SELECTION}
|
|
116
112
|
}
|
|
113
|
+
pageInfo {
|
|
114
|
+
hasNextPage
|
|
115
|
+
hasPreviousPage
|
|
116
|
+
startCursor
|
|
117
|
+
endCursor
|
|
118
|
+
}
|
|
117
119
|
}
|
|
118
120
|
}`,
|
|
119
121
|
variables,
|
|
@@ -121,9 +123,10 @@ export function issueTools() {
|
|
|
121
123
|
);
|
|
122
124
|
|
|
123
125
|
const issues = data.issues.nodes;
|
|
126
|
+
const pageInfo = data.issues.pageInfo;
|
|
124
127
|
return {
|
|
125
|
-
content: [{ type: 'text', text: JSON.stringify({ issues }, null, 2) }],
|
|
126
|
-
details: { issues },
|
|
128
|
+
content: [{ type: 'text', text: JSON.stringify({ issues, pageInfo }, null, 2) }],
|
|
129
|
+
details: { issues, pageInfo },
|
|
127
130
|
};
|
|
128
131
|
});
|
|
129
132
|
},
|
|
@@ -641,20 +644,15 @@ export function issueTools() {
|
|
|
641
644
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
642
645
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
643
646
|
const variables = compactObject({
|
|
647
|
+
...paginationVariables(params, 20),
|
|
644
648
|
term: params.term,
|
|
645
649
|
includeComments: params.includeComments,
|
|
646
650
|
teamId: params.teamId,
|
|
647
|
-
after: params.after,
|
|
648
|
-
before: params.before,
|
|
649
651
|
filter: asObject(params.filter),
|
|
650
|
-
first: params.first ?? 20,
|
|
651
|
-
includeArchived: params.includeArchived,
|
|
652
|
-
last: params.last,
|
|
653
|
-
orderBy: params.orderBy,
|
|
654
652
|
});
|
|
655
653
|
|
|
656
654
|
const data = await linearGraphQL<{
|
|
657
|
-
searchIssues:
|
|
655
|
+
searchIssues: LinearConnection<LinearIssue>;
|
|
658
656
|
}>(
|
|
659
657
|
apiKey,
|
|
660
658
|
`query SearchIssues(
|
|
@@ -684,6 +682,12 @@ export function issueTools() {
|
|
|
684
682
|
nodes {
|
|
685
683
|
${ISSUE_SELECTION}
|
|
686
684
|
}
|
|
685
|
+
pageInfo {
|
|
686
|
+
hasNextPage
|
|
687
|
+
hasPreviousPage
|
|
688
|
+
startCursor
|
|
689
|
+
endCursor
|
|
690
|
+
}
|
|
687
691
|
}
|
|
688
692
|
}`,
|
|
689
693
|
variables,
|
|
@@ -691,9 +695,10 @@ export function issueTools() {
|
|
|
691
695
|
);
|
|
692
696
|
|
|
693
697
|
const issues = data.searchIssues.nodes;
|
|
698
|
+
const pageInfo = data.searchIssues.pageInfo;
|
|
694
699
|
return {
|
|
695
|
-
content: [{ type: 'text', text: JSON.stringify({ issues }, null, 2) }],
|
|
696
|
-
details: { issues },
|
|
700
|
+
content: [{ type: 'text', text: JSON.stringify({ issues, pageInfo }, null, 2) }],
|
|
701
|
+
details: { issues, pageInfo },
|
|
697
702
|
};
|
|
698
703
|
});
|
|
699
704
|
},
|
|
@@ -1,9 +1,9 @@
|
|
|
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, RawInputParam } from '../params';
|
|
4
|
+
import { PaginationParams, paginationVariables, FilterParam, RawInputParam } from '../params';
|
|
5
5
|
import { MILESTONE_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
6
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
7
|
import { compactObject, asObject, asString, GenericObjectSchema } from '../util';
|
|
8
8
|
import {
|
|
9
9
|
renderLinearMilestoneDeleteCall,
|
|
@@ -30,17 +30,12 @@ export function milestoneTools() {
|
|
|
30
30
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
31
31
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
32
32
|
const variables = compactObject({
|
|
33
|
-
|
|
34
|
-
before: params.before,
|
|
33
|
+
...paginationVariables(params, 20),
|
|
35
34
|
filter: asObject(params.filter),
|
|
36
|
-
first: params.first ?? 20,
|
|
37
|
-
includeArchived: params.includeArchived,
|
|
38
|
-
last: params.last,
|
|
39
|
-
orderBy: params.orderBy,
|
|
40
35
|
});
|
|
41
36
|
|
|
42
37
|
const data = await linearGraphQL<{
|
|
43
|
-
projectMilestones:
|
|
38
|
+
projectMilestones: LinearConnection<JsonObject>;
|
|
44
39
|
}>(
|
|
45
40
|
apiKey,
|
|
46
41
|
`query ListMilestones(
|
|
@@ -64,6 +59,12 @@ export function milestoneTools() {
|
|
|
64
59
|
nodes {
|
|
65
60
|
${MILESTONE_SELECTION}
|
|
66
61
|
}
|
|
62
|
+
pageInfo {
|
|
63
|
+
hasNextPage
|
|
64
|
+
hasPreviousPage
|
|
65
|
+
startCursor
|
|
66
|
+
endCursor
|
|
67
|
+
}
|
|
67
68
|
}
|
|
68
69
|
}`,
|
|
69
70
|
variables,
|
|
@@ -71,9 +72,10 @@ export function milestoneTools() {
|
|
|
71
72
|
);
|
|
72
73
|
|
|
73
74
|
const milestones = data.projectMilestones.nodes;
|
|
75
|
+
const pageInfo = data.projectMilestones.pageInfo;
|
|
74
76
|
return {
|
|
75
|
-
content: [{ type: 'text', text: JSON.stringify({ milestones }, null, 2) }],
|
|
76
|
-
details: { milestones },
|
|
77
|
+
content: [{ type: 'text', text: JSON.stringify({ milestones, pageInfo }, null, 2) }],
|
|
78
|
+
details: { milestones, pageInfo },
|
|
77
79
|
};
|
|
78
80
|
});
|
|
79
81
|
},
|
|
@@ -1,9 +1,9 @@
|
|
|
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, RawInputParam } from '../params';
|
|
4
|
+
import { PaginationParams, paginationVariables, FilterParam, RawInputParam } from '../params';
|
|
5
5
|
import { PROJECT_LABEL_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
6
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
7
|
import { compactObject, asObject, asString } from '../util';
|
|
8
8
|
import {
|
|
9
9
|
renderLinearCreateProjectLabelCall,
|
|
@@ -29,17 +29,12 @@ export function projectLabelTools() {
|
|
|
29
29
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
30
30
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
31
31
|
const variables = compactObject({
|
|
32
|
-
|
|
33
|
-
before: params.before,
|
|
32
|
+
...paginationVariables(params, 50),
|
|
34
33
|
filter: asObject(params.filter),
|
|
35
|
-
first: params.first ?? 50,
|
|
36
|
-
includeArchived: params.includeArchived,
|
|
37
|
-
last: params.last,
|
|
38
|
-
orderBy: params.orderBy,
|
|
39
34
|
});
|
|
40
35
|
|
|
41
36
|
const data = await linearGraphQL<{
|
|
42
|
-
projectLabels:
|
|
37
|
+
projectLabels: LinearConnection<JsonObject>;
|
|
43
38
|
}>(
|
|
44
39
|
apiKey,
|
|
45
40
|
`query ListProjectLabels(
|
|
@@ -63,6 +58,12 @@ export function projectLabelTools() {
|
|
|
63
58
|
nodes {
|
|
64
59
|
${PROJECT_LABEL_SELECTION}
|
|
65
60
|
}
|
|
61
|
+
pageInfo {
|
|
62
|
+
hasNextPage
|
|
63
|
+
hasPreviousPage
|
|
64
|
+
startCursor
|
|
65
|
+
endCursor
|
|
66
|
+
}
|
|
66
67
|
}
|
|
67
68
|
}`,
|
|
68
69
|
variables,
|
|
@@ -70,9 +71,10 @@ export function projectLabelTools() {
|
|
|
70
71
|
);
|
|
71
72
|
|
|
72
73
|
const labels = data.projectLabels.nodes;
|
|
74
|
+
const pageInfo = data.projectLabels.pageInfo;
|
|
73
75
|
return {
|
|
74
|
-
content: [{ type: 'text', text: JSON.stringify({ labels }, null, 2) }],
|
|
75
|
-
details: { labels },
|
|
76
|
+
content: [{ type: 'text', text: JSON.stringify({ labels, pageInfo }, null, 2) }],
|
|
77
|
+
details: { labels, pageInfo },
|
|
76
78
|
};
|
|
77
79
|
});
|
|
78
80
|
},
|
|
@@ -1,9 +1,9 @@
|
|
|
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 } from '../params';
|
|
4
|
+
import { PaginationParams, paginationVariables } from '../params';
|
|
5
5
|
import { PROJECT_RELATION_SELECTION } from '../selections';
|
|
6
|
-
import type { JsonObject } from '../types';
|
|
6
|
+
import type { JsonObject, LinearConnection } from '../types';
|
|
7
7
|
import { compactObject } from '../util';
|
|
8
8
|
import {
|
|
9
9
|
renderLinearCreateProjectRelationCall,
|
|
@@ -27,17 +27,10 @@ export function projectRelationTools() {
|
|
|
27
27
|
renderCall: renderLinearProjectRelationListCall,
|
|
28
28
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
29
29
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
30
|
-
const variables =
|
|
31
|
-
after: params.after,
|
|
32
|
-
before: params.before,
|
|
33
|
-
first: params.first ?? 20,
|
|
34
|
-
includeArchived: params.includeArchived,
|
|
35
|
-
last: params.last,
|
|
36
|
-
orderBy: params.orderBy,
|
|
37
|
-
});
|
|
30
|
+
const variables = paginationVariables(params, 20);
|
|
38
31
|
|
|
39
32
|
const data = await linearGraphQL<{
|
|
40
|
-
projectRelations:
|
|
33
|
+
projectRelations: LinearConnection<JsonObject>;
|
|
41
34
|
}>(
|
|
42
35
|
apiKey,
|
|
43
36
|
`query ListProjectRelations(
|
|
@@ -59,6 +52,12 @@ export function projectRelationTools() {
|
|
|
59
52
|
nodes {
|
|
60
53
|
${PROJECT_RELATION_SELECTION}
|
|
61
54
|
}
|
|
55
|
+
pageInfo {
|
|
56
|
+
hasNextPage
|
|
57
|
+
hasPreviousPage
|
|
58
|
+
startCursor
|
|
59
|
+
endCursor
|
|
60
|
+
}
|
|
62
61
|
}
|
|
63
62
|
}`,
|
|
64
63
|
variables,
|
|
@@ -66,9 +65,12 @@ export function projectRelationTools() {
|
|
|
66
65
|
);
|
|
67
66
|
|
|
68
67
|
const projectRelations = data.projectRelations.nodes;
|
|
68
|
+
const pageInfo = data.projectRelations.pageInfo;
|
|
69
69
|
return {
|
|
70
|
-
content: [
|
|
71
|
-
|
|
70
|
+
content: [
|
|
71
|
+
{ type: 'text', text: JSON.stringify({ projectRelations, pageInfo }, null, 2) },
|
|
72
|
+
],
|
|
73
|
+
details: { projectRelations, pageInfo },
|
|
72
74
|
};
|
|
73
75
|
});
|
|
74
76
|
},
|
|
@@ -1,9 +1,15 @@
|
|
|
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';
|
|
8
14
|
import {
|
|
9
15
|
renderLinearArchiveProjectCall,
|
|
@@ -33,18 +39,13 @@ export function projectTools() {
|
|
|
33
39
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
34
40
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
35
41
|
const variables = compactObject({
|
|
36
|
-
|
|
37
|
-
before: params.before,
|
|
42
|
+
...paginationVariables(params, 20),
|
|
38
43
|
filter: asObject(params.filter),
|
|
39
|
-
first: params.first ?? 20,
|
|
40
|
-
includeArchived: params.includeArchived,
|
|
41
|
-
last: params.last,
|
|
42
|
-
orderBy: params.orderBy,
|
|
43
44
|
sort: asObjectArray(params.sort),
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
const data = await linearGraphQL<{
|
|
47
|
-
projects:
|
|
48
|
+
projects: LinearConnection<JsonObject>;
|
|
48
49
|
}>(
|
|
49
50
|
apiKey,
|
|
50
51
|
`query ListProjects(
|
|
@@ -68,7 +69,13 @@ export function projectTools() {
|
|
|
68
69
|
sort: $sort
|
|
69
70
|
) {
|
|
70
71
|
nodes {
|
|
71
|
-
${
|
|
72
|
+
${PROJECT_LIST_SELECTION}
|
|
73
|
+
}
|
|
74
|
+
pageInfo {
|
|
75
|
+
hasNextPage
|
|
76
|
+
hasPreviousPage
|
|
77
|
+
startCursor
|
|
78
|
+
endCursor
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
}`,
|
|
@@ -77,9 +84,10 @@ export function projectTools() {
|
|
|
77
84
|
);
|
|
78
85
|
|
|
79
86
|
const projects = data.projects.nodes;
|
|
87
|
+
const pageInfo = data.projects.pageInfo;
|
|
80
88
|
return {
|
|
81
|
-
content: [{ type: 'text', text: JSON.stringify({ projects }, null, 2) }],
|
|
82
|
-
details: { projects },
|
|
89
|
+
content: [{ type: 'text', text: JSON.stringify({ projects, pageInfo }, null, 2) }],
|
|
90
|
+
details: { projects, pageInfo },
|
|
83
91
|
};
|
|
84
92
|
});
|
|
85
93
|
},
|
|
@@ -99,7 +107,7 @@ export function projectTools() {
|
|
|
99
107
|
apiKey,
|
|
100
108
|
`query GetProject($id: String!) {
|
|
101
109
|
project(id: $id) {
|
|
102
|
-
${
|
|
110
|
+
${PROJECT_DETAIL_SELECTION}
|
|
103
111
|
}
|
|
104
112
|
}`,
|
|
105
113
|
{ id: params.projectId },
|
|
@@ -220,7 +228,7 @@ export function projectTools() {
|
|
|
220
228
|
projectUpdate(id: $id, input: $input) {
|
|
221
229
|
success
|
|
222
230
|
project {
|
|
223
|
-
${
|
|
231
|
+
${PROJECT_DETAIL_SELECTION}
|
|
224
232
|
}
|
|
225
233
|
}
|
|
226
234
|
}`,
|
|
@@ -255,7 +263,7 @@ export function projectTools() {
|
|
|
255
263
|
projectCreate(input: $input, slackChannelName: $slackChannelName) {
|
|
256
264
|
success
|
|
257
265
|
project {
|
|
258
|
-
${
|
|
266
|
+
${PROJECT_DETAIL_SELECTION}
|
|
259
267
|
}
|
|
260
268
|
}
|
|
261
269
|
}`,
|
|
@@ -1,9 +1,9 @@
|
|
|
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
8
|
import {
|
|
9
9
|
renderLinearGetTeamCall,
|
|
@@ -27,16 +27,11 @@ export function teamTools() {
|
|
|
27
27
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
28
28
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
29
29
|
const variables = compactObject({
|
|
30
|
-
|
|
31
|
-
before: params.before,
|
|
30
|
+
...paginationVariables(params, 50),
|
|
32
31
|
filter: asObject(params.filter),
|
|
33
|
-
first: params.first,
|
|
34
|
-
includeArchived: params.includeArchived,
|
|
35
|
-
last: params.last,
|
|
36
|
-
orderBy: params.orderBy,
|
|
37
32
|
});
|
|
38
33
|
|
|
39
|
-
const data = await linearGraphQL<{ teams:
|
|
34
|
+
const data = await linearGraphQL<{ teams: LinearConnection<LinearTeam> }>(
|
|
40
35
|
apiKey,
|
|
41
36
|
`query ListTeams(
|
|
42
37
|
$after: String
|
|
@@ -66,6 +61,12 @@ export function teamTools() {
|
|
|
66
61
|
}
|
|
67
62
|
}
|
|
68
63
|
}
|
|
64
|
+
pageInfo {
|
|
65
|
+
hasNextPage
|
|
66
|
+
hasPreviousPage
|
|
67
|
+
startCursor
|
|
68
|
+
endCursor
|
|
69
|
+
}
|
|
69
70
|
}
|
|
70
71
|
}`,
|
|
71
72
|
variables,
|
|
@@ -73,9 +74,10 @@ export function teamTools() {
|
|
|
73
74
|
);
|
|
74
75
|
|
|
75
76
|
const teams = data.teams.nodes;
|
|
77
|
+
const pageInfo = data.teams.pageInfo;
|
|
76
78
|
return {
|
|
77
|
-
content: [{ type: 'text', text: JSON.stringify({ teams }, null, 2) }],
|
|
78
|
-
details: { teams },
|
|
79
|
+
content: [{ type: 'text', text: JSON.stringify({ teams, pageInfo }, null, 2) }],
|
|
80
|
+
details: { teams, pageInfo },
|
|
79
81
|
};
|
|
80
82
|
});
|
|
81
83
|
},
|
|
@@ -1,9 +1,9 @@
|
|
|
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
8
|
import {
|
|
9
9
|
renderLinearGetUserCall,
|
|
@@ -28,19 +28,14 @@ export function userTools() {
|
|
|
28
28
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
29
29
|
return withLinearAuth(ctx, signal, async (apiKey) => {
|
|
30
30
|
const variables = compactObject({
|
|
31
|
-
|
|
32
|
-
before: params.before,
|
|
31
|
+
...paginationVariables(params, 50),
|
|
33
32
|
filter: asObject(params.filter),
|
|
34
|
-
first: params.first ?? 50,
|
|
35
|
-
includeArchived: params.includeArchived,
|
|
36
33
|
includeDisabled: params.includeDisabled,
|
|
37
|
-
last: params.last,
|
|
38
|
-
orderBy: params.orderBy,
|
|
39
34
|
sort: asObjectArray(params.sort),
|
|
40
35
|
});
|
|
41
36
|
|
|
42
37
|
const data = await linearGraphQL<{
|
|
43
|
-
users:
|
|
38
|
+
users: LinearConnection<JsonObject>;
|
|
44
39
|
}>(
|
|
45
40
|
apiKey,
|
|
46
41
|
`query ListUsers(
|
|
@@ -68,6 +63,12 @@ export function userTools() {
|
|
|
68
63
|
nodes {
|
|
69
64
|
${USER_SELECTION}
|
|
70
65
|
}
|
|
66
|
+
pageInfo {
|
|
67
|
+
hasNextPage
|
|
68
|
+
hasPreviousPage
|
|
69
|
+
startCursor
|
|
70
|
+
endCursor
|
|
71
|
+
}
|
|
71
72
|
}
|
|
72
73
|
}`,
|
|
73
74
|
variables,
|
|
@@ -75,9 +76,10 @@ export function userTools() {
|
|
|
75
76
|
);
|
|
76
77
|
|
|
77
78
|
const users = data.users.nodes;
|
|
79
|
+
const pageInfo = data.users.pageInfo;
|
|
78
80
|
return {
|
|
79
|
-
content: [{ type: 'text', text: JSON.stringify({ users }, null, 2) }],
|
|
80
|
-
details: { users },
|
|
81
|
+
content: [{ type: 'text', text: JSON.stringify({ users, pageInfo }, null, 2) }],
|
|
82
|
+
details: { users, pageInfo },
|
|
81
83
|
};
|
|
82
84
|
});
|
|
83
85
|
},
|
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;
|