linear-sdk-cli 0.1.0 → 0.1.2

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +46 -46
  2. package/COVERAGE.md +5 -5
  3. package/MIGRATING.md +69 -71
  4. package/README.md +88 -96
  5. package/package.json +8 -9
  6. package/skills/linear-sdk-cli/SKILL.md +3 -13
  7. package/skills/linear-sdk-cli/references/api.md +9 -9
  8. package/skills/linear-sdk-cli/references/auth.md +0 -18
  9. package/skills/linear-sdk-cli/references/commands.md +2 -2
  10. package/skills/linear-sdk-cli/references/config.md +11 -9
  11. package/skills/linear-sdk-cli/references/issue.md +12 -63
  12. package/skills/linear-sdk-cli/references/team.md +0 -16
  13. package/skills/linear-sdk-cli/scripts/generate-docs.ts +2 -6
  14. package/src/bin/linear.ts +6 -16
  15. package/src/cli.ts +1 -3
  16. package/src/commands/agent-session.ts +5 -13
  17. package/src/commands/api.ts +9 -15
  18. package/src/commands/attach.ts +4 -15
  19. package/src/commands/comment.ts +2 -6
  20. package/src/commands/completion.ts +6 -2
  21. package/src/commands/cycle.ts +1 -6
  22. package/src/commands/discover.ts +2 -6
  23. package/src/commands/document.ts +1 -4
  24. package/src/commands/initiative.ts +1 -5
  25. package/src/commands/issue.ts +88 -376
  26. package/src/commands/meta.ts +31 -139
  27. package/src/commands/milestone.ts +1 -4
  28. package/src/commands/notification.ts +6 -15
  29. package/src/commands/project.ts +4 -17
  30. package/src/commands/team.ts +0 -13
  31. package/src/commands/webhook.ts +2 -12
  32. package/src/config.ts +183 -500
  33. package/src/context.ts +4 -13
  34. package/src/git.ts +3 -28
  35. package/src/lib/body.ts +2 -26
  36. package/src/lib/errors.ts +7 -32
  37. package/src/lib/introspect.ts +7 -76
  38. package/src/lib/keyring.ts +9 -51
  39. package/src/lib/options.ts +12 -108
  40. package/src/lib/output-shapes.ts +9 -81
  41. package/src/lib/pagination.ts +17 -50
  42. package/src/lib/resolve.ts +7 -40
  43. package/src/lib/shape.ts +12 -16
  44. package/src/lib/upload.ts +1 -3
  45. package/src/output/format.ts +18 -96
  46. package/src/output/table.ts +7 -7
  47. package/src/services/agent-session.ts +3 -11
  48. package/src/services/attachment.ts +5 -14
  49. package/src/services/comment.ts +4 -12
  50. package/src/services/cycle.ts +4 -11
  51. package/src/services/document.ts +10 -29
  52. package/src/services/favorite.ts +9 -15
  53. package/src/services/initiative-update.ts +15 -16
  54. package/src/services/initiative.ts +10 -15
  55. package/src/services/issue.ts +18 -262
  56. package/src/services/label.ts +2 -12
  57. package/src/services/milestone.ts +5 -8
  58. package/src/services/notification.ts +2 -16
  59. package/src/services/organization.ts +18 -23
  60. package/src/services/project.ts +34 -55
  61. package/src/services/roadmap.ts +6 -7
  62. package/src/services/state.ts +3 -9
  63. package/src/services/team.ts +24 -67
  64. package/src/services/user.ts +2 -2
  65. package/src/services/webhook.ts +17 -28
  66. package/skills/linear-sdk-cli/references/open.md +0 -29
  67. package/src/commands/open.ts +0 -84
  68. package/src/lib/open.ts +0 -32
  69. package/src/output/color.ts +0 -52
  70. package/src/output/markdown.ts +0 -133
  71. package/src/output/pager.ts +0 -131
@@ -148,14 +148,15 @@ export function selectPairs(
148
148
  export function renderTable<T>(
149
149
  rows: T[],
150
150
  columns: Column<T>[],
151
- opts: { color?: boolean; empty?: string } = {},
151
+ opts: { color?: boolean } = {},
152
152
  ): string {
153
153
  const color = opts.color ?? false;
154
- const colors = pc.createColors(color);
155
- if (rows.length === 0) return colors.dim(sanitizeForTerminal(opts.empty ?? "(no results)"));
154
+ if (rows.length === 0) return color ? pc.dim("(no results)") : "(no results)";
156
155
 
157
156
  const headers = columns.map((c) => c.header ?? c.key);
158
- const body = rows.map((row) => columns.map((c) => truncate(cell(c.value(row)), c.max ?? 60)));
157
+ const body = rows.map((row) =>
158
+ columns.map((c) => truncate(cell(c.value(row)), c.max ?? 60)),
159
+ );
159
160
 
160
161
  const widths = columns.map((_, i) => {
161
162
  const header = headers[i] ?? "";
@@ -166,7 +167,7 @@ export function renderTable<T>(
166
167
  const pad = (s: string, w: number) => s + " ".repeat(Math.max(0, w - displayWidth(s)));
167
168
 
168
169
  const headerLine = headers
169
- .map((h, i) => pad(colors.bold(h), widths[i] ?? 0))
170
+ .map((h, i) => pad(color ? pc.bold(h) : h, widths[i] ?? 0))
170
171
  .join(" ")
171
172
  .trimEnd();
172
173
 
@@ -186,13 +187,12 @@ export function renderDetail(
186
187
  opts: { color?: boolean } = {},
187
188
  ): string {
188
189
  const color = opts.color ?? false;
189
- const colors = pc.createColors(color);
190
190
  const visible = pairs.filter(([, v]) => v !== undefined && v !== null);
191
191
  const keyWidth = visible.reduce((m, [k]) => Math.max(m, k.length), 0);
192
192
  return visible
193
193
  .map(([k, v]) => {
194
194
  const label = (k + ":").padEnd(keyWidth + 1);
195
- return `${colors.dim(label)} ${cell(v)}`;
195
+ return `${color ? pc.dim(label) : label} ${cell(v)}`;
196
196
  })
197
197
  .join("\n");
198
198
  }
@@ -14,7 +14,7 @@
14
14
  import type { LinearClient } from "@linear/sdk";
15
15
  import { withRetry } from "../client.js";
16
16
  import { shape } from "../lib/shape.js";
17
- import { collectRawQuery, hasMoreResults, setPaginationMetadata } from "../lib/pagination.js";
17
+ import { collectRawQuery } from "../lib/pagination.js";
18
18
  import { notFound } from "../lib/errors.js";
19
19
 
20
20
  /** The statuses Linear reports for a session (AgentSessionStatus). */
@@ -35,11 +35,7 @@ export interface SessionUser {
35
35
  displayName: string;
36
36
  }
37
37
 
38
- const SESSION_USER_SHAPE = shape<SessionUser>({
39
- id: "string",
40
- name: "string",
41
- displayName: "string",
42
- });
38
+ const SESSION_USER_SHAPE = shape<SessionUser>({ id: "string", name: "string", displayName: "string" });
43
39
 
44
40
  export interface AgentSessionRow {
45
41
  id: string;
@@ -158,11 +154,7 @@ function finish(
158
154
  const filtered = opts.status ? present.filter((r) => r.status === opts.status) : present;
159
155
  // Newest first, whichever query found them (an issue's comments come oldest first).
160
156
  filtered.sort((a, b) => (a.createdAt < b.createdAt ? 1 : a.createdAt > b.createdAt ? -1 : 0));
161
- if (limit === Infinity) return setPaginationMetadata(filtered, false);
162
- return setPaginationMetadata(
163
- filtered.slice(0, limit),
164
- filtered.length > limit || (!opts.status && filtered.length >= limit && hasMoreResults(rows)),
165
- );
157
+ return limit === Infinity ? filtered : filtered.slice(0, limit);
166
158
  }
167
159
 
168
160
  function toRow(s: any): AgentSessionRow {
@@ -11,7 +11,7 @@
11
11
  import type { LinearClient } from "@linear/sdk";
12
12
  import { withRetry } from "../client.js";
13
13
  import { shape } from "../lib/shape.js";
14
- import { collect, inheritPaginationMetadata, pageSize } from "../lib/pagination.js";
14
+ import { collect, pageSize } from "../lib/pagination.js";
15
15
  import { notFound, usageError } from "../lib/errors.js";
16
16
  import { assertMutation, unwrapMutation } from "../lib/mutation.js";
17
17
  import { resolveIssue } from "../lib/resolve.js";
@@ -65,7 +65,7 @@ export async function listAttachments(
65
65
  const issue = await resolveIssue(client, issueArg);
66
66
  const conn = await withRetry(() => issue.attachments({ first: pageSize(limit) }));
67
67
  const nodes = await collect(conn as any, limit);
68
- return inheritPaginationMetadata(nodes.map(toRow), nodes);
68
+ return nodes.map(toRow);
69
69
  }
70
70
 
71
71
  export interface CreateOptions {
@@ -128,15 +128,9 @@ export async function attachFiles(
128
128
  issueArg: string,
129
129
  paths: string[],
130
130
  opts: AttachFilesOptions,
131
- ): Promise<{
132
- issue: { id: string; identifier: string };
133
- attachments: AttachedFile[];
134
- comment?: { id: string; url: string };
135
- }> {
131
+ ): Promise<{ issue: { id: string; identifier: string }; attachments: AttachedFile[]; comment?: { id: string; url: string } }> {
136
132
  if (opts.title !== undefined && paths.length > 1) {
137
- throw usageError(
138
- "--title names a single attachment; with several files, drop it to use each file's name.",
139
- );
133
+ throw usageError("--title names a single attachment; with several files, drop it to use each file's name.");
140
134
  }
141
135
  validateUploads(paths, { public: opts.public });
142
136
  const issue = await resolveIssue(client, issueArg);
@@ -184,10 +178,7 @@ export async function attachFiles(
184
178
  export async function deleteAttachment(client: LinearClient, id: string) {
185
179
  const attachment = await withRetry(() => client.attachment(id));
186
180
  if (!attachment) throw notFound(`No attachment ${id}.`);
187
- await assertMutation(
188
- withRetry(() => client.deleteAttachment(id)),
189
- "Attachment deletion",
190
- );
181
+ await assertMutation(withRetry(() => client.deleteAttachment(id)), "Attachment deletion");
191
182
  return { id: attachment.id, title: attachment.title };
192
183
  }
193
184
 
@@ -210,12 +210,9 @@ export async function updateComment(
210
210
  current?: string,
211
211
  ) {
212
212
  if (body.trim() === "") {
213
- throw usageError(
214
- "Refusing to blank the comment body. To remove a comment, use 'comment delete'.",
215
- );
213
+ throw usageError("Refusing to blank the comment body. To remove a comment, use 'comment delete'.");
216
214
  }
217
- if (current !== undefined && body === current)
218
- throw usageError("Comment body unchanged; nothing to update.");
215
+ if (current !== undefined && body === current) throw usageError("Comment body unchanged; nothing to update.");
219
216
  return unwrapMutation(
220
217
  withRetry(() => client.updateComment(commentId, { body })),
221
218
  "comment",
@@ -224,19 +221,14 @@ export async function updateComment(
224
221
  }
225
222
 
226
223
  export async function deleteComment(client: LinearClient, commentId: string) {
227
- await assertMutation(
228
- withRetry(() => client.deleteComment(commentId)),
229
- "Comment deletion",
230
- );
224
+ await assertMutation(withRetry(() => client.deleteComment(commentId)), "Comment deletion");
231
225
  return { id: commentId };
232
226
  }
233
227
 
234
228
  /** Resolve (or unresolve) a comment thread. */
235
229
  export async function setResolved(client: LinearClient, commentId: string, resolved: boolean) {
236
230
  return unwrapMutation(
237
- withRetry(() =>
238
- resolved ? client.commentResolve(commentId) : client.commentUnresolve(commentId),
239
- ),
231
+ withRetry(() => (resolved ? client.commentResolve(commentId) : client.commentUnresolve(commentId))),
240
232
  "comment",
241
233
  `Comment ${resolved ? "resolve" : "unresolve"}`,
242
234
  );
@@ -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, setPaginationMetadata } from "../lib/pagination.js";
11
+ import { collect, pageSize } 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,16 +44,11 @@ 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
- // 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);
47
+ const nodes = await collect(conn as any, limit);
50
48
  const rows = nodes.map(toRow);
51
49
  // Surface most-recent (highest number) cycle first.
52
50
  rows.sort((a, b) => b.number - a.number);
53
- return setPaginationMetadata(
54
- limit === Infinity ? rows : rows.slice(0, limit),
55
- rows.length > limit,
56
- );
51
+ return rows;
57
52
  }
58
53
 
59
54
  /** The team's currently active cycle, if any. */
@@ -179,9 +174,7 @@ async function resolveCycleArg(
179
174
  if (isUuid(idArg)) return idArg;
180
175
  const teamKey = teamInput ?? defaultTeamKey;
181
176
  if (!teamKey)
182
- throw usageError(
183
- "Resolving a cycle by number or 'current' requires --team (or pass a cycle id).",
184
- );
177
+ throw usageError("Resolving a cycle by number or 'current' requires --team (or pass a cycle id).");
185
178
  const team = await resolveTeam(client, teamKey, undefined);
186
179
  return resolveCycleId(client, team.id, idArg);
187
180
  }
@@ -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, normalizeError } from "../lib/errors.js";
22
+ import { usageError, notFound } from "../lib/errors.js";
23
23
  import { assertMutation, unwrapMutation } from "../lib/mutation.js";
24
24
  import {
25
25
  resolveProjectId,
@@ -100,9 +100,7 @@ export async function resolveTarget(
100
100
  case "cycle": {
101
101
  const teamKey = sel.team ?? defaultTeamKey;
102
102
  if (!teamKey)
103
- throw usageError(
104
- "--cycle needs a team to look the cycle up in: pass --team <KEY> or set a default team.",
105
- );
103
+ throw usageError("--cycle needs a team to look the cycle up in: pass --team <KEY> or set a default team.");
106
104
  const team = await resolveTeam(client, teamKey, undefined);
107
105
  return { kind: "cycle", id: await resolveCycleId(client, team.id, sel.value) };
108
106
  }
@@ -171,9 +169,7 @@ function targets(n: any): DocumentTargets {
171
169
  initiative: n.initiative ?? null,
172
170
  team: n.team ?? null,
173
171
  cycle: n.cycle ? { id: n.cycle.id, number: n.cycle.number, name: n.cycle.name ?? null } : null,
174
- release: n.release
175
- ? { id: n.release.id, name: n.release.name, version: n.release.version ?? null }
176
- : null,
172
+ release: n.release ? { id: n.release.id, name: n.release.name, version: n.release.version ?? null } : null,
177
173
  };
178
174
  }
179
175
 
@@ -188,8 +184,7 @@ export function describeTarget(t: DocumentTargets): string | null {
188
184
  if (t.initiative) return `Initiative: ${t.initiative.name}`;
189
185
  if (t.team) return `Team: ${t.team.key} ${t.team.name}`;
190
186
  if (t.cycle) return `Cycle: #${t.cycle.number}${t.cycle.name ? ` ${t.cycle.name}` : ""}`;
191
- if (t.release)
192
- return `Release: ${t.release.name}${t.release.version ? ` (${t.release.version})` : ""}`;
187
+ if (t.release) return `Release: ${t.release.name}${t.release.version ? ` (${t.release.version})` : ""}`;
193
188
  return null;
194
189
  }
195
190
 
@@ -238,15 +233,10 @@ query CliDocumentDetail($id: String!) {
238
233
  }
239
234
  }`;
240
235
 
241
- export async function getDocumentDetail(
242
- client: LinearClient,
243
- idArg: string,
244
- ): Promise<DocumentDetail> {
236
+ export async function getDocumentDetail(client: LinearClient, idArg: string): Promise<DocumentDetail> {
245
237
  // An unknown id is an API error ("Could not find referenced Document"), which
246
238
  // the error boundary already reads as not-found (exit 3); a null is guarded too.
247
- const data: any = await withRetry(() =>
248
- (client as any).client.rawRequest(DETAIL_QUERY, { id: idArg }),
249
- );
239
+ const data: any = await withRetry(() => (client as any).client.rawRequest(DETAIL_QUERY, { id: idArg }));
250
240
  const n = data?.data?.document;
251
241
  if (!n) throw notFound(`No document matching '${idArg}'.`);
252
242
  return {
@@ -277,11 +267,7 @@ export interface CreateOptions extends DocumentTargetOptions {
277
267
  * NOT a fallback here: the command decides that, so the service never turns
278
268
  * "no target" into "the team from config" behind the caller's back.
279
269
  */
280
- export async function createDocument(
281
- client: LinearClient,
282
- opts: CreateOptions,
283
- defaultTeamKey?: string,
284
- ) {
270
+ export async function createDocument(client: LinearClient, opts: CreateOptions, defaultTeamKey?: string) {
285
271
  const sel = selectTarget(opts);
286
272
  if (!sel) throw usageError(`A document needs a target: pass one of ${TARGET_FLAGS}.`);
287
273
  const input: Record<string, any> = { title: opts.title };
@@ -332,10 +318,7 @@ export async function updateDocument(
332
318
 
333
319
  export async function deleteDocument(client: LinearClient, idArg: string) {
334
320
  const document = await resolveDocument(client, idArg);
335
- await assertMutation(
336
- withRetry(() => client.deleteDocument(document.id)),
337
- "Document deletion",
338
- );
321
+ await assertMutation(withRetry(() => client.deleteDocument(document.id)), "Document deletion");
339
322
  return document;
340
323
  }
341
324
 
@@ -349,9 +332,7 @@ async function resolveDocument(client: LinearClient, idArg: string) {
349
332
  // The SDK's document() also resolves a slugId; fall back to it directly.
350
333
  try {
351
334
  return await withRetry(() => client.document(idArg));
352
- } catch (err) {
353
- const normalized = normalizeError(err);
354
- if (normalized.code === "not_found") throw notFound(`No document matching '${idArg}'.`);
355
- throw normalized;
335
+ } catch {
336
+ throw notFound(`No document matching '${idArg}'.`);
356
337
  }
357
338
  }
@@ -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, inheritPaginationMetadata, pageSize } from "../lib/pagination.js";
16
+ import { collect, 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,16 +69,13 @@ 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 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,
72
+ return Promise.all(
73
+ nodes.map(async (f: any) => ({
74
+ id: f.id,
75
+ type: f.type,
76
+ name: await favoriteName(f),
77
+ url: f.url ?? null,
78
+ })),
82
79
  );
83
80
  }
84
81
 
@@ -139,9 +136,6 @@ export async function addFavorite(client: LinearClient, opts: AddOptions) {
139
136
 
140
137
  /** Delete a favorite by id. */
141
138
  export async function removeFavorite(client: LinearClient, id: string) {
142
- await assertMutation(
143
- withRetry(() => client.deleteFavorite(id)),
144
- "Favorite removal",
145
- );
139
+ await assertMutation(withRetry(() => client.deleteFavorite(id)), "Favorite removal");
146
140
  return { id };
147
141
  }
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { LinearClient } from "@linear/sdk";
9
9
  import { withRetry } from "../client.js";
10
- import { collect, inheritPaginationMetadata, pageSize } from "../lib/pagination.js";
10
+ import { collect } 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,22 +20,21 @@ 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(() => initiative.initiativeUpdates({ first: pageSize(limit) }));
23
+ const conn = await withRetry(() =>
24
+ initiative.initiativeUpdates({ first: Math.min(limit === Infinity ? 100 : limit, 100) }),
25
+ );
24
26
  const nodes = await collect(conn as any, limit);
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,
27
+ return Promise.all(
28
+ nodes.map(async (u: any) => {
29
+ const user = await u.user;
30
+ return {
31
+ id: u.id,
32
+ createdAt: u.createdAt?.toISOString?.() ?? String(u.createdAt),
33
+ user: user?.displayName ?? "unknown",
34
+ body: u.body ?? "",
35
+ health: u.health ?? null,
36
+ };
37
+ }),
39
38
  );
40
39
  }
41
40
 
@@ -164,9 +164,7 @@ export const INITIATIVE_DETAIL_SHAPE = shape<InitiativeDetail>({
164
164
  archivedAt: "string|null",
165
165
  owner: "string|null",
166
166
  creator: "string|null",
167
- projects: [
168
- { id: "string", name: "string", status: { nullable: { name: "string", type: "string" } } },
169
- ],
167
+ projects: [{ id: "string", name: "string", status: { nullable: { name: "string", type: "string" } } }],
170
168
  });
171
169
 
172
170
  /** How many linked projects `view` reads; more than this is unusual and shows a truncation note. */
@@ -189,11 +187,7 @@ export async function getInitiativeDetail(
189
187
  const projectRows = await Promise.all(
190
188
  (projects?.nodes ?? []).map(async (p: any) => {
191
189
  const status = await p.status;
192
- return {
193
- id: p.id,
194
- name: p.name,
195
- status: status ? { name: status.name, type: status.type } : null,
196
- };
190
+ return { id: p.id, name: p.name, status: status ? { name: status.name, type: status.type } : null };
197
191
  }),
198
192
  );
199
193
  return {
@@ -263,7 +257,11 @@ export interface UpdateOptions {
263
257
  color?: string;
264
258
  }
265
259
 
266
- export async function updateInitiative(client: LinearClient, idArg: string, opts: UpdateOptions) {
260
+ export async function updateInitiative(
261
+ client: LinearClient,
262
+ idArg: string,
263
+ opts: UpdateOptions,
264
+ ) {
267
265
  const initiative = await resolveInitiative(client, idArg);
268
266
  const input: Record<string, any> = {};
269
267
  if (opts.name !== undefined) input.name = opts.name;
@@ -422,11 +420,7 @@ export async function resolveInitiative(
422
420
  const matches: any[] = [];
423
421
  for (;;) {
424
422
  const conn = await withRetry(() =>
425
- client.initiatives({
426
- first: 100,
427
- after,
428
- includeArchived: opts.includeArchived === true,
429
- } as any),
423
+ client.initiatives({ first: 100, after, includeArchived: opts.includeArchived === true } as any),
430
424
  );
431
425
  for (const n of conn.nodes) {
432
426
  if (n.name.toLowerCase() === lower) matches.push(n);
@@ -444,6 +438,7 @@ export async function resolveInitiative(
444
438
  export function resolveStatus(input: string): string {
445
439
  const lower = input.toLowerCase();
446
440
  const match = STATUSES.find((s) => s.toLowerCase() === lower);
447
- if (!match) throw usageError(`Invalid status '${input}'. Valid: ${STATUSES.join(", ")}.`);
441
+ if (!match)
442
+ throw usageError(`Invalid status '${input}'. Valid: ${STATUSES.join(", ")}.`);
448
443
  return match;
449
444
  }