@rehpic/vcli 0.1.0-beta.10.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/dist/index.js ADDED
@@ -0,0 +1,2060 @@
1
+ #!/usr/bin/env node
2
+
3
+ // ../../src/cli/index.ts
4
+ import { readFile as readFile2 } from "fs/promises";
5
+ import { extname } from "path";
6
+ import { config as loadEnv } from "dotenv";
7
+ import { Command } from "commander";
8
+ import { makeFunctionReference } from "convex/server";
9
+
10
+ // ../../convex/_generated/api.js
11
+ import { anyApi, componentsGeneric } from "convex/server";
12
+ var api = anyApi;
13
+ var components = componentsGeneric();
14
+
15
+ // ../../src/cli/auth.ts
16
+ import { isCancel, password as passwordPrompt, text } from "@clack/prompts";
17
+ function buildUrl(appUrl, pathname) {
18
+ return new URL(pathname, appUrl).toString();
19
+ }
20
+ function cookieHeader(cookies) {
21
+ return Object.entries(cookies).map(([name, value]) => `${name}=${value}`).join("; ");
22
+ }
23
+ function splitSetCookieHeader(value) {
24
+ return value.split(/,(?=[^;,]+=)/g);
25
+ }
26
+ function applySetCookieHeaders(session, response) {
27
+ const nextCookies = { ...session.cookies };
28
+ const rawSetCookies = response.headers.getSetCookie?.() ?? (response.headers.get("set-cookie") ? splitSetCookieHeader(response.headers.get("set-cookie")) : []);
29
+ for (const rawCookie of rawSetCookies) {
30
+ const [cookiePart, ...attributeParts] = rawCookie.split(";");
31
+ const separatorIndex = cookiePart.indexOf("=");
32
+ if (separatorIndex <= 0) {
33
+ continue;
34
+ }
35
+ const name = cookiePart.slice(0, separatorIndex).trim();
36
+ const value = cookiePart.slice(separatorIndex + 1).trim();
37
+ const attributes = attributeParts.map((part) => part.trim().toLowerCase());
38
+ const maxAge = attributes.find((part) => part.startsWith("max-age="));
39
+ const expires = attributes.find((part) => part.startsWith("expires="));
40
+ const expired = value.length === 0 || maxAge === "max-age=0" || (expires ? Number.isFinite(Date.parse(expires.slice(8))) && Date.parse(expires.slice(8)) <= Date.now() : false);
41
+ if (expired) {
42
+ delete nextCookies[name];
43
+ } else {
44
+ nextCookies[name] = value;
45
+ }
46
+ }
47
+ return {
48
+ ...session,
49
+ cookies: nextCookies
50
+ };
51
+ }
52
+ async function authRequest(session, appUrl, pathname, init = {}) {
53
+ const headers = new Headers(init.headers);
54
+ const origin = new URL(appUrl).origin;
55
+ if (Object.keys(session.cookies).length > 0) {
56
+ headers.set("cookie", cookieHeader(session.cookies));
57
+ }
58
+ if (!headers.has("origin")) {
59
+ headers.set("origin", origin);
60
+ }
61
+ if (!headers.has("referer")) {
62
+ headers.set("referer", `${origin}/`);
63
+ }
64
+ if (init.body && !headers.has("content-type")) {
65
+ headers.set("content-type", "application/json");
66
+ }
67
+ const response = await fetch(buildUrl(appUrl, pathname), {
68
+ ...init,
69
+ headers,
70
+ redirect: "manual"
71
+ });
72
+ const nextSession = applySetCookieHeaders(session, response);
73
+ return { response, session: nextSession };
74
+ }
75
+ async function parseError(response) {
76
+ try {
77
+ const data = await response.json();
78
+ return data.error?.message ?? `Request failed with HTTP ${response.status}`;
79
+ } catch {
80
+ return `Request failed with HTTP ${response.status}`;
81
+ }
82
+ }
83
+ async function loginWithPassword(session, appUrl, identifier, password) {
84
+ const pathname = identifier.includes("@") ? "/api/auth/sign-in/email" : "/api/auth/sign-in/username";
85
+ const body = identifier.includes("@") ? { email: identifier, password } : { username: identifier, password };
86
+ const { response, session: nextSession } = await authRequest(
87
+ session,
88
+ appUrl,
89
+ pathname,
90
+ {
91
+ method: "POST",
92
+ body: JSON.stringify(body)
93
+ }
94
+ );
95
+ if (!response.ok) {
96
+ throw new Error(await parseError(response));
97
+ }
98
+ return nextSession;
99
+ }
100
+ async function signUpWithEmail(session, appUrl, email, username, password) {
101
+ const { response, session: nextSession } = await authRequest(
102
+ session,
103
+ appUrl,
104
+ "/api/auth/sign-up/email",
105
+ {
106
+ method: "POST",
107
+ body: JSON.stringify({
108
+ email,
109
+ password,
110
+ name: username,
111
+ username
112
+ })
113
+ }
114
+ );
115
+ if (!response.ok) {
116
+ throw new Error(await parseError(response));
117
+ }
118
+ return nextSession;
119
+ }
120
+ async function logout(session, appUrl) {
121
+ const { response } = await authRequest(
122
+ session,
123
+ appUrl,
124
+ "/api/auth/sign-out",
125
+ {
126
+ method: "POST",
127
+ body: JSON.stringify({})
128
+ }
129
+ );
130
+ if (!response.ok) {
131
+ throw new Error(await parseError(response));
132
+ }
133
+ }
134
+ async function fetchAuthSession(session, appUrl) {
135
+ const { response, session: nextSession } = await authRequest(
136
+ session,
137
+ appUrl,
138
+ "/api/auth/get-session",
139
+ {
140
+ method: "GET"
141
+ }
142
+ );
143
+ if (!response.ok) {
144
+ throw new Error(await parseError(response));
145
+ }
146
+ const data = await response.json();
147
+ return {
148
+ session: nextSession,
149
+ user: data.user ?? null
150
+ };
151
+ }
152
+ async function fetchConvexToken(session, appUrl) {
153
+ const { response, session: nextSession } = await authRequest(
154
+ session,
155
+ appUrl,
156
+ "/api/auth/convex/token",
157
+ {
158
+ method: "GET"
159
+ }
160
+ );
161
+ if (!response.ok) {
162
+ throw new Error(await parseError(response));
163
+ }
164
+ const data = await response.json();
165
+ if (!data.token) {
166
+ throw new Error("Missing Convex token");
167
+ }
168
+ return {
169
+ session: nextSession,
170
+ token: data.token
171
+ };
172
+ }
173
+ async function prompt(question) {
174
+ const value = await text({
175
+ message: question.replace(/:\s*$/, "")
176
+ });
177
+ if (isCancel(value)) {
178
+ throw new Error("Canceled");
179
+ }
180
+ return String(value).trim();
181
+ }
182
+ async function promptSecret(question) {
183
+ const value = await passwordPrompt({
184
+ message: question.replace(/:\s*$/, ""),
185
+ mask: "*"
186
+ });
187
+ if (isCancel(value)) {
188
+ throw new Error("Canceled");
189
+ }
190
+ return String(value);
191
+ }
192
+
193
+ // ../../src/cli/convex.ts
194
+ import { ConvexHttpClient } from "convex/browser";
195
+ async function createConvexClient(session, appUrl, convexUrl) {
196
+ const { token } = await fetchConvexToken(session, appUrl);
197
+ const client = new ConvexHttpClient(convexUrl);
198
+ client.setAuth(token);
199
+ return client;
200
+ }
201
+ async function runQuery(client, ref, ...args) {
202
+ return await client.query(ref, ...args);
203
+ }
204
+ async function runMutation(client, ref, ...args) {
205
+ return await client.mutation(ref, ...args);
206
+ }
207
+ async function runAction(client, ref, ...args) {
208
+ return await client.action(ref, ...args);
209
+ }
210
+
211
+ // ../../src/cli/output.ts
212
+ function simplify(value) {
213
+ if (value === null || value === void 0) {
214
+ return value;
215
+ }
216
+ if (Array.isArray(value)) {
217
+ if (value.length === 0) {
218
+ return [];
219
+ }
220
+ if (value.every((item) => typeof item !== "object" || item === null)) {
221
+ return value.join(", ");
222
+ }
223
+ return JSON.stringify(value);
224
+ }
225
+ if (typeof value === "object") {
226
+ return JSON.stringify(value);
227
+ }
228
+ return value;
229
+ }
230
+ function printOutput(data, json = false) {
231
+ if (json) {
232
+ console.log(JSON.stringify(data, null, 2));
233
+ return;
234
+ }
235
+ if (Array.isArray(data)) {
236
+ if (data.length === 0) {
237
+ console.log("No results.");
238
+ return;
239
+ }
240
+ if (data.every((item) => typeof item === "object" && item !== null)) {
241
+ console.table(
242
+ data.map(
243
+ (item) => Object.fromEntries(
244
+ Object.entries(item).map(([key, value]) => [key, simplify(value)])
245
+ )
246
+ )
247
+ );
248
+ return;
249
+ }
250
+ }
251
+ if (typeof data === "object" && data !== null) {
252
+ console.dir(data, { depth: null, colors: true });
253
+ return;
254
+ }
255
+ console.log(String(data));
256
+ }
257
+
258
+ // ../../src/cli/session.ts
259
+ import { mkdir, readFile, rm, writeFile } from "fs/promises";
260
+ import { homedir } from "os";
261
+ import path from "path";
262
+ var SESSION_ROOT = path.join(homedir(), ".vector");
263
+ function getSessionPath(profile = "default") {
264
+ return path.join(SESSION_ROOT, `cli-${profile}.json`);
265
+ }
266
+ async function readSession(profile = "default") {
267
+ try {
268
+ const raw = await readFile(getSessionPath(profile), "utf8");
269
+ const parsed = JSON.parse(raw);
270
+ return {
271
+ version: 1,
272
+ cookies: {},
273
+ ...parsed
274
+ };
275
+ } catch {
276
+ return null;
277
+ }
278
+ }
279
+ async function writeSession(session, profile = "default") {
280
+ await mkdir(SESSION_ROOT, { recursive: true });
281
+ await writeFile(
282
+ getSessionPath(profile),
283
+ `${JSON.stringify(session, null, 2)}
284
+ `,
285
+ "utf8"
286
+ );
287
+ }
288
+ async function clearSession(profile = "default") {
289
+ await rm(getSessionPath(profile), { force: true });
290
+ }
291
+ function createEmptySession() {
292
+ return {
293
+ version: 1,
294
+ cookies: {}
295
+ };
296
+ }
297
+
298
+ // ../../src/cli/index.ts
299
+ loadEnv({ path: ".env.local", override: false });
300
+ loadEnv({ path: ".env", override: false });
301
+ var cliApi = {
302
+ listWorkspaceReferenceData: makeFunctionReference(
303
+ "cli:listWorkspaceReferenceData"
304
+ ),
305
+ searchIcons: makeFunctionReference("cli:searchIcons"),
306
+ listDocuments: makeFunctionReference("cli:listDocuments"),
307
+ getDocument: makeFunctionReference("cli:getDocument"),
308
+ createDocument: makeFunctionReference("cli:createDocument"),
309
+ updateDocument: makeFunctionReference("cli:updateDocument"),
310
+ deleteDocument: makeFunctionReference("cli:deleteDocument"),
311
+ moveDocumentToFolder: makeFunctionReference(
312
+ "cli:moveDocumentToFolder"
313
+ ),
314
+ listIssues: makeFunctionReference("cli:listIssues"),
315
+ getIssue: makeFunctionReference("cli:getIssue"),
316
+ createIssue: makeFunctionReference("cli:createIssue"),
317
+ updateIssue: makeFunctionReference("cli:updateIssue"),
318
+ deleteIssue: makeFunctionReference("cli:deleteIssue"),
319
+ assignIssue: makeFunctionReference("cli:assignIssue"),
320
+ unassignIssue: makeFunctionReference("cli:unassignIssue"),
321
+ listProjects: makeFunctionReference("cli:listProjects"),
322
+ getProject: makeFunctionReference("cli:getProject"),
323
+ createProject: makeFunctionReference("cli:createProject"),
324
+ updateProject: makeFunctionReference("cli:updateProject"),
325
+ deleteProject: makeFunctionReference("cli:deleteProject"),
326
+ addProjectMember: makeFunctionReference("cli:addProjectMember"),
327
+ removeProjectMember: makeFunctionReference(
328
+ "cli:removeProjectMember"
329
+ ),
330
+ changeProjectLead: makeFunctionReference("cli:changeProjectLead"),
331
+ listTeams: makeFunctionReference("cli:listTeams"),
332
+ getTeam: makeFunctionReference("cli:getTeam"),
333
+ createTeam: makeFunctionReference("cli:createTeam"),
334
+ updateTeam: makeFunctionReference("cli:updateTeam"),
335
+ deleteTeam: makeFunctionReference("cli:deleteTeam"),
336
+ addTeamMember: makeFunctionReference("cli:addTeamMember"),
337
+ removeTeamMember: makeFunctionReference("cli:removeTeamMember"),
338
+ changeTeamLead: makeFunctionReference("cli:changeTeamLead"),
339
+ listFolders: makeFunctionReference("cli:listFolders"),
340
+ createFolder: makeFunctionReference("cli:createFolder"),
341
+ updateFolder: makeFunctionReference("cli:updateFolder"),
342
+ deleteFolder: makeFunctionReference("cli:deleteFolder")
343
+ };
344
+ var rolesApi = api.roles.index;
345
+ var ISSUE_STATE_TYPES = [
346
+ "backlog",
347
+ "todo",
348
+ "in_progress",
349
+ "done",
350
+ "canceled"
351
+ ];
352
+ var PROJECT_STATUS_TYPES = [
353
+ "backlog",
354
+ "planned",
355
+ "in_progress",
356
+ "completed",
357
+ "canceled"
358
+ ];
359
+ var NOTIFICATION_CATEGORIES = [
360
+ "invites",
361
+ "assignments",
362
+ "mentions",
363
+ "comments"
364
+ ];
365
+ function requiredString(value, label) {
366
+ if (!value?.trim()) {
367
+ throw new Error(`${label} is required`);
368
+ }
369
+ return value.trim();
370
+ }
371
+ function optionalNumber(value, label) {
372
+ if (value === void 0) {
373
+ return void 0;
374
+ }
375
+ const parsed = Number(value);
376
+ if (!Number.isFinite(parsed)) {
377
+ throw new Error(`${label} must be a valid number`);
378
+ }
379
+ return parsed;
380
+ }
381
+ function requiredNumber(value, label) {
382
+ const parsed = optionalNumber(value, label);
383
+ if (parsed === void 0) {
384
+ throw new Error(`${label} is required`);
385
+ }
386
+ return parsed;
387
+ }
388
+ function parseBoolean(value, label) {
389
+ const normalized = value.trim().toLowerCase();
390
+ if (normalized === "true") return true;
391
+ if (normalized === "false") return false;
392
+ throw new Error(`${label} must be "true" or "false"`);
393
+ }
394
+ function parseList(value) {
395
+ if (!value) return [];
396
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
397
+ }
398
+ function buildPaginationOptions(limit, cursor) {
399
+ return {
400
+ cursor: cursor ?? null,
401
+ numItems: optionalNumber(limit, "limit") ?? 20
402
+ };
403
+ }
404
+ function normalizeMatch(value) {
405
+ return value?.trim().toLowerCase();
406
+ }
407
+ async function fetchConvexUrl(appUrl) {
408
+ try {
409
+ const url = new URL("/api/config", appUrl).toString();
410
+ const response = await fetch(url);
411
+ if (!response.ok) {
412
+ throw new Error(`HTTP ${response.status}`);
413
+ }
414
+ const data = await response.json();
415
+ if (data.convexUrl) {
416
+ return data.convexUrl;
417
+ }
418
+ } catch {
419
+ }
420
+ return "http://127.0.0.1:3210";
421
+ }
422
+ async function getRuntime(command) {
423
+ const options = command.optsWithGlobals();
424
+ const profile = options.profile ?? "default";
425
+ const session = await readSession(profile);
426
+ const appUrlSource = options.appUrl ?? session?.appUrl ?? process.env.NEXT_PUBLIC_APP_URL;
427
+ const appUrl = requiredString(appUrlSource, "app URL");
428
+ let convexUrl = options.convexUrl ?? session?.convexUrl ?? process.env.NEXT_PUBLIC_CONVEX_URL ?? process.env.CONVEX_URL;
429
+ if (!convexUrl) {
430
+ convexUrl = await fetchConvexUrl(appUrl);
431
+ }
432
+ return {
433
+ appUrl,
434
+ convexUrl,
435
+ json: Boolean(options.json),
436
+ org: options.org ?? session?.activeOrgSlug,
437
+ profile,
438
+ session
439
+ };
440
+ }
441
+ function requireSession(runtime) {
442
+ if (!runtime.session || Object.keys(runtime.session.cookies).length === 0) {
443
+ throw new Error("Not logged in. Run `vcli auth login` first.");
444
+ }
445
+ return runtime.session;
446
+ }
447
+ function requireOrg(runtime, explicit) {
448
+ const orgSlug = explicit ?? runtime.org;
449
+ if (!orgSlug) {
450
+ throw new Error(
451
+ "Organization slug is required. Pass `--org <slug>` or run `vcli org use <slug>`."
452
+ );
453
+ }
454
+ return orgSlug;
455
+ }
456
+ async function getClient(command) {
457
+ const runtime = await getRuntime(command);
458
+ const session = requireSession(runtime);
459
+ const client = await createConvexClient(
460
+ session,
461
+ runtime.appUrl,
462
+ runtime.convexUrl
463
+ );
464
+ return { client, runtime, session };
465
+ }
466
+ async function resolveMemberId(client, orgSlug, ref) {
467
+ const members = await runQuery(
468
+ client,
469
+ api.organizations.queries.listMembers,
470
+ {
471
+ orgSlug
472
+ }
473
+ );
474
+ const needle = normalizeMatch(ref);
475
+ const matches = members.filter((member) => {
476
+ const user = member.user;
477
+ if (!user) return false;
478
+ return normalizeMatch(String(user._id)) === needle || normalizeMatch(user.email) === needle || normalizeMatch(user.name) === needle || normalizeMatch(user.username) === needle;
479
+ });
480
+ if (matches.length === 0) {
481
+ throw new Error(`No member matched "${ref}"`);
482
+ }
483
+ if (matches.length > 1) {
484
+ throw new Error(`Multiple members matched "${ref}"`);
485
+ }
486
+ return matches[0].user._id;
487
+ }
488
+ async function resolveRoleId(client, orgSlug, ref) {
489
+ const roles = await runQuery(client, rolesApi.list, { orgSlug });
490
+ const needle = normalizeMatch(ref);
491
+ const matches = roles.filter((role) => {
492
+ const candidate = role;
493
+ return normalizeMatch(String(candidate._id)) === needle || normalizeMatch(candidate.name) === needle || normalizeMatch(candidate.key) === needle;
494
+ });
495
+ if (matches.length === 0) {
496
+ throw new Error(`No role matched "${ref}"`);
497
+ }
498
+ if (matches.length > 1) {
499
+ throw new Error(`Multiple roles matched "${ref}"`);
500
+ }
501
+ return matches[0]._id;
502
+ }
503
+ function parsePermissions(value) {
504
+ return value.split(",").map((permission) => permission.trim()).filter(Boolean);
505
+ }
506
+ function nullableOption(value, clear = false) {
507
+ if (clear) return null;
508
+ return value;
509
+ }
510
+ function mimeTypeForFile(filePath) {
511
+ switch (extname(filePath).toLowerCase()) {
512
+ case ".png":
513
+ return "image/png";
514
+ case ".jpg":
515
+ case ".jpeg":
516
+ return "image/jpeg";
517
+ case ".webp":
518
+ return "image/webp";
519
+ case ".gif":
520
+ return "image/gif";
521
+ case ".svg":
522
+ return "image/svg+xml";
523
+ default:
524
+ return "application/octet-stream";
525
+ }
526
+ }
527
+ async function uploadFile(uploadUrl, filePath) {
528
+ const body = await readFile2(filePath);
529
+ const response = await fetch(uploadUrl, {
530
+ method: "POST",
531
+ headers: {
532
+ "Content-Type": mimeTypeForFile(filePath)
533
+ },
534
+ body
535
+ });
536
+ if (!response.ok) {
537
+ throw new Error(`Upload failed with HTTP ${response.status}`);
538
+ }
539
+ const data = await response.json();
540
+ if (!data.storageId) {
541
+ throw new Error("Upload response did not include a storageId");
542
+ }
543
+ return data.storageId;
544
+ }
545
+ async function resolveTeamId(client, orgSlug, teamKey) {
546
+ if (!teamKey) {
547
+ return void 0;
548
+ }
549
+ const team = await runAction(client, cliApi.getTeam, { orgSlug, teamKey });
550
+ return team.id;
551
+ }
552
+ async function resolveProjectId(client, orgSlug, projectKey) {
553
+ if (!projectKey) {
554
+ return void 0;
555
+ }
556
+ const project = await runAction(client, cliApi.getProject, {
557
+ orgSlug,
558
+ projectKey
559
+ });
560
+ return project.id;
561
+ }
562
+ async function resolveIssueId(client, orgSlug, issueKey) {
563
+ const issue = await runAction(client, cliApi.getIssue, { orgSlug, issueKey });
564
+ return issue.id;
565
+ }
566
+ async function resolveDocumentId(client, orgSlug, documentId) {
567
+ const document = await runAction(client, cliApi.getDocument, {
568
+ orgSlug,
569
+ documentId
570
+ });
571
+ return document.id;
572
+ }
573
+ async function resolveIssueStateId(client, orgSlug, ref) {
574
+ const states = await runQuery(
575
+ client,
576
+ api.organizations.queries.listIssueStates,
577
+ {
578
+ orgSlug
579
+ }
580
+ );
581
+ const needle = normalizeMatch(ref);
582
+ const match = states.find((state) => {
583
+ return normalizeMatch(String(state._id)) === needle || normalizeMatch(state.name) === needle || normalizeMatch(state.type) === needle;
584
+ });
585
+ if (!match) {
586
+ throw new Error(`No issue state matched "${ref}"`);
587
+ }
588
+ return match._id;
589
+ }
590
+ async function resolveIssuePriorityId(client, orgSlug, ref) {
591
+ const priorities = await runQuery(
592
+ client,
593
+ api.organizations.queries.listIssuePriorities,
594
+ { orgSlug }
595
+ );
596
+ const needle = normalizeMatch(ref);
597
+ const match = priorities.find((priority) => {
598
+ return normalizeMatch(String(priority._id)) === needle || normalizeMatch(priority.name) === needle;
599
+ });
600
+ if (!match) {
601
+ throw new Error(`No issue priority matched "${ref}"`);
602
+ }
603
+ return match._id;
604
+ }
605
+ async function resolveProjectStatusId(client, orgSlug, ref) {
606
+ const statuses = await runQuery(
607
+ client,
608
+ api.organizations.queries.listProjectStatuses,
609
+ { orgSlug }
610
+ );
611
+ const needle = normalizeMatch(ref);
612
+ const match = statuses.find((status) => {
613
+ return normalizeMatch(String(status._id)) === needle || normalizeMatch(status.name) === needle || normalizeMatch(status.type) === needle;
614
+ });
615
+ if (!match) {
616
+ throw new Error(`No project status matched "${ref}"`);
617
+ }
618
+ return match._id;
619
+ }
620
+ async function parseEstimatedTimes(client, orgSlug, value) {
621
+ const entries = parseList(value);
622
+ const estimatedTimes = {};
623
+ for (const entry of entries) {
624
+ const separatorIndex = entry.indexOf("=");
625
+ if (separatorIndex <= 0) {
626
+ throw new Error(
627
+ 'estimated times must use the format "state=hours,state=hours"'
628
+ );
629
+ }
630
+ const stateRef = entry.slice(0, separatorIndex).trim();
631
+ const hours = Number(entry.slice(separatorIndex + 1).trim());
632
+ if (!Number.isFinite(hours)) {
633
+ throw new Error(`Invalid estimate for "${stateRef}"`);
634
+ }
635
+ const stateId = await resolveIssueStateId(client, orgSlug, stateRef);
636
+ estimatedTimes[String(stateId)] = hours;
637
+ }
638
+ return estimatedTimes;
639
+ }
640
+ var program = new Command();
641
+ program.name("vcli").description("Vector CLI").showHelpAfterError().option(
642
+ "--app-url <url>",
643
+ "Vector app URL. Required unless saved in the profile or NEXT_PUBLIC_APP_URL is set."
644
+ ).option("--convex-url <url>", "Convex deployment URL").option("--org <slug>", "Organization slug override").option("--profile <name>", "CLI profile name", "default").option("--json", "Output JSON");
645
+ var authCommand = program.command("auth").description("Authentication");
646
+ authCommand.command("signup").option("--email <email>", "Email address").option("--username <username>", "Username").option("--password <password>", "Password").action(async (options, command) => {
647
+ const runtime = await getRuntime(command);
648
+ const email = requiredString(
649
+ options.email?.trim() || await prompt("Email: "),
650
+ "email"
651
+ ).toLowerCase();
652
+ const username = requiredString(
653
+ options.username?.trim() || await prompt("Username: "),
654
+ "username"
655
+ );
656
+ const password = options.password?.trim() || await promptSecret("Password: ");
657
+ let session = createEmptySession();
658
+ session.appUrl = runtime.appUrl;
659
+ session.convexUrl = runtime.convexUrl;
660
+ session = await signUpWithEmail(
661
+ session,
662
+ runtime.appUrl,
663
+ email,
664
+ username,
665
+ password
666
+ );
667
+ const authState = await fetchAuthSession(session, runtime.appUrl);
668
+ session = authState.session;
669
+ const client = await createConvexClient(
670
+ session,
671
+ runtime.appUrl,
672
+ runtime.convexUrl
673
+ );
674
+ const orgs = await runQuery(client, api.users.getOrganizations, {});
675
+ session.activeOrgSlug = orgs[0]?.slug ?? session.activeOrgSlug;
676
+ await writeSession(session, runtime.profile);
677
+ printOutput(
678
+ {
679
+ signedUpAs: authState.user?.email ?? authState.user?.username ?? authState.user?.name,
680
+ activeOrgSlug: session.activeOrgSlug ?? null
681
+ },
682
+ runtime.json
683
+ );
684
+ });
685
+ authCommand.command("login [identifier]").option("--password <password>", "Password").action(async (identifier, options, command) => {
686
+ const runtime = await getRuntime(command);
687
+ const loginId = identifier?.trim() || await prompt("Email or username: ");
688
+ const password = options.password?.trim() || await promptSecret("Password: ");
689
+ let session = createEmptySession();
690
+ session.appUrl = runtime.appUrl;
691
+ session.convexUrl = runtime.convexUrl;
692
+ session = await loginWithPassword(
693
+ session,
694
+ runtime.appUrl,
695
+ loginId,
696
+ password
697
+ );
698
+ const authState = await fetchAuthSession(session, runtime.appUrl);
699
+ session = authState.session;
700
+ const client = await createConvexClient(
701
+ session,
702
+ runtime.appUrl,
703
+ runtime.convexUrl
704
+ );
705
+ const orgs = await runQuery(client, api.users.getOrganizations, {});
706
+ session.activeOrgSlug = orgs[0]?.slug ?? session.activeOrgSlug;
707
+ await writeSession(session, runtime.profile);
708
+ printOutput(
709
+ {
710
+ loggedInAs: authState.user?.email ?? authState.user?.username ?? authState.user?.name,
711
+ activeOrgSlug: session.activeOrgSlug ?? null
712
+ },
713
+ runtime.json
714
+ );
715
+ });
716
+ authCommand.command("logout").action(async (_options, command) => {
717
+ const runtime = await getRuntime(command);
718
+ const session = requireSession(runtime);
719
+ await logout(session, runtime.appUrl);
720
+ await clearSession(runtime.profile);
721
+ printOutput({ success: true }, runtime.json);
722
+ });
723
+ authCommand.command("whoami").action(async (_options, command) => {
724
+ const { client, runtime } = await getClient(command);
725
+ const [user, orgs] = await Promise.all([
726
+ runQuery(client, api.users.getCurrentUser, {}),
727
+ runQuery(client, api.users.getOrganizations, {})
728
+ ]);
729
+ printOutput(
730
+ {
731
+ user,
732
+ organizations: orgs,
733
+ activeOrgSlug: runtime.org ?? null
734
+ },
735
+ runtime.json
736
+ );
737
+ });
738
+ var orgCommand = program.command("org").description("Organizations");
739
+ orgCommand.command("list").action(async (_options, command) => {
740
+ const { client, runtime } = await getClient(command);
741
+ const orgs = await runQuery(client, api.users.getOrganizations, {});
742
+ printOutput(orgs, runtime.json);
743
+ });
744
+ orgCommand.command("current").action(async (_options, command) => {
745
+ const runtime = await getRuntime(command);
746
+ printOutput({ activeOrgSlug: runtime.org ?? null }, runtime.json);
747
+ });
748
+ orgCommand.command("use <slug>").action(async (slug, _options, command) => {
749
+ const runtime = await getRuntime(command);
750
+ const session = requireSession(runtime);
751
+ session.activeOrgSlug = slug;
752
+ session.appUrl = runtime.appUrl;
753
+ session.convexUrl = runtime.convexUrl;
754
+ await writeSession(session, runtime.profile);
755
+ printOutput({ activeOrgSlug: slug }, runtime.json);
756
+ });
757
+ orgCommand.command("create").requiredOption("--name <name>").requiredOption("--slug <slug>").action(async (options, command) => {
758
+ const { client, runtime, session } = await getClient(command);
759
+ const result = await runMutation(
760
+ client,
761
+ api.organizations.mutations.create,
762
+ {
763
+ data: {
764
+ name: options.name,
765
+ slug: options.slug
766
+ }
767
+ }
768
+ );
769
+ if (session) {
770
+ session.activeOrgSlug = options.slug;
771
+ session.appUrl = runtime.appUrl;
772
+ session.convexUrl = runtime.convexUrl;
773
+ await writeSession(session, runtime.profile);
774
+ }
775
+ printOutput(result, runtime.json);
776
+ });
777
+ orgCommand.command("update [slug]").option("--name <name>").option("--new-slug <slug>").action(async (slug, options, command) => {
778
+ const { client, runtime, session } = await getClient(command);
779
+ const orgSlug = requireOrg(runtime, slug);
780
+ const result = await runMutation(
781
+ client,
782
+ api.organizations.mutations.update,
783
+ {
784
+ orgSlug,
785
+ data: {
786
+ ...options.name ? { name: options.name } : {},
787
+ ...options.newSlug ? { slug: options.newSlug } : {}
788
+ }
789
+ }
790
+ );
791
+ if (session && options.newSlug && session.activeOrgSlug === orgSlug) {
792
+ session.activeOrgSlug = options.newSlug;
793
+ await writeSession(session, runtime.profile);
794
+ }
795
+ printOutput(result, runtime.json);
796
+ });
797
+ orgCommand.command("stats [slug]").action(async (slug, _options, command) => {
798
+ const { client, runtime } = await getClient(command);
799
+ const orgSlug = requireOrg(runtime, slug);
800
+ const result = await runQuery(
801
+ client,
802
+ api.organizations.queries.getOrganizationStats,
803
+ { orgSlug }
804
+ );
805
+ printOutput(result, runtime.json);
806
+ });
807
+ orgCommand.command("logo [slug]").option("--file <path>").option("--remove").action(async (slug, options, command) => {
808
+ const { client, runtime } = await getClient(command);
809
+ const orgSlug = requireOrg(runtime, slug);
810
+ if (options.remove) {
811
+ throw new Error(
812
+ "Organization logo removal is not exposed by the current backend API."
813
+ );
814
+ }
815
+ const filePath = requiredString(options.file, "file");
816
+ const uploadUrl = await runMutation(
817
+ client,
818
+ api.organizations.mutations.generateLogoUploadUrl,
819
+ { orgSlug }
820
+ );
821
+ const storageId = await uploadFile(uploadUrl, filePath);
822
+ const result = await runMutation(
823
+ client,
824
+ api.organizations.mutations.updateLogoWithStorageId,
825
+ {
826
+ orgSlug,
827
+ storageId
828
+ }
829
+ );
830
+ printOutput(
831
+ { ...result ?? { success: true }, storageId, orgSlug },
832
+ runtime.json
833
+ );
834
+ });
835
+ orgCommand.command("members [slug]").action(async (slug, _options, command) => {
836
+ const { client, runtime } = await getClient(command);
837
+ const orgSlug = requireOrg(runtime, slug);
838
+ const members = await runQuery(
839
+ client,
840
+ api.organizations.queries.listMembersWithRoles,
841
+ {
842
+ orgSlug
843
+ }
844
+ );
845
+ printOutput(members, runtime.json);
846
+ });
847
+ orgCommand.command("invites [slug]").action(async (slug, _options, command) => {
848
+ const { client, runtime } = await getClient(command);
849
+ const orgSlug = requireOrg(runtime, slug);
850
+ const invites = await runQuery(
851
+ client,
852
+ api.organizations.queries.listInvites,
853
+ {
854
+ orgSlug
855
+ }
856
+ );
857
+ printOutput(invites, runtime.json);
858
+ });
859
+ orgCommand.command("invite [slug]").requiredOption("--email <email>").option("--role <role>", "member or admin", "member").action(async (slug, options, command) => {
860
+ const { client, runtime } = await getClient(command);
861
+ const orgSlug = requireOrg(runtime, slug);
862
+ const result = await runMutation(
863
+ client,
864
+ api.organizations.mutations.invite,
865
+ {
866
+ orgSlug,
867
+ email: options.email,
868
+ role: options.role
869
+ }
870
+ );
871
+ printOutput(result, runtime.json);
872
+ });
873
+ orgCommand.command("member-role <member>").requiredOption("--role <role>", "member or admin").action(async (member, options, command) => {
874
+ const { client, runtime } = await getClient(command);
875
+ const orgSlug = requireOrg(runtime);
876
+ const userId = await resolveMemberId(client, orgSlug, member);
877
+ const result = await runMutation(
878
+ client,
879
+ api.organizations.mutations.updateMemberRole,
880
+ {
881
+ orgSlug,
882
+ userId,
883
+ role: options.role
884
+ }
885
+ );
886
+ printOutput(result, runtime.json);
887
+ });
888
+ orgCommand.command("remove-member <member>").action(async (member, _options, command) => {
889
+ const { client, runtime } = await getClient(command);
890
+ const orgSlug = requireOrg(runtime);
891
+ const userId = await resolveMemberId(client, orgSlug, member);
892
+ const result = await runMutation(
893
+ client,
894
+ api.organizations.mutations.removeMember,
895
+ {
896
+ orgSlug,
897
+ userId
898
+ }
899
+ );
900
+ printOutput(result ?? { success: true }, runtime.json);
901
+ });
902
+ orgCommand.command("revoke-invite <inviteId>").action(async (inviteId, _options, command) => {
903
+ const { client, runtime } = await getClient(command);
904
+ const result = await runMutation(
905
+ client,
906
+ api.organizations.mutations.revokeInvite,
907
+ {
908
+ inviteId
909
+ }
910
+ );
911
+ printOutput(result ?? { success: true }, runtime.json);
912
+ });
913
+ var roleCommand = program.command("role").description("Organization roles");
914
+ roleCommand.command("list [slug]").action(async (slug, _options, command) => {
915
+ const { client, runtime } = await getClient(command);
916
+ const orgSlug = requireOrg(runtime, slug);
917
+ const roles = await runQuery(client, rolesApi.list, { orgSlug });
918
+ printOutput(roles, runtime.json);
919
+ });
920
+ roleCommand.command("get <role>").action(async (role, _options, command) => {
921
+ const { client, runtime } = await getClient(command);
922
+ const orgSlug = requireOrg(runtime);
923
+ const roleId = await resolveRoleId(client, orgSlug, role);
924
+ const [summary, permissions] = await Promise.all([
925
+ runQuery(client, rolesApi.get, { orgSlug, roleId }),
926
+ runQuery(client, rolesApi.getPermissions, { roleId })
927
+ ]);
928
+ printOutput({ summary, permissions }, runtime.json);
929
+ });
930
+ roleCommand.command("create").requiredOption("--name <name>").requiredOption("--permissions <permissions>", "Comma-separated permissions").option("--description <description>").action(async (options, command) => {
931
+ const { client, runtime } = await getClient(command);
932
+ const orgSlug = requireOrg(runtime);
933
+ const result = await runMutation(client, rolesApi.create, {
934
+ orgSlug,
935
+ name: options.name,
936
+ description: options.description,
937
+ permissions: parsePermissions(options.permissions)
938
+ });
939
+ printOutput({ roleId: result }, runtime.json);
940
+ });
941
+ roleCommand.command("update <role>").requiredOption("--name <name>").requiredOption("--permissions <permissions>", "Comma-separated permissions").option("--description <description>").action(async (role, options, command) => {
942
+ const { client, runtime } = await getClient(command);
943
+ const orgSlug = requireOrg(runtime);
944
+ const roleId = await resolveRoleId(client, orgSlug, role);
945
+ const result = await runMutation(client, rolesApi.update, {
946
+ orgSlug,
947
+ roleId,
948
+ name: options.name,
949
+ description: options.description,
950
+ permissions: parsePermissions(options.permissions)
951
+ });
952
+ printOutput(result ?? { success: true }, runtime.json);
953
+ });
954
+ roleCommand.command("assign <role> <member>").action(async (role, member, _options, command) => {
955
+ const { client, runtime } = await getClient(command);
956
+ const orgSlug = requireOrg(runtime);
957
+ const [roleId, userId] = await Promise.all([
958
+ resolveRoleId(client, orgSlug, role),
959
+ resolveMemberId(client, orgSlug, member)
960
+ ]);
961
+ const result = await runMutation(client, rolesApi.assign, {
962
+ orgSlug,
963
+ roleId,
964
+ userId
965
+ });
966
+ printOutput({ assignmentId: result }, runtime.json);
967
+ });
968
+ roleCommand.command("unassign <role> <member>").action(async (role, member, _options, command) => {
969
+ const { client, runtime } = await getClient(command);
970
+ const orgSlug = requireOrg(runtime);
971
+ const [roleId, userId] = await Promise.all([
972
+ resolveRoleId(client, orgSlug, role),
973
+ resolveMemberId(client, orgSlug, member)
974
+ ]);
975
+ const result = await runMutation(client, rolesApi.removeAssignment, {
976
+ orgSlug,
977
+ roleId,
978
+ userId
979
+ });
980
+ printOutput(result ?? { success: true }, runtime.json);
981
+ });
982
+ var inviteCommand = program.command("invite").description("Invitations");
983
+ inviteCommand.command("list").action(async (_options, command) => {
984
+ const { client, runtime } = await getClient(command);
985
+ const invites = await runQuery(client, api.users.getPendingInvitations, {});
986
+ printOutput(invites, runtime.json);
987
+ });
988
+ inviteCommand.command("accept <inviteId>").action(async (inviteId, _options, command) => {
989
+ const { client, runtime } = await getClient(command);
990
+ const result = await runMutation(
991
+ client,
992
+ api.organizations.mutations.acceptInvitation,
993
+ { inviteId }
994
+ );
995
+ printOutput(result ?? { success: true }, runtime.json);
996
+ });
997
+ inviteCommand.command("decline <inviteId>").action(async (inviteId, _options, command) => {
998
+ const { client, runtime } = await getClient(command);
999
+ const result = await runMutation(
1000
+ client,
1001
+ api.organizations.mutations.declineInvitation,
1002
+ { inviteId }
1003
+ );
1004
+ printOutput(result ?? { success: true }, runtime.json);
1005
+ });
1006
+ program.command("refdata [slug]").action(async (slug, _options, command) => {
1007
+ const { client, runtime } = await getClient(command);
1008
+ const orgSlug = requireOrg(runtime, slug);
1009
+ const result = await runAction(client, cliApi.listWorkspaceReferenceData, {
1010
+ orgSlug
1011
+ });
1012
+ printOutput(result, runtime.json);
1013
+ });
1014
+ program.command("icons <query>").option("--limit <n>").action(async (query, options, command) => {
1015
+ const { client, runtime } = await getClient(command);
1016
+ const result = await runAction(client, cliApi.searchIcons, {
1017
+ query,
1018
+ limit: options.limit ? Number(options.limit) : void 0
1019
+ });
1020
+ printOutput(result, runtime.json);
1021
+ });
1022
+ program.command("search <query>").option("--limit <n>").action(async (query, options, command) => {
1023
+ const { client, runtime } = await getClient(command);
1024
+ const orgSlug = requireOrg(runtime);
1025
+ const result = await runQuery(client, api.search.queries.searchEntities, {
1026
+ orgSlug,
1027
+ query,
1028
+ limit: optionalNumber(options.limit, "limit")
1029
+ });
1030
+ printOutput(result, runtime.json);
1031
+ });
1032
+ var permissionCommand = program.command("permission").description("Permission checks");
1033
+ permissionCommand.command("check <permission>").option("--team <teamKey>").option("--project <projectKey>").action(async (permission, options, command) => {
1034
+ const { client, runtime } = await getClient(command);
1035
+ const orgSlug = requireOrg(runtime);
1036
+ const [teamId, projectId] = await Promise.all([
1037
+ resolveTeamId(client, orgSlug, options.team),
1038
+ resolveProjectId(client, orgSlug, options.project)
1039
+ ]);
1040
+ const result = await runQuery(client, api.permissions.utils.has, {
1041
+ orgSlug,
1042
+ permission,
1043
+ teamId,
1044
+ projectId
1045
+ });
1046
+ printOutput(
1047
+ { permission, allowed: result, teamId, projectId },
1048
+ runtime.json
1049
+ );
1050
+ });
1051
+ permissionCommand.command("check-many <permissions>").option("--team <teamKey>").option("--project <projectKey>").action(async (permissions, options, command) => {
1052
+ const { client, runtime } = await getClient(command);
1053
+ const orgSlug = requireOrg(runtime);
1054
+ const [teamId, projectId] = await Promise.all([
1055
+ resolveTeamId(client, orgSlug, options.team),
1056
+ resolveProjectId(client, orgSlug, options.project)
1057
+ ]);
1058
+ const permissionList = parsePermissions(permissions);
1059
+ const result = await runQuery(client, api.permissions.utils.hasMultiple, {
1060
+ orgSlug,
1061
+ permissions: permissionList,
1062
+ teamId,
1063
+ projectId
1064
+ });
1065
+ printOutput(result, runtime.json);
1066
+ });
1067
+ var activityCommand = program.command("activity").description("Activity feed");
1068
+ activityCommand.command("project <projectKey>").option("--limit <n>").option("--cursor <cursor>").action(async (projectKey, options, command) => {
1069
+ const { client, runtime } = await getClient(command);
1070
+ const orgSlug = requireOrg(runtime);
1071
+ const projectId = await resolveProjectId(client, orgSlug, projectKey);
1072
+ const result = await runQuery(
1073
+ client,
1074
+ api.activities.queries.listProjectActivity,
1075
+ {
1076
+ projectId,
1077
+ paginationOpts: buildPaginationOptions(options.limit, options.cursor)
1078
+ }
1079
+ );
1080
+ printOutput(result, runtime.json);
1081
+ });
1082
+ activityCommand.command("team <teamKey>").option("--limit <n>").option("--cursor <cursor>").action(async (teamKey, options, command) => {
1083
+ const { client, runtime } = await getClient(command);
1084
+ const orgSlug = requireOrg(runtime);
1085
+ const teamId = await resolveTeamId(client, orgSlug, teamKey);
1086
+ const result = await runQuery(
1087
+ client,
1088
+ api.activities.queries.listTeamActivity,
1089
+ {
1090
+ teamId,
1091
+ paginationOpts: buildPaginationOptions(options.limit, options.cursor)
1092
+ }
1093
+ );
1094
+ printOutput(result, runtime.json);
1095
+ });
1096
+ activityCommand.command("issue <issueKey>").option("--limit <n>").option("--cursor <cursor>").action(async (issueKey, options, command) => {
1097
+ const { client, runtime } = await getClient(command);
1098
+ const orgSlug = requireOrg(runtime);
1099
+ const issueId = await resolveIssueId(client, orgSlug, issueKey);
1100
+ const result = await runQuery(
1101
+ client,
1102
+ api.activities.queries.listIssueActivity,
1103
+ {
1104
+ issueId,
1105
+ paginationOpts: buildPaginationOptions(options.limit, options.cursor)
1106
+ }
1107
+ );
1108
+ printOutput(result, runtime.json);
1109
+ });
1110
+ activityCommand.command("document <documentId>").option("--limit <n>").option("--cursor <cursor>").action(async (documentId, options, command) => {
1111
+ const { client, runtime } = await getClient(command);
1112
+ const orgSlug = requireOrg(runtime);
1113
+ const resolvedDocumentId = await resolveDocumentId(
1114
+ client,
1115
+ orgSlug,
1116
+ documentId
1117
+ );
1118
+ const result = await runQuery(
1119
+ client,
1120
+ api.activities.queries.listDocumentActivity,
1121
+ {
1122
+ documentId: resolvedDocumentId,
1123
+ paginationOpts: buildPaginationOptions(options.limit, options.cursor)
1124
+ }
1125
+ );
1126
+ printOutput(result, runtime.json);
1127
+ });
1128
+ var notificationCommand = program.command("notification").description("Notifications");
1129
+ notificationCommand.command("inbox").option("--filter <filter>", "all or unread").option("--limit <n>").option("--cursor <cursor>").action(async (options, command) => {
1130
+ const { client, runtime } = await getClient(command);
1131
+ const result = await runQuery(client, api.notifications.queries.listInbox, {
1132
+ filter: options.filter,
1133
+ paginationOpts: buildPaginationOptions(options.limit, options.cursor)
1134
+ });
1135
+ printOutput(result, runtime.json);
1136
+ });
1137
+ notificationCommand.command("unread-count").action(async (_options, command) => {
1138
+ const { client, runtime } = await getClient(command);
1139
+ const result = await runQuery(
1140
+ client,
1141
+ api.notifications.queries.unreadCount,
1142
+ {}
1143
+ );
1144
+ printOutput({ unreadCount: result }, runtime.json);
1145
+ });
1146
+ notificationCommand.command("mark-read <recipientId>").action(async (recipientId, _options, command) => {
1147
+ const { client, runtime } = await getClient(command);
1148
+ const result = await runMutation(
1149
+ client,
1150
+ api.notifications.mutations.markRead,
1151
+ {
1152
+ recipientId
1153
+ }
1154
+ );
1155
+ printOutput(result, runtime.json);
1156
+ });
1157
+ notificationCommand.command("mark-all-read").action(async (_options, command) => {
1158
+ const { client, runtime } = await getClient(command);
1159
+ const result = await runMutation(
1160
+ client,
1161
+ api.notifications.mutations.markAllRead,
1162
+ {}
1163
+ );
1164
+ printOutput(result, runtime.json);
1165
+ });
1166
+ notificationCommand.command("archive <recipientId>").action(async (recipientId, _options, command) => {
1167
+ const { client, runtime } = await getClient(command);
1168
+ const result = await runMutation(
1169
+ client,
1170
+ api.notifications.mutations.archive,
1171
+ {
1172
+ recipientId
1173
+ }
1174
+ );
1175
+ printOutput(result, runtime.json);
1176
+ });
1177
+ notificationCommand.command("preferences").action(async (_options, command) => {
1178
+ const { client, runtime } = await getClient(command);
1179
+ const result = await runQuery(
1180
+ client,
1181
+ api.notifications.queries.getPreferences,
1182
+ {}
1183
+ );
1184
+ printOutput(result, runtime.json);
1185
+ });
1186
+ notificationCommand.command("set-preference <category>").requiredOption("--in-app <true|false>").requiredOption("--email <true|false>").requiredOption("--push <true|false>").action(async (category, options, command) => {
1187
+ const { client, runtime } = await getClient(command);
1188
+ if (!NOTIFICATION_CATEGORIES.includes(category)) {
1189
+ throw new Error(
1190
+ `category must be one of: ${NOTIFICATION_CATEGORIES.join(", ")}`
1191
+ );
1192
+ }
1193
+ const result = await runMutation(
1194
+ client,
1195
+ api.notifications.mutations.updatePreferences,
1196
+ {
1197
+ category,
1198
+ inAppEnabled: parseBoolean(options.inApp, "in-app"),
1199
+ emailEnabled: parseBoolean(options.email, "email"),
1200
+ pushEnabled: parseBoolean(options.push, "push")
1201
+ }
1202
+ );
1203
+ printOutput(result, runtime.json);
1204
+ });
1205
+ notificationCommand.command("subscriptions").action(async (_options, command) => {
1206
+ const { client, runtime } = await getClient(command);
1207
+ const result = await runQuery(
1208
+ client,
1209
+ api.notifications.queries.listPushSubscriptions,
1210
+ {}
1211
+ );
1212
+ printOutput(result, runtime.json);
1213
+ });
1214
+ notificationCommand.command("remove-subscription <subscriptionId>").action(async (subscriptionId, _options, command) => {
1215
+ const { client, runtime } = await getClient(command);
1216
+ const result = await runMutation(
1217
+ client,
1218
+ api.notifications.mutations.removePushSubscription,
1219
+ { subscriptionId }
1220
+ );
1221
+ printOutput(result, runtime.json);
1222
+ });
1223
+ var priorityCommand = program.command("priority").description("Issue priorities");
1224
+ priorityCommand.command("list [slug]").action(async (slug, _options, command) => {
1225
+ const { client, runtime } = await getClient(command);
1226
+ const orgSlug = requireOrg(runtime, slug);
1227
+ const result = await runQuery(
1228
+ client,
1229
+ api.organizations.queries.listIssuePriorities,
1230
+ { orgSlug }
1231
+ );
1232
+ printOutput(result, runtime.json);
1233
+ });
1234
+ priorityCommand.command("create").requiredOption("--name <name>").requiredOption("--weight <n>").requiredOption("--color <hex>").option("--icon <icon>").action(async (options, command) => {
1235
+ const { client, runtime } = await getClient(command);
1236
+ const orgSlug = requireOrg(runtime);
1237
+ const result = await runMutation(
1238
+ client,
1239
+ api.organizations.mutations.createIssuePriority,
1240
+ {
1241
+ orgSlug,
1242
+ name: options.name,
1243
+ weight: requiredNumber(options.weight, "weight"),
1244
+ color: options.color,
1245
+ icon: options.icon
1246
+ }
1247
+ );
1248
+ printOutput(result, runtime.json);
1249
+ });
1250
+ priorityCommand.command("update <priority>").requiredOption("--name <name>").requiredOption("--color <hex>").option("--weight <n>").option("--icon <icon>").action(async (priority, options, command) => {
1251
+ const { client, runtime } = await getClient(command);
1252
+ const orgSlug = requireOrg(runtime);
1253
+ const priorityId = await resolveIssuePriorityId(client, orgSlug, priority);
1254
+ const result = await runMutation(
1255
+ client,
1256
+ api.organizations.mutations.updateIssuePriority,
1257
+ {
1258
+ orgSlug,
1259
+ priorityId,
1260
+ name: options.name,
1261
+ weight: optionalNumber(options.weight, "weight"),
1262
+ color: options.color,
1263
+ icon: options.icon
1264
+ }
1265
+ );
1266
+ printOutput(result ?? { success: true }, runtime.json);
1267
+ });
1268
+ priorityCommand.command("delete <priority>").action(async (priority, _options, command) => {
1269
+ const { client, runtime } = await getClient(command);
1270
+ const orgSlug = requireOrg(runtime);
1271
+ const priorityId = await resolveIssuePriorityId(client, orgSlug, priority);
1272
+ const result = await runMutation(
1273
+ client,
1274
+ api.organizations.mutations.deleteIssuePriority,
1275
+ {
1276
+ orgSlug,
1277
+ priorityId
1278
+ }
1279
+ );
1280
+ printOutput(result ?? { success: true }, runtime.json);
1281
+ });
1282
+ priorityCommand.command("reset [slug]").action(async (slug, _options, command) => {
1283
+ const { client, runtime } = await getClient(command);
1284
+ const orgSlug = requireOrg(runtime, slug);
1285
+ const result = await runMutation(
1286
+ client,
1287
+ api.organizations.mutations.resetIssuePriorities,
1288
+ { orgSlug }
1289
+ );
1290
+ printOutput(result ?? { success: true }, runtime.json);
1291
+ });
1292
+ var stateCommand = program.command("state").description("Issue states");
1293
+ stateCommand.command("list [slug]").action(async (slug, _options, command) => {
1294
+ const { client, runtime } = await getClient(command);
1295
+ const orgSlug = requireOrg(runtime, slug);
1296
+ const result = await runQuery(
1297
+ client,
1298
+ api.organizations.queries.listIssueStates,
1299
+ {
1300
+ orgSlug
1301
+ }
1302
+ );
1303
+ printOutput(result, runtime.json);
1304
+ });
1305
+ stateCommand.command("create").requiredOption("--name <name>").requiredOption("--position <n>").requiredOption("--type <type>").requiredOption("--color <hex>").option("--icon <icon>").action(async (options, command) => {
1306
+ const { client, runtime } = await getClient(command);
1307
+ const orgSlug = requireOrg(runtime);
1308
+ if (!ISSUE_STATE_TYPES.includes(options.type)) {
1309
+ throw new Error(`type must be one of: ${ISSUE_STATE_TYPES.join(", ")}`);
1310
+ }
1311
+ const result = await runMutation(
1312
+ client,
1313
+ api.organizations.mutations.createIssueState,
1314
+ {
1315
+ orgSlug,
1316
+ name: options.name,
1317
+ position: requiredNumber(options.position, "position"),
1318
+ type: options.type,
1319
+ color: options.color,
1320
+ icon: options.icon
1321
+ }
1322
+ );
1323
+ printOutput(result, runtime.json);
1324
+ });
1325
+ stateCommand.command("update <state>").requiredOption("--name <name>").requiredOption("--position <n>").requiredOption("--type <type>").requiredOption("--color <hex>").option("--icon <icon>").action(async (state, options, command) => {
1326
+ const { client, runtime } = await getClient(command);
1327
+ const orgSlug = requireOrg(runtime);
1328
+ if (!ISSUE_STATE_TYPES.includes(options.type)) {
1329
+ throw new Error(`type must be one of: ${ISSUE_STATE_TYPES.join(", ")}`);
1330
+ }
1331
+ const stateId = await resolveIssueStateId(client, orgSlug, state);
1332
+ const result = await runMutation(
1333
+ client,
1334
+ api.organizations.mutations.updateIssueState,
1335
+ {
1336
+ orgSlug,
1337
+ stateId,
1338
+ name: options.name,
1339
+ position: requiredNumber(options.position, "position"),
1340
+ type: options.type,
1341
+ color: options.color,
1342
+ icon: options.icon
1343
+ }
1344
+ );
1345
+ printOutput(result ?? { success: true }, runtime.json);
1346
+ });
1347
+ stateCommand.command("delete <state>").action(async (state, _options, command) => {
1348
+ const { client, runtime } = await getClient(command);
1349
+ const orgSlug = requireOrg(runtime);
1350
+ const stateId = await resolveIssueStateId(client, orgSlug, state);
1351
+ const result = await runMutation(
1352
+ client,
1353
+ api.organizations.mutations.deleteIssueState,
1354
+ {
1355
+ orgSlug,
1356
+ stateId
1357
+ }
1358
+ );
1359
+ printOutput(result ?? { success: true }, runtime.json);
1360
+ });
1361
+ stateCommand.command("reset [slug]").action(async (slug, _options, command) => {
1362
+ const { client, runtime } = await getClient(command);
1363
+ const orgSlug = requireOrg(runtime, slug);
1364
+ const result = await runMutation(
1365
+ client,
1366
+ api.organizations.mutations.resetIssueStates,
1367
+ { orgSlug }
1368
+ );
1369
+ printOutput(result ?? { success: true }, runtime.json);
1370
+ });
1371
+ var statusCommand = program.command("status").description("Project statuses");
1372
+ statusCommand.command("list [slug]").action(async (slug, _options, command) => {
1373
+ const { client, runtime } = await getClient(command);
1374
+ const orgSlug = requireOrg(runtime, slug);
1375
+ const result = await runQuery(
1376
+ client,
1377
+ api.organizations.queries.listProjectStatuses,
1378
+ { orgSlug }
1379
+ );
1380
+ printOutput(result, runtime.json);
1381
+ });
1382
+ statusCommand.command("create").requiredOption("--name <name>").requiredOption("--position <n>").requiredOption("--type <type>").requiredOption("--color <hex>").option("--icon <icon>").action(async (options, command) => {
1383
+ const { client, runtime } = await getClient(command);
1384
+ const orgSlug = requireOrg(runtime);
1385
+ if (!PROJECT_STATUS_TYPES.includes(options.type)) {
1386
+ throw new Error(
1387
+ `type must be one of: ${PROJECT_STATUS_TYPES.join(", ")}`
1388
+ );
1389
+ }
1390
+ const result = await runMutation(
1391
+ client,
1392
+ api.organizations.mutations.createProjectStatus,
1393
+ {
1394
+ orgSlug,
1395
+ name: options.name,
1396
+ position: requiredNumber(options.position, "position"),
1397
+ type: options.type,
1398
+ color: options.color,
1399
+ icon: options.icon
1400
+ }
1401
+ );
1402
+ printOutput(result, runtime.json);
1403
+ });
1404
+ statusCommand.command("update <status>").requiredOption("--name <name>").requiredOption("--position <n>").requiredOption("--type <type>").requiredOption("--color <hex>").option("--icon <icon>").action(async (status, options, command) => {
1405
+ const { client, runtime } = await getClient(command);
1406
+ const orgSlug = requireOrg(runtime);
1407
+ if (!PROJECT_STATUS_TYPES.includes(options.type)) {
1408
+ throw new Error(
1409
+ `type must be one of: ${PROJECT_STATUS_TYPES.join(", ")}`
1410
+ );
1411
+ }
1412
+ const statusId = await resolveProjectStatusId(client, orgSlug, status);
1413
+ const result = await runMutation(
1414
+ client,
1415
+ api.organizations.mutations.updateProjectStatus,
1416
+ {
1417
+ orgSlug,
1418
+ statusId,
1419
+ name: options.name,
1420
+ position: requiredNumber(options.position, "position"),
1421
+ type: options.type,
1422
+ color: options.color,
1423
+ icon: options.icon
1424
+ }
1425
+ );
1426
+ printOutput(result ?? { success: true }, runtime.json);
1427
+ });
1428
+ statusCommand.command("delete <status>").action(async (status, _options, command) => {
1429
+ const { client, runtime } = await getClient(command);
1430
+ const orgSlug = requireOrg(runtime);
1431
+ const statusId = await resolveProjectStatusId(client, orgSlug, status);
1432
+ const result = await runMutation(
1433
+ client,
1434
+ api.organizations.mutations.deleteProjectStatus,
1435
+ {
1436
+ orgSlug,
1437
+ statusId
1438
+ }
1439
+ );
1440
+ printOutput(result ?? { success: true }, runtime.json);
1441
+ });
1442
+ statusCommand.command("reset [slug]").action(async (slug, _options, command) => {
1443
+ const { client, runtime } = await getClient(command);
1444
+ const orgSlug = requireOrg(runtime, slug);
1445
+ const result = await runMutation(
1446
+ client,
1447
+ api.organizations.mutations.resetProjectStatuses,
1448
+ { orgSlug }
1449
+ );
1450
+ printOutput(result ?? { success: true }, runtime.json);
1451
+ });
1452
+ var adminCommand = program.command("admin").description("Platform admin");
1453
+ adminCommand.command("branding").action(async (_options, command) => {
1454
+ const { client, runtime } = await getClient(command);
1455
+ const result = await runQuery(
1456
+ client,
1457
+ api.platformAdmin.queries.getBranding,
1458
+ {}
1459
+ );
1460
+ printOutput(result, runtime.json);
1461
+ });
1462
+ adminCommand.command("set-branding").option("--name <name>").option("--description <description>").option("--theme-color <hex>").option("--accent-color <hex>").option("--logo <path>").option("--remove-logo").action(async (options, command) => {
1463
+ const { client, runtime } = await getClient(command);
1464
+ let logoStorageId;
1465
+ if (options.logo) {
1466
+ const uploadUrl = await runMutation(
1467
+ client,
1468
+ api.platformAdmin.mutations.generateBrandLogoUploadUrl,
1469
+ {}
1470
+ );
1471
+ logoStorageId = await uploadFile(uploadUrl, options.logo);
1472
+ }
1473
+ const result = await runMutation(
1474
+ client,
1475
+ api.platformAdmin.mutations.updateBranding,
1476
+ {
1477
+ name: options.name,
1478
+ description: options.description,
1479
+ logoStorageId,
1480
+ removeLogo: options.removeLogo ? true : void 0,
1481
+ themeColor: options.themeColor,
1482
+ accentColor: options.accentColor
1483
+ }
1484
+ );
1485
+ printOutput(
1486
+ {
1487
+ ...result ?? { success: true },
1488
+ logoStorageId: logoStorageId ?? null
1489
+ },
1490
+ runtime.json
1491
+ );
1492
+ });
1493
+ adminCommand.command("signup-policy").action(async (_options, command) => {
1494
+ const { client, runtime } = await getClient(command);
1495
+ const result = await runQuery(
1496
+ client,
1497
+ api.platformAdmin.queries.getSignupPolicy,
1498
+ {}
1499
+ );
1500
+ printOutput(result, runtime.json);
1501
+ });
1502
+ adminCommand.command("set-signup-policy").option("--blocked <domains>").option("--allowed <domains>").action(async (options, command) => {
1503
+ const { client, runtime } = await getClient(command);
1504
+ const result = await runMutation(
1505
+ client,
1506
+ api.platformAdmin.mutations.updateSignupEmailDomainPolicy,
1507
+ {
1508
+ blockedDomains: parseList(options.blocked),
1509
+ allowedDomains: parseList(options.allowed)
1510
+ }
1511
+ );
1512
+ printOutput(result ?? { success: true }, runtime.json);
1513
+ });
1514
+ adminCommand.command("sync-disposable-domains").action(async (_options, command) => {
1515
+ const { client, runtime } = await getClient(command);
1516
+ const result = await runAction(
1517
+ client,
1518
+ api.platformAdmin.actions.runDisposableDomainSyncNow,
1519
+ {}
1520
+ );
1521
+ printOutput(result, runtime.json);
1522
+ });
1523
+ var teamCommand = program.command("team").description("Teams");
1524
+ teamCommand.command("list [slug]").option("--limit <n>").action(async (slug, options, command) => {
1525
+ const { client, runtime } = await getClient(command);
1526
+ const orgSlug = requireOrg(runtime, slug);
1527
+ const result = await runAction(client, cliApi.listTeams, {
1528
+ orgSlug,
1529
+ limit: options.limit ? Number(options.limit) : void 0
1530
+ });
1531
+ printOutput(result, runtime.json);
1532
+ });
1533
+ teamCommand.command("get <teamKey>").action(async (teamKey, _options, command) => {
1534
+ const { client, runtime } = await getClient(command);
1535
+ const orgSlug = requireOrg(runtime);
1536
+ const result = await runAction(client, cliApi.getTeam, {
1537
+ orgSlug,
1538
+ teamKey
1539
+ });
1540
+ printOutput(result, runtime.json);
1541
+ });
1542
+ teamCommand.command("create").requiredOption("--key <key>").requiredOption("--name <name>").option("--description <description>").option("--visibility <visibility>").option("--icon <icon>").option("--color <color>").action(async (options, command) => {
1543
+ const { client, runtime } = await getClient(command);
1544
+ const orgSlug = requireOrg(runtime);
1545
+ const result = await runAction(client, cliApi.createTeam, {
1546
+ orgSlug,
1547
+ key: options.key,
1548
+ name: options.name,
1549
+ description: options.description,
1550
+ visibility: options.visibility,
1551
+ icon: options.icon,
1552
+ color: options.color
1553
+ });
1554
+ printOutput(result, runtime.json);
1555
+ });
1556
+ teamCommand.command("update <teamKey>").option("--name <name>").option("--description <description>").option("--clear-description").option("--visibility <visibility>").option("--icon <icon>").option("--clear-icon").option("--color <color>").option("--clear-color").action(async (teamKey, options, command) => {
1557
+ const { client, runtime } = await getClient(command);
1558
+ const orgSlug = requireOrg(runtime);
1559
+ const result = await runAction(client, cliApi.updateTeam, {
1560
+ orgSlug,
1561
+ teamKey,
1562
+ name: options.name,
1563
+ description: nullableOption(
1564
+ options.description,
1565
+ options.clearDescription
1566
+ ),
1567
+ visibility: options.visibility,
1568
+ icon: nullableOption(options.icon, options.clearIcon),
1569
+ color: nullableOption(options.color, options.clearColor)
1570
+ });
1571
+ printOutput(result, runtime.json);
1572
+ });
1573
+ teamCommand.command("delete <teamKey>").action(async (teamKey, _options, command) => {
1574
+ const { client, runtime } = await getClient(command);
1575
+ const orgSlug = requireOrg(runtime);
1576
+ const result = await runAction(client, cliApi.deleteTeam, {
1577
+ orgSlug,
1578
+ teamKey
1579
+ });
1580
+ printOutput(result, runtime.json);
1581
+ });
1582
+ teamCommand.command("members <teamKey>").action(async (teamKey, _options, command) => {
1583
+ const { client, runtime } = await getClient(command);
1584
+ const orgSlug = requireOrg(runtime);
1585
+ const team = await runAction(client, cliApi.getTeam, { orgSlug, teamKey });
1586
+ const result = await runQuery(client, api.teams.queries.listMembers, {
1587
+ teamId: team.id
1588
+ });
1589
+ printOutput(result, runtime.json);
1590
+ });
1591
+ teamCommand.command("add-member <teamKey> <member>").option("--role <role>", "member or lead", "member").action(async (teamKey, member, options, command) => {
1592
+ const { client, runtime } = await getClient(command);
1593
+ const orgSlug = requireOrg(runtime);
1594
+ const result = await runAction(client, cliApi.addTeamMember, {
1595
+ orgSlug,
1596
+ teamKey,
1597
+ memberName: member,
1598
+ role: options.role
1599
+ });
1600
+ printOutput(result, runtime.json);
1601
+ });
1602
+ teamCommand.command("remove-member <teamKey> <member>").action(async (teamKey, member, _options, command) => {
1603
+ const { client, runtime } = await getClient(command);
1604
+ const orgSlug = requireOrg(runtime);
1605
+ const result = await runAction(client, cliApi.removeTeamMember, {
1606
+ orgSlug,
1607
+ teamKey,
1608
+ memberName: member
1609
+ });
1610
+ printOutput(result, runtime.json);
1611
+ });
1612
+ teamCommand.command("set-lead <teamKey> <member>").action(async (teamKey, member, _options, command) => {
1613
+ const { client, runtime } = await getClient(command);
1614
+ const orgSlug = requireOrg(runtime);
1615
+ const leadName = member === "null" ? null : member;
1616
+ const result = await runAction(client, cliApi.changeTeamLead, {
1617
+ orgSlug,
1618
+ teamKey,
1619
+ leadName
1620
+ });
1621
+ printOutput(result, runtime.json);
1622
+ });
1623
+ var projectCommand = program.command("project").description("Projects");
1624
+ projectCommand.command("list [slug]").option("--team <teamKey>").option("--limit <n>").action(async (slug, options, command) => {
1625
+ const { client, runtime } = await getClient(command);
1626
+ const orgSlug = requireOrg(runtime, slug);
1627
+ const result = await runAction(client, cliApi.listProjects, {
1628
+ orgSlug,
1629
+ teamKey: options.team,
1630
+ limit: options.limit ? Number(options.limit) : void 0
1631
+ });
1632
+ printOutput(result, runtime.json);
1633
+ });
1634
+ projectCommand.command("get <projectKey>").action(async (projectKey, _options, command) => {
1635
+ const { client, runtime } = await getClient(command);
1636
+ const orgSlug = requireOrg(runtime);
1637
+ const result = await runAction(client, cliApi.getProject, {
1638
+ orgSlug,
1639
+ projectKey
1640
+ });
1641
+ printOutput(result, runtime.json);
1642
+ });
1643
+ projectCommand.command("create").requiredOption("--key <key>").requiredOption("--name <name>").option("--description <description>").option("--team <teamKey>").option("--status <statusName>").option("--visibility <visibility>").option("--icon <icon>").option("--color <color>").action(async (options, command) => {
1644
+ const { client, runtime } = await getClient(command);
1645
+ const orgSlug = requireOrg(runtime);
1646
+ const result = await runAction(client, cliApi.createProject, {
1647
+ orgSlug,
1648
+ key: options.key,
1649
+ name: options.name,
1650
+ description: options.description,
1651
+ teamKey: options.team,
1652
+ statusName: options.status,
1653
+ visibility: options.visibility,
1654
+ icon: options.icon,
1655
+ color: options.color
1656
+ });
1657
+ printOutput(result, runtime.json);
1658
+ });
1659
+ projectCommand.command("update <projectKey>").option("--name <name>").option("--description <description>").option("--team <teamKey>").option("--clear-team").option("--status <statusName>").option("--clear-status").option("--visibility <visibility>").option("--start-date <date>").option("--clear-start-date").option("--due-date <date>").option("--clear-due-date").option("--icon <icon>").option("--clear-icon").option("--color <color>").option("--clear-color").action(async (projectKey, options, command) => {
1660
+ const { client, runtime } = await getClient(command);
1661
+ const orgSlug = requireOrg(runtime);
1662
+ const result = await runAction(client, cliApi.updateProject, {
1663
+ orgSlug,
1664
+ projectKey,
1665
+ name: options.name,
1666
+ description: options.description,
1667
+ teamKey: nullableOption(options.team, options.clearTeam),
1668
+ statusName: nullableOption(options.status, options.clearStatus),
1669
+ visibility: options.visibility,
1670
+ startDate: nullableOption(options.startDate, options.clearStartDate),
1671
+ dueDate: nullableOption(options.dueDate, options.clearDueDate),
1672
+ icon: nullableOption(options.icon, options.clearIcon),
1673
+ color: nullableOption(options.color, options.clearColor)
1674
+ });
1675
+ printOutput(result, runtime.json);
1676
+ });
1677
+ projectCommand.command("delete <projectKey>").action(async (projectKey, _options, command) => {
1678
+ const { client, runtime } = await getClient(command);
1679
+ const orgSlug = requireOrg(runtime);
1680
+ const result = await runAction(client, cliApi.deleteProject, {
1681
+ orgSlug,
1682
+ projectKey
1683
+ });
1684
+ printOutput(result, runtime.json);
1685
+ });
1686
+ projectCommand.command("members <projectKey>").action(async (projectKey, _options, command) => {
1687
+ const { client, runtime } = await getClient(command);
1688
+ const orgSlug = requireOrg(runtime);
1689
+ const project = await runAction(client, cliApi.getProject, {
1690
+ orgSlug,
1691
+ projectKey
1692
+ });
1693
+ const result = await runQuery(client, api.projects.queries.listMembers, {
1694
+ projectId: project.id
1695
+ });
1696
+ printOutput(result, runtime.json);
1697
+ });
1698
+ projectCommand.command("add-member <projectKey> <member>").option("--role <role>", "member or lead", "member").action(async (projectKey, member, options, command) => {
1699
+ const { client, runtime } = await getClient(command);
1700
+ const orgSlug = requireOrg(runtime);
1701
+ const result = await runAction(client, cliApi.addProjectMember, {
1702
+ orgSlug,
1703
+ projectKey,
1704
+ memberName: member,
1705
+ role: options.role
1706
+ });
1707
+ printOutput(result, runtime.json);
1708
+ });
1709
+ projectCommand.command("remove-member <projectKey> <member>").action(async (projectKey, member, _options, command) => {
1710
+ const { client, runtime } = await getClient(command);
1711
+ const orgSlug = requireOrg(runtime);
1712
+ const result = await runAction(client, cliApi.removeProjectMember, {
1713
+ orgSlug,
1714
+ projectKey,
1715
+ memberName: member
1716
+ });
1717
+ printOutput(result, runtime.json);
1718
+ });
1719
+ projectCommand.command("set-lead <projectKey> <member>").action(async (projectKey, member, _options, command) => {
1720
+ const { client, runtime } = await getClient(command);
1721
+ const orgSlug = requireOrg(runtime);
1722
+ const leadName = member === "null" ? null : member;
1723
+ const result = await runAction(client, cliApi.changeProjectLead, {
1724
+ orgSlug,
1725
+ projectKey,
1726
+ leadName
1727
+ });
1728
+ printOutput(result, runtime.json);
1729
+ });
1730
+ var issueCommand = program.command("issue").description("Issues");
1731
+ issueCommand.command("list [slug]").option("--project <projectKey>").option("--team <teamKey>").option("--limit <n>").action(async (slug, options, command) => {
1732
+ const { client, runtime } = await getClient(command);
1733
+ const orgSlug = requireOrg(runtime, slug);
1734
+ const result = await runAction(client, cliApi.listIssues, {
1735
+ orgSlug,
1736
+ projectKey: options.project,
1737
+ teamKey: options.team,
1738
+ limit: options.limit ? Number(options.limit) : void 0
1739
+ });
1740
+ printOutput(result, runtime.json);
1741
+ });
1742
+ issueCommand.command("get <issueKey>").action(async (issueKey, _options, command) => {
1743
+ const { client, runtime } = await getClient(command);
1744
+ const orgSlug = requireOrg(runtime);
1745
+ const result = await runAction(client, cliApi.getIssue, {
1746
+ orgSlug,
1747
+ issueKey
1748
+ });
1749
+ printOutput(result, runtime.json);
1750
+ });
1751
+ issueCommand.command("create").requiredOption("--title <title>").option("--description <description>").option("--project <projectKey>").option("--team <teamKey>").option("--priority <priorityName>").option("--visibility <visibility>").option("--assignee <member>").option("--state <stateName>").option("--start-date <date>").option("--due-date <date>").option("--parent <issueKey>").action(async (options, command) => {
1752
+ const { client, runtime } = await getClient(command);
1753
+ const orgSlug = requireOrg(runtime);
1754
+ const result = await runAction(client, cliApi.createIssue, {
1755
+ orgSlug,
1756
+ title: options.title,
1757
+ description: options.description,
1758
+ projectKey: options.project,
1759
+ teamKey: options.team,
1760
+ priorityName: options.priority,
1761
+ visibility: options.visibility,
1762
+ assigneeName: options.assignee,
1763
+ stateName: options.state,
1764
+ startDate: options.startDate,
1765
+ dueDate: options.dueDate,
1766
+ parentIssueKey: options.parent
1767
+ });
1768
+ printOutput(result, runtime.json);
1769
+ });
1770
+ issueCommand.command("update <issueKey>").option("--title <title>").option("--description <description>").option("--priority <priorityName>").option("--clear-priority").option("--team <teamKey>").option("--clear-team").option("--project <projectKey>").option("--clear-project").option("--visibility <visibility>").option("--assignee <member>").option("--clear-assignee").option("--state <stateName>").option("--start-date <date>").option("--clear-start-date").option("--due-date <date>").option("--clear-due-date").option("--parent <issueKey>").option("--clear-parent").action(async (issueKey, options, command) => {
1771
+ const { client, runtime } = await getClient(command);
1772
+ const orgSlug = requireOrg(runtime);
1773
+ const result = await runAction(client, cliApi.updateIssue, {
1774
+ orgSlug,
1775
+ issueKey,
1776
+ title: options.title,
1777
+ description: options.description,
1778
+ priorityName: nullableOption(options.priority, options.clearPriority),
1779
+ teamKey: nullableOption(options.team, options.clearTeam),
1780
+ projectKey: nullableOption(options.project, options.clearProject),
1781
+ visibility: options.visibility,
1782
+ assigneeName: nullableOption(options.assignee, options.clearAssignee),
1783
+ stateName: options.state,
1784
+ startDate: nullableOption(options.startDate, options.clearStartDate),
1785
+ dueDate: nullableOption(options.dueDate, options.clearDueDate),
1786
+ parentIssueKey: nullableOption(options.parent, options.clearParent)
1787
+ });
1788
+ printOutput(result, runtime.json);
1789
+ });
1790
+ issueCommand.command("delete <issueKey>").action(async (issueKey, _options, command) => {
1791
+ const { client, runtime } = await getClient(command);
1792
+ const orgSlug = requireOrg(runtime);
1793
+ const result = await runAction(client, cliApi.deleteIssue, {
1794
+ orgSlug,
1795
+ issueKey
1796
+ });
1797
+ printOutput(result, runtime.json);
1798
+ });
1799
+ issueCommand.command("assign <issueKey> <member>").option("--state <stateName>").action(async (issueKey, member, options, command) => {
1800
+ const { client, runtime } = await getClient(command);
1801
+ const orgSlug = requireOrg(runtime);
1802
+ const result = await runAction(client, cliApi.assignIssue, {
1803
+ orgSlug,
1804
+ issueKey,
1805
+ assigneeName: member,
1806
+ stateName: options.state
1807
+ });
1808
+ printOutput(result, runtime.json);
1809
+ });
1810
+ issueCommand.command("unassign <issueKey> <member>").action(async (issueKey, member, _options, command) => {
1811
+ const { client, runtime } = await getClient(command);
1812
+ const orgSlug = requireOrg(runtime);
1813
+ const result = await runAction(client, cliApi.unassignIssue, {
1814
+ orgSlug,
1815
+ issueKey,
1816
+ assigneeName: member
1817
+ });
1818
+ printOutput(result, runtime.json);
1819
+ });
1820
+ issueCommand.command("assignments <issueKey>").action(async (issueKey, _options, command) => {
1821
+ const { client, runtime } = await getClient(command);
1822
+ const orgSlug = requireOrg(runtime);
1823
+ const issueId = await resolveIssueId(client, orgSlug, issueKey);
1824
+ const result = await runQuery(client, api.issues.queries.getAssignments, {
1825
+ issueId
1826
+ });
1827
+ printOutput(result, runtime.json);
1828
+ });
1829
+ issueCommand.command("set-assignment-state <assignmentId> <state>").action(async (assignmentId, state, _options, command) => {
1830
+ const { client, runtime } = await getClient(command);
1831
+ const orgSlug = requireOrg(runtime);
1832
+ const stateId = await resolveIssueStateId(client, orgSlug, state);
1833
+ const result = await runMutation(
1834
+ client,
1835
+ api.issues.mutations.changeAssignmentState,
1836
+ {
1837
+ assignmentId,
1838
+ stateId
1839
+ }
1840
+ );
1841
+ printOutput(result ?? { success: true }, runtime.json);
1842
+ });
1843
+ issueCommand.command("reassign-assignment <assignmentId> <member>").action(async (assignmentId, member, _options, command) => {
1844
+ const { client, runtime } = await getClient(command);
1845
+ const orgSlug = requireOrg(runtime);
1846
+ const assigneeId = await resolveMemberId(client, orgSlug, member);
1847
+ const result = await runMutation(
1848
+ client,
1849
+ api.issues.mutations.updateAssignmentAssignee,
1850
+ {
1851
+ assignmentId,
1852
+ assigneeId
1853
+ }
1854
+ );
1855
+ printOutput(result ?? { success: true }, runtime.json);
1856
+ });
1857
+ issueCommand.command("remove-assignment <assignmentId>").action(async (assignmentId, _options, command) => {
1858
+ const { client, runtime } = await getClient(command);
1859
+ const result = await runMutation(
1860
+ client,
1861
+ api.issues.mutations.deleteAssignment,
1862
+ {
1863
+ assignmentId
1864
+ }
1865
+ );
1866
+ printOutput(result ?? { success: true }, runtime.json);
1867
+ });
1868
+ issueCommand.command("set-priority <issueKey> <priority>").action(async (issueKey, priority, _options, command) => {
1869
+ const { client, runtime } = await getClient(command);
1870
+ const orgSlug = requireOrg(runtime);
1871
+ const [issueId, priorityId] = await Promise.all([
1872
+ resolveIssueId(client, orgSlug, issueKey),
1873
+ resolveIssuePriorityId(client, orgSlug, priority)
1874
+ ]);
1875
+ const result = await runMutation(
1876
+ client,
1877
+ api.issues.mutations.changePriority,
1878
+ {
1879
+ issueId,
1880
+ priorityId
1881
+ }
1882
+ );
1883
+ printOutput(result ?? { success: true }, runtime.json);
1884
+ });
1885
+ issueCommand.command("replace-assignees <issueKey> <members>").action(async (issueKey, members, _options, command) => {
1886
+ const { client, runtime } = await getClient(command);
1887
+ const orgSlug = requireOrg(runtime);
1888
+ const issueId = await resolveIssueId(client, orgSlug, issueKey);
1889
+ const assigneeIds = await Promise.all(
1890
+ parseList(members).map(
1891
+ (member) => resolveMemberId(client, orgSlug, member)
1892
+ )
1893
+ );
1894
+ const result = await runMutation(
1895
+ client,
1896
+ api.issues.mutations.updateAssignees,
1897
+ {
1898
+ issueId,
1899
+ assigneeIds
1900
+ }
1901
+ );
1902
+ printOutput(result ?? { success: true }, runtime.json);
1903
+ });
1904
+ issueCommand.command("set-estimates <issueKey>").requiredOption("--values <state=hours,...>").action(async (issueKey, options, command) => {
1905
+ const { client, runtime } = await getClient(command);
1906
+ const orgSlug = requireOrg(runtime);
1907
+ const issueId = await resolveIssueId(client, orgSlug, issueKey);
1908
+ const estimatedTimes = await parseEstimatedTimes(
1909
+ client,
1910
+ orgSlug,
1911
+ options.values
1912
+ );
1913
+ const result = await runMutation(
1914
+ client,
1915
+ api.issues.mutations.updateEstimatedTimes,
1916
+ {
1917
+ issueId,
1918
+ estimatedTimes
1919
+ }
1920
+ );
1921
+ printOutput(result ?? { success: true }, runtime.json);
1922
+ });
1923
+ issueCommand.command("comment <issueKey>").requiredOption("--body <body>").action(async (issueKey, options, command) => {
1924
+ const { client, runtime } = await getClient(command);
1925
+ const orgSlug = requireOrg(runtime);
1926
+ const issue = await runAction(client, cliApi.getIssue, {
1927
+ orgSlug,
1928
+ issueKey
1929
+ });
1930
+ const result = await runMutation(client, api.issues.mutations.addComment, {
1931
+ issueId: issue.id,
1932
+ body: options.body
1933
+ });
1934
+ printOutput(result, runtime.json);
1935
+ });
1936
+ var documentCommand = program.command("document").description("Documents");
1937
+ documentCommand.command("list [slug]").option("--folder-id <id>").option("--limit <n>").action(async (slug, options, command) => {
1938
+ const { client, runtime } = await getClient(command);
1939
+ const orgSlug = requireOrg(runtime, slug);
1940
+ const result = await runAction(client, cliApi.listDocuments, {
1941
+ orgSlug,
1942
+ folderId: options.folderId,
1943
+ limit: options.limit ? Number(options.limit) : void 0
1944
+ });
1945
+ printOutput(result, runtime.json);
1946
+ });
1947
+ documentCommand.command("get <documentId>").action(async (documentId, _options, command) => {
1948
+ const { client, runtime } = await getClient(command);
1949
+ const orgSlug = requireOrg(runtime);
1950
+ const result = await runAction(client, cliApi.getDocument, {
1951
+ orgSlug,
1952
+ documentId
1953
+ });
1954
+ printOutput(result, runtime.json);
1955
+ });
1956
+ documentCommand.command("create").requiredOption("--title <title>").option("--content <content>").option("--team <teamKey>").option("--project <projectKey>").option("--folder-id <id>").option("--visibility <visibility>").option("--icon <icon>").option("--color <color>").action(async (options, command) => {
1957
+ const { client, runtime } = await getClient(command);
1958
+ const orgSlug = requireOrg(runtime);
1959
+ const result = await runAction(client, cliApi.createDocument, {
1960
+ orgSlug,
1961
+ title: options.title,
1962
+ content: options.content,
1963
+ teamKey: options.team,
1964
+ projectKey: options.project,
1965
+ folderId: options.folderId,
1966
+ visibility: options.visibility,
1967
+ icon: options.icon,
1968
+ color: options.color
1969
+ });
1970
+ printOutput(result, runtime.json);
1971
+ });
1972
+ documentCommand.command("update <documentId>").option("--title <title>").option("--content <content>").option("--team <teamKey>").option("--clear-team").option("--project <projectKey>").option("--clear-project").option("--folder-id <id>").option("--clear-folder").option("--visibility <visibility>").option("--icon <icon>").option("--clear-icon").option("--color <color>").option("--clear-color").action(async (documentId, options, command) => {
1973
+ const { client, runtime } = await getClient(command);
1974
+ const orgSlug = requireOrg(runtime);
1975
+ const result = await runAction(client, cliApi.updateDocument, {
1976
+ orgSlug,
1977
+ documentId,
1978
+ title: options.title,
1979
+ content: options.content,
1980
+ teamKey: nullableOption(options.team, options.clearTeam),
1981
+ projectKey: nullableOption(options.project, options.clearProject),
1982
+ folderId: nullableOption(options.folderId, options.clearFolder),
1983
+ visibility: options.visibility,
1984
+ icon: nullableOption(options.icon, options.clearIcon),
1985
+ color: nullableOption(options.color, options.clearColor)
1986
+ });
1987
+ printOutput(result, runtime.json);
1988
+ });
1989
+ documentCommand.command("move <documentId>").option("--folder-id <id>").option("--clear-folder").action(async (documentId, options, command) => {
1990
+ const { client, runtime } = await getClient(command);
1991
+ const orgSlug = requireOrg(runtime);
1992
+ const folderId = options.clearFolder ? null : requiredString(options.folderId, "folder-id");
1993
+ const result = await runAction(client, cliApi.moveDocumentToFolder, {
1994
+ orgSlug,
1995
+ documentId,
1996
+ folderId
1997
+ });
1998
+ printOutput(result, runtime.json);
1999
+ });
2000
+ documentCommand.command("delete <documentId>").action(async (documentId, _options, command) => {
2001
+ const { client, runtime } = await getClient(command);
2002
+ const orgSlug = requireOrg(runtime);
2003
+ const result = await runAction(client, cliApi.deleteDocument, {
2004
+ orgSlug,
2005
+ documentId
2006
+ });
2007
+ printOutput(result, runtime.json);
2008
+ });
2009
+ var folderCommand = program.command("folder").description("Document folders");
2010
+ folderCommand.command("list [slug]").action(async (slug, _options, command) => {
2011
+ const { client, runtime } = await getClient(command);
2012
+ const orgSlug = requireOrg(runtime, slug);
2013
+ const result = await runAction(client, cliApi.listFolders, { orgSlug });
2014
+ printOutput(result, runtime.json);
2015
+ });
2016
+ folderCommand.command("create").requiredOption("--name <name>").option("--description <description>").option("--icon <icon>").option("--color <color>").action(async (options, command) => {
2017
+ const { client, runtime } = await getClient(command);
2018
+ const orgSlug = requireOrg(runtime);
2019
+ const result = await runAction(client, cliApi.createFolder, {
2020
+ orgSlug,
2021
+ name: options.name,
2022
+ description: options.description,
2023
+ icon: options.icon,
2024
+ color: options.color
2025
+ });
2026
+ printOutput(result, runtime.json);
2027
+ });
2028
+ folderCommand.command("update <folderId>").option("--name <name>").option("--description <description>").option("--clear-description").option("--icon <icon>").option("--clear-icon").option("--color <color>").option("--clear-color").action(async (folderId, options, command) => {
2029
+ const { client, runtime } = await getClient(command);
2030
+ const orgSlug = requireOrg(runtime);
2031
+ const result = await runAction(client, cliApi.updateFolder, {
2032
+ orgSlug,
2033
+ folderId,
2034
+ name: options.name,
2035
+ description: nullableOption(
2036
+ options.description,
2037
+ options.clearDescription
2038
+ ),
2039
+ icon: nullableOption(options.icon, options.clearIcon),
2040
+ color: nullableOption(options.color, options.clearColor)
2041
+ });
2042
+ printOutput(result, runtime.json);
2043
+ });
2044
+ folderCommand.command("delete <folderId>").action(async (folderId, _options, command) => {
2045
+ const { client, runtime } = await getClient(command);
2046
+ const orgSlug = requireOrg(runtime);
2047
+ const result = await runAction(client, cliApi.deleteFolder, {
2048
+ orgSlug,
2049
+ folderId
2050
+ });
2051
+ printOutput(result, runtime.json);
2052
+ });
2053
+ async function main() {
2054
+ await program.parseAsync(process.argv);
2055
+ }
2056
+ main().catch((error) => {
2057
+ console.error(error instanceof Error ? error.message : String(error));
2058
+ process.exitCode = 1;
2059
+ });
2060
+ //# sourceMappingURL=index.js.map