linear-cli-agents 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +166 -3
  2. package/bin/dev.js +0 -0
  3. package/dist/commands/comments/add.d.ts +13 -0
  4. package/dist/commands/comments/add.js +89 -0
  5. package/dist/commands/comments/delete.d.ts +12 -0
  6. package/dist/commands/comments/delete.js +50 -0
  7. package/dist/commands/comments/list.d.ts +14 -0
  8. package/dist/commands/comments/list.js +103 -0
  9. package/dist/commands/comments/update.d.ts +13 -0
  10. package/dist/commands/comments/update.js +81 -0
  11. package/dist/commands/issues/add-labels.d.ts +13 -0
  12. package/dist/commands/issues/add-labels.js +90 -0
  13. package/dist/commands/issues/archive.d.ts +13 -0
  14. package/dist/commands/issues/archive.js +83 -0
  15. package/dist/commands/issues/remove-labels.d.ts +13 -0
  16. package/dist/commands/issues/remove-labels.js +90 -0
  17. package/dist/commands/labels/create.d.ts +14 -0
  18. package/dist/commands/labels/create.js +102 -0
  19. package/dist/commands/labels/delete.d.ts +12 -0
  20. package/dist/commands/labels/delete.js +50 -0
  21. package/dist/commands/labels/list.d.ts +12 -0
  22. package/dist/commands/labels/list.js +117 -0
  23. package/dist/commands/labels/update.d.ts +16 -0
  24. package/dist/commands/labels/update.js +109 -0
  25. package/dist/commands/me.js +1 -5
  26. package/dist/commands/milestones/create.d.ts +15 -0
  27. package/dist/commands/milestones/create.js +90 -0
  28. package/dist/commands/milestones/get.d.ts +12 -0
  29. package/dist/commands/milestones/get.js +74 -0
  30. package/dist/commands/milestones/list.d.ts +14 -0
  31. package/dist/commands/milestones/list.js +97 -0
  32. package/dist/commands/milestones/update.d.ts +15 -0
  33. package/dist/commands/milestones/update.js +94 -0
  34. package/dist/commands/project-updates/create.d.ts +14 -0
  35. package/dist/commands/project-updates/create.js +96 -0
  36. package/dist/commands/project-updates/get.d.ts +12 -0
  37. package/dist/commands/project-updates/get.js +80 -0
  38. package/dist/commands/project-updates/list.d.ts +14 -0
  39. package/dist/commands/project-updates/list.js +120 -0
  40. package/dist/commands/project-updates/update.d.ts +14 -0
  41. package/dist/commands/project-updates/update.js +96 -0
  42. package/dist/commands/projects/archive.d.ts +13 -0
  43. package/dist/commands/projects/archive.js +79 -0
  44. package/dist/commands/projects/create.d.ts +16 -0
  45. package/dist/commands/projects/create.js +115 -0
  46. package/dist/commands/projects/delete.d.ts +12 -0
  47. package/dist/commands/projects/delete.js +50 -0
  48. package/dist/commands/projects/get.d.ts +12 -0
  49. package/dist/commands/projects/get.js +102 -0
  50. package/dist/commands/projects/list.d.ts +13 -0
  51. package/dist/commands/projects/list.js +141 -0
  52. package/dist/commands/projects/update.d.ts +18 -0
  53. package/dist/commands/projects/update.js +125 -0
  54. package/dist/commands/relations/create.d.ts +14 -0
  55. package/dist/commands/relations/create.js +98 -0
  56. package/dist/commands/relations/delete.d.ts +12 -0
  57. package/dist/commands/relations/delete.js +47 -0
  58. package/dist/commands/relations/list.d.ts +12 -0
  59. package/dist/commands/relations/list.js +128 -0
  60. package/dist/commands/search.d.ts +15 -0
  61. package/dist/commands/search.js +102 -0
  62. package/dist/commands/states/list.d.ts +12 -0
  63. package/dist/commands/states/list.js +151 -0
  64. package/dist/commands/templates/create.d.ts +14 -0
  65. package/dist/commands/templates/create.js +102 -0
  66. package/dist/commands/templates/get.d.ts +12 -0
  67. package/dist/commands/templates/get.js +84 -0
  68. package/dist/commands/templates/list.d.ts +12 -0
  69. package/dist/commands/templates/list.js +110 -0
  70. package/dist/commands/templates/update.d.ts +15 -0
  71. package/dist/commands/templates/update.js +101 -0
  72. package/dist/commands/users/get.d.ts +12 -0
  73. package/dist/commands/users/get.js +91 -0
  74. package/dist/commands/users/list.d.ts +12 -0
  75. package/dist/commands/users/list.js +99 -0
  76. package/dist/lib/config.js +1 -1
  77. package/oclif.manifest.json +2397 -184
  78. package/package.json +47 -17
@@ -0,0 +1,90 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { getClient } from '../../lib/client.js';
3
+ import { success, print, printItem } from '../../lib/output.js';
4
+ import { handleError, CliError, ErrorCodes } from '../../lib/errors.js';
5
+ export default class MilestonesCreate extends Command {
6
+ static description = 'Create a project milestone';
7
+ static examples = [
8
+ '<%= config.bin %> milestones create PROJECT_ID --name "Beta Release"',
9
+ '<%= config.bin %> milestones create PROJECT_ID --name "Launch" --target-date 2024-03-01',
10
+ ];
11
+ static args = {
12
+ projectId: Args.string({
13
+ description: 'Project ID',
14
+ required: true,
15
+ }),
16
+ };
17
+ static flags = {
18
+ format: Flags.string({
19
+ char: 'F',
20
+ description: 'Output format',
21
+ options: ['json', 'table', 'plain'],
22
+ default: 'json',
23
+ }),
24
+ name: Flags.string({
25
+ char: 'n',
26
+ description: 'Milestone name',
27
+ required: true,
28
+ }),
29
+ description: Flags.string({
30
+ char: 'd',
31
+ description: 'Milestone description',
32
+ }),
33
+ 'target-date': Flags.string({
34
+ description: 'Target date (YYYY-MM-DD)',
35
+ }),
36
+ };
37
+ async run() {
38
+ try {
39
+ const { args, flags } = await this.parse(MilestonesCreate);
40
+ const format = flags.format;
41
+ const client = getClient();
42
+ const project = await client.project(args.projectId);
43
+ if (!project) {
44
+ throw new CliError(ErrorCodes.NOT_FOUND, `Project ${args.projectId} not found`);
45
+ }
46
+ const payload = await client.createProjectMilestone({
47
+ projectId: args.projectId,
48
+ name: flags.name,
49
+ description: flags.description,
50
+ targetDate: flags['target-date'],
51
+ });
52
+ if (!payload.success || !payload.projectMilestone) {
53
+ throw new CliError(ErrorCodes.API_ERROR, 'Failed to create milestone');
54
+ }
55
+ const milestone = await payload.projectMilestone;
56
+ const data = {
57
+ id: milestone.id,
58
+ name: milestone.name,
59
+ description: milestone.description,
60
+ targetDate: milestone.targetDate,
61
+ sortOrder: milestone.sortOrder,
62
+ project: {
63
+ id: project.id,
64
+ name: project.name,
65
+ },
66
+ createdAt: milestone.createdAt,
67
+ };
68
+ if (format === 'json') {
69
+ print(success(data));
70
+ }
71
+ else if (format === 'table') {
72
+ printItem({
73
+ id: data.id,
74
+ name: data.name,
75
+ description: data.description ?? 'N/A',
76
+ targetDate: data.targetDate ?? 'N/A',
77
+ project: data.project.name,
78
+ createdAt: data.createdAt,
79
+ }, format);
80
+ }
81
+ else {
82
+ console.log(data.id);
83
+ }
84
+ }
85
+ catch (err) {
86
+ handleError(err);
87
+ this.exit(1);
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class MilestonesGet extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,74 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { getClient } from '../../lib/client.js';
3
+ import { success, print, printItem } from '../../lib/output.js';
4
+ import { handleError, CliError, ErrorCodes } from '../../lib/errors.js';
5
+ export default class MilestonesGet extends Command {
6
+ static description = 'Get a project milestone by ID';
7
+ static examples = [
8
+ '<%= config.bin %> milestones get MILESTONE_ID',
9
+ '<%= config.bin %> milestones get MILESTONE_ID --format table',
10
+ ];
11
+ static args = {
12
+ id: Args.string({
13
+ description: 'Milestone ID',
14
+ required: true,
15
+ }),
16
+ };
17
+ static flags = {
18
+ format: Flags.string({
19
+ char: 'F',
20
+ description: 'Output format',
21
+ options: ['json', 'table', 'plain'],
22
+ default: 'json',
23
+ }),
24
+ };
25
+ async run() {
26
+ try {
27
+ const { args, flags } = await this.parse(MilestonesGet);
28
+ const format = flags.format;
29
+ const client = getClient();
30
+ const milestone = await client.projectMilestone(args.id);
31
+ if (!milestone) {
32
+ throw new CliError(ErrorCodes.NOT_FOUND, `Milestone ${args.id} not found`);
33
+ }
34
+ const project = await milestone.project;
35
+ const data = {
36
+ id: milestone.id,
37
+ name: milestone.name,
38
+ description: milestone.description,
39
+ targetDate: milestone.targetDate,
40
+ sortOrder: milestone.sortOrder,
41
+ project: project
42
+ ? {
43
+ id: project.id,
44
+ name: project.name,
45
+ }
46
+ : null,
47
+ createdAt: milestone.createdAt,
48
+ updatedAt: milestone.updatedAt,
49
+ };
50
+ if (format === 'json') {
51
+ print(success(data));
52
+ }
53
+ else if (format === 'table') {
54
+ printItem({
55
+ id: data.id,
56
+ name: data.name,
57
+ description: data.description ?? 'N/A',
58
+ targetDate: data.targetDate ?? 'N/A',
59
+ project: data.project?.name ?? 'N/A',
60
+ sortOrder: data.sortOrder,
61
+ createdAt: data.createdAt,
62
+ updatedAt: data.updatedAt,
63
+ }, format);
64
+ }
65
+ else {
66
+ console.log(data.id);
67
+ }
68
+ }
69
+ catch (err) {
70
+ handleError(err);
71
+ this.exit(1);
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,14 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class MilestonesList extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ projectId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ first: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
11
+ after: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,97 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { getClient } from '../../lib/client.js';
3
+ import { successList, print, printList } from '../../lib/output.js';
4
+ import { handleError, CliError, ErrorCodes } from '../../lib/errors.js';
5
+ import { colors, truncate } from '../../lib/formatter.js';
6
+ const COLUMNS = [
7
+ {
8
+ key: 'name',
9
+ header: 'NAME',
10
+ format: (value) => colors.bold(truncate(String(value), 30)),
11
+ },
12
+ {
13
+ key: 'projectName',
14
+ header: 'PROJECT',
15
+ format: (value) => colors.cyan(truncate(String(value), 20)),
16
+ },
17
+ {
18
+ key: 'targetDate',
19
+ header: 'TARGET',
20
+ format: (value) => (value ? colors.dim(String(value)) : colors.gray('No date')),
21
+ },
22
+ ];
23
+ export default class MilestonesList extends Command {
24
+ static description = 'List project milestones';
25
+ static examples = [
26
+ '<%= config.bin %> milestones list PROJECT_ID',
27
+ '<%= config.bin %> milestones list PROJECT_ID --format table',
28
+ ];
29
+ static args = {
30
+ projectId: Args.string({
31
+ description: 'Project ID',
32
+ required: true,
33
+ }),
34
+ };
35
+ static flags = {
36
+ format: Flags.string({
37
+ char: 'F',
38
+ description: 'Output format',
39
+ options: ['json', 'table', 'plain'],
40
+ default: 'json',
41
+ }),
42
+ first: Flags.integer({
43
+ description: 'Number of milestones to fetch (default: 50)',
44
+ default: 50,
45
+ }),
46
+ after: Flags.string({
47
+ description: 'Cursor for pagination',
48
+ }),
49
+ };
50
+ async run() {
51
+ try {
52
+ const { args, flags } = await this.parse(MilestonesList);
53
+ const format = flags.format;
54
+ const client = getClient();
55
+ const project = await client.project(args.projectId);
56
+ if (!project) {
57
+ throw new CliError(ErrorCodes.NOT_FOUND, `Project ${args.projectId} not found`);
58
+ }
59
+ const milestones = await project.projectMilestones({
60
+ first: flags.first,
61
+ after: flags.after,
62
+ });
63
+ const data = milestones.nodes.map((milestone) => ({
64
+ id: milestone.id,
65
+ name: milestone.name,
66
+ description: milestone.description ?? undefined,
67
+ targetDate: milestone.targetDate ?? undefined,
68
+ sortOrder: milestone.sortOrder,
69
+ projectId: project.id,
70
+ projectName: project.name,
71
+ createdAt: milestone.createdAt,
72
+ updatedAt: milestone.updatedAt,
73
+ }));
74
+ const pageInfo = {
75
+ hasNextPage: milestones.pageInfo.hasNextPage,
76
+ hasPreviousPage: milestones.pageInfo.hasPreviousPage,
77
+ startCursor: milestones.pageInfo.startCursor,
78
+ endCursor: milestones.pageInfo.endCursor,
79
+ };
80
+ if (format === 'json') {
81
+ print(successList(data, pageInfo));
82
+ }
83
+ else {
84
+ printList(data, format, {
85
+ columns: COLUMNS,
86
+ primaryKey: 'name',
87
+ secondaryKey: 'targetDate',
88
+ pageInfo,
89
+ });
90
+ }
91
+ }
92
+ catch (err) {
93
+ handleError(err);
94
+ this.exit(1);
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class MilestonesUpdate extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'target-date': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
@@ -0,0 +1,94 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { getClient } from '../../lib/client.js';
3
+ import { success, print, printItem } from '../../lib/output.js';
4
+ import { handleError, CliError, ErrorCodes } from '../../lib/errors.js';
5
+ export default class MilestonesUpdate extends Command {
6
+ static description = 'Update a project milestone';
7
+ static examples = [
8
+ '<%= config.bin %> milestones update MILESTONE_ID --name "Updated Name"',
9
+ '<%= config.bin %> milestones update MILESTONE_ID --target-date 2024-06-01',
10
+ ];
11
+ static args = {
12
+ id: Args.string({
13
+ description: 'Milestone ID',
14
+ required: true,
15
+ }),
16
+ };
17
+ static flags = {
18
+ format: Flags.string({
19
+ char: 'F',
20
+ description: 'Output format',
21
+ options: ['json', 'table', 'plain'],
22
+ default: 'json',
23
+ }),
24
+ name: Flags.string({
25
+ char: 'n',
26
+ description: 'Milestone name',
27
+ }),
28
+ description: Flags.string({
29
+ char: 'd',
30
+ description: 'Milestone description',
31
+ }),
32
+ 'target-date': Flags.string({
33
+ description: 'Target date (YYYY-MM-DD)',
34
+ }),
35
+ };
36
+ async run() {
37
+ try {
38
+ const { args, flags } = await this.parse(MilestonesUpdate);
39
+ const format = flags.format;
40
+ const client = getClient();
41
+ const input = {};
42
+ if (flags.name)
43
+ input.name = flags.name;
44
+ if (flags.description)
45
+ input.description = flags.description;
46
+ if (flags['target-date'])
47
+ input.targetDate = flags['target-date'];
48
+ if (Object.keys(input).length === 0) {
49
+ throw new CliError(ErrorCodes.INVALID_INPUT, 'At least one field to update is required');
50
+ }
51
+ const payload = await client.updateProjectMilestone(args.id, input);
52
+ if (!payload.success || !payload.projectMilestone) {
53
+ throw new CliError(ErrorCodes.API_ERROR, 'Failed to update milestone');
54
+ }
55
+ const milestone = await payload.projectMilestone;
56
+ const project = await milestone.project;
57
+ const data = {
58
+ id: milestone.id,
59
+ name: milestone.name,
60
+ description: milestone.description,
61
+ targetDate: milestone.targetDate,
62
+ sortOrder: milestone.sortOrder,
63
+ project: project
64
+ ? {
65
+ id: project.id,
66
+ name: project.name,
67
+ }
68
+ : null,
69
+ createdAt: milestone.createdAt,
70
+ updatedAt: milestone.updatedAt,
71
+ };
72
+ if (format === 'json') {
73
+ print(success(data));
74
+ }
75
+ else if (format === 'table') {
76
+ printItem({
77
+ id: data.id,
78
+ name: data.name,
79
+ description: data.description ?? 'N/A',
80
+ targetDate: data.targetDate ?? 'N/A',
81
+ project: data.project?.name ?? 'N/A',
82
+ updatedAt: data.updatedAt,
83
+ }, format);
84
+ }
85
+ else {
86
+ console.log(data.id);
87
+ }
88
+ }
89
+ catch (err) {
90
+ handleError(err);
91
+ this.exit(1);
92
+ }
93
+ }
94
+ }
@@ -0,0 +1,14 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ProjectUpdatesCreate extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ projectId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ body: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ health: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,96 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { getClient } from '../../lib/client.js';
3
+ import { success, print, printItem } from '../../lib/output.js';
4
+ import { handleError, CliError, ErrorCodes } from '../../lib/errors.js';
5
+ const HEALTH_OPTIONS = ['onTrack', 'atRisk', 'offTrack'];
6
+ export default class ProjectUpdatesCreate extends Command {
7
+ static description = 'Create a project update';
8
+ static examples = [
9
+ '<%= config.bin %> project-updates create PROJECT_ID --body "Sprint completed successfully"',
10
+ '<%= config.bin %> project-updates create PROJECT_ID --body "Delayed due to dependencies" --health atRisk',
11
+ ];
12
+ static args = {
13
+ projectId: Args.string({
14
+ description: 'Project ID',
15
+ required: true,
16
+ }),
17
+ };
18
+ static flags = {
19
+ format: Flags.string({
20
+ char: 'F',
21
+ description: 'Output format',
22
+ options: ['json', 'table', 'plain'],
23
+ default: 'json',
24
+ }),
25
+ body: Flags.string({
26
+ char: 'b',
27
+ description: 'Update body (supports markdown)',
28
+ required: true,
29
+ }),
30
+ health: Flags.string({
31
+ char: 'h',
32
+ description: 'Project health status',
33
+ options: [...HEALTH_OPTIONS],
34
+ default: 'onTrack',
35
+ }),
36
+ };
37
+ async run() {
38
+ try {
39
+ const { args, flags } = await this.parse(ProjectUpdatesCreate);
40
+ const format = flags.format;
41
+ const health = flags.health;
42
+ const client = getClient();
43
+ const project = await client.project(args.projectId);
44
+ if (!project) {
45
+ throw new CliError(ErrorCodes.NOT_FOUND, `Project ${args.projectId} not found`);
46
+ }
47
+ const payload = await client.createProjectUpdate({
48
+ projectId: args.projectId,
49
+ body: flags.body,
50
+ health,
51
+ });
52
+ if (!payload.success || !payload.projectUpdate) {
53
+ throw new CliError(ErrorCodes.API_ERROR, 'Failed to create project update');
54
+ }
55
+ const update = await payload.projectUpdate;
56
+ const user = await update.user;
57
+ const data = {
58
+ id: update.id,
59
+ body: update.body,
60
+ health: update.health,
61
+ url: update.url,
62
+ project: {
63
+ id: project.id,
64
+ name: project.name,
65
+ },
66
+ user: user
67
+ ? {
68
+ id: user.id,
69
+ name: user.name,
70
+ }
71
+ : null,
72
+ createdAt: update.createdAt,
73
+ };
74
+ if (format === 'json') {
75
+ print(success(data));
76
+ }
77
+ else if (format === 'table') {
78
+ printItem({
79
+ id: data.id,
80
+ project: data.project.name,
81
+ health: data.health,
82
+ body: data.body,
83
+ user: data.user?.name ?? 'Unknown',
84
+ createdAt: data.createdAt,
85
+ }, format);
86
+ }
87
+ else {
88
+ console.log(data.id);
89
+ }
90
+ }
91
+ catch (err) {
92
+ handleError(err);
93
+ this.exit(1);
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ProjectUpdatesGet extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,80 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { getClient } from '../../lib/client.js';
3
+ import { success, print, printItem } from '../../lib/output.js';
4
+ import { handleError, CliError, ErrorCodes } from '../../lib/errors.js';
5
+ export default class ProjectUpdatesGet extends Command {
6
+ static description = 'Get a project update by ID';
7
+ static examples = [
8
+ '<%= config.bin %> project-updates get UPDATE_ID',
9
+ '<%= config.bin %> project-updates get UPDATE_ID --format table',
10
+ ];
11
+ static args = {
12
+ id: Args.string({
13
+ description: 'Project update ID',
14
+ required: true,
15
+ }),
16
+ };
17
+ static flags = {
18
+ format: Flags.string({
19
+ char: 'F',
20
+ description: 'Output format',
21
+ options: ['json', 'table', 'plain'],
22
+ default: 'json',
23
+ }),
24
+ };
25
+ async run() {
26
+ try {
27
+ const { args, flags } = await this.parse(ProjectUpdatesGet);
28
+ const format = flags.format;
29
+ const client = getClient();
30
+ const update = await client.projectUpdate(args.id);
31
+ if (!update) {
32
+ throw new CliError(ErrorCodes.NOT_FOUND, `Project update ${args.id} not found`);
33
+ }
34
+ const [project, user] = await Promise.all([update.project, update.user]);
35
+ const data = {
36
+ id: update.id,
37
+ body: update.body,
38
+ health: update.health,
39
+ url: update.url,
40
+ project: project
41
+ ? {
42
+ id: project.id,
43
+ name: project.name,
44
+ }
45
+ : null,
46
+ user: user
47
+ ? {
48
+ id: user.id,
49
+ name: user.name,
50
+ email: user.email,
51
+ }
52
+ : null,
53
+ createdAt: update.createdAt,
54
+ updatedAt: update.updatedAt,
55
+ };
56
+ if (format === 'json') {
57
+ print(success(data));
58
+ }
59
+ else if (format === 'table') {
60
+ printItem({
61
+ id: data.id,
62
+ project: data.project?.name ?? 'N/A',
63
+ health: data.health,
64
+ body: data.body,
65
+ user: data.user?.name ?? 'Unknown',
66
+ url: data.url,
67
+ createdAt: data.createdAt,
68
+ updatedAt: data.updatedAt,
69
+ }, format);
70
+ }
71
+ else {
72
+ console.log(data.id);
73
+ }
74
+ }
75
+ catch (err) {
76
+ handleError(err);
77
+ this.exit(1);
78
+ }
79
+ }
80
+ }
@@ -0,0 +1,14 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ProjectUpdatesList extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ projectId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ first: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
11
+ after: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ }