bitbucketdc-cli 1.0.6 → 1.0.8

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 (177) hide show
  1. package/dist/index.js +980 -34
  2. package/package.json +5 -4
  3. package/dist/commands/commit/changes.d.ts +0 -3
  4. package/dist/commands/commit/changes.d.ts.map +0 -1
  5. package/dist/commands/commit/changes.js +0 -27
  6. package/dist/commands/commit/changes.js.map +0 -1
  7. package/dist/commands/commit/diff.d.ts +0 -3
  8. package/dist/commands/commit/diff.d.ts.map +0 -1
  9. package/dist/commands/commit/diff.js +0 -38
  10. package/dist/commands/commit/diff.js.map +0 -1
  11. package/dist/commands/commit/index.d.ts +0 -3
  12. package/dist/commands/commit/index.d.ts.map +0 -1
  13. package/dist/commands/commit/index.js +0 -16
  14. package/dist/commands/commit/index.js.map +0 -1
  15. package/dist/commands/compare/changes.d.ts +0 -3
  16. package/dist/commands/compare/changes.d.ts.map +0 -1
  17. package/dist/commands/compare/changes.js +0 -30
  18. package/dist/commands/compare/changes.js.map +0 -1
  19. package/dist/commands/compare/diff.d.ts +0 -3
  20. package/dist/commands/compare/diff.d.ts.map +0 -1
  21. package/dist/commands/compare/diff.js +0 -32
  22. package/dist/commands/compare/diff.js.map +0 -1
  23. package/dist/commands/compare/index.d.ts +0 -3
  24. package/dist/commands/compare/index.d.ts.map +0 -1
  25. package/dist/commands/compare/index.js +0 -16
  26. package/dist/commands/compare/index.js.map +0 -1
  27. package/dist/commands/file/index.d.ts +0 -3
  28. package/dist/commands/file/index.d.ts.map +0 -1
  29. package/dist/commands/file/index.js +0 -16
  30. package/dist/commands/file/index.js.map +0 -1
  31. package/dist/commands/file/list.d.ts +0 -3
  32. package/dist/commands/file/list.d.ts.map +0 -1
  33. package/dist/commands/file/list.js +0 -30
  34. package/dist/commands/file/list.js.map +0 -1
  35. package/dist/commands/file/show.d.ts +0 -3
  36. package/dist/commands/file/show.d.ts.map +0 -1
  37. package/dist/commands/file/show.js +0 -24
  38. package/dist/commands/file/show.js.map +0 -1
  39. package/dist/commands/pr/activities.d.ts +0 -3
  40. package/dist/commands/pr/activities.d.ts.map +0 -1
  41. package/dist/commands/pr/activities.js +0 -37
  42. package/dist/commands/pr/activities.js.map +0 -1
  43. package/dist/commands/pr/can-merge.d.ts +0 -3
  44. package/dist/commands/pr/can-merge.d.ts.map +0 -1
  45. package/dist/commands/pr/can-merge.js +0 -21
  46. package/dist/commands/pr/can-merge.js.map +0 -1
  47. package/dist/commands/pr/changes.d.ts +0 -3
  48. package/dist/commands/pr/changes.d.ts.map +0 -1
  49. package/dist/commands/pr/changes.js +0 -23
  50. package/dist/commands/pr/changes.js.map +0 -1
  51. package/dist/commands/pr/comment.d.ts +0 -3
  52. package/dist/commands/pr/comment.d.ts.map +0 -1
  53. package/dist/commands/pr/comment.js +0 -27
  54. package/dist/commands/pr/comment.js.map +0 -1
  55. package/dist/commands/pr/create.d.ts +0 -3
  56. package/dist/commands/pr/create.d.ts.map +0 -1
  57. package/dist/commands/pr/create.js +0 -50
  58. package/dist/commands/pr/create.js.map +0 -1
  59. package/dist/commands/pr/decline.d.ts +0 -3
  60. package/dist/commands/pr/decline.d.ts.map +0 -1
  61. package/dist/commands/pr/decline.js +0 -21
  62. package/dist/commands/pr/decline.js.map +0 -1
  63. package/dist/commands/pr/delete-comment.d.ts +0 -3
  64. package/dist/commands/pr/delete-comment.d.ts.map +0 -1
  65. package/dist/commands/pr/delete-comment.js +0 -31
  66. package/dist/commands/pr/delete-comment.js.map +0 -1
  67. package/dist/commands/pr/delete.d.ts +0 -3
  68. package/dist/commands/pr/delete.d.ts.map +0 -1
  69. package/dist/commands/pr/delete.js +0 -21
  70. package/dist/commands/pr/delete.js.map +0 -1
  71. package/dist/commands/pr/diff.d.ts +0 -3
  72. package/dist/commands/pr/diff.d.ts.map +0 -1
  73. package/dist/commands/pr/diff.js +0 -43
  74. package/dist/commands/pr/diff.js.map +0 -1
  75. package/dist/commands/pr/edit-comment.d.ts +0 -3
  76. package/dist/commands/pr/edit-comment.d.ts.map +0 -1
  77. package/dist/commands/pr/edit-comment.js +0 -33
  78. package/dist/commands/pr/edit-comment.js.map +0 -1
  79. package/dist/commands/pr/file-comment.d.ts +0 -3
  80. package/dist/commands/pr/file-comment.d.ts.map +0 -1
  81. package/dist/commands/pr/file-comment.js +0 -25
  82. package/dist/commands/pr/file-comment.js.map +0 -1
  83. package/dist/commands/pr/file-diff.d.ts +0 -3
  84. package/dist/commands/pr/file-diff.d.ts.map +0 -1
  85. package/dist/commands/pr/file-diff.js +0 -25
  86. package/dist/commands/pr/file-diff.js.map +0 -1
  87. package/dist/commands/pr/get.d.ts +0 -3
  88. package/dist/commands/pr/get.d.ts.map +0 -1
  89. package/dist/commands/pr/get.js +0 -21
  90. package/dist/commands/pr/get.js.map +0 -1
  91. package/dist/commands/pr/inbox.d.ts +0 -3
  92. package/dist/commands/pr/inbox.d.ts.map +0 -1
  93. package/dist/commands/pr/inbox.js +0 -19
  94. package/dist/commands/pr/inbox.js.map +0 -1
  95. package/dist/commands/pr/index.d.ts +0 -3
  96. package/dist/commands/pr/index.d.ts.map +0 -1
  97. package/dist/commands/pr/index.js +0 -61
  98. package/dist/commands/pr/index.js.map +0 -1
  99. package/dist/commands/pr/line-comment.d.ts +0 -3
  100. package/dist/commands/pr/line-comment.d.ts.map +0 -1
  101. package/dist/commands/pr/line-comment.js +0 -36
  102. package/dist/commands/pr/line-comment.js.map +0 -1
  103. package/dist/commands/pr/merge.d.ts +0 -3
  104. package/dist/commands/pr/merge.d.ts.map +0 -1
  105. package/dist/commands/pr/merge.js +0 -28
  106. package/dist/commands/pr/merge.js.map +0 -1
  107. package/dist/commands/pr/reaction-add.d.ts +0 -3
  108. package/dist/commands/pr/reaction-add.d.ts.map +0 -1
  109. package/dist/commands/pr/reaction-add.js +0 -30
  110. package/dist/commands/pr/reaction-add.js.map +0 -1
  111. package/dist/commands/pr/reaction-remove.d.ts +0 -3
  112. package/dist/commands/pr/reaction-remove.d.ts.map +0 -1
  113. package/dist/commands/pr/reaction-remove.js +0 -29
  114. package/dist/commands/pr/reaction-remove.js.map +0 -1
  115. package/dist/commands/pr/review.d.ts +0 -3
  116. package/dist/commands/pr/review.d.ts.map +0 -1
  117. package/dist/commands/pr/review.js +0 -29
  118. package/dist/commands/pr/review.js.map +0 -1
  119. package/dist/commands/pr/update.d.ts +0 -3
  120. package/dist/commands/pr/update.d.ts.map +0 -1
  121. package/dist/commands/pr/update.js +0 -32
  122. package/dist/commands/pr/update.js.map +0 -1
  123. package/dist/commands/project/index.d.ts +0 -3
  124. package/dist/commands/project/index.d.ts.map +0 -1
  125. package/dist/commands/project/index.js +0 -13
  126. package/dist/commands/project/index.js.map +0 -1
  127. package/dist/commands/project/list.d.ts +0 -3
  128. package/dist/commands/project/list.d.ts.map +0 -1
  129. package/dist/commands/project/list.js +0 -23
  130. package/dist/commands/project/list.js.map +0 -1
  131. package/dist/commands/repo/attachment/download.d.ts +0 -3
  132. package/dist/commands/repo/attachment/download.d.ts.map +0 -1
  133. package/dist/commands/repo/attachment/download.js +0 -23
  134. package/dist/commands/repo/attachment/download.js.map +0 -1
  135. package/dist/commands/repo/attachment/index.d.ts +0 -3
  136. package/dist/commands/repo/attachment/index.d.ts.map +0 -1
  137. package/dist/commands/repo/attachment/index.js +0 -15
  138. package/dist/commands/repo/attachment/index.js.map +0 -1
  139. package/dist/commands/repo/attachment/upload.d.ts +0 -3
  140. package/dist/commands/repo/attachment/upload.d.ts.map +0 -1
  141. package/dist/commands/repo/attachment/upload.js +0 -41
  142. package/dist/commands/repo/attachment/upload.js.map +0 -1
  143. package/dist/commands/repo/index.d.ts +0 -3
  144. package/dist/commands/repo/index.d.ts.map +0 -1
  145. package/dist/commands/repo/index.js +0 -15
  146. package/dist/commands/repo/index.js.map +0 -1
  147. package/dist/commands/repo/list.d.ts +0 -3
  148. package/dist/commands/repo/list.d.ts.map +0 -1
  149. package/dist/commands/repo/list.js +0 -14
  150. package/dist/commands/repo/list.js.map +0 -1
  151. package/dist/commands/user/index.d.ts +0 -3
  152. package/dist/commands/user/index.d.ts.map +0 -1
  153. package/dist/commands/user/index.js +0 -15
  154. package/dist/commands/user/index.js.map +0 -1
  155. package/dist/commands/user/list.d.ts +0 -3
  156. package/dist/commands/user/list.d.ts.map +0 -1
  157. package/dist/commands/user/list.js +0 -15
  158. package/dist/commands/user/list.js.map +0 -1
  159. package/dist/commands/user/profile.d.ts +0 -3
  160. package/dist/commands/user/profile.d.ts.map +0 -1
  161. package/dist/commands/user/profile.js +0 -14
  162. package/dist/commands/user/profile.js.map +0 -1
  163. package/dist/index.d.ts +0 -3
  164. package/dist/index.d.ts.map +0 -1
  165. package/dist/index.js.map +0 -1
  166. package/dist/utils/client.d.ts +0 -3
  167. package/dist/utils/client.d.ts.map +0 -1
  168. package/dist/utils/client.js +0 -19
  169. package/dist/utils/client.js.map +0 -1
  170. package/dist/utils/output.d.ts +0 -3
  171. package/dist/utils/output.d.ts.map +0 -1
  172. package/dist/utils/output.js +0 -48
  173. package/dist/utils/output.js.map +0 -1
  174. package/dist/utils/strip-response.d.ts +0 -6
  175. package/dist/utils/strip-response.d.ts.map +0 -1
  176. package/dist/utils/strip-response.js +0 -30
  177. package/dist/utils/strip-response.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,42 +1,990 @@
1
1
  #!/usr/bin/env node
2
- import { styleText } from 'node:util';
3
- import { Command } from 'commander';
4
- import { registerCommitCommands } from './commands/commit/index.js';
5
- import { registerCompareCommands } from './commands/compare/index.js';
6
- import { registerFileCommands } from './commands/file/index.js';
7
- import { registerPrCommands } from './commands/pr/index.js';
8
- import { registerProjectCommands } from './commands/project/index.js';
9
- import { registerRepoCommands } from './commands/repo/index.js';
10
- import { registerUserCommands } from './commands/user/index.js';
11
- import { handleError } from './utils/output.js';
12
- const DIM = '\x1b[2m';
13
- const RESET = '\x1b[0m';
14
- const program = new Command();
15
- program
16
- .name('bitbucketdc')
17
- .description('Bitbucket Data Center CLI')
18
- .version('1.0.0')
19
- .configureHelp({
20
- styleTitle: (str) => styleText('bold', str),
21
- styleUsage: (str) => styleText('dim', str),
22
- styleCommandDescription: (str) => styleText('dim', str),
23
- styleOptionDescription: (str) => styleText('dim', str),
24
- styleSubcommandDescription: (str) => styleText('dim', str),
25
- })
26
- .addHelpText('beforeAll', `\n${styleText('bold', 'bitbucketdc')} ${DIM}— Bitbucket Data Center CLI${RESET}\n`)
27
- .addHelpText('after', `
28
- ${styleText('bold', 'Environment:')}
2
+
3
+ // src/index.ts
4
+ import { styleText } from "util";
5
+ import { Command as Command8 } from "commander";
6
+
7
+ // src/utils/client.ts
8
+ import { BitbucketClient } from "bitbucket-data-center-client";
9
+
10
+ // src/utils/credentials.ts
11
+ function getCredentialInfo() {
12
+ const baseUrl = process.env.BITBUCKET_URL;
13
+ const token = process.env.BITBUCKET_TOKEN;
14
+ return {
15
+ environment: {
16
+ BITBUCKET_URL: {
17
+ value: baseUrl ?? null,
18
+ description: "Your Bitbucket Server base URL (e.g., https://bitbucket.example.com)"
19
+ },
20
+ BITBUCKET_TOKEN: {
21
+ value: token ? "<set>" : null,
22
+ description: "Personal Access Token"
23
+ }
24
+ },
25
+ tokenUrl: `${baseUrl ?? "https://bitbucket.example.com"}/plugins/servlet/access-tokens/users/<username>/manage`,
26
+ hint: "Export environment variables in your shell profile (e.g., ~/.zshrc)."
27
+ };
28
+ }
29
+
30
+ // src/utils/client.ts
31
+ function getClient() {
32
+ const baseUrl = process.env.BITBUCKET_URL;
33
+ const token = process.env.BITBUCKET_TOKEN;
34
+ if (!baseUrl || !token) {
35
+ const missing = [...!baseUrl ? ["BITBUCKET_URL"] : [], ...!token ? ["BITBUCKET_TOKEN"] : []];
36
+ process.stderr.write(
37
+ `${JSON.stringify({
38
+ error: `Missing required environment variables: ${missing.join(", ")}`,
39
+ ...getCredentialInfo()
40
+ })}
41
+ `
42
+ );
43
+ process.exit(1);
44
+ }
45
+ return new BitbucketClient({ baseUrl, token });
46
+ }
47
+
48
+ // src/utils/strip-response.ts
49
+ function stripResponse(obj) {
50
+ if (Array.isArray(obj)) {
51
+ return obj.map(stripResponse);
52
+ }
53
+ if (obj === null || typeof obj !== "object") {
54
+ return obj;
55
+ }
56
+ const record = obj;
57
+ const result = {};
58
+ for (const [key, value] of Object.entries(record)) {
59
+ if (key === "self" || key === "links" || key === "_links" || key === "_expandable" || key === "expand" || key === "avatarUrls" || key === "avatarId" || key === "iconUrl") {
60
+ continue;
61
+ }
62
+ result[key] = stripResponse(value);
63
+ }
64
+ return result;
65
+ }
66
+
67
+ // src/utils/output.ts
68
+ function output(data) {
69
+ process.stdout.write(`${JSON.stringify(stripResponse(data), null, 2)}
70
+ `);
71
+ }
72
+ function handleError(err) {
73
+ const message = err instanceof Error ? err.message : String(err);
74
+ const axiosStatus = err?.response?.status;
75
+ if (axiosStatus === 400) {
76
+ const responseData = err?.response?.data;
77
+ const apiErrors = responseData && typeof responseData === "object" ? responseData : void 0;
78
+ process.stderr.write(
79
+ `${JSON.stringify({
80
+ error: "Bad request (HTTP 400)",
81
+ detail: apiErrors ?? message,
82
+ hint: "Check that all parameters are valid (project keys, repository slugs, branch names, etc.)."
83
+ })}
84
+ `
85
+ );
86
+ } else if (axiosStatus === 401) {
87
+ process.stderr.write(
88
+ `${JSON.stringify({
89
+ error: "Authentication failed (HTTP 401)",
90
+ ...getCredentialInfo()
91
+ })}
92
+ `
93
+ );
94
+ } else if (axiosStatus === 403) {
95
+ const responseData = err?.response?.data;
96
+ process.stderr.write(
97
+ `${JSON.stringify({
98
+ error: "Forbidden (HTTP 403)",
99
+ detail: responseData && typeof responseData === "object" ? responseData : message,
100
+ hint: "Your account does not have permission for this operation. Check repository permissions and token scope."
101
+ })}
102
+ `
103
+ );
104
+ } else if (message.includes("ENOTFOUND") || message.includes("ECONNREFUSED") || message.includes("ECONNRESET")) {
105
+ process.stderr.write(
106
+ `${JSON.stringify({
107
+ error: `Cannot connect to Bitbucket server: ${message}`,
108
+ hint: "Verify that BITBUCKET_URL is correct and the server is reachable."
109
+ })}
110
+ `
111
+ );
112
+ } else if (axiosStatus === 500) {
113
+ process.stderr.write(
114
+ `${JSON.stringify({
115
+ error: `Server error (HTTP 500): ${message}`,
116
+ hint: "The server returned an internal error. Check that all parameters are valid (project keys, repository slugs, branch names, IDs)."
117
+ })}
118
+ `
119
+ );
120
+ } else {
121
+ process.stderr.write(`${JSON.stringify({ error: message })}
122
+ `);
123
+ }
124
+ process.exit(1);
125
+ }
126
+
127
+ // src/commands/commit/changes.ts
128
+ function changes(parent) {
129
+ parent.command("changes").description("List files changed in a specific commit").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--commit <hash>", "Commit hash").option("--limit <n>", "Number of items to return (default: 25)", parseInt).option("--start <n>", "Start index for pagination (default: 0)", parseInt).addHelpText(
130
+ "after",
131
+ `
132
+ Examples:
133
+ bitbucketdc commit changes --project AI --repo my-app --commit abc123
134
+ bitbucketdc commit changes --project AI --repo my-app --commit abc123 --limit 100`
135
+ ).action(async (opts) => {
136
+ const client = getClient();
137
+ const result = await client.repositories.getCommitChanges({
138
+ projectKey: opts.project,
139
+ repositorySlug: opts.repo,
140
+ commitId: opts.commit,
141
+ limit: opts.limit,
142
+ start: opts.start
143
+ });
144
+ output(result);
145
+ });
146
+ }
147
+
148
+ // src/commands/commit/diff.ts
149
+ import { Option } from "commander";
150
+ function diff(parent) {
151
+ parent.command("diff").description("Get diff for a specific commit").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--commit <hash>", "Commit hash").option("--path <path>", "Scope diff to a single file").option("--context <n>", "Number of context lines around changes", parseInt).addOption(new Option("--whitespace <mode>", "Whitespace handling").choices(["show", "ignore-all"])).addOption(new Option("--format <fmt>", "Response format (default: text)").choices(["text", "json"])).addHelpText(
152
+ "after",
153
+ `
154
+ Examples:
155
+ bitbucketdc commit diff --project AI --repo my-app --commit abc123
156
+ bitbucketdc commit diff --project AI --repo my-app --commit abc123 --path src/main.ts
157
+ bitbucketdc commit diff --project AI --repo my-app --commit abc123 --format json`
158
+ ).action(
159
+ async (opts) => {
160
+ const client = getClient();
161
+ const result = await client.repositories.getCommitDiff({
162
+ projectKey: opts.project,
163
+ repositorySlug: opts.repo,
164
+ commitId: opts.commit,
165
+ path: opts.path,
166
+ contextLines: opts.context,
167
+ whitespace: opts.whitespace,
168
+ format: opts.format || "text"
169
+ });
170
+ if (typeof result === "string") {
171
+ process.stdout.write(result);
172
+ } else {
173
+ output(result);
174
+ }
175
+ }
176
+ );
177
+ }
178
+
179
+ // src/commands/commit/index.ts
180
+ function registerCommitCommands(program2) {
181
+ const commit = program2.command("commit").description("Commit inspection operations").addHelpText(
182
+ "after",
183
+ `
184
+ Examples:
185
+ $ bitbucketdc commit changes --project AI --repo my-app --commit abc123
186
+ $ bitbucketdc commit diff --project AI --repo my-app --commit abc123
187
+ $ bitbucketdc commit diff --project AI --repo my-app --commit abc123 --path src/main.ts
188
+ `
189
+ );
190
+ changes(commit);
191
+ diff(commit);
192
+ }
193
+
194
+ // src/commands/compare/changes.ts
195
+ function changes2(parent) {
196
+ parent.command("changes").description("List files that differ between two refs").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--from <ref>", "Source ref (branch, tag, or commit)").requiredOption("--to <ref>", "Target ref (branch, tag, or commit)").option("--limit <n>", "Number of items to return (default: 25)", parseInt).option("--start <n>", "Start index for pagination (default: 0)", parseInt).addHelpText(
197
+ "after",
198
+ `
199
+ Examples:
200
+ bitbucketdc compare changes --project AI --repo my-app --from develop --to main
201
+ bitbucketdc compare changes --project AI --repo my-app --from feature/x --to main --limit 100
202
+ bitbucketdc compare changes --project AI --repo my-app --from develop --to main --start 25`
203
+ ).action(
204
+ async (opts) => {
205
+ const client = getClient();
206
+ const result = await client.repositories.getCompareChanges({
207
+ projectKey: opts.project,
208
+ repositorySlug: opts.repo,
209
+ from: opts.from,
210
+ to: opts.to,
211
+ limit: opts.limit,
212
+ start: opts.start
213
+ });
214
+ output(result);
215
+ }
216
+ );
217
+ }
218
+
219
+ // src/commands/compare/diff.ts
220
+ import { Option as Option2 } from "commander";
221
+ function diff2(parent) {
222
+ parent.command("diff").description("Get diff between two refs (structured JSON)").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--from <ref>", "Source ref (branch, tag, or commit)").requiredOption("--to <ref>", "Target ref (branch, tag, or commit)").option("--path <path>", "Scope diff to a single file").option("--context <n>", "Number of context lines around changes", parseInt).addOption(new Option2("--whitespace <mode>", "Whitespace handling").choices(["show", "ignore-all"])).addHelpText(
223
+ "after",
224
+ `
225
+ Examples:
226
+ bitbucketdc compare diff --project AI --repo my-app --from develop --to main
227
+ bitbucketdc compare diff --project AI --repo my-app --from develop --to main --path src/main.ts`
228
+ ).action(
229
+ async (opts) => {
230
+ const client = getClient();
231
+ const result = await client.repositories.getCompareDiff({
232
+ projectKey: opts.project,
233
+ repositorySlug: opts.repo,
234
+ from: opts.from,
235
+ to: opts.to,
236
+ path: opts.path,
237
+ contextLines: opts.context,
238
+ whitespace: opts.whitespace
239
+ });
240
+ output(result);
241
+ }
242
+ );
243
+ }
244
+
245
+ // src/commands/compare/index.ts
246
+ function registerCompareCommands(program2) {
247
+ const compare = program2.command("compare").description("Compare refs (branches, tags, commits)").addHelpText(
248
+ "after",
249
+ `
250
+ Examples:
251
+ $ bitbucketdc compare changes --project AI --repo my-app --from develop --to main
252
+ $ bitbucketdc compare diff --project AI --repo my-app --from develop --to main
253
+ $ bitbucketdc compare diff --project AI --repo my-app --from develop --to main --path src/main.ts
254
+ `
255
+ );
256
+ changes2(compare);
257
+ diff2(compare);
258
+ }
259
+
260
+ // src/commands/file/list.ts
261
+ function list(parent) {
262
+ parent.command("list").description("List directory contents in a repository").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").option("--path <path>", "Directory path (defaults to root)").option("--at <ref>", "Branch, tag, or commit hash").option("--limit <n>", "Number of items to return (default: 500)", parseInt).option("--start <n>", "Start index for pagination (default: 0)", parseInt).addHelpText(
263
+ "after",
264
+ `
265
+ Examples:
266
+ bitbucketdc file list --project PROJ --repo my-app
267
+ bitbucketdc file list --project PROJ --repo my-app --path src/
268
+ bitbucketdc file list --project PROJ --repo my-app --path src/ --at develop`
269
+ ).action(
270
+ async (opts) => {
271
+ const client = getClient();
272
+ const result = await client.repositories.browse({
273
+ projectKey: opts.project,
274
+ repositorySlug: opts.repo,
275
+ path: opts.path,
276
+ at: opts.at,
277
+ limit: opts.limit,
278
+ start: opts.start
279
+ });
280
+ output(result);
281
+ }
282
+ );
283
+ }
284
+
285
+ // src/commands/file/show.ts
286
+ function show(parent) {
287
+ parent.command("show").description("Show raw file content from a repository").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--path <path>", "File path").option("--at <ref>", "Branch, tag, or commit hash").addHelpText(
288
+ "after",
289
+ `
290
+ Examples:
291
+ bitbucketdc file show --project PROJ --repo my-app --path README.md
292
+ bitbucketdc file show --project PROJ --repo my-app --path config/settings.yaml --at release/2.0`
293
+ ).action(async (opts) => {
294
+ const client = getClient();
295
+ const result = await client.repositories.getRawContent({
296
+ projectKey: opts.project,
297
+ repositorySlug: opts.repo,
298
+ path: opts.path,
299
+ at: opts.at
300
+ });
301
+ process.stdout.write(result);
302
+ });
303
+ }
304
+
305
+ // src/commands/file/index.ts
306
+ function registerFileCommands(program2) {
307
+ const file = program2.command("file").description("File and directory operations").addHelpText(
308
+ "after",
309
+ `
310
+ Examples:
311
+ $ bitbucketdc file list --project PROJ --repo my-app
312
+ $ bitbucketdc file list --project PROJ --repo my-app --path src/ --at develop
313
+ $ bitbucketdc file show --project PROJ --repo my-app --path README.md
314
+ `
315
+ );
316
+ list(file);
317
+ show(file);
318
+ }
319
+
320
+ // src/commands/pr/activities.ts
321
+ function activities(parent) {
322
+ parent.command("activities").description("Get activity on a pull request (comments, approvals, merges, etc.)").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").option(
323
+ "--types <types>",
324
+ "Comma-separated activity types (APPROVED, COMMENTED, DECLINED, MERGED, OPENED, REOPENED, RESCOPED, REVIEW_COMMENTED, REVIEW_DISCARDED, REVIEW_FINISHED, REVIEWED, UNAPPROVED, UPDATED)"
325
+ ).option("--start <n>", "Starting index for pagination (default: 0)", parseInt).option("--limit <n>", "Maximum number of items to return (default: 25)", parseInt).addHelpText(
326
+ "after",
327
+ `
328
+ Examples:
329
+ bitbucketdc pr activities --project PROJ --repo my-repo --id 42
330
+ bitbucketdc pr activities --project PROJ --repo my-repo --id 42 --types COMMENTED,REVIEW_COMMENTED
331
+ bitbucketdc pr activities --project PROJ --repo my-repo --id 42 --types APPROVED,UNAPPROVED --limit 50`
332
+ ).action(
333
+ async (opts) => {
334
+ const client = getClient();
335
+ const result = await client.pullRequests.getActivities({
336
+ projectKey: opts.project,
337
+ repositorySlug: opts.repo,
338
+ pullRequestId: parseInt(opts.id),
339
+ start: opts.start,
340
+ limit: opts.limit
341
+ });
342
+ if (opts.types) {
343
+ const types = opts.types.split(",").map((t) => t.trim());
344
+ const filtered = result.values.filter((a) => types.includes(a.action));
345
+ output({ ...result, values: filtered, size: filtered.length });
346
+ } else {
347
+ output(result);
348
+ }
349
+ }
350
+ );
351
+ }
352
+
353
+ // src/commands/pr/can-merge.ts
354
+ function canMerge(parent) {
355
+ parent.command("can-merge").description("Check if a pull request can be merged").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID", parseInt).addHelpText("after", "\nExamples:\n bitbucketdc pr can-merge --project PROJ --repo my-repo --id 42").action(async (opts) => {
356
+ const client = getClient();
357
+ const result = await client.pullRequests.canMerge({
358
+ projectKey: opts.project,
359
+ repositorySlug: opts.repo,
360
+ pullRequestId: opts.id
361
+ });
362
+ output(result);
363
+ });
364
+ }
365
+
366
+ // src/commands/pr/changes.ts
367
+ function changes3(parent) {
368
+ parent.command("changes").description("List changed files in a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").option("--limit <n>", "Number of items to return (default: 25)", parseInt).addHelpText(
369
+ "after",
370
+ "\nExamples:\n bitbucketdc pr changes --project PROJ --repo my-repo --id 42\n bitbucketdc pr changes --project PROJ --repo my-repo --id 42 --limit 100"
371
+ ).action(async (opts) => {
372
+ const client = getClient();
373
+ const result = await client.pullRequests.getChanges({
374
+ projectKey: opts.project,
375
+ repositorySlug: opts.repo,
376
+ pullRequestId: parseInt(opts.id),
377
+ limit: opts.limit
378
+ });
379
+ output(result);
380
+ });
381
+ }
382
+
383
+ // src/commands/pr/comment.ts
384
+ function comment(parent) {
385
+ parent.command("comment").description("Add a general comment to a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").requiredOption("--text <text>", "Comment text").option("--parent <n>", "Parent comment ID to reply to").addHelpText(
386
+ "after",
387
+ `
388
+ Examples:
389
+ bitbucketdc pr comment --project PROJ --repo my-repo --id 42 --text "Looks good!"
390
+ bitbucketdc pr comment --project PROJ --repo my-repo --id 42 --text "I agree" --parent 123`
391
+ ).action(async (opts) => {
392
+ const client = getClient();
393
+ const result = await client.pullRequests.addComment({
394
+ projectKey: opts.project,
395
+ repositorySlug: opts.repo,
396
+ pullRequestId: parseInt(opts.id),
397
+ text: opts.text,
398
+ parentId: opts.parent ? parseInt(opts.parent) : void 0
399
+ });
400
+ output(result);
401
+ });
402
+ }
403
+
404
+ // src/commands/pr/create.ts
405
+ function create(parent) {
406
+ parent.command("create").description("Create a new pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--from <branch>", "Source branch name (e.g., feature-x)").requiredOption("--to <branch>", "Target branch name (e.g., main)").requiredOption("--title <text>", "Pull request title").option("--description <text>", "Pull request description in markdown").option("--reviewers <usernames>", "Comma-separated reviewer usernames").option("--draft", "Create as draft pull request").addHelpText(
407
+ "after",
408
+ `
409
+ Examples:
410
+ bitbucketdc pr create --project PROJ --repo my-repo --from feature-x --to main --title "Add feature"
411
+ bitbucketdc pr create --project PROJ --repo my-repo --from fix/bug --to develop --title "Fix bug" --reviewers jsmith,jdoe
412
+ bitbucketdc pr create --project PROJ --repo my-repo --from wip --to main --title "WIP" --draft`
413
+ ).action(
414
+ async (opts) => {
415
+ const client = getClient();
416
+ let reviewers = opts.reviewers?.split(",").map((r) => r.trim());
417
+ if (!reviewers || reviewers.length === 0) {
418
+ const repo = await client.repositories.get({
419
+ projectKey: opts.project,
420
+ repositorySlug: opts.repo
421
+ });
422
+ const defaultReviewers = await client.pullRequests.getRequiredReviewers({
423
+ projectKey: opts.project,
424
+ repositorySlug: opts.repo,
425
+ repositoryId: repo.id,
426
+ sourceBranch: opts.from,
427
+ targetBranch: opts.to
428
+ });
429
+ reviewers = defaultReviewers.map((r) => r.name);
430
+ }
431
+ const result = await client.pullRequests.create({
432
+ projectKey: opts.project,
433
+ repositorySlug: opts.repo,
434
+ fromBranch: opts.from,
435
+ toBranch: opts.to,
436
+ title: opts.title,
437
+ description: opts.description,
438
+ reviewers,
439
+ draft: opts.draft
440
+ });
441
+ output(result);
442
+ }
443
+ );
444
+ }
445
+
446
+ // src/commands/pr/decline.ts
447
+ function decline(parent) {
448
+ parent.command("decline").description("Decline a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID", parseInt).addHelpText("after", "\nExamples:\n bitbucketdc pr decline --project PROJ --repo my-repo --id 42").action(async (opts) => {
449
+ const client = getClient();
450
+ const result = await client.pullRequests.decline({
451
+ projectKey: opts.project,
452
+ repositorySlug: opts.repo,
453
+ pullRequestId: opts.id
454
+ });
455
+ output(result);
456
+ });
457
+ }
458
+
459
+ // src/commands/pr/delete-comment.ts
460
+ function deleteComment(parent) {
461
+ parent.command("delete-comment").description("Delete a pull request comment").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID", parseInt).requiredOption("--comment-id <n>", "Comment ID to delete", parseInt).addHelpText(
462
+ "after",
463
+ "\nExamples:\n bitbucketdc pr delete-comment --project PROJ --repo my-repo --id 42 --comment-id 123"
464
+ ).action(async (opts) => {
465
+ const client = getClient();
466
+ const comment2 = await client.pullRequests.getComment({
467
+ projectKey: opts.project,
468
+ repositorySlug: opts.repo,
469
+ pullRequestId: opts.id,
470
+ commentId: opts.commentId
471
+ });
472
+ await client.pullRequests.deleteComment({
473
+ projectKey: opts.project,
474
+ repositorySlug: opts.repo,
475
+ pullRequestId: opts.id,
476
+ commentId: opts.commentId,
477
+ version: comment2.version
478
+ });
479
+ output({ deleted: true, commentId: opts.commentId });
480
+ });
481
+ }
482
+
483
+ // src/commands/pr/delete.ts
484
+ function deletePr(parent) {
485
+ parent.command("delete").description("Delete a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID", parseInt).addHelpText("after", "\nExamples:\n bitbucketdc pr delete --project PROJ --repo my-repo --id 42").action(async (opts) => {
486
+ const client = getClient();
487
+ await client.pullRequests.deletePullRequest({
488
+ projectKey: opts.project,
489
+ repositorySlug: opts.repo,
490
+ pullRequestId: opts.id
491
+ });
492
+ output({ deleted: true, pullRequestId: opts.id });
493
+ });
494
+ }
495
+
496
+ // src/commands/pr/diff.ts
497
+ import { Option as Option3 } from "commander";
498
+ function diff3(parent) {
499
+ parent.command("diff").description("Get diff for a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").option("--path <path>", "File path (omit for full PR diff)").option("--since <hash>", "Since commit hash").option("--until <hash>", "Until commit hash").option("--context <n>", "Number of context lines around changes (default: 10)", parseInt).addOption(new Option3("--whitespace <mode>", "Whitespace handling (default: show)").choices(["show", "ignore-all"])).addOption(new Option3("--format <fmt>", "Response format (default: text)").choices(["text", "json"])).addHelpText(
500
+ "after",
501
+ `
502
+ Examples:
503
+ bitbucketdc pr diff --project PROJ --repo my-repo --id 42
504
+ bitbucketdc pr diff --project PROJ --repo my-repo --id 42 --path src/main.ts
505
+ bitbucketdc pr diff --project PROJ --repo my-repo --id 42 --format json
506
+ bitbucketdc pr diff --project PROJ --repo my-repo --id 42 --context 5 --whitespace ignore-all`
507
+ ).action(
508
+ async (opts) => {
509
+ const client = getClient();
510
+ const result = await client.pullRequests.getDiff({
511
+ projectKey: opts.project,
512
+ repositorySlug: opts.repo,
513
+ pullRequestId: parseInt(opts.id),
514
+ path: opts.path,
515
+ sinceId: opts.since,
516
+ untilId: opts.until,
517
+ contextLines: opts.context,
518
+ whitespace: opts.whitespace,
519
+ format: opts.format || "text"
520
+ });
521
+ if (typeof result === "string") {
522
+ process.stdout.write(result);
523
+ } else {
524
+ output(result);
525
+ }
526
+ }
527
+ );
528
+ }
529
+
530
+ // src/commands/pr/edit-comment.ts
531
+ function editComment(parent) {
532
+ parent.command("edit-comment").description("Edit a pull request comment").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID", parseInt).requiredOption("--comment-id <n>", "Comment ID to edit", parseInt).requiredOption("--text <content>", "New comment text").addHelpText(
533
+ "after",
534
+ '\nExamples:\n bitbucketdc pr edit-comment --project PROJ --repo my-repo --id 42 --comment-id 123 --text "Updated text"'
535
+ ).action(async (opts) => {
536
+ const client = getClient();
537
+ const comment2 = await client.pullRequests.getComment({
538
+ projectKey: opts.project,
539
+ repositorySlug: opts.repo,
540
+ pullRequestId: opts.id,
541
+ commentId: opts.commentId
542
+ });
543
+ const result = await client.pullRequests.editComment({
544
+ projectKey: opts.project,
545
+ repositorySlug: opts.repo,
546
+ pullRequestId: opts.id,
547
+ commentId: opts.commentId,
548
+ text: opts.text,
549
+ version: comment2.version
550
+ });
551
+ output(result);
552
+ });
553
+ }
554
+
555
+ // src/commands/pr/file-comment.ts
556
+ function fileComment(parent) {
557
+ parent.command("file-comment").description("Add a file-level comment to a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").requiredOption("--text <text>", "Comment text").requiredOption("--path <path>", "File path to attach comment to (e.g., src/main.ts)").addHelpText(
558
+ "after",
559
+ '\nExamples:\n bitbucketdc pr file-comment --project PROJ --repo my-repo --id 42 --text "This file needs refactoring" --path src/main.ts'
560
+ ).action(async (opts) => {
561
+ const client = getClient();
562
+ const result = await client.pullRequests.addComment({
563
+ projectKey: opts.project,
564
+ repositorySlug: opts.repo,
565
+ pullRequestId: parseInt(opts.id),
566
+ text: opts.text,
567
+ path: opts.path
568
+ });
569
+ output(result);
570
+ });
571
+ }
572
+
573
+ // src/commands/pr/file-diff.ts
574
+ function fileDiff(parent) {
575
+ parent.command("file-diff").description("Get structured line-by-line diff for a specific file").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").requiredOption("--path <path>", "File path (e.g., src/main.ts)").option("--context <n>", "Number of context lines around changes (default: 10)", parseInt).addHelpText(
576
+ "after",
577
+ "\nExamples:\n bitbucketdc pr file-diff --project PROJ --repo my-repo --id 42 --path src/main.ts\n bitbucketdc pr file-diff --project PROJ --repo my-repo --id 42 --path src/main.ts --context 5"
578
+ ).action(async (opts) => {
579
+ const client = getClient();
580
+ const result = await client.pullRequests.getFileDiff({
581
+ projectKey: opts.project,
582
+ repositorySlug: opts.repo,
583
+ pullRequestId: parseInt(opts.id),
584
+ path: opts.path,
585
+ contextLines: opts.context
586
+ });
587
+ output(result);
588
+ });
589
+ }
590
+
591
+ // src/commands/pr/get.ts
592
+ function get(parent) {
593
+ parent.command("get").description("Get pull request details").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").addHelpText("after", "\nExamples:\n bitbucketdc pr get --project PROJ --repo my-repo --id 42").action(async (opts) => {
594
+ const client = getClient();
595
+ const result = await client.pullRequests.get({
596
+ projectKey: opts.project,
597
+ repositorySlug: opts.repo,
598
+ pullRequestId: parseInt(opts.id)
599
+ });
600
+ output(result);
601
+ });
602
+ }
603
+
604
+ // src/commands/pr/inbox.ts
605
+ function inbox(parent) {
606
+ parent.command("inbox").description("List pull requests in your reviewer inbox").option("--start <n>", "Starting index for pagination (default: 0)", parseInt).option("--limit <n>", "Maximum number of pull requests to return (default: 25)", parseInt).addHelpText(
607
+ "after",
608
+ "\nExamples:\n bitbucketdc pr inbox\n bitbucketdc pr inbox --limit 10\n bitbucketdc pr inbox --start 25 --limit 25"
609
+ ).action(async (opts) => {
610
+ const client = getClient();
611
+ const result = await client.pullRequests.getInbox({
612
+ start: opts.start,
613
+ limit: opts.limit
614
+ });
615
+ output(result);
616
+ });
617
+ }
618
+
619
+ // src/commands/pr/line-comment.ts
620
+ import { Option as Option4 } from "commander";
621
+ function lineComment(parent) {
622
+ parent.command("line-comment").description("Add an inline comment to a specific line in a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").requiredOption("--text <text>", "Comment text").requiredOption("--path <path>", "File path (e.g., src/main.ts)").requiredOption("--line <n>", "Line number to comment on").addOption(
623
+ new Option4("--line-type <type>", "Type of line").choices(["ADDED", "REMOVED", "CONTEXT"]).makeOptionMandatory()
624
+ ).addOption(
625
+ new Option4("--file-type <type>", "Side of diff: FROM (source/old) or TO (destination/new)").choices(["FROM", "TO"]).makeOptionMandatory()
626
+ ).addHelpText(
627
+ "after",
628
+ `
629
+ Examples:
630
+ bitbucketdc pr line-comment --project PROJ --repo my-repo --id 42 --text "Use const here" --path src/main.ts --line 15 --line-type ADDED --file-type TO
631
+ bitbucketdc pr line-comment --project PROJ --repo my-repo --id 42 --text "Was this intentional?" --path src/old.ts --line 8 --line-type REMOVED --file-type FROM`
632
+ ).action(
633
+ async (opts) => {
634
+ const client = getClient();
635
+ const result = await client.pullRequests.addComment({
636
+ projectKey: opts.project,
637
+ repositorySlug: opts.repo,
638
+ pullRequestId: parseInt(opts.id),
639
+ text: opts.text,
640
+ path: opts.path,
641
+ line: parseInt(opts.line),
642
+ lineType: opts.lineType,
643
+ fileType: opts.fileType
644
+ });
645
+ output(result);
646
+ }
647
+ );
648
+ }
649
+
650
+ // src/commands/pr/merge.ts
651
+ function merge(parent) {
652
+ parent.command("merge").description("Merge a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID", parseInt).option("--strategy <id>", "Merge strategy (e.g., squash, no-ff, ff, ff-only, rebase-no-ff, rebase-ff-only)").option("--message <text>", "Custom merge commit message").addHelpText(
653
+ "after",
654
+ `
655
+ Examples:
656
+ bitbucketdc pr merge --project PROJ --repo my-repo --id 42
657
+ bitbucketdc pr merge --project PROJ --repo my-repo --id 42 --strategy squash
658
+ bitbucketdc pr merge --project PROJ --repo my-repo --id 42 --message "Merge feature X"`
659
+ ).action(async (opts) => {
660
+ const client = getClient();
661
+ const result = await client.pullRequests.merge({
662
+ projectKey: opts.project,
663
+ repositorySlug: opts.repo,
664
+ pullRequestId: opts.id,
665
+ strategyId: opts.strategy,
666
+ message: opts.message
667
+ });
668
+ output(result);
669
+ });
670
+ }
671
+
672
+ // src/commands/pr/reaction-add.ts
673
+ import { Option as Option5 } from "commander";
674
+ function reactionAdd(parent) {
675
+ parent.command("reaction-add").description("Add an emoticon reaction to a PR comment").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").requiredOption("--comment-id <n>", "Comment ID").addOption(
676
+ new Option5("--emoticon <name>", "Emoticon to react with").choices(["thumbsup", "thumbsdown", "heart", "thinking_face", "laughing"]).makeOptionMandatory()
677
+ ).addHelpText(
678
+ "after",
679
+ `
680
+ Examples:
681
+ bitbucketdc pr reaction-add --project PROJ --repo my-repo --id 42 --comment-id 123 --emoticon thumbsup
682
+ bitbucketdc pr reaction-add --project PROJ --repo my-repo --id 42 --comment-id 123 --emoticon heart`
683
+ ).action(async (opts) => {
684
+ const client = getClient();
685
+ const result = await client.pullRequests.addReaction({
686
+ projectKey: opts.project,
687
+ repositorySlug: opts.repo,
688
+ pullRequestId: parseInt(opts.id),
689
+ commentId: parseInt(opts.commentId),
690
+ emoticon: opts.emoticon
691
+ });
692
+ output(result);
693
+ });
694
+ }
695
+
696
+ // src/commands/pr/reaction-remove.ts
697
+ import { Option as Option6 } from "commander";
698
+ function reactionRemove(parent) {
699
+ parent.command("reaction-remove").description("Remove an emoticon reaction from a PR comment").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").requiredOption("--comment-id <n>", "Comment ID").addOption(
700
+ new Option6("--emoticon <name>", "Emoticon to remove").choices(["thumbsup", "thumbsdown", "heart", "thinking_face", "laughing"]).makeOptionMandatory()
701
+ ).addHelpText(
702
+ "after",
703
+ `
704
+ Examples:
705
+ bitbucketdc pr reaction-remove --project PROJ --repo my-repo --id 42 --comment-id 123 --emoticon thumbsup`
706
+ ).action(async (opts) => {
707
+ const client = getClient();
708
+ await client.pullRequests.removeReaction({
709
+ projectKey: opts.project,
710
+ repositorySlug: opts.repo,
711
+ pullRequestId: parseInt(opts.id),
712
+ commentId: parseInt(opts.commentId),
713
+ emoticon: opts.emoticon
714
+ });
715
+ output({ removed: true, emoticon: opts.emoticon });
716
+ });
717
+ }
718
+
719
+ // src/commands/pr/review.ts
720
+ import { Option as Option7 } from "commander";
721
+ function review(parent) {
722
+ parent.command("review").description("Update review status for a pull request").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID").addOption(
723
+ new Option7("--status <status>", "Review status").choices(["APPROVED", "NEEDS_WORK", "UNAPPROVED"]).makeOptionMandatory()
724
+ ).addHelpText(
725
+ "after",
726
+ `
727
+ Examples:
728
+ bitbucketdc pr review --project PROJ --repo my-repo --id 42 --status APPROVED
729
+ bitbucketdc pr review --project PROJ --repo my-repo --id 42 --status NEEDS_WORK
730
+ bitbucketdc pr review --project PROJ --repo my-repo --id 42 --status UNAPPROVED`
731
+ ).action(async (opts) => {
732
+ const client = getClient();
733
+ const result = await client.pullRequests.updateReviewStatus({
734
+ projectKey: opts.project,
735
+ repositorySlug: opts.repo,
736
+ pullRequestId: parseInt(opts.id),
737
+ status: opts.status
738
+ });
739
+ output(result);
740
+ });
741
+ }
742
+
743
+ // src/commands/pr/update.ts
744
+ function update(parent) {
745
+ parent.command("update").description("Update a pull request title and/or description").requiredOption("--project <key>", "Bitbucket project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <n>", "Pull request ID", parseInt).option("--title <title>", "New pull request title").option("--description <text>", "New pull request description").addHelpText(
746
+ "after",
747
+ `
748
+ Examples:
749
+ bitbucketdc pr update --project PROJ --repo my-repo --id 42 --title "New title"
750
+ bitbucketdc pr update --project PROJ --repo my-repo --id 42 --description "Updated description"
751
+ bitbucketdc pr update --project PROJ --repo my-repo --id 42 --title "New" --description "Both"`
752
+ ).action(async (opts) => {
753
+ if (!opts.title && !opts.description) {
754
+ process.stderr.write(`${JSON.stringify({ error: "At least one of --title or --description is required" })}
755
+ `);
756
+ process.exit(1);
757
+ }
758
+ const client = getClient();
759
+ const result = await client.pullRequests.update({
760
+ projectKey: opts.project,
761
+ repositorySlug: opts.repo,
762
+ pullRequestId: opts.id,
763
+ title: opts.title,
764
+ description: opts.description
765
+ });
766
+ output(result);
767
+ });
768
+ }
769
+
770
+ // src/commands/pr/index.ts
771
+ function registerPrCommands(program2) {
772
+ const pr = program2.command("pr").description("Pull request operations").addHelpText(
773
+ "after",
774
+ `
775
+ Examples:
776
+ $ bitbucketdc pr inbox
777
+ $ bitbucketdc pr get --project PROJ --repo my-repo --id 42
778
+ $ bitbucketdc pr changes --project PROJ --repo my-repo --id 42
779
+ $ bitbucketdc pr diff --project PROJ --repo my-repo --id 42
780
+ $ bitbucketdc pr create --project PROJ --repo my-repo --from feature-x --to main --title "Add feature"
781
+ $ bitbucketdc pr comment --project PROJ --repo my-repo --id 42 --text "Looks good!"
782
+ $ bitbucketdc pr review --project PROJ --repo my-repo --id 42 --status APPROVED
783
+ $ bitbucketdc pr update --project PROJ --repo my-repo --id 42 --title "New title"
784
+ $ bitbucketdc pr can-merge --project PROJ --repo my-repo --id 42
785
+ $ bitbucketdc pr merge --project PROJ --repo my-repo --id 42
786
+ $ bitbucketdc pr decline --project PROJ --repo my-repo --id 42
787
+ $ bitbucketdc pr delete --project PROJ --repo my-repo --id 42
788
+ `
789
+ );
790
+ inbox(pr);
791
+ get(pr);
792
+ changes3(pr);
793
+ diff3(pr);
794
+ fileDiff(pr);
795
+ activities(pr);
796
+ create(pr);
797
+ comment(pr);
798
+ fileComment(pr);
799
+ lineComment(pr);
800
+ deleteComment(pr);
801
+ editComment(pr);
802
+ reactionAdd(pr);
803
+ reactionRemove(pr);
804
+ review(pr);
805
+ update(pr);
806
+ canMerge(pr);
807
+ merge(pr);
808
+ decline(pr);
809
+ deletePr(pr);
810
+ }
811
+
812
+ // src/commands/project/list.ts
813
+ function list2(parent) {
814
+ parent.command("list").description("List projects").option("--name <name>", "Filter projects by name (partial match)").option("--permission <permission>", "Filter by permission (e.g., PROJECT_READ, PROJECT_WRITE, PROJECT_ADMIN)").option("--start <start>", "Starting index for pagination", parseInt).option("--limit <limit>", "Maximum number of projects to return", parseInt).addHelpText(
815
+ "after",
816
+ '\nExamples:\n bitbucketdc project list\n bitbucketdc project list --name "My Project"\n bitbucketdc project list --permission PROJECT_READ --limit 10'
817
+ ).action(async (opts) => {
818
+ const client = getClient();
819
+ const result = await client.projects.list({
820
+ name: opts.name,
821
+ permission: opts.permission,
822
+ start: opts.start,
823
+ limit: opts.limit
824
+ });
825
+ output(result);
826
+ });
827
+ }
828
+
829
+ // src/commands/project/index.ts
830
+ function registerProjectCommands(program2) {
831
+ const project = program2.command("project").description("Project operations").addHelpText(
832
+ "after",
833
+ `
834
+ Examples:
835
+ $ bitbucketdc project list
836
+ $ bitbucketdc project list --name "My Project" --limit 10
837
+ `
838
+ );
839
+ list2(project);
840
+ }
841
+
842
+ // src/commands/repo/attachment/download.ts
843
+ function download(parent) {
844
+ parent.command("download").description("Download a repository attachment to disk").requiredOption("--project <key>", "Project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--id <attachmentId>", "Attachment ID").requiredOption("--output <path>", "Destination file path").addHelpText(
845
+ "after",
846
+ "\nExamples:\n bitbucketdc repo attachment download --project PROJ --repo my-repo --id abc123 --output ./file.png"
847
+ ).action(async (opts) => {
848
+ const client = getClient();
849
+ await client.repositories.downloadAttachment({
850
+ projectKey: opts.project,
851
+ repositorySlug: opts.repo,
852
+ attachmentId: opts.id,
853
+ destinationPath: opts.output
854
+ });
855
+ output({ downloaded: true, path: opts.output, attachmentId: opts.id });
856
+ });
857
+ }
858
+
859
+ // src/commands/repo/attachment/upload.ts
860
+ function upload(parent) {
861
+ parent.command("upload").description("Upload file attachments to a repository").requiredOption("--project <key>", "Project key").requiredOption("--repo <slug>", "Repository slug").requiredOption("--files <paths>", "Comma-separated local file paths").addHelpText(
862
+ "after",
863
+ "\nExamples:\n bitbucketdc repo attachment upload --project PROJ --repo my-repo --files screenshot.png\n bitbucketdc repo attachment upload --project PROJ --repo my-repo --files file1.png,file2.pdf"
864
+ ).action(async (opts) => {
865
+ const client = getClient();
866
+ const filePaths = opts.files.split(",").map((p) => p.trim()).filter(Boolean);
867
+ const results = [];
868
+ const failed = [];
869
+ for (const filePath of filePaths) {
870
+ try {
871
+ const result = await client.repositories.uploadAttachment({
872
+ projectKey: opts.project,
873
+ repositorySlug: opts.repo,
874
+ filePath
875
+ });
876
+ results.push({ id: result.id, url: result.url });
877
+ } catch (err) {
878
+ failed.push({ filePath, error: err instanceof Error ? err.message : String(err) });
879
+ }
880
+ }
881
+ output({
882
+ project: opts.project,
883
+ repo: opts.repo,
884
+ uploaded: results.length,
885
+ attachments: results,
886
+ ...failed.length > 0 && { failed }
887
+ });
888
+ });
889
+ }
890
+
891
+ // src/commands/repo/attachment/index.ts
892
+ function registerAttachmentCommands(parent) {
893
+ const attachment = parent.command("attachment").description("Attachment operations").addHelpText(
894
+ "after",
895
+ `
896
+ Examples:
897
+ $ bitbucketdc repo attachment download --project PROJ --repo my-repo --id 706 --output ./image.png
898
+ $ bitbucketdc repo attachment upload --project PROJ --repo my-repo --files screenshot.png,report.pdf
899
+ `
900
+ );
901
+ download(attachment);
902
+ upload(attachment);
903
+ }
904
+
905
+ // src/commands/repo/list.ts
906
+ function list3(parent) {
907
+ parent.command("list <projectKey>").description("List repositories in a project").addHelpText("after", "\nExamples:\n bitbucketdc repo list PROJ\n bitbucketdc repo list MYPROJ").action(async (projectKey) => {
908
+ const client = getClient();
909
+ const result = await client.repositories.list({ projectKey });
910
+ output(result);
911
+ });
912
+ }
913
+
914
+ // src/commands/repo/index.ts
915
+ function registerRepoCommands(program2) {
916
+ const repo = program2.command("repo").description("Repository operations").addHelpText(
917
+ "after",
918
+ `
919
+ Examples:
920
+ $ bitbucketdc repo list PROJ
921
+ $ bitbucketdc repo attachment download --project PROJ --repo my-repo --id abc123 --output ./file.png
922
+ `
923
+ );
924
+ list3(repo);
925
+ registerAttachmentCommands(repo);
926
+ }
927
+
928
+ // src/commands/user/list.ts
929
+ function list4(parent) {
930
+ parent.command("list").description("List all users").option("--filter <filter>", "Filter users by username, name or email (partial match)").addHelpText("after", "\nExamples:\n bitbucketdc user list\n bitbucketdc user list --filter john").action(async (opts) => {
931
+ const client = getClient();
932
+ const result = await client.users.getAll(opts.filter ? { filter: opts.filter } : void 0);
933
+ output(result);
934
+ });
935
+ }
936
+
937
+ // src/commands/user/profile.ts
938
+ function profile(parent) {
939
+ parent.command("profile <username>").description("Get a user profile by username").addHelpText("after", "\nExamples:\n bitbucketdc user profile jsmith\n bitbucketdc user profile admin").action(async (username) => {
940
+ const client = getClient();
941
+ const result = await client.users.getProfile({ username });
942
+ output(result);
943
+ });
944
+ }
945
+
946
+ // src/commands/user/index.ts
947
+ function registerUserCommands(program2) {
948
+ const user = program2.command("user").description("User operations").addHelpText(
949
+ "after",
950
+ `
951
+ Examples:
952
+ $ bitbucketdc user profile jsmith
953
+ $ bitbucketdc user list --filter john
954
+ `
955
+ );
956
+ profile(user);
957
+ list4(user);
958
+ }
959
+
960
+ // src/index.ts
961
+ var DIM = "\x1B[2m";
962
+ var RESET = "\x1B[0m";
963
+ var program = new Command8();
964
+ program.name("bitbucketdc").description("Bitbucket Data Center CLI").version("1.0.0").configureHelp({
965
+ styleTitle: (str) => styleText("bold", str),
966
+ styleUsage: (str) => styleText("dim", str),
967
+ styleCommandDescription: (str) => styleText("dim", str),
968
+ styleOptionDescription: (str) => styleText("dim", str),
969
+ styleSubcommandDescription: (str) => styleText("dim", str)
970
+ }).addHelpText("beforeAll", `
971
+ ${styleText("bold", "bitbucketdc")} ${DIM}\u2014 Bitbucket Data Center CLI${RESET}
972
+ `).addHelpText(
973
+ "after",
974
+ `
975
+ ${styleText("bold", "Environment:")}
29
976
  BITBUCKET_URL Bitbucket Server base URL ${DIM}(e.g., https://bitbucket.example.com)${RESET}
30
977
  BITBUCKET_TOKEN Personal Access Token ${DIM}(generate in Bitbucket > Profile > Personal Access Tokens)${RESET}
31
978
 
32
- ${styleText('bold', 'Examples:')}
979
+ ${styleText("bold", "Examples:")}
33
980
  ${DIM}$${RESET} bitbucketdc user profile jsmith
34
981
  ${DIM}$${RESET} bitbucketdc user list --filter john
35
982
  ${DIM}$${RESET} bitbucketdc project list --name "My Project"
36
983
  ${DIM}$${RESET} bitbucketdc repo list PROJ
37
984
  ${DIM}$${RESET} bitbucketdc pr inbox
38
985
  ${DIM}$${RESET} bitbucketdc pr get --project PROJ --repo my-repo --pr 42
39
- `);
986
+ `
987
+ );
40
988
  registerUserCommands(program);
41
989
  registerProjectCommands(program);
42
990
  registerRepoCommands(program);
@@ -45,9 +993,7 @@ registerCommitCommands(program);
45
993
  registerCompareCommands(program);
46
994
  registerPrCommands(program);
47
995
  try {
48
- await program.parseAsync();
49
- }
50
- catch (err) {
51
- handleError(err);
996
+ await program.parseAsync();
997
+ } catch (err) {
998
+ handleError(err);
52
999
  }
53
- //# sourceMappingURL=index.js.map