@sentry/junior-linear 0.122.0 → 0.122.1
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 +1 -1
- package/dist/index.js +21 -236
- package/dist/plugin.d.ts +1 -1
- package/package.json +2 -2
- package/skills/linear/SKILL.md +1 -2
- package/skills/linear/references/api-surface.md +2 -2
- package/dist/tools/create-issue.d.ts +0 -67
- package/dist/tools/update-issue.d.ts +0 -47
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ export const plugins = defineJuniorPlugins([linearPlugin()]);
|
|
|
19
19
|
|
|
20
20
|
This package does not require a shared `LINEAR_API_KEY` or a custom OAuth app for the default setup. Each user connects their own Linear account the first time Junior calls a Linear MCP tool. Junior sends the authorization link privately and resumes the same Slack thread automatically after the user authorizes.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Linear operations use Linear's hosted MCP tools directly. When an issue is created through that path, Junior links it to the current conversation.
|
|
23
23
|
|
|
24
24
|
Optional: set channel defaults when a Slack thread usually routes work to the same Linear destination:
|
|
25
25
|
|
package/dist/index.js
CHANGED
|
@@ -2,245 +2,36 @@
|
|
|
2
2
|
import {
|
|
3
3
|
defineJuniorPlugin
|
|
4
4
|
} from "@sentry/junior-plugin-api";
|
|
5
|
-
|
|
6
|
-
// src/tools/create-issue.ts
|
|
7
|
-
import {
|
|
8
|
-
definePluginTool,
|
|
9
|
-
pluginToolResultSchema
|
|
10
|
-
} from "@sentry/junior-plugin-api";
|
|
11
5
|
import { z } from "zod";
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
id: z.string().optional(),
|
|
21
|
-
identifier: z.string().optional(),
|
|
22
|
-
title: z.string().optional(),
|
|
23
|
-
url: z.string().url().optional()
|
|
24
|
-
}).strict();
|
|
25
|
-
var outputSchema = pluginToolResultSchema.extend({
|
|
26
|
-
ok: z.literal(true),
|
|
27
|
-
status: z.literal("success"),
|
|
28
|
-
target: z.literal("createIssue"),
|
|
29
|
-
data: z.object({
|
|
30
|
-
issue: issueSchema.nullable()
|
|
31
|
-
}),
|
|
32
|
-
issue: issueSchema.nullable()
|
|
33
|
-
});
|
|
34
|
-
function collectObjects(value, objects) {
|
|
35
|
-
if (!value || typeof value !== "object") {
|
|
6
|
+
var saveIssueResultSchema = z.object({
|
|
7
|
+
issue: z.object({
|
|
8
|
+
identifier: z.string().trim().min(1),
|
|
9
|
+
url: z.url()
|
|
10
|
+
}).passthrough()
|
|
11
|
+
}).passthrough();
|
|
12
|
+
async function annotateCreatedIssue(ctx) {
|
|
13
|
+
if (ctx.tool.name !== "save_issue" || ctx.tool.arguments.id !== void 0) {
|
|
36
14
|
return;
|
|
37
15
|
}
|
|
38
|
-
if (
|
|
39
|
-
for (const item of value) collectObjects(item, objects);
|
|
16
|
+
if (!ctx.annotations) {
|
|
40
17
|
return;
|
|
41
18
|
}
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
for (const object of objects) {
|
|
48
|
-
const value = object[field];
|
|
49
|
-
if (typeof value === "string" && value.trim()) return value.trim();
|
|
50
|
-
}
|
|
51
|
-
return void 0;
|
|
52
|
-
}
|
|
53
|
-
function parseJsonText(text) {
|
|
54
|
-
try {
|
|
55
|
-
return JSON.parse(text);
|
|
56
|
-
} catch {
|
|
57
|
-
return void 0;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
function extractIssue(result) {
|
|
61
|
-
const objects = [];
|
|
62
|
-
collectObjects(result.structuredContent, objects);
|
|
63
|
-
const textParts = result.content.flatMap(
|
|
64
|
-
(part) => part.type === "text" ? [part.text] : []
|
|
65
|
-
);
|
|
66
|
-
for (const text of textParts) {
|
|
67
|
-
collectObjects(parseJsonText(text), objects);
|
|
68
|
-
}
|
|
69
|
-
const urlMatch = textParts.map(
|
|
70
|
-
(text) => text.match(
|
|
71
|
-
/https:\/\/linear\.app\/[^\s<>)"']+\/issue\/([A-Z][A-Z0-9]*-\d+)[^\s<>)"']*/i
|
|
72
|
-
)
|
|
73
|
-
).find((match) => match !== null);
|
|
74
|
-
const identifierMatch = textParts.map((text) => text.match(/\b[A-Z][A-Z0-9]*-\d+\b/)).find((match) => match !== null);
|
|
75
|
-
const issue = {
|
|
76
|
-
id: stringField(objects, "id"),
|
|
77
|
-
identifier: stringField(objects, "identifier") ?? urlMatch?.[1]?.toUpperCase() ?? identifierMatch?.[0],
|
|
78
|
-
title: stringField(objects, "title"),
|
|
79
|
-
url: stringField(objects, "url") ?? urlMatch?.[0]
|
|
80
|
-
};
|
|
81
|
-
const parsed = issueSchema.safeParse(
|
|
82
|
-
Object.fromEntries(
|
|
83
|
-
Object.entries(issue).filter((entry) => entry[1] !== void 0)
|
|
84
|
-
)
|
|
85
|
-
);
|
|
86
|
-
if (!parsed.success || Object.keys(parsed.data).length === 0) {
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
return parsed.data;
|
|
90
|
-
}
|
|
91
|
-
function toolResult(issue, content) {
|
|
92
|
-
const data = { issue };
|
|
93
|
-
return {
|
|
94
|
-
content,
|
|
95
|
-
details: {
|
|
96
|
-
ok: true,
|
|
97
|
-
status: "success",
|
|
98
|
-
target: "createIssue",
|
|
99
|
-
data,
|
|
100
|
-
...data
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
function authorizationPendingResult() {
|
|
105
|
-
return toolResult(null, [{ type: "text", text: "Authorization pending." }]);
|
|
106
|
-
}
|
|
107
|
-
async function annotateIssue(ctx, issue) {
|
|
108
|
-
if (!issue?.identifier || !issue.url) {
|
|
19
|
+
const result = saveIssueResultSchema.safeParse(ctx.result.structuredContent);
|
|
20
|
+
if (!result.success) {
|
|
21
|
+
ctx.log.warn("linear.issue_annotation.skipped", {
|
|
22
|
+
"app.reason": "unexpected_save_response"
|
|
23
|
+
});
|
|
109
24
|
return;
|
|
110
25
|
}
|
|
111
|
-
|
|
26
|
+
const identifier = result.data.issue.identifier.toUpperCase();
|
|
27
|
+
await ctx.annotations.upsert({
|
|
112
28
|
kind: "resource_link",
|
|
113
|
-
key:
|
|
114
|
-
label:
|
|
115
|
-
url: issue.url,
|
|
29
|
+
key: identifier,
|
|
30
|
+
label: identifier,
|
|
31
|
+
url: result.data.issue.url,
|
|
116
32
|
status: "open"
|
|
117
33
|
});
|
|
118
34
|
}
|
|
119
|
-
function createLinearIssueTool(ctx) {
|
|
120
|
-
return definePluginTool({
|
|
121
|
-
description: "Create a Linear issue through Linear's hosted MCP provider and link the created issue to the current Junior conversation.",
|
|
122
|
-
inputSchema,
|
|
123
|
-
outputSchema,
|
|
124
|
-
annotations: {
|
|
125
|
-
destructiveHint: false,
|
|
126
|
-
idempotentHint: false,
|
|
127
|
-
openWorldHint: true,
|
|
128
|
-
readOnlyHint: false,
|
|
129
|
-
title: "Create Linear issue"
|
|
130
|
-
},
|
|
131
|
-
describeProposal(input) {
|
|
132
|
-
return `Create a Linear issue in ${input.team}: ${input.title}`;
|
|
133
|
-
},
|
|
134
|
-
async execute(input, options) {
|
|
135
|
-
const mcp = ctx.mcp;
|
|
136
|
-
if (!mcp) {
|
|
137
|
-
throw new Error("Linear MCP provider is unavailable.");
|
|
138
|
-
}
|
|
139
|
-
const result = await mcp.callTool({
|
|
140
|
-
name: "save_issue",
|
|
141
|
-
arguments: input,
|
|
142
|
-
toolCallId: options.toolCallId
|
|
143
|
-
});
|
|
144
|
-
if (result.status === "authorization_pending") {
|
|
145
|
-
return authorizationPendingResult();
|
|
146
|
-
}
|
|
147
|
-
if (result.status === "error") {
|
|
148
|
-
throw new Error(result.message);
|
|
149
|
-
}
|
|
150
|
-
const issue = extractIssue(result);
|
|
151
|
-
await annotateIssue(ctx, issue);
|
|
152
|
-
return toolResult(issue, result.content);
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// src/tools/update-issue.ts
|
|
158
|
-
import {
|
|
159
|
-
definePluginTool as definePluginTool2,
|
|
160
|
-
pluginToolResultSchema as pluginToolResultSchema2
|
|
161
|
-
} from "@sentry/junior-plugin-api";
|
|
162
|
-
import { z as z2 } from "zod";
|
|
163
|
-
var nullableName = (description) => z2.string().trim().min(1).nullable().describe(description).optional();
|
|
164
|
-
var inputSchema2 = z2.object({
|
|
165
|
-
id: z2.string().trim().min(1).describe("Linear issue identifier or ID to update."),
|
|
166
|
-
assignee: nullableName(
|
|
167
|
-
'Assignee name, email, identifier, or "me". Use null to clear.'
|
|
168
|
-
),
|
|
169
|
-
cycle: nullableName("Cycle name or identifier. Use null to clear."),
|
|
170
|
-
description: z2.string().nullable().describe("Issue description. Use null to clear.").optional(),
|
|
171
|
-
estimate: z2.number().nonnegative().nullable().describe("Issue estimate. Use null to clear.").optional(),
|
|
172
|
-
labels: z2.array(z2.string().trim().min(1)).describe("Complete set of issue label names or identifiers.").optional(),
|
|
173
|
-
priority: z2.enum(["low", "medium", "high", "urgent"]).nullable().describe("Linear priority. Use null to clear.").optional(),
|
|
174
|
-
project: nullableName("Project name or identifier. Use null to clear."),
|
|
175
|
-
state: z2.string().trim().min(1).describe("Workflow state name or identifier.").optional(),
|
|
176
|
-
team: z2.string().trim().min(1).describe("Team name or identifier.").optional(),
|
|
177
|
-
title: z2.string().trim().min(1).max(60).describe("Issue title.").optional()
|
|
178
|
-
}).strict().superRefine((input, ctx) => {
|
|
179
|
-
if (Object.keys(input).every((key) => key === "id")) {
|
|
180
|
-
ctx.addIssue({
|
|
181
|
-
code: "custom",
|
|
182
|
-
message: "At least one issue field must be provided."
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
var outputSchema2 = pluginToolResultSchema2.extend({
|
|
187
|
-
ok: z2.literal(true),
|
|
188
|
-
status: z2.literal("success"),
|
|
189
|
-
target: z2.literal("updateIssue")
|
|
190
|
-
});
|
|
191
|
-
function toolResult2(content) {
|
|
192
|
-
return {
|
|
193
|
-
content,
|
|
194
|
-
details: {
|
|
195
|
-
ok: true,
|
|
196
|
-
status: "success",
|
|
197
|
-
target: "updateIssue"
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
function authorizationPendingResult2() {
|
|
202
|
-
return toolResult2([{ type: "text", text: "Authorization pending." }]);
|
|
203
|
-
}
|
|
204
|
-
function createLinearUpdateIssueTool(ctx) {
|
|
205
|
-
return definePluginTool2({
|
|
206
|
-
description: "Update an existing Linear issue through Linear's hosted MCP provider. Fetch the issue first when a change could overwrite existing fields.",
|
|
207
|
-
inputSchema: inputSchema2,
|
|
208
|
-
outputSchema: outputSchema2,
|
|
209
|
-
annotations: {
|
|
210
|
-
destructiveHint: false,
|
|
211
|
-
idempotentHint: true,
|
|
212
|
-
openWorldHint: true,
|
|
213
|
-
readOnlyHint: false,
|
|
214
|
-
title: "Update Linear issue"
|
|
215
|
-
},
|
|
216
|
-
describeProposal(input) {
|
|
217
|
-
return `Update Linear issue ${input.id}`;
|
|
218
|
-
},
|
|
219
|
-
async execute(input, options) {
|
|
220
|
-
const mcp = ctx.mcp;
|
|
221
|
-
if (!mcp) {
|
|
222
|
-
throw new Error("Linear MCP provider is unavailable.");
|
|
223
|
-
}
|
|
224
|
-
if (await mcp.prepare() === "authorization_pending") {
|
|
225
|
-
return authorizationPendingResult2();
|
|
226
|
-
}
|
|
227
|
-
const result = await mcp.callTool({
|
|
228
|
-
name: "save_issue",
|
|
229
|
-
arguments: input,
|
|
230
|
-
toolCallId: options.toolCallId
|
|
231
|
-
});
|
|
232
|
-
if (result.status === "authorization_pending") {
|
|
233
|
-
return authorizationPendingResult2();
|
|
234
|
-
}
|
|
235
|
-
if (result.status === "error") {
|
|
236
|
-
throw new Error(result.message);
|
|
237
|
-
}
|
|
238
|
-
return toolResult2(result.content);
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// src/plugin.ts
|
|
244
35
|
function linearPlugin() {
|
|
245
36
|
return defineJuniorPlugin({
|
|
246
37
|
packageName: "@sentry/junior-linear",
|
|
@@ -250,18 +41,12 @@ function linearPlugin() {
|
|
|
250
41
|
displayName: "Linear",
|
|
251
42
|
mcp: {
|
|
252
43
|
transport: "http",
|
|
253
|
-
url: "https://mcp.linear.app/mcp"
|
|
254
|
-
wrappedTools: ["save_issue"]
|
|
44
|
+
url: "https://mcp.linear.app/mcp"
|
|
255
45
|
},
|
|
256
46
|
name: "linear"
|
|
257
47
|
},
|
|
258
48
|
hooks: {
|
|
259
|
-
|
|
260
|
-
return {
|
|
261
|
-
createIssue: createLinearIssueTool(ctx),
|
|
262
|
-
updateIssue: createLinearUpdateIssueTool(ctx)
|
|
263
|
-
};
|
|
264
|
-
}
|
|
49
|
+
afterMcpTool: annotateCreatedIssue
|
|
265
50
|
}
|
|
266
51
|
});
|
|
267
52
|
}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type PluginRegistration } from "@sentry/junior-plugin-api";
|
|
2
|
-
/** Register Linear's hosted MCP provider and
|
|
2
|
+
/** Register Linear's hosted MCP provider and conversation-link side effects. */
|
|
3
3
|
export declare function linearPlugin(): PluginRegistration;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-linear",
|
|
3
|
-
"version": "0.122.
|
|
3
|
+
"version": "0.122.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"zod": "^4.4.3",
|
|
26
|
-
"@sentry/junior-plugin-api": "0.122.
|
|
26
|
+
"@sentry/junior-plugin-api": "0.122.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^25.9.1",
|
package/skills/linear/SKILL.md
CHANGED
|
@@ -67,8 +67,7 @@ If any gate fails, revise and re-check before calling the Linear create/update t
|
|
|
67
67
|
|
|
68
68
|
6. Execute:
|
|
69
69
|
|
|
70
|
-
- Create
|
|
71
|
-
- Update existing issues with `linear_updateIssue`.
|
|
70
|
+
- Create or update issues with Linear's live hosted MCP tools. Discover the current create/update tool and copy only fields justified by its live schema.
|
|
72
71
|
- For updates, prefer partial changes over full rewrites. Fetch current issue state first if the mutation could overwrite structured fields or duplicate an existing comment.
|
|
73
72
|
- Check for duplicates silently before creating a new issue when the request appears related to existing work.
|
|
74
73
|
|
|
@@ -21,8 +21,8 @@ The current public docs describe support for finding, creating, and updating obj
|
|
|
21
21
|
| Intent | Minimum tool pattern |
|
|
22
22
|
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
23
23
|
| Inspect an issue | Resolve the issue by key, URL, or search query, then fetch current state before answering. |
|
|
24
|
-
| Create an issue | Confirm the team first, then create the
|
|
25
|
-
| Update fields | Fetch current issue state first, then mutate only the requested fields. |
|
|
24
|
+
| Create an issue | Confirm the team first, then create via the live hosted MCP tools with grounded title/body content and only fields justified by the current schema. |
|
|
25
|
+
| Update fields | Fetch current issue state first, then mutate via the live hosted MCP tools with only the requested fields. |
|
|
26
26
|
| Add a comment | Resolve the exact issue first, then add a concise comment with durable links and next steps. |
|
|
27
27
|
| Move state or assign | Read the current issue and team workflow first when state, workflow, or assignee ambiguity could cause the wrong mutation. |
|
|
28
28
|
| Check for duplicates | Search for an existing matching issue before opening a new one when the request appears related to ongoing work. |
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { type PluginToolResultEnvelope, type ToolRegistrationHookContext } from "@sentry/junior-plugin-api";
|
|
2
|
-
/** Create a Linear issue through the hosted MCP provider and link it to the conversation. */
|
|
3
|
-
export declare function createLinearIssueTool(ctx: ToolRegistrationHookContext): import("@sentry/junior-plugin-api").PluginToolDefinition<{
|
|
4
|
-
team: string;
|
|
5
|
-
title: string;
|
|
6
|
-
description?: string | undefined;
|
|
7
|
-
priority?: "low" | "medium" | "high" | "urgent" | undefined;
|
|
8
|
-
project?: string | undefined;
|
|
9
|
-
}, {
|
|
10
|
-
[x: string]: unknown;
|
|
11
|
-
ok: true;
|
|
12
|
-
status: "success";
|
|
13
|
-
target: "createIssue";
|
|
14
|
-
data: {
|
|
15
|
-
issue: {
|
|
16
|
-
id?: string | undefined;
|
|
17
|
-
identifier?: string | undefined;
|
|
18
|
-
title?: string | undefined;
|
|
19
|
-
url?: string | undefined;
|
|
20
|
-
} | null;
|
|
21
|
-
};
|
|
22
|
-
issue: {
|
|
23
|
-
id?: string | undefined;
|
|
24
|
-
identifier?: string | undefined;
|
|
25
|
-
title?: string | undefined;
|
|
26
|
-
url?: string | undefined;
|
|
27
|
-
} | null;
|
|
28
|
-
truncated?: boolean | undefined;
|
|
29
|
-
continuation?: {
|
|
30
|
-
arguments: Record<string, unknown>;
|
|
31
|
-
reason?: string | undefined;
|
|
32
|
-
} | undefined;
|
|
33
|
-
error?: string | {
|
|
34
|
-
kind: string;
|
|
35
|
-
message: string;
|
|
36
|
-
retryable?: boolean | undefined;
|
|
37
|
-
} | undefined;
|
|
38
|
-
}, PluginToolResultEnvelope<{
|
|
39
|
-
[x: string]: unknown;
|
|
40
|
-
ok: true;
|
|
41
|
-
status: "success";
|
|
42
|
-
target: "createIssue";
|
|
43
|
-
data: {
|
|
44
|
-
issue: {
|
|
45
|
-
id?: string | undefined;
|
|
46
|
-
identifier?: string | undefined;
|
|
47
|
-
title?: string | undefined;
|
|
48
|
-
url?: string | undefined;
|
|
49
|
-
} | null;
|
|
50
|
-
};
|
|
51
|
-
issue: {
|
|
52
|
-
id?: string | undefined;
|
|
53
|
-
identifier?: string | undefined;
|
|
54
|
-
title?: string | undefined;
|
|
55
|
-
url?: string | undefined;
|
|
56
|
-
} | null;
|
|
57
|
-
truncated?: boolean | undefined;
|
|
58
|
-
continuation?: {
|
|
59
|
-
arguments: Record<string, unknown>;
|
|
60
|
-
reason?: string | undefined;
|
|
61
|
-
} | undefined;
|
|
62
|
-
error?: string | {
|
|
63
|
-
kind: string;
|
|
64
|
-
message: string;
|
|
65
|
-
retryable?: boolean | undefined;
|
|
66
|
-
} | undefined;
|
|
67
|
-
}>>;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { type PluginToolResultEnvelope, type ToolRegistrationHookContext } from "@sentry/junior-plugin-api";
|
|
2
|
-
/** Update a Linear issue through the hosted MCP provider. */
|
|
3
|
-
export declare function createLinearUpdateIssueTool(ctx: ToolRegistrationHookContext): import("@sentry/junior-plugin-api").PluginToolDefinition<{
|
|
4
|
-
id: string;
|
|
5
|
-
assignee?: string | null | undefined;
|
|
6
|
-
cycle?: string | null | undefined;
|
|
7
|
-
description?: string | null | undefined;
|
|
8
|
-
estimate?: number | null | undefined;
|
|
9
|
-
labels?: string[] | undefined;
|
|
10
|
-
priority?: "low" | "medium" | "high" | "urgent" | null | undefined;
|
|
11
|
-
project?: string | null | undefined;
|
|
12
|
-
state?: string | undefined;
|
|
13
|
-
team?: string | undefined;
|
|
14
|
-
title?: string | undefined;
|
|
15
|
-
}, {
|
|
16
|
-
[x: string]: unknown;
|
|
17
|
-
ok: true;
|
|
18
|
-
status: "success";
|
|
19
|
-
target: "updateIssue";
|
|
20
|
-
data?: unknown;
|
|
21
|
-
truncated?: boolean | undefined;
|
|
22
|
-
continuation?: {
|
|
23
|
-
arguments: Record<string, unknown>;
|
|
24
|
-
reason?: string | undefined;
|
|
25
|
-
} | undefined;
|
|
26
|
-
error?: string | {
|
|
27
|
-
kind: string;
|
|
28
|
-
message: string;
|
|
29
|
-
retryable?: boolean | undefined;
|
|
30
|
-
} | undefined;
|
|
31
|
-
}, PluginToolResultEnvelope<{
|
|
32
|
-
[x: string]: unknown;
|
|
33
|
-
ok: true;
|
|
34
|
-
status: "success";
|
|
35
|
-
target: "updateIssue";
|
|
36
|
-
data?: unknown;
|
|
37
|
-
truncated?: boolean | undefined;
|
|
38
|
-
continuation?: {
|
|
39
|
-
arguments: Record<string, unknown>;
|
|
40
|
-
reason?: string | undefined;
|
|
41
|
-
} | undefined;
|
|
42
|
-
error?: string | {
|
|
43
|
-
kind: string;
|
|
44
|
-
message: string;
|
|
45
|
-
retryable?: boolean | undefined;
|
|
46
|
-
} | undefined;
|
|
47
|
-
}>>;
|