@nulab/bee 0.0.0 → 1.0.0-rc.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.
Files changed (135) hide show
  1. package/README.md +36 -0
  2. package/bin/cli.mjs +2 -0
  3. package/dist/chunks/activities.mjs +90 -0
  4. package/dist/chunks/activities2.mjs +91 -0
  5. package/dist/chunks/activities3.mjs +91 -0
  6. package/dist/chunks/add-user.mjs +42 -0
  7. package/dist/chunks/add.mjs +62 -0
  8. package/dist/chunks/add2.mjs +40 -0
  9. package/dist/chunks/api.mjs +138 -0
  10. package/dist/chunks/attachments.mjs +48 -0
  11. package/dist/chunks/attachments2.mjs +48 -0
  12. package/dist/chunks/attachments3.mjs +49 -0
  13. package/dist/chunks/browse.mjs +270 -0
  14. package/dist/chunks/clone.mjs +61 -0
  15. package/dist/chunks/close.mjs +51 -0
  16. package/dist/chunks/comment.mjs +124 -0
  17. package/dist/chunks/comment2.mjs +112 -0
  18. package/dist/chunks/comments.mjs +58 -0
  19. package/dist/chunks/completion.mjs +118 -0
  20. package/dist/chunks/count.mjs +74 -0
  21. package/dist/chunks/count2.mjs +70 -0
  22. package/dist/chunks/count3.mjs +60 -0
  23. package/dist/chunks/count4.mjs +35 -0
  24. package/dist/chunks/count5.mjs +53 -0
  25. package/dist/chunks/create.mjs +61 -0
  26. package/dist/chunks/create2.mjs +83 -0
  27. package/dist/chunks/create3.mjs +65 -0
  28. package/dist/chunks/create4.mjs +74 -0
  29. package/dist/chunks/create5.mjs +57 -0
  30. package/dist/chunks/create6.mjs +38 -0
  31. package/dist/chunks/create7.mjs +46 -0
  32. package/dist/chunks/create8.mjs +50 -0
  33. package/dist/chunks/create9.mjs +50 -0
  34. package/dist/chunks/dashboard.mjs +85 -0
  35. package/dist/chunks/delete.mjs +48 -0
  36. package/dist/chunks/delete2.mjs +47 -0
  37. package/dist/chunks/delete3.mjs +47 -0
  38. package/dist/chunks/delete4.mjs +47 -0
  39. package/dist/chunks/delete5.mjs +48 -0
  40. package/dist/chunks/delete6.mjs +48 -0
  41. package/dist/chunks/delete7.mjs +55 -0
  42. package/dist/chunks/delete8.mjs +54 -0
  43. package/dist/chunks/delete9.mjs +49 -0
  44. package/dist/chunks/edit.mjs +56 -0
  45. package/dist/chunks/edit2.mjs +73 -0
  46. package/dist/chunks/edit3.mjs +65 -0
  47. package/dist/chunks/edit4.mjs +52 -0
  48. package/dist/chunks/edit5.mjs +38 -0
  49. package/dist/chunks/edit6.mjs +51 -0
  50. package/dist/chunks/edit7.mjs +47 -0
  51. package/dist/chunks/edit8.mjs +47 -0
  52. package/dist/chunks/history.mjs +57 -0
  53. package/dist/chunks/index.mjs +15 -0
  54. package/dist/chunks/index10.mjs +18 -0
  55. package/dist/chunks/index11.mjs +13 -0
  56. package/dist/chunks/index12.mjs +13 -0
  57. package/dist/chunks/index13.mjs +13 -0
  58. package/dist/chunks/index14.mjs +8 -0
  59. package/dist/chunks/index15.mjs +13 -0
  60. package/dist/chunks/index16.mjs +13 -0
  61. package/dist/chunks/index17.mjs +14 -0
  62. package/dist/chunks/index2.mjs +18 -0
  63. package/dist/chunks/index3.mjs +20 -0
  64. package/dist/chunks/index4.mjs +15 -0
  65. package/dist/chunks/index5.mjs +13 -0
  66. package/dist/chunks/index6.mjs +17 -0
  67. package/dist/chunks/index7.mjs +8 -0
  68. package/dist/chunks/index8.mjs +8 -0
  69. package/dist/chunks/index9.mjs +13 -0
  70. package/dist/chunks/list.mjs +53 -0
  71. package/dist/chunks/list10.mjs +44 -0
  72. package/dist/chunks/list11.mjs +49 -0
  73. package/dist/chunks/list12.mjs +45 -0
  74. package/dist/chunks/list13.mjs +45 -0
  75. package/dist/chunks/list14.mjs +55 -0
  76. package/dist/chunks/list15.mjs +47 -0
  77. package/dist/chunks/list2.mjs +95 -0
  78. package/dist/chunks/list3.mjs +86 -0
  79. package/dist/chunks/list4.mjs +80 -0
  80. package/dist/chunks/list5.mjs +78 -0
  81. package/dist/chunks/list6.mjs +45 -0
  82. package/dist/chunks/list7.mjs +49 -0
  83. package/dist/chunks/list8.mjs +47 -0
  84. package/dist/chunks/list9.mjs +53 -0
  85. package/dist/chunks/login.mjs +206 -0
  86. package/dist/chunks/logout.mjs +57 -0
  87. package/dist/chunks/me.mjs +49 -0
  88. package/dist/chunks/read-all.mjs +30 -0
  89. package/dist/chunks/read.mjs +30 -0
  90. package/dist/chunks/read2.mjs +28 -0
  91. package/dist/chunks/refresh.mjs +77 -0
  92. package/dist/chunks/remove-user.mjs +42 -0
  93. package/dist/chunks/remove.mjs +28 -0
  94. package/dist/chunks/reopen.mjs +43 -0
  95. package/dist/chunks/status.mjs +62 -0
  96. package/dist/chunks/status2.mjs +62 -0
  97. package/dist/chunks/status3.mjs +67 -0
  98. package/dist/chunks/switch.mjs +52 -0
  99. package/dist/chunks/tags.mjs +41 -0
  100. package/dist/chunks/token.mjs +39 -0
  101. package/dist/chunks/tree.mjs +61 -0
  102. package/dist/chunks/users.mjs +48 -0
  103. package/dist/chunks/view.mjs +58 -0
  104. package/dist/chunks/view2.mjs +95 -0
  105. package/dist/chunks/view3.mjs +69 -0
  106. package/dist/chunks/view4.mjs +71 -0
  107. package/dist/chunks/view5.mjs +62 -0
  108. package/dist/chunks/view6.mjs +53 -0
  109. package/dist/chunks/view7.mjs +49 -0
  110. package/dist/chunks/view8.mjs +62 -0
  111. package/dist/chunks/view9.mjs +49 -0
  112. package/dist/index.mjs +152 -0
  113. package/dist/shared/bee.-8tk76YJ.mjs +42 -0
  114. package/dist/shared/bee.BTBGpv4K.mjs +34 -0
  115. package/dist/shared/bee.BXiuAfjJ.mjs +10 -0
  116. package/dist/shared/bee.BeQSH2t0.mjs +25 -0
  117. package/dist/shared/bee.Btmq3TXs.mjs +19 -0
  118. package/dist/shared/bee.C--ZWPxf.mjs +14 -0
  119. package/dist/shared/bee.CCNmDHVv.mjs +33 -0
  120. package/dist/shared/bee.CQ3kBgas.mjs +58 -0
  121. package/dist/shared/bee.CThuQMit.mjs +124 -0
  122. package/dist/shared/bee.ChBdZ0cH.mjs +9 -0
  123. package/dist/shared/bee.CktwmH8R.mjs +25 -0
  124. package/dist/shared/bee.CzKcWSES.mjs +42 -0
  125. package/dist/shared/bee.D6yQ6Pqf.mjs +18 -0
  126. package/dist/shared/bee.DHTPkjMh.mjs +48 -0
  127. package/dist/shared/bee.DVTuFf-T.mjs +276 -0
  128. package/dist/shared/bee.DoTvz3uW.mjs +13 -0
  129. package/dist/shared/bee.Ds2l-nTJ.mjs +308 -0
  130. package/dist/shared/bee.IM3QELRf.mjs +32 -0
  131. package/dist/shared/bee.XxOB1Her.mjs +8 -0
  132. package/dist/shared/bee.n5MYN4a6.mjs +12 -0
  133. package/dist/shared/bee.sHWg0IFT.mjs +22 -0
  134. package/package.json +50 -2
  135. package/.github/workflows/initial-release.yml +0 -23
package/README.md CHANGED
@@ -1,3 +1,39 @@
1
1
  # bee
2
2
 
3
3
  Bring [Backlog](https://backlog.com/) to your command line.
4
+
5
+ **Note:** This is not an officially supported Nulab product. It is maintained by volunteers.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install -g @nulab/bee
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ Authenticate with your Backlog space:
16
+
17
+ ```sh
18
+ bee auth login
19
+ ```
20
+
21
+ Then start using bee:
22
+
23
+ ```sh
24
+ bee issue list
25
+ bee issue view PROJECT-123
26
+ bee project list
27
+ ```
28
+
29
+ ## Documentation
30
+
31
+ See the [documentation site](https://nulab.github.io/bee) for the full command reference and guides.
32
+
33
+ ## Development
34
+
35
+ See the [repository root README](https://github.com/nulab/bee) for development setup and contributing instructions.
36
+
37
+ ## License
38
+
39
+ MIT
package/bin/cli.mjs ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "../dist/index.mjs";
@@ -0,0 +1,90 @@
1
+ import consola from 'consola';
2
+ import { A as ACTIVITY_LABELS } from '../shared/bee.CCNmDHVv.mjs';
3
+ import { g as getClient } from '../shared/bee.CThuQMit.mjs';
4
+ import 'backlog-js';
5
+ import 'node:http';
6
+ import 'open';
7
+ import 'node:child_process';
8
+ import { o as outputResult } from '../shared/bee.BTBGpv4K.mjs';
9
+ import 'node:stream/consumers';
10
+ import 'valibot';
11
+ import { f as formatDate } from '../shared/bee.n5MYN4a6.mjs';
12
+ import { p as printTable } from '../shared/bee.IM3QELRf.mjs';
13
+ import { B as BeeCommand, E as ENV_AUTH, a as ENV_PROJECT } from '../shared/bee.CQ3kBgas.mjs';
14
+ import { a as collectNum, b as count, o as order, j as json, s as space } from '../shared/bee.DHTPkjMh.mjs';
15
+ import '../shared/bee.XxOB1Her.mjs';
16
+ import '../shared/bee.CktwmH8R.mjs';
17
+ import '../shared/bee.DVTuFf-T.mjs';
18
+ import 'node:fs';
19
+ import 'node:path';
20
+ import 'node:os';
21
+ import '../shared/bee.BeQSH2t0.mjs';
22
+ import '../shared/bee.-8tk76YJ.mjs';
23
+ import '../shared/bee.Ds2l-nTJ.mjs';
24
+ import 'commander';
25
+ import 'consola/utils';
26
+
27
+ const getActivitySummary = (activity) => {
28
+ if (activity.type === 34 && activity.content.deletedStatus?.name) {
29
+ return activity.content.deletedStatus.name;
30
+ }
31
+ if (activity.content.summary) {
32
+ return activity.content.summary;
33
+ }
34
+ if (activity.content.link && activity.content.link.length > 0) {
35
+ return activity.content.link.map((item) => item.key_id ? `#${item.key_id}` : item.title ?? "").filter(Boolean).join(", ");
36
+ }
37
+ if (activity.content.key_id) {
38
+ return `#${activity.content.key_id}`;
39
+ }
40
+ return "";
41
+ };
42
+ const activities = new BeeCommand("activities").summary("List project activities").description(
43
+ `Results are ordered by most recent first. Use \`--activity-type\` to filter by type.
44
+
45
+ For activity type IDs, see:
46
+ https://developer.nulab.com/docs/backlog/api/2/get-project-recent-updates/#response-description`
47
+ ).argument("<project>", "Project ID or project key").option(
48
+ "--activity-type <id>",
49
+ "Filter by activity type IDs (repeatable)",
50
+ collectNum,
51
+ []
52
+ ).addOption(count()).addOption(order()).addOption(json()).addOption(space()).envVars([...ENV_AUTH, ENV_PROJECT]).examples([
53
+ { description: "List recent activities", command: "bee project activities PROJECT_KEY" },
54
+ {
55
+ description: "Show only issue-related activities",
56
+ command: "bee project activities PROJECT_KEY --activity-type 1 --activity-type 2 --activity-type 3"
57
+ },
58
+ {
59
+ description: "Show last 50 activities",
60
+ command: "bee project activities PROJECT_KEY --count 50"
61
+ },
62
+ {
63
+ description: "Output as JSON",
64
+ command: "bee project activities PROJECT_KEY --json"
65
+ }
66
+ ]).action(async (project, opts) => {
67
+ const { client } = await getClient(opts.space);
68
+ const activityTypeId = opts.activityType;
69
+ const activityList = await client.getProjectActivities(project, {
70
+ activityTypeId,
71
+ count: opts.count ? Number(opts.count) : void 0,
72
+ order: opts.order
73
+ });
74
+ const jsonArg = opts.json === true ? "" : opts.json;
75
+ outputResult(activityList, { ...opts, json: jsonArg }, (data) => {
76
+ if (data.length === 0) {
77
+ consola.info("No activities found.");
78
+ return;
79
+ }
80
+ const rows = data.map((activity) => [
81
+ { header: "DATE", value: formatDate(activity.created) },
82
+ { header: "TYPE", value: ACTIVITY_LABELS[activity.type] ?? `Type ${activity.type}` },
83
+ { header: "USER", value: activity.createdUser?.name ?? "Unknown" },
84
+ { header: "SUMMARY", value: getActivitySummary(activity) }
85
+ ]);
86
+ printTable(rows);
87
+ });
88
+ });
89
+
90
+ export { activities as default };
@@ -0,0 +1,91 @@
1
+ import consola from 'consola';
2
+ import { A as ACTIVITY_LABELS } from '../shared/bee.CCNmDHVv.mjs';
3
+ import { g as getClient } from '../shared/bee.CThuQMit.mjs';
4
+ import 'backlog-js';
5
+ import 'node:http';
6
+ import 'open';
7
+ import 'node:child_process';
8
+ import { o as outputResult } from '../shared/bee.BTBGpv4K.mjs';
9
+ import 'node:stream/consumers';
10
+ import 'valibot';
11
+ import { f as formatDate } from '../shared/bee.n5MYN4a6.mjs';
12
+ import { p as printTable } from '../shared/bee.IM3QELRf.mjs';
13
+ import { B as BeeCommand, E as ENV_AUTH } from '../shared/bee.CQ3kBgas.mjs';
14
+ import { a as collectNum, b as count, o as order, m as minId, l as maxId, j as json, s as space } from '../shared/bee.DHTPkjMh.mjs';
15
+ import '../shared/bee.XxOB1Her.mjs';
16
+ import '../shared/bee.CktwmH8R.mjs';
17
+ import '../shared/bee.DVTuFf-T.mjs';
18
+ import 'node:fs';
19
+ import 'node:path';
20
+ import 'node:os';
21
+ import '../shared/bee.BeQSH2t0.mjs';
22
+ import '../shared/bee.-8tk76YJ.mjs';
23
+ import '../shared/bee.Ds2l-nTJ.mjs';
24
+ import 'commander';
25
+ import 'consola/utils';
26
+
27
+ const getActivitySummary = (activity) => {
28
+ if (activity.type === 34 && activity.content.deletedStatus?.name) {
29
+ return activity.content.deletedStatus.name;
30
+ }
31
+ if (activity.content.summary) {
32
+ return activity.content.summary;
33
+ }
34
+ if (activity.content.link && activity.content.link.length > 0) {
35
+ return activity.content.link.map((item) => item.key_id ? `#${item.key_id}` : item.title ?? "").filter(Boolean).join(", ");
36
+ }
37
+ if (activity.content.key_id) {
38
+ return `#${activity.content.key_id}`;
39
+ }
40
+ return "";
41
+ };
42
+ const activities = new BeeCommand("activities").summary("List user activities").description(
43
+ `Results are ordered by most recent first. Use \`--activity-type\` to filter by type.
44
+
45
+ For activity type IDs, see:
46
+ https://developer.nulab.com/docs/backlog/api/2/get-user-recent-updates/#response-description`
47
+ ).argument("<user>", "User ID").option(
48
+ "--activity-type <id>",
49
+ "Filter by activity type IDs (repeatable)",
50
+ collectNum,
51
+ []
52
+ ).addOption(count()).addOption(order()).addOption(minId()).addOption(maxId()).addOption(json()).addOption(space()).envVars([...ENV_AUTH]).examples([
53
+ { description: "List user activities", command: "bee user activities 12345" },
54
+ {
55
+ description: "Show only issue-related activities",
56
+ command: "bee user activities 12345 --activity-type 1 --activity-type 2 --activity-type 3"
57
+ },
58
+ {
59
+ description: "Show last 50 activities",
60
+ command: "bee user activities 12345 --count 50"
61
+ },
62
+ {
63
+ description: "Output as JSON",
64
+ command: "bee user activities 12345 --json"
65
+ }
66
+ ]).action(async (user, opts) => {
67
+ const { client } = await getClient(opts.space);
68
+ const activityTypeId = opts.activityType;
69
+ const activityList = await client.getUserActivities(Number(user), {
70
+ activityTypeId,
71
+ count: opts.count ? Number(opts.count) : void 0,
72
+ order: opts.order,
73
+ minId: opts.minId ? Number(opts.minId) : void 0,
74
+ maxId: opts.maxId ? Number(opts.maxId) : void 0
75
+ });
76
+ outputResult(activityList, opts, (data) => {
77
+ if (data.length === 0) {
78
+ consola.info("No activities found.");
79
+ return;
80
+ }
81
+ const rows = data.map((activity) => [
82
+ { header: "DATE", value: formatDate(activity.created) },
83
+ { header: "TYPE", value: ACTIVITY_LABELS[activity.type] ?? `Type ${activity.type}` },
84
+ { header: "PROJECT", value: activity.project?.name ?? "" },
85
+ { header: "SUMMARY", value: getActivitySummary(activity) }
86
+ ]);
87
+ printTable(rows);
88
+ });
89
+ });
90
+
91
+ export { activities as default };
@@ -0,0 +1,91 @@
1
+ import consola from 'consola';
2
+ import { A as ACTIVITY_LABELS } from '../shared/bee.CCNmDHVv.mjs';
3
+ import { g as getClient } from '../shared/bee.CThuQMit.mjs';
4
+ import 'backlog-js';
5
+ import 'node:http';
6
+ import 'open';
7
+ import 'node:child_process';
8
+ import { o as outputResult } from '../shared/bee.BTBGpv4K.mjs';
9
+ import 'node:stream/consumers';
10
+ import 'valibot';
11
+ import { f as formatDate } from '../shared/bee.n5MYN4a6.mjs';
12
+ import { p as printTable } from '../shared/bee.IM3QELRf.mjs';
13
+ import { B as BeeCommand, E as ENV_AUTH } from '../shared/bee.CQ3kBgas.mjs';
14
+ import { a as collectNum, b as count, o as order, m as minId, l as maxId, j as json, s as space } from '../shared/bee.DHTPkjMh.mjs';
15
+ import '../shared/bee.XxOB1Her.mjs';
16
+ import '../shared/bee.CktwmH8R.mjs';
17
+ import '../shared/bee.DVTuFf-T.mjs';
18
+ import 'node:fs';
19
+ import 'node:path';
20
+ import 'node:os';
21
+ import '../shared/bee.BeQSH2t0.mjs';
22
+ import '../shared/bee.-8tk76YJ.mjs';
23
+ import '../shared/bee.Ds2l-nTJ.mjs';
24
+ import 'commander';
25
+ import 'consola/utils';
26
+
27
+ const getActivitySummary = (activity) => {
28
+ if (activity.type === 34 && activity.content.deletedStatus?.name) {
29
+ return activity.content.deletedStatus.name;
30
+ }
31
+ if (activity.content.summary) {
32
+ return activity.content.summary;
33
+ }
34
+ if (activity.content.link && activity.content.link.length > 0) {
35
+ return activity.content.link.map((item) => item.key_id ? `#${item.key_id}` : item.title ?? "").filter(Boolean).join(", ");
36
+ }
37
+ if (activity.content.key_id) {
38
+ return `#${activity.content.key_id}`;
39
+ }
40
+ return "";
41
+ };
42
+ const activities = new BeeCommand("activities").summary("List space activities").description(
43
+ `Results are ordered by most recent first. Use \`--activity-type\` to filter by type.
44
+
45
+ For activity type IDs, see:
46
+ https://developer.nulab.com/docs/backlog/api/2/get-recent-updates/#response-description`
47
+ ).option(
48
+ "--activity-type <id>",
49
+ "Filter by activity type IDs (repeatable)",
50
+ collectNum,
51
+ []
52
+ ).addOption(count()).addOption(order()).addOption(minId()).addOption(maxId()).addOption(json()).addOption(space()).envVars([...ENV_AUTH]).examples([
53
+ { description: "List space activities", command: "bee space activities" },
54
+ {
55
+ description: "Show only issue-related activities",
56
+ command: "bee space activities --activity-type 1 --activity-type 2 --activity-type 3"
57
+ },
58
+ {
59
+ description: "Show last 50 activities",
60
+ command: "bee space activities --count 50"
61
+ },
62
+ {
63
+ description: "Output as JSON",
64
+ command: "bee space activities --json"
65
+ }
66
+ ]).action(async (opts) => {
67
+ const { client } = await getClient(opts.space);
68
+ const activityTypeId = opts.activityType;
69
+ const activityList = await client.getSpaceActivities({
70
+ activityTypeId,
71
+ count: opts.count ? Number(opts.count) : void 0,
72
+ order: opts.order,
73
+ minId: opts.minId ? Number(opts.minId) : void 0,
74
+ maxId: opts.maxId ? Number(opts.maxId) : void 0
75
+ });
76
+ outputResult(activityList, opts, (data) => {
77
+ if (data.length === 0) {
78
+ consola.info("No activities found.");
79
+ return;
80
+ }
81
+ const rows = data.map((activity) => [
82
+ { header: "DATE", value: formatDate(activity.created) },
83
+ { header: "TYPE", value: ACTIVITY_LABELS[activity.type] ?? `Type ${activity.type}` },
84
+ { header: "PROJECT", value: activity.project?.name ?? "" },
85
+ { header: "SUMMARY", value: getActivitySummary(activity) }
86
+ ]);
87
+ printTable(rows);
88
+ });
89
+ });
90
+
91
+ export { activities as default };
@@ -0,0 +1,42 @@
1
+ import consola from 'consola';
2
+ import { g as getClient } from '../shared/bee.CThuQMit.mjs';
3
+ import 'backlog-js';
4
+ import 'node:http';
5
+ import 'open';
6
+ import 'node:child_process';
7
+ import { o as outputResult } from '../shared/bee.BTBGpv4K.mjs';
8
+ import { U as UserError } from '../shared/bee.XxOB1Her.mjs';
9
+ import 'node:stream/consumers';
10
+ import 'valibot';
11
+ import { B as BeeCommand, E as ENV_AUTH, a as ENV_PROJECT } from '../shared/bee.CQ3kBgas.mjs';
12
+ import { p as project, R as RequiredOption, j as json, s as space, r as resolveOptions } from '../shared/bee.DHTPkjMh.mjs';
13
+ import '../shared/bee.CktwmH8R.mjs';
14
+ import '../shared/bee.DVTuFf-T.mjs';
15
+ import 'node:fs';
16
+ import 'node:path';
17
+ import 'node:os';
18
+ import '../shared/bee.BeQSH2t0.mjs';
19
+ import '../shared/bee.-8tk76YJ.mjs';
20
+ import 'commander';
21
+ import 'consola/utils';
22
+
23
+ const addUser = new BeeCommand("add-user").summary("Add a user to a project").description(`Use \`bee project users\` to look up user IDs.`).addOption(project()).addOption(new RequiredOption("--user-id <id>", "User ID")).addOption(json()).addOption(space()).envVars([...ENV_AUTH, ENV_PROJECT]).examples([
24
+ {
25
+ description: "Add a user to a project",
26
+ command: "bee project add-user -p PROJECT_KEY --user-id 12345"
27
+ }
28
+ ]).action(async (opts, cmd) => {
29
+ await resolveOptions(cmd);
30
+ const userId = Number(opts.userId);
31
+ if (Number.isNaN(userId)) {
32
+ throw new UserError("User ID must be a number.");
33
+ }
34
+ const { client } = await getClient(opts.space);
35
+ const user = await client.postProjectUser(opts.project, String(userId));
36
+ const jsonArg = opts.json === true ? "" : opts.json;
37
+ outputResult(user, { ...opts, json: jsonArg }, (data) => {
38
+ consola.success(`Added user ${data.name} to project ${opts.project}.`);
39
+ });
40
+ });
41
+
42
+ export { addUser as default };
@@ -0,0 +1,62 @@
1
+ import consola from 'consola';
2
+ import { g as getClient } from '../shared/bee.CThuQMit.mjs';
3
+ import 'backlog-js';
4
+ import 'node:http';
5
+ import 'open';
6
+ import 'node:child_process';
7
+ import { U as UserError } from '../shared/bee.XxOB1Her.mjs';
8
+ import 'node:stream/consumers';
9
+ import 'valibot';
10
+ import { B as BeeCommand, E as ENV_AUTH } from '../shared/bee.CQ3kBgas.mjs';
11
+ import { t as issue, s as space } from '../shared/bee.DHTPkjMh.mjs';
12
+ import '../shared/bee.CktwmH8R.mjs';
13
+ import '../shared/bee.DVTuFf-T.mjs';
14
+ import 'node:fs';
15
+ import 'node:path';
16
+ import 'node:os';
17
+ import '../shared/bee.BeQSH2t0.mjs';
18
+ import '../shared/bee.-8tk76YJ.mjs';
19
+ import 'commander';
20
+ import 'consola/utils';
21
+
22
+ const add = new BeeCommand("add").summary("Add a star").description(
23
+ `Specify exactly one target: \`--issue\` (accepts key or ID), \`--comment\`, \`--wiki\`, or \`--pr-comment\`.`
24
+ ).addOption(issue()).option("--comment <number>", "Comment ID to star").option("--wiki <number>", "Wiki page ID to star").option("--pr-comment <number>", "Pull request comment ID to star").addOption(space()).envVars([...ENV_AUTH]).examples([
25
+ { description: "Star an issue by key", command: "bee star add --issue PROJECT-123" },
26
+ { description: "Star an issue by ID", command: "bee star add --issue 12345" },
27
+ { description: "Star a comment", command: "bee star add --comment 67890" },
28
+ { description: "Star a wiki page", command: "bee star add --wiki 111" },
29
+ { description: "Star a pull request comment", command: "bee star add --pr-comment 222" }
30
+ ]).action(async (opts) => {
31
+ const flags = [opts.issue, opts.comment, opts.wiki, opts.prComment].filter(
32
+ (v) => v !== void 0
33
+ );
34
+ if (flags.length === 0) {
35
+ throw new UserError(
36
+ "Exactly one of --issue, --comment, --wiki, or --pr-comment must be provided."
37
+ );
38
+ }
39
+ if (flags.length > 1) {
40
+ throw new UserError(
41
+ "Only one of --issue, --comment, --wiki, or --pr-comment can be provided at a time."
42
+ );
43
+ }
44
+ const { client } = await getClient(opts.space);
45
+ if (opts.issue) {
46
+ const issue = /^\d+$/.test(opts.issue) ? { id: Number(opts.issue) } : await client.getIssue(opts.issue);
47
+ const issueId = issue.id;
48
+ await client.postStar({ issueId });
49
+ consola.success(`Starred issue ${opts.issue}.`);
50
+ } else if (opts.comment) {
51
+ await client.postStar({ commentId: Number(opts.comment) });
52
+ consola.success(`Starred comment ${opts.comment}.`);
53
+ } else if (opts.wiki) {
54
+ await client.postStar({ wikiId: Number(opts.wiki) });
55
+ consola.success(`Starred wiki ${opts.wiki}.`);
56
+ } else if (opts.prComment) {
57
+ await client.postStar({ pullRequestCommentId: Number(opts.prComment) });
58
+ consola.success(`Starred pull request comment ${opts.prComment}.`);
59
+ }
60
+ });
61
+
62
+ export { add as default };
@@ -0,0 +1,40 @@
1
+ import consola from 'consola';
2
+ import { g as getClient } from '../shared/bee.CThuQMit.mjs';
3
+ import 'backlog-js';
4
+ import 'node:http';
5
+ import 'open';
6
+ import 'node:child_process';
7
+ import { o as outputResult } from '../shared/bee.BTBGpv4K.mjs';
8
+ import 'node:stream/consumers';
9
+ import 'valibot';
10
+ import { B as BeeCommand, E as ENV_AUTH } from '../shared/bee.CQ3kBgas.mjs';
11
+ import { j as json, s as space } from '../shared/bee.DHTPkjMh.mjs';
12
+ import '../shared/bee.XxOB1Her.mjs';
13
+ import '../shared/bee.CktwmH8R.mjs';
14
+ import '../shared/bee.DVTuFf-T.mjs';
15
+ import 'node:fs';
16
+ import 'node:path';
17
+ import 'node:os';
18
+ import '../shared/bee.BeQSH2t0.mjs';
19
+ import '../shared/bee.-8tk76YJ.mjs';
20
+ import 'commander';
21
+ import 'consola/utils';
22
+
23
+ const add = new BeeCommand("add").summary("Add a watching item").description(`Subscribe to an issue to receive update notifications.`).requiredOption("--issue <key>", "Issue ID or issue key").option("--note <text>", "Note to attach to the watching item").addOption(json()).addOption(space()).envVars([...ENV_AUTH]).examples([
24
+ { description: "Watch an issue", command: "bee watching add --issue PROJECT-123" },
25
+ {
26
+ description: "Watch an issue with a note",
27
+ command: 'bee watching add --issue PROJECT-123 --note "Track progress"'
28
+ }
29
+ ]).action(async (opts) => {
30
+ const { client } = await getClient(opts.space);
31
+ const result = await client.postWatchingListItem({
32
+ issueIdOrKey: opts.issue,
33
+ note: opts.note ?? ""
34
+ });
35
+ outputResult(result, opts, (data) => {
36
+ consola.success(`Added watching for issue ${data.issue.issueKey} (ID: ${data.id}).`);
37
+ });
38
+ });
39
+
40
+ export { add as default };
@@ -0,0 +1,138 @@
1
+ import 'consola';
2
+ import { g as getClient } from '../shared/bee.CThuQMit.mjs';
3
+ import 'backlog-js';
4
+ import 'node:http';
5
+ import 'open';
6
+ import 'node:child_process';
7
+ import { o as outputResult } from '../shared/bee.BTBGpv4K.mjs';
8
+ import { U as UserError } from '../shared/bee.XxOB1Her.mjs';
9
+ import 'node:stream/consumers';
10
+ import 'valibot';
11
+ import { B as BeeCommand, E as ENV_AUTH } from '../shared/bee.CQ3kBgas.mjs';
12
+ import { c as collect, s as space } from '../shared/bee.DHTPkjMh.mjs';
13
+ import '../shared/bee.CktwmH8R.mjs';
14
+ import '../shared/bee.DVTuFf-T.mjs';
15
+ import 'node:fs';
16
+ import 'node:path';
17
+ import 'node:os';
18
+ import '../shared/bee.BeQSH2t0.mjs';
19
+ import '../shared/bee.-8tk76YJ.mjs';
20
+ import 'commander';
21
+ import 'consola/utils';
22
+
23
+ const api = new BeeCommand("api").summary("Make an authenticated API request").description(
24
+ `The endpoint is a Backlog API path (e.g. \`users/myself\`). A leading \`/api/v2/\` prefix is stripped automatically.
25
+
26
+ \`-f\` infers types (number, boolean, string); \`-F\` always sends strings. Repeated keys become arrays. Append \`[]\` for a single-element array (e.g. \`-f projectId[]=12345\`).
27
+
28
+ For GET, fields are query parameters. For POST/PUT/PATCH/DELETE, fields are the request body.`
29
+ ).argument("<endpoint>", "API endpoint path").option("-X, --method <method>", "HTTP method", "GET").option(
30
+ "-f, --field <key=value>",
31
+ "Add a parameter with type inference (key=value, repeatable)",
32
+ collect,
33
+ []
34
+ ).option(
35
+ "-F, --raw-field <key=value>",
36
+ "Add a string parameter (key=value, repeatable)",
37
+ collect,
38
+ []
39
+ ).option("--json [fields]", "Output as JSON (optionally filter by field names, comma-separated)").option("--silent", "Do not print the response body").addOption(space()).envVars([...ENV_AUTH]).examples([
40
+ { description: "Get your user profile", command: "bee api users/myself" },
41
+ {
42
+ description: "List issues in a project",
43
+ command: "bee api issues -f 'projectId[]=12345' -f count=5"
44
+ },
45
+ {
46
+ description: "Filter by multiple statuses",
47
+ command: "bee api issues -f 'projectId[]=12345' -f statusId=1 -f statusId=2"
48
+ },
49
+ {
50
+ description: "Create an issue",
51
+ command: 'bee api issues -X POST -f projectId=12345 -f summary="Test issue" -f issueTypeId=1 -f priorityId=3'
52
+ },
53
+ {
54
+ description: "Select specific fields",
55
+ command: "bee api users/myself --json id,name,mailAddress"
56
+ }
57
+ ]).action(async (endpoint, opts) => {
58
+ const { client } = await getClient(opts.space);
59
+ const method = opts.method.toUpperCase();
60
+ const normalizedEndpoint = normalizeEndpoint(endpoint);
61
+ const params = buildParams(opts.field, opts.rawField);
62
+ const data = await makeRequest(client, method, normalizedEndpoint, params);
63
+ if (opts.silent) {
64
+ return;
65
+ }
66
+ const jsonVal = typeof opts.json === "string" ? opts.json : "";
67
+ outputResult(data, { json: jsonVal }, () => {
68
+ });
69
+ });
70
+ const normalizeEndpoint = (endpoint) => {
71
+ const stripped = endpoint.replace(/^\/?(api\/v2\/?)/, "");
72
+ return stripped;
73
+ };
74
+ const buildParams = (fields, rawFields) => {
75
+ const params = {};
76
+ const addParam = (rawKey, value) => {
77
+ const isArray = rawKey.endsWith("[]");
78
+ const key = isArray ? rawKey.slice(0, -2) : rawKey;
79
+ const existing = params[key];
80
+ if (existing === void 0) {
81
+ params[key] = isArray ? [value] : value;
82
+ } else {
83
+ params[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];
84
+ }
85
+ };
86
+ for (const pair of fields) {
87
+ const eqIndex = pair.indexOf("=");
88
+ if (eqIndex === -1) {
89
+ throw new UserError(`Invalid field format: "${pair}". Expected key=value.`);
90
+ }
91
+ addParam(pair.slice(0, eqIndex), inferType(pair.slice(eqIndex + 1)));
92
+ }
93
+ for (const pair of rawFields) {
94
+ const eqIndex = pair.indexOf("=");
95
+ if (eqIndex === -1) {
96
+ throw new UserError(`Invalid field format: "${pair}". Expected key=value.`);
97
+ }
98
+ addParam(pair.slice(0, eqIndex), pair.slice(eqIndex + 1));
99
+ }
100
+ return params;
101
+ };
102
+ const inferType = (value) => {
103
+ if (value === "true") {
104
+ return true;
105
+ }
106
+ if (value === "false") {
107
+ return false;
108
+ }
109
+ const num = Number(value);
110
+ if (value !== "" && !Number.isNaN(num)) {
111
+ return num;
112
+ }
113
+ return value;
114
+ };
115
+ const makeRequest = async (client, method, endpoint, params) => {
116
+ switch (method) {
117
+ case "GET": {
118
+ return client.get(endpoint, params);
119
+ }
120
+ case "POST": {
121
+ return client.post(endpoint, params);
122
+ }
123
+ case "PUT": {
124
+ return client.put(endpoint, params);
125
+ }
126
+ case "PATCH": {
127
+ return client.patch(endpoint, params);
128
+ }
129
+ case "DELETE": {
130
+ return client.delete(endpoint, params);
131
+ }
132
+ default: {
133
+ throw new UserError(`Unsupported HTTP method: ${method}`);
134
+ }
135
+ }
136
+ };
137
+
138
+ export { api as default };
@@ -0,0 +1,48 @@
1
+ import consola from 'consola';
2
+ import { g as getClient } from '../shared/bee.CThuQMit.mjs';
3
+ import 'backlog-js';
4
+ import 'node:http';
5
+ import 'open';
6
+ import 'node:child_process';
7
+ import { o as outputResult } from '../shared/bee.BTBGpv4K.mjs';
8
+ import 'node:stream/consumers';
9
+ import 'valibot';
10
+ import { a as formatSize, f as formatDate } from '../shared/bee.n5MYN4a6.mjs';
11
+ import { p as printTable } from '../shared/bee.IM3QELRf.mjs';
12
+ import { B as BeeCommand, E as ENV_AUTH } from '../shared/bee.CQ3kBgas.mjs';
13
+ import { j as json, s as space } from '../shared/bee.DHTPkjMh.mjs';
14
+ import '../shared/bee.XxOB1Her.mjs';
15
+ import '../shared/bee.CktwmH8R.mjs';
16
+ import '../shared/bee.DVTuFf-T.mjs';
17
+ import 'node:fs';
18
+ import 'node:path';
19
+ import 'node:os';
20
+ import '../shared/bee.BeQSH2t0.mjs';
21
+ import '../shared/bee.-8tk76YJ.mjs';
22
+ import '../shared/bee.Ds2l-nTJ.mjs';
23
+ import 'commander';
24
+ import 'consola/utils';
25
+
26
+ const attachments = new BeeCommand("attachments").summary("List issue attachments").description(`Shows file name, size, creator, and creation date.`).argument("<issue>", "Issue ID or issue key").addOption(json()).addOption(space()).envVars([...ENV_AUTH]).examples([
27
+ { description: "List attachments", command: "bee issue attachments PROJECT-123" },
28
+ { description: "Output as JSON", command: "bee issue attachments PROJECT-123 --json" }
29
+ ]).action(async (issue, opts) => {
30
+ const { client } = await getClient(opts.space);
31
+ const files = await client.getIssueAttachments(issue);
32
+ outputResult(files, opts, (data) => {
33
+ if (data.length === 0) {
34
+ consola.info("No attachments found.");
35
+ return;
36
+ }
37
+ const rows = data.map((file) => [
38
+ { header: "ID", value: String(file.id) },
39
+ { header: "NAME", value: file.name },
40
+ { header: "SIZE", value: formatSize(file.size) },
41
+ { header: "CREATED BY", value: file.createdUser?.name ?? "Unknown" },
42
+ { header: "CREATED", value: formatDate(file.created) }
43
+ ]);
44
+ printTable(rows);
45
+ });
46
+ });
47
+
48
+ export { attachments as default };