linear-sdk-cli 0.1.3 → 0.2.3
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +96 -58
- package/COVERAGE.md +5 -5
- package/MIGRATING.md +71 -69
- package/README.md +115 -90
- package/package.json +6 -7
- package/skills/README.md +15 -0
- package/skills/linear-sdk-cli/SKILL.md +27 -3
- package/skills/linear-sdk-cli/references/api.md +9 -9
- package/skills/linear-sdk-cli/references/auth.md +18 -0
- package/skills/linear-sdk-cli/references/commands.md +2 -2
- package/skills/linear-sdk-cli/references/comment.md +9 -6
- package/skills/linear-sdk-cli/references/config.md +9 -11
- package/skills/linear-sdk-cli/references/issue.md +72 -18
- package/skills/linear-sdk-cli/references/open.md +29 -0
- package/skills/linear-sdk-cli/references/team.md +16 -0
- package/skills/linear-sdk-cli/scripts/generate-docs.ts +6 -2
- package/skills/linear-sdk-cli-maintenance/SKILL.md +97 -0
- package/src/bin/linear.ts +16 -6
- package/src/cli.ts +3 -1
- package/src/commands/agent-session.ts +13 -5
- package/src/commands/api.ts +15 -9
- package/src/commands/attach.ts +15 -4
- package/src/commands/comment.ts +50 -11
- package/src/commands/completion.ts +2 -6
- package/src/commands/cycle.ts +6 -1
- package/src/commands/discover.ts +6 -2
- package/src/commands/document.ts +4 -1
- package/src/commands/initiative.ts +5 -1
- package/src/commands/issue.ts +392 -91
- package/src/commands/meta.ts +139 -31
- package/src/commands/milestone.ts +4 -1
- package/src/commands/notification.ts +15 -6
- package/src/commands/open.ts +84 -0
- package/src/commands/project.ts +17 -4
- package/src/commands/team.ts +13 -0
- package/src/commands/user.ts +2 -2
- package/src/commands/webhook.ts +12 -2
- package/src/config.ts +501 -184
- package/src/context.ts +13 -4
- package/src/git.ts +28 -3
- package/src/lib/body.ts +26 -2
- package/src/lib/errors.ts +33 -8
- package/src/lib/introspect.ts +76 -7
- package/src/lib/keyring.ts +51 -9
- package/src/lib/mentions.ts +49 -0
- package/src/lib/open.ts +32 -0
- package/src/lib/options.ts +108 -12
- package/src/lib/output-shapes.ts +81 -9
- package/src/lib/pagination.ts +50 -17
- package/src/lib/resolve.ts +40 -7
- package/src/lib/shape.ts +16 -12
- package/src/lib/upload.ts +3 -1
- package/src/output/color.ts +52 -0
- package/src/output/format.ts +96 -18
- package/src/output/markdown.ts +133 -0
- package/src/output/pager.ts +131 -0
- package/src/output/sanitize.ts +1 -1
- package/src/output/table.ts +7 -7
- package/src/services/agent-session.ts +11 -3
- package/src/services/attachment.ts +14 -5
- package/src/services/comment.ts +37 -9
- package/src/services/cycle.ts +11 -4
- package/src/services/document.ts +29 -10
- package/src/services/favorite.ts +15 -9
- package/src/services/initiative-update.ts +16 -15
- package/src/services/initiative.ts +15 -10
- package/src/services/issue.ts +263 -19
- package/src/services/label.ts +12 -2
- package/src/services/milestone.ts +8 -5
- package/src/services/notification.ts +16 -2
- package/src/services/organization.ts +23 -18
- package/src/services/project.ts +55 -34
- package/src/services/roadmap.ts +7 -6
- package/src/services/state.ts +9 -3
- package/src/services/team.ts +67 -24
- package/src/services/user.ts +2 -2
- package/src/services/webhook.ts +28 -17
package/src/services/comment.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { usageError, notFound } from "../lib/errors.js";
|
|
|
26
26
|
import { assertMutation, unwrapMutation } from "../lib/mutation.js";
|
|
27
27
|
import { resolveIssue } from "../lib/resolve.js";
|
|
28
28
|
import { appendEmbeds, uploadFile, validateUploads, type UploadResult } from "../lib/upload.js";
|
|
29
|
+
import { prependMentions } from "../lib/mentions.js";
|
|
29
30
|
|
|
30
31
|
export interface CommentRow {
|
|
31
32
|
id: string;
|
|
@@ -139,6 +140,8 @@ export interface AddCommentOptions {
|
|
|
139
140
|
attachments?: string[];
|
|
140
141
|
/** Upload the attachments to public, world-readable URLs (raster images only). */
|
|
141
142
|
public?: boolean;
|
|
143
|
+
/** Explicit user references to emit as real Linear mentions before the body. */
|
|
144
|
+
mentions?: string[];
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
/** Add a comment to an issue, optionally with uploaded files embedded in it. */
|
|
@@ -152,10 +155,13 @@ export async function addComment(
|
|
|
152
155
|
// Every file first — a missing one fails before anything is uploaded or resolved.
|
|
153
156
|
validateUploads(paths, { public: opts.public });
|
|
154
157
|
const issue = await resolveIssue(client, issueArg);
|
|
158
|
+
const mentionedBody = await prependMentions(client, body, opts.mentions);
|
|
155
159
|
const uploads: UploadResult[] = [];
|
|
156
160
|
for (const path of paths) uploads.push(await uploadFile(client, path, { public: opts.public }));
|
|
157
161
|
const comment = await unwrapMutation(
|
|
158
|
-
withRetry(() =>
|
|
162
|
+
withRetry(() =>
|
|
163
|
+
client.createComment({ issueId: issue.id, body: appendEmbeds(mentionedBody, uploads) }),
|
|
164
|
+
),
|
|
159
165
|
"comment",
|
|
160
166
|
"Comment creation",
|
|
161
167
|
);
|
|
@@ -184,11 +190,23 @@ export interface CommentLookup {
|
|
|
184
190
|
* still requires the owning entity, so we look the parent up (for its issueId)
|
|
185
191
|
* and pass both. Returns the new comment plus the parent's issue for output.
|
|
186
192
|
*/
|
|
187
|
-
export async function replyToComment(
|
|
193
|
+
export async function replyToComment(
|
|
194
|
+
client: LinearClient,
|
|
195
|
+
commentId: string,
|
|
196
|
+
body: string,
|
|
197
|
+
mentions: string[] = [],
|
|
198
|
+
) {
|
|
188
199
|
const parent = await getComment(client, commentId);
|
|
189
200
|
if (!parent.issueId) throw usageError("Can only reply to comments that belong to an issue.");
|
|
201
|
+
const mentionedBody = await prependMentions(client, body, mentions);
|
|
190
202
|
const comment = await unwrapMutation(
|
|
191
|
-
withRetry(() =>
|
|
203
|
+
withRetry(() =>
|
|
204
|
+
client.createComment({
|
|
205
|
+
parentId: parent.id,
|
|
206
|
+
issueId: parent.issueId!,
|
|
207
|
+
body: mentionedBody,
|
|
208
|
+
}),
|
|
209
|
+
),
|
|
192
210
|
"comment",
|
|
193
211
|
"Reply creation",
|
|
194
212
|
);
|
|
@@ -208,27 +226,37 @@ export async function updateComment(
|
|
|
208
226
|
commentId: string,
|
|
209
227
|
body: string,
|
|
210
228
|
current?: string,
|
|
229
|
+
mentions: string[] = [],
|
|
211
230
|
) {
|
|
212
|
-
|
|
213
|
-
|
|
231
|
+
const mentionedBody = await prependMentions(client, body, mentions);
|
|
232
|
+
if (mentionedBody.trim() === "") {
|
|
233
|
+
throw usageError(
|
|
234
|
+
"Refusing to blank the comment body. To remove a comment, use 'comment delete'.",
|
|
235
|
+
);
|
|
214
236
|
}
|
|
215
|
-
if (current !== undefined &&
|
|
237
|
+
if (current !== undefined && mentionedBody === current)
|
|
238
|
+
throw usageError("Comment body unchanged; nothing to update.");
|
|
216
239
|
return unwrapMutation(
|
|
217
|
-
withRetry(() => client.updateComment(commentId, { body })),
|
|
240
|
+
withRetry(() => client.updateComment(commentId, { body: mentionedBody })),
|
|
218
241
|
"comment",
|
|
219
242
|
"Comment update",
|
|
220
243
|
);
|
|
221
244
|
}
|
|
222
245
|
|
|
223
246
|
export async function deleteComment(client: LinearClient, commentId: string) {
|
|
224
|
-
await assertMutation(
|
|
247
|
+
await assertMutation(
|
|
248
|
+
withRetry(() => client.deleteComment(commentId)),
|
|
249
|
+
"Comment deletion",
|
|
250
|
+
);
|
|
225
251
|
return { id: commentId };
|
|
226
252
|
}
|
|
227
253
|
|
|
228
254
|
/** Resolve (or unresolve) a comment thread. */
|
|
229
255
|
export async function setResolved(client: LinearClient, commentId: string, resolved: boolean) {
|
|
230
256
|
return unwrapMutation(
|
|
231
|
-
withRetry(() =>
|
|
257
|
+
withRetry(() =>
|
|
258
|
+
resolved ? client.commentResolve(commentId) : client.commentUnresolve(commentId),
|
|
259
|
+
),
|
|
232
260
|
"comment",
|
|
233
261
|
`Comment ${resolved ? "resolve" : "unresolve"}`,
|
|
234
262
|
);
|
package/src/services/cycle.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type { LinearClient } from "@linear/sdk";
|
|
9
9
|
import { withRetry } from "../client.js";
|
|
10
10
|
import { shape } from "../lib/shape.js";
|
|
11
|
-
import { collect, pageSize } from "../lib/pagination.js";
|
|
11
|
+
import { collect, pageSize, setPaginationMetadata } from "../lib/pagination.js";
|
|
12
12
|
import { usageError, notFound } from "../lib/errors.js";
|
|
13
13
|
import { unwrapMutation } from "../lib/mutation.js";
|
|
14
14
|
import { resolveTeam, resolveCycleId, isUuid } from "../lib/resolve.js";
|
|
@@ -44,11 +44,16 @@ export async function listCycles(
|
|
|
44
44
|
const team = await resolveTeam(client, teamInput, defaultTeamKey);
|
|
45
45
|
const teamModel = await withRetry(() => client.team(team.id));
|
|
46
46
|
const conn = await withRetry(() => teamModel.cycles({ first: pageSize(limit) }));
|
|
47
|
-
|
|
47
|
+
// Cycle connection order is not its user-facing number order. Sort first so
|
|
48
|
+
// `--limit` means the newest cycles, not an arbitrary API prefix.
|
|
49
|
+
const nodes = await collect(conn as any, Infinity);
|
|
48
50
|
const rows = nodes.map(toRow);
|
|
49
51
|
// Surface most-recent (highest number) cycle first.
|
|
50
52
|
rows.sort((a, b) => b.number - a.number);
|
|
51
|
-
return
|
|
53
|
+
return setPaginationMetadata(
|
|
54
|
+
limit === Infinity ? rows : rows.slice(0, limit),
|
|
55
|
+
rows.length > limit,
|
|
56
|
+
);
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
/** The team's currently active cycle, if any. */
|
|
@@ -174,7 +179,9 @@ async function resolveCycleArg(
|
|
|
174
179
|
if (isUuid(idArg)) return idArg;
|
|
175
180
|
const teamKey = teamInput ?? defaultTeamKey;
|
|
176
181
|
if (!teamKey)
|
|
177
|
-
throw usageError(
|
|
182
|
+
throw usageError(
|
|
183
|
+
"Resolving a cycle by number or 'current' requires --team (or pass a cycle id).",
|
|
184
|
+
);
|
|
178
185
|
const team = await resolveTeam(client, teamKey, undefined);
|
|
179
186
|
return resolveCycleId(client, team.id, idArg);
|
|
180
187
|
}
|
package/src/services/document.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import type { LinearClient } from "@linear/sdk";
|
|
20
20
|
import { withRetry } from "../client.js";
|
|
21
21
|
import { collectRawQuery } from "../lib/pagination.js";
|
|
22
|
-
import { usageError, notFound } from "../lib/errors.js";
|
|
22
|
+
import { usageError, notFound, normalizeError } from "../lib/errors.js";
|
|
23
23
|
import { assertMutation, unwrapMutation } from "../lib/mutation.js";
|
|
24
24
|
import {
|
|
25
25
|
resolveProjectId,
|
|
@@ -100,7 +100,9 @@ export async function resolveTarget(
|
|
|
100
100
|
case "cycle": {
|
|
101
101
|
const teamKey = sel.team ?? defaultTeamKey;
|
|
102
102
|
if (!teamKey)
|
|
103
|
-
throw usageError(
|
|
103
|
+
throw usageError(
|
|
104
|
+
"--cycle needs a team to look the cycle up in: pass --team <KEY> or set a default team.",
|
|
105
|
+
);
|
|
104
106
|
const team = await resolveTeam(client, teamKey, undefined);
|
|
105
107
|
return { kind: "cycle", id: await resolveCycleId(client, team.id, sel.value) };
|
|
106
108
|
}
|
|
@@ -169,7 +171,9 @@ function targets(n: any): DocumentTargets {
|
|
|
169
171
|
initiative: n.initiative ?? null,
|
|
170
172
|
team: n.team ?? null,
|
|
171
173
|
cycle: n.cycle ? { id: n.cycle.id, number: n.cycle.number, name: n.cycle.name ?? null } : null,
|
|
172
|
-
release: n.release
|
|
174
|
+
release: n.release
|
|
175
|
+
? { id: n.release.id, name: n.release.name, version: n.release.version ?? null }
|
|
176
|
+
: null,
|
|
173
177
|
};
|
|
174
178
|
}
|
|
175
179
|
|
|
@@ -184,7 +188,8 @@ export function describeTarget(t: DocumentTargets): string | null {
|
|
|
184
188
|
if (t.initiative) return `Initiative: ${t.initiative.name}`;
|
|
185
189
|
if (t.team) return `Team: ${t.team.key} ${t.team.name}`;
|
|
186
190
|
if (t.cycle) return `Cycle: #${t.cycle.number}${t.cycle.name ? ` ${t.cycle.name}` : ""}`;
|
|
187
|
-
if (t.release)
|
|
191
|
+
if (t.release)
|
|
192
|
+
return `Release: ${t.release.name}${t.release.version ? ` (${t.release.version})` : ""}`;
|
|
188
193
|
return null;
|
|
189
194
|
}
|
|
190
195
|
|
|
@@ -233,10 +238,15 @@ query CliDocumentDetail($id: String!) {
|
|
|
233
238
|
}
|
|
234
239
|
}`;
|
|
235
240
|
|
|
236
|
-
export async function getDocumentDetail(
|
|
241
|
+
export async function getDocumentDetail(
|
|
242
|
+
client: LinearClient,
|
|
243
|
+
idArg: string,
|
|
244
|
+
): Promise<DocumentDetail> {
|
|
237
245
|
// An unknown id is an API error ("Could not find referenced Document"), which
|
|
238
246
|
// the error boundary already reads as not-found (exit 3); a null is guarded too.
|
|
239
|
-
const data: any = await withRetry(() =>
|
|
247
|
+
const data: any = await withRetry(() =>
|
|
248
|
+
(client as any).client.rawRequest(DETAIL_QUERY, { id: idArg }),
|
|
249
|
+
);
|
|
240
250
|
const n = data?.data?.document;
|
|
241
251
|
if (!n) throw notFound(`No document matching '${idArg}'.`);
|
|
242
252
|
return {
|
|
@@ -267,7 +277,11 @@ export interface CreateOptions extends DocumentTargetOptions {
|
|
|
267
277
|
* NOT a fallback here: the command decides that, so the service never turns
|
|
268
278
|
* "no target" into "the team from config" behind the caller's back.
|
|
269
279
|
*/
|
|
270
|
-
export async function createDocument(
|
|
280
|
+
export async function createDocument(
|
|
281
|
+
client: LinearClient,
|
|
282
|
+
opts: CreateOptions,
|
|
283
|
+
defaultTeamKey?: string,
|
|
284
|
+
) {
|
|
271
285
|
const sel = selectTarget(opts);
|
|
272
286
|
if (!sel) throw usageError(`A document needs a target: pass one of ${TARGET_FLAGS}.`);
|
|
273
287
|
const input: Record<string, any> = { title: opts.title };
|
|
@@ -318,7 +332,10 @@ export async function updateDocument(
|
|
|
318
332
|
|
|
319
333
|
export async function deleteDocument(client: LinearClient, idArg: string) {
|
|
320
334
|
const document = await resolveDocument(client, idArg);
|
|
321
|
-
await assertMutation(
|
|
335
|
+
await assertMutation(
|
|
336
|
+
withRetry(() => client.deleteDocument(document.id)),
|
|
337
|
+
"Document deletion",
|
|
338
|
+
);
|
|
322
339
|
return document;
|
|
323
340
|
}
|
|
324
341
|
|
|
@@ -332,7 +349,9 @@ async function resolveDocument(client: LinearClient, idArg: string) {
|
|
|
332
349
|
// The SDK's document() also resolves a slugId; fall back to it directly.
|
|
333
350
|
try {
|
|
334
351
|
return await withRetry(() => client.document(idArg));
|
|
335
|
-
} catch {
|
|
336
|
-
|
|
352
|
+
} catch (err) {
|
|
353
|
+
const normalized = normalizeError(err);
|
|
354
|
+
if (normalized.code === "not_found") throw notFound(`No document matching '${idArg}'.`);
|
|
355
|
+
throw normalized;
|
|
337
356
|
}
|
|
338
357
|
}
|
package/src/services/favorite.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import type { LinearClient } from "@linear/sdk";
|
|
14
14
|
import { withRetry } from "../client.js";
|
|
15
15
|
import { shape } from "../lib/shape.js";
|
|
16
|
-
import { collect, pageSize } from "../lib/pagination.js";
|
|
16
|
+
import { collect, inheritPaginationMetadata, pageSize } from "../lib/pagination.js";
|
|
17
17
|
import { usageError } from "../lib/errors.js";
|
|
18
18
|
import { assertMutation, unwrapMutation } from "../lib/mutation.js";
|
|
19
19
|
import { resolveIssue, resolveProjectId, isUuid } from "../lib/resolve.js";
|
|
@@ -69,13 +69,16 @@ export function entityLabel(entity: any): string {
|
|
|
69
69
|
export async function listFavorites(client: LinearClient, limit: number): Promise<FavoriteRow[]> {
|
|
70
70
|
const conn = await withRetry(() => client.favorites({ first: pageSize(limit) }));
|
|
71
71
|
const nodes = await collect(conn as any, limit);
|
|
72
|
-
return
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
return inheritPaginationMetadata(
|
|
73
|
+
await Promise.all(
|
|
74
|
+
nodes.map(async (f: any) => ({
|
|
75
|
+
id: f.id,
|
|
76
|
+
type: f.type,
|
|
77
|
+
name: await favoriteName(f),
|
|
78
|
+
url: f.url ?? null,
|
|
79
|
+
})),
|
|
80
|
+
),
|
|
81
|
+
nodes,
|
|
79
82
|
);
|
|
80
83
|
}
|
|
81
84
|
|
|
@@ -136,6 +139,9 @@ export async function addFavorite(client: LinearClient, opts: AddOptions) {
|
|
|
136
139
|
|
|
137
140
|
/** Delete a favorite by id. */
|
|
138
141
|
export async function removeFavorite(client: LinearClient, id: string) {
|
|
139
|
-
await assertMutation(
|
|
142
|
+
await assertMutation(
|
|
143
|
+
withRetry(() => client.deleteFavorite(id)),
|
|
144
|
+
"Favorite removal",
|
|
145
|
+
);
|
|
140
146
|
return { id };
|
|
141
147
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import type { LinearClient } from "@linear/sdk";
|
|
9
9
|
import { withRetry } from "../client.js";
|
|
10
|
-
import { collect } from "../lib/pagination.js";
|
|
10
|
+
import { collect, inheritPaginationMetadata, pageSize } from "../lib/pagination.js";
|
|
11
11
|
import { normalizeUpdatePayload, type Health, type UpdateRow } from "../lib/status-update.js";
|
|
12
12
|
import { resolveInitiative } from "./initiative.js";
|
|
13
13
|
|
|
@@ -20,21 +20,22 @@ export async function listInitiativeUpdates(
|
|
|
20
20
|
limit: number,
|
|
21
21
|
): Promise<UpdateRow[]> {
|
|
22
22
|
const initiative = await resolveInitiative(client, idArg);
|
|
23
|
-
const conn = await withRetry(() =>
|
|
24
|
-
initiative.initiativeUpdates({ first: Math.min(limit === Infinity ? 100 : limit, 100) }),
|
|
25
|
-
);
|
|
23
|
+
const conn = await withRetry(() => initiative.initiativeUpdates({ first: pageSize(limit) }));
|
|
26
24
|
const nodes = await collect(conn as any, limit);
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
return inheritPaginationMetadata(
|
|
26
|
+
await Promise.all(
|
|
27
|
+
nodes.map(async (u: any) => {
|
|
28
|
+
const user = await u.user;
|
|
29
|
+
return {
|
|
30
|
+
id: u.id,
|
|
31
|
+
createdAt: u.createdAt?.toISOString?.() ?? String(u.createdAt),
|
|
32
|
+
user: user?.displayName ?? "unknown",
|
|
33
|
+
body: u.body ?? "",
|
|
34
|
+
health: u.health ?? null,
|
|
35
|
+
};
|
|
36
|
+
}),
|
|
37
|
+
),
|
|
38
|
+
nodes,
|
|
38
39
|
);
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -164,7 +164,9 @@ export const INITIATIVE_DETAIL_SHAPE = shape<InitiativeDetail>({
|
|
|
164
164
|
archivedAt: "string|null",
|
|
165
165
|
owner: "string|null",
|
|
166
166
|
creator: "string|null",
|
|
167
|
-
projects: [
|
|
167
|
+
projects: [
|
|
168
|
+
{ id: "string", name: "string", status: { nullable: { name: "string", type: "string" } } },
|
|
169
|
+
],
|
|
168
170
|
});
|
|
169
171
|
|
|
170
172
|
/** How many linked projects `view` reads; more than this is unusual and shows a truncation note. */
|
|
@@ -187,7 +189,11 @@ export async function getInitiativeDetail(
|
|
|
187
189
|
const projectRows = await Promise.all(
|
|
188
190
|
(projects?.nodes ?? []).map(async (p: any) => {
|
|
189
191
|
const status = await p.status;
|
|
190
|
-
return {
|
|
192
|
+
return {
|
|
193
|
+
id: p.id,
|
|
194
|
+
name: p.name,
|
|
195
|
+
status: status ? { name: status.name, type: status.type } : null,
|
|
196
|
+
};
|
|
191
197
|
}),
|
|
192
198
|
);
|
|
193
199
|
return {
|
|
@@ -257,11 +263,7 @@ export interface UpdateOptions {
|
|
|
257
263
|
color?: string;
|
|
258
264
|
}
|
|
259
265
|
|
|
260
|
-
export async function updateInitiative(
|
|
261
|
-
client: LinearClient,
|
|
262
|
-
idArg: string,
|
|
263
|
-
opts: UpdateOptions,
|
|
264
|
-
) {
|
|
266
|
+
export async function updateInitiative(client: LinearClient, idArg: string, opts: UpdateOptions) {
|
|
265
267
|
const initiative = await resolveInitiative(client, idArg);
|
|
266
268
|
const input: Record<string, any> = {};
|
|
267
269
|
if (opts.name !== undefined) input.name = opts.name;
|
|
@@ -420,7 +422,11 @@ export async function resolveInitiative(
|
|
|
420
422
|
const matches: any[] = [];
|
|
421
423
|
for (;;) {
|
|
422
424
|
const conn = await withRetry(() =>
|
|
423
|
-
client.initiatives({
|
|
425
|
+
client.initiatives({
|
|
426
|
+
first: 100,
|
|
427
|
+
after,
|
|
428
|
+
includeArchived: opts.includeArchived === true,
|
|
429
|
+
} as any),
|
|
424
430
|
);
|
|
425
431
|
for (const n of conn.nodes) {
|
|
426
432
|
if (n.name.toLowerCase() === lower) matches.push(n);
|
|
@@ -438,7 +444,6 @@ export async function resolveInitiative(
|
|
|
438
444
|
export function resolveStatus(input: string): string {
|
|
439
445
|
const lower = input.toLowerCase();
|
|
440
446
|
const match = STATUSES.find((s) => s.toLowerCase() === lower);
|
|
441
|
-
if (!match)
|
|
442
|
-
throw usageError(`Invalid status '${input}'. Valid: ${STATUSES.join(", ")}.`);
|
|
447
|
+
if (!match) throw usageError(`Invalid status '${input}'. Valid: ${STATUSES.join(", ")}.`);
|
|
443
448
|
return match;
|
|
444
449
|
}
|