nixelo 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -0
- package/dist/commands/apiKeys.d.ts +3 -0
- package/dist/commands/apiKeys.d.ts.map +1 -0
- package/dist/commands/apiKeys.js +200 -0
- package/dist/commands/apiKeys.js.map +1 -0
- package/dist/commands/auth.d.ts +7 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +201 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/automations.d.ts +3 -0
- package/dist/commands/automations.d.ts.map +1 -0
- package/dist/commands/automations.js +302 -0
- package/dist/commands/automations.js.map +1 -0
- package/dist/commands/commandTree.d.ts +10 -0
- package/dist/commands/commandTree.d.ts.map +1 -0
- package/dist/commands/commandTree.js +36 -0
- package/dist/commands/commandTree.js.map +1 -0
- package/dist/commands/completion.d.ts +6 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +101 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +133 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/documents.d.ts +3 -0
- package/dist/commands/documents.d.ts.map +1 -0
- package/dist/commands/documents.js +200 -0
- package/dist/commands/documents.js.map +1 -0
- package/dist/commands/fields.d.ts +3 -0
- package/dist/commands/fields.d.ts.map +1 -0
- package/dist/commands/fields.js +199 -0
- package/dist/commands/fields.js.map +1 -0
- package/dist/commands/filters.d.ts +3 -0
- package/dist/commands/filters.d.ts.map +1 -0
- package/dist/commands/filters.js +243 -0
- package/dist/commands/filters.js.map +1 -0
- package/dist/commands/global.d.ts +5 -0
- package/dist/commands/global.d.ts.map +1 -0
- package/dist/commands/global.js +42 -0
- package/dist/commands/global.js.map +1 -0
- package/dist/commands/index.d.ts +23 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +23 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/invites.d.ts +3 -0
- package/dist/commands/invites.d.ts.map +1 -0
- package/dist/commands/invites.js +113 -0
- package/dist/commands/invites.js.map +1 -0
- package/dist/commands/issues/filter.d.ts +19 -0
- package/dist/commands/issues/filter.d.ts.map +1 -0
- package/dist/commands/issues/filter.js +72 -0
- package/dist/commands/issues/filter.js.map +1 -0
- package/dist/commands/issues/options.d.ts +33 -0
- package/dist/commands/issues/options.d.ts.map +1 -0
- package/dist/commands/issues/options.js +68 -0
- package/dist/commands/issues/options.js.map +1 -0
- package/dist/commands/issues/output.d.ts +12 -0
- package/dist/commands/issues/output.d.ts.map +1 -0
- package/dist/commands/issues/output.js +285 -0
- package/dist/commands/issues/output.js.map +1 -0
- package/dist/commands/issues.d.ts +3 -0
- package/dist/commands/issues.d.ts.map +1 -0
- package/dist/commands/issues.js +483 -0
- package/dist/commands/issues.js.map +1 -0
- package/dist/commands/labels.d.ts +3 -0
- package/dist/commands/labels.d.ts.map +1 -0
- package/dist/commands/labels.js +222 -0
- package/dist/commands/labels.js.map +1 -0
- package/dist/commands/notifications.d.ts +3 -0
- package/dist/commands/notifications.d.ts.map +1 -0
- package/dist/commands/notifications.js +127 -0
- package/dist/commands/notifications.js.map +1 -0
- package/dist/commands/projects.d.ts +5 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +749 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/registerAll.d.ts +3 -0
- package/dist/commands/registerAll.d.ts.map +1 -0
- package/dist/commands/registerAll.js +54 -0
- package/dist/commands/registerAll.js.map +1 -0
- package/dist/commands/sprints.d.ts +3 -0
- package/dist/commands/sprints.d.ts.map +1 -0
- package/dist/commands/sprints.js +359 -0
- package/dist/commands/sprints.js.map +1 -0
- package/dist/commands/stats.d.ts +3 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +206 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/teams.d.ts +3 -0
- package/dist/commands/teams.d.ts.map +1 -0
- package/dist/commands/teams.js +435 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/templates.d.ts +3 -0
- package/dist/commands/templates.d.ts.map +1 -0
- package/dist/commands/templates.js +264 -0
- package/dist/commands/templates.js.map +1 -0
- package/dist/commands/time.d.ts +3 -0
- package/dist/commands/time.d.ts.map +1 -0
- package/dist/commands/time.js +191 -0
- package/dist/commands/time.js.map +1 -0
- package/dist/commands/tokens.d.ts +3 -0
- package/dist/commands/tokens.d.ts.map +1 -0
- package/dist/commands/tokens.js +76 -0
- package/dist/commands/tokens.js.map +1 -0
- package/dist/commands/users.d.ts +5 -0
- package/dist/commands/users.d.ts.map +1 -0
- package/dist/commands/users.js +160 -0
- package/dist/commands/users.js.map +1 -0
- package/dist/commands/version.d.ts +3 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +17 -0
- package/dist/commands/version.js.map +1 -0
- package/dist/commands/webhooks.d.ts +3 -0
- package/dist/commands/webhooks.d.ts.map +1 -0
- package/dist/commands/webhooks.js +407 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/commands/workspaces.d.ts +3 -0
- package/dist/commands/workspaces.d.ts.map +1 -0
- package/dist/commands/workspaces.js +424 -0
- package/dist/commands/workspaces.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth.d.ts +20 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +80 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/convex.d.ts +1243 -0
- package/dist/lib/convex.d.ts.map +1 -0
- package/dist/lib/convex.js +675 -0
- package/dist/lib/convex.js.map +1 -0
- package/dist/lib/options.d.ts +10 -0
- package/dist/lib/options.d.ts.map +1 -0
- package/dist/lib/options.js +79 -0
- package/dist/lib/options.js.map +1 -0
- package/dist/lib/output.d.ts +19 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +60 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/project-key.d.ts +5 -0
- package/dist/lib/project-key.d.ts.map +1 -0
- package/dist/lib/project-key.js +56 -0
- package/dist/lib/project-key.js.map +1 -0
- package/dist/lib/prompt.d.ts +5 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +28 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/user-picker.d.ts +4 -0
- package/dist/lib/user-picker.d.ts.map +1 -0
- package/dist/lib/user-picker.js +57 -0
- package/dist/lib/user-picker.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { getStatsCycleTime, getStatsOrg, getStatsProject, getStatsSprint, getStatsTeam } from "../lib/convex.js";
|
|
2
|
+
import { parsePositiveIntegerOption, readRequiredText } from "../lib/options.js";
|
|
3
|
+
import { getActiveOutputFormat, printError, printJson, printOutput, printRows } from "../lib/output.js";
|
|
4
|
+
import { resolveRequiredProjectKey } from "../lib/project-key.js";
|
|
5
|
+
import { addOutputOptions } from "./global.js";
|
|
6
|
+
import { printProjectStatsResult } from "./projects.js";
|
|
7
|
+
const SPRINT_STATS_COLUMNS = [
|
|
8
|
+
{ header: "id", value: sprint => sprint.id },
|
|
9
|
+
{ header: "project", value: sprint => sprint.projectKey },
|
|
10
|
+
{ header: "name", value: sprint => sprint.name },
|
|
11
|
+
{ header: "status", value: sprint => sprint.status },
|
|
12
|
+
{ header: "issueCount", value: sprint => sprint.issueCount },
|
|
13
|
+
{ header: "completedCount", value: sprint => sprint.completedCount },
|
|
14
|
+
{ header: "totalPoints", value: sprint => sprint.totalPoints },
|
|
15
|
+
{ header: "completedPoints", value: sprint => sprint.completedPoints },
|
|
16
|
+
{ header: "truncated", value: sprint => sprint.truncated }
|
|
17
|
+
];
|
|
18
|
+
const TEAM_STATS_COLUMNS = [
|
|
19
|
+
{ header: "slug", value: team => team.slug },
|
|
20
|
+
{ header: "name", value: team => team.name },
|
|
21
|
+
{ header: "memberCount", value: team => team.memberCount },
|
|
22
|
+
{ header: "projectCount", value: team => team.projectCount },
|
|
23
|
+
{ header: "leadName", value: team => team.leadName },
|
|
24
|
+
{ header: "workspaceId", value: team => team.workspaceId },
|
|
25
|
+
{ header: "id", value: team => team.id }
|
|
26
|
+
];
|
|
27
|
+
const CYCLE_TIME_STATS_COLUMNS = [
|
|
28
|
+
{ header: "project", value: metrics => metrics.key },
|
|
29
|
+
{ header: "name", value: metrics => metrics.name },
|
|
30
|
+
{ header: "sampleSize", value: metrics => metrics.sampleSize },
|
|
31
|
+
{ header: "cycleTimeMedianDays", value: metrics => metrics.cycleTimeMedianDays },
|
|
32
|
+
{ header: "leadTimeMedianDays", value: metrics => metrics.leadTimeMedianDays }
|
|
33
|
+
];
|
|
34
|
+
const ORG_STATS_COLUMNS = [
|
|
35
|
+
{ header: "slug", value: stats => stats.slug },
|
|
36
|
+
{ header: "name", value: stats => stats.name },
|
|
37
|
+
{ header: "projectCount", value: stats => stats.projectCount },
|
|
38
|
+
{ header: "totalIssues", value: stats => stats.totalIssues },
|
|
39
|
+
{ header: "completedCount", value: stats => stats.completedCount },
|
|
40
|
+
{ header: "unassignedCount", value: stats => stats.unassignedCount },
|
|
41
|
+
{ header: "isProjectsTruncated", value: stats => stats.isProjectsTruncated },
|
|
42
|
+
{ header: "id", value: stats => stats.id }
|
|
43
|
+
];
|
|
44
|
+
function formatDays(value) {
|
|
45
|
+
return value === null ? "unavailable" : `${value} days`;
|
|
46
|
+
}
|
|
47
|
+
function printCycleTimeStatsResult(metrics, projectKey) {
|
|
48
|
+
const format = getActiveOutputFormat();
|
|
49
|
+
if (!metrics) {
|
|
50
|
+
if (format === "json")
|
|
51
|
+
printJson(null);
|
|
52
|
+
else if (format === "csv")
|
|
53
|
+
printRows([], CYCLE_TIME_STATS_COLUMNS, format);
|
|
54
|
+
else
|
|
55
|
+
printOutput(`Project ${projectKey} not found or has no done workflow.`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (format === "json")
|
|
59
|
+
printJson(metrics);
|
|
60
|
+
else if (format === "csv")
|
|
61
|
+
printRows([metrics], CYCLE_TIME_STATS_COLUMNS, format);
|
|
62
|
+
else {
|
|
63
|
+
printOutput(`${metrics.key} ${metrics.name}`);
|
|
64
|
+
printOutput(`Completed sample: ${metrics.sampleSize}`);
|
|
65
|
+
printOutput(`Median cycle time: ${formatDays(metrics.cycleTimeMedianDays)}`);
|
|
66
|
+
printOutput(`Median lead time: ${formatDays(metrics.leadTimeMedianDays)}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function printOrgStatsResult(stats) {
|
|
70
|
+
const format = getActiveOutputFormat();
|
|
71
|
+
if (!stats) {
|
|
72
|
+
if (format === "json")
|
|
73
|
+
printJson(null);
|
|
74
|
+
else if (format === "csv")
|
|
75
|
+
printRows([], ORG_STATS_COLUMNS, format);
|
|
76
|
+
else
|
|
77
|
+
printOutput("Selected organization not found or no longer accessible.");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (format === "json")
|
|
81
|
+
printJson(stats);
|
|
82
|
+
else if (format === "csv")
|
|
83
|
+
printRows([stats], ORG_STATS_COLUMNS, format);
|
|
84
|
+
else {
|
|
85
|
+
printOutput(`${stats.slug} ${stats.name}`);
|
|
86
|
+
printOutput(`Projects: ${stats.projectCount}`);
|
|
87
|
+
printOutput(`Issues: ${stats.completedCount}/${stats.totalIssues} completed`);
|
|
88
|
+
printOutput(`Unassigned: ${stats.unassignedCount}`);
|
|
89
|
+
if (stats.isProjectsTruncated) {
|
|
90
|
+
printOutput("Results truncated at the organization project scan limit.");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function printSprintStatsResult(sprint, sprintId) {
|
|
95
|
+
const format = getActiveOutputFormat();
|
|
96
|
+
if (!sprint) {
|
|
97
|
+
if (format === "json")
|
|
98
|
+
printJson(null);
|
|
99
|
+
else if (format === "csv")
|
|
100
|
+
printRows([], SPRINT_STATS_COLUMNS, format);
|
|
101
|
+
else
|
|
102
|
+
printOutput(`Sprint ${sprintId} not found.`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (format === "json")
|
|
106
|
+
printJson(sprint);
|
|
107
|
+
else if (format === "csv")
|
|
108
|
+
printRows([sprint], SPRINT_STATS_COLUMNS, format);
|
|
109
|
+
else {
|
|
110
|
+
printOutput(`${sprint.name} [${sprint.status}]`);
|
|
111
|
+
printOutput(`Project: ${sprint.projectKey}`);
|
|
112
|
+
printOutput(`Issues: ${sprint.completedCount}/${sprint.issueCount} completed`);
|
|
113
|
+
printOutput(`Points: ${sprint.completedPoints}/${sprint.totalPoints} completed`);
|
|
114
|
+
if (sprint.truncated)
|
|
115
|
+
printOutput("Results truncated at the sprint statistics scan limit.");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function printTeamStatsResult(team, teamSlug) {
|
|
119
|
+
const format = getActiveOutputFormat();
|
|
120
|
+
if (!team) {
|
|
121
|
+
if (format === "json")
|
|
122
|
+
printJson(null);
|
|
123
|
+
else if (format === "csv")
|
|
124
|
+
printRows([], TEAM_STATS_COLUMNS, format);
|
|
125
|
+
else
|
|
126
|
+
printOutput(`Team ${teamSlug} not found.`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (format === "json")
|
|
130
|
+
printJson(team);
|
|
131
|
+
else if (format === "csv")
|
|
132
|
+
printRows([team], TEAM_STATS_COLUMNS, format);
|
|
133
|
+
else {
|
|
134
|
+
printOutput(`${team.slug} ${team.name}`);
|
|
135
|
+
printOutput(`Members: ${team.memberCount}`);
|
|
136
|
+
printOutput(`Projects: ${team.projectCount}`);
|
|
137
|
+
if (team.leadName)
|
|
138
|
+
printOutput(`Lead: ${team.leadName}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export function registerStatsCommands(program) {
|
|
142
|
+
const statsCmd = program.command("stats").description("Show analytics statistics");
|
|
143
|
+
addOutputOptions(statsCmd.command("cycle-time").argument("<project>", "Project key"))
|
|
144
|
+
.option("-l, --limit <number>", "Maximum recent completed issues (max 100)")
|
|
145
|
+
.description("Show bounded project cycle-time and lead-time statistics")
|
|
146
|
+
.action(async (project, opts) => {
|
|
147
|
+
try {
|
|
148
|
+
const projectKey = readRequiredText(project, "Project key", "<project>");
|
|
149
|
+
const limit = parsePositiveIntegerOption(opts.limit);
|
|
150
|
+
printCycleTimeStatsResult(await getStatsCycleTime(projectKey, { limit }), projectKey);
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
addOutputOptions(statsCmd.command("org"))
|
|
158
|
+
.description("Show bounded selected-organization statistics")
|
|
159
|
+
.action(async () => {
|
|
160
|
+
try {
|
|
161
|
+
printOrgStatsResult(await getStatsOrg());
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
addOutputOptions(statsCmd.command("project"))
|
|
169
|
+
.option("-p, --project <key>", "Project key; defaults to config.defaultProject")
|
|
170
|
+
.description("Show bounded project issue statistics")
|
|
171
|
+
.action(async (opts) => {
|
|
172
|
+
try {
|
|
173
|
+
const projectKey = await resolveRequiredProjectKey(opts.project);
|
|
174
|
+
printProjectStatsResult(await getStatsProject(projectKey), projectKey);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
addOutputOptions(statsCmd.command("sprint").argument("<id>", "Sprint ID"))
|
|
182
|
+
.description("Show bounded sprint issue statistics")
|
|
183
|
+
.action(async (id) => {
|
|
184
|
+
try {
|
|
185
|
+
const sprintId = readRequiredText(id, "Sprint ID", "<id>");
|
|
186
|
+
printSprintStatsResult(await getStatsSprint(sprintId), sprintId);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
addOutputOptions(statsCmd.command("team").argument("<slug>", "Team slug"))
|
|
194
|
+
.description("Show bounded team membership and project statistics")
|
|
195
|
+
.action(async (slug) => {
|
|
196
|
+
try {
|
|
197
|
+
const teamSlug = readRequiredText(slug, "Team slug", "<slug>");
|
|
198
|
+
printTeamStatsResult(await getStatsTeam(teamSlug), teamSlug);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/commands/stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../src/commands/teams.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAuUxC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoM5D"}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import { addTeamMember, createTeam, deleteTeam, getTeam, listTeams, removeTeamMember, restoreTeam, updateTeam, updateTeamMemberRole } from "../lib/convex.js";
|
|
2
|
+
import { parsePositiveIntegerOption, readOptionalText, readRequiredText } from "../lib/options.js";
|
|
3
|
+
import { getActiveOutputFormat, printError, printJson, printOutput, printRows } from "../lib/output.js";
|
|
4
|
+
import { requireConfirmation } from "../lib/prompt.js";
|
|
5
|
+
import { resolveRequiredUserEmail } from "../lib/user-picker.js";
|
|
6
|
+
import { addOutputOptions } from "./global.js";
|
|
7
|
+
const TEAM_COLUMNS = [
|
|
8
|
+
{ header: "slug", value: team => team.slug },
|
|
9
|
+
{ header: "name", value: team => team.name },
|
|
10
|
+
{ header: "description", value: team => team.description },
|
|
11
|
+
{ header: "leadName", value: team => team.leadName },
|
|
12
|
+
{ header: "memberCount", value: team => team.memberCount },
|
|
13
|
+
{ header: "projectCount", value: team => team.projectCount },
|
|
14
|
+
{ header: "userRole", value: team => team.userRole },
|
|
15
|
+
{ header: "workspaceId", value: team => team.workspaceId },
|
|
16
|
+
{ header: "id", value: team => team.id }
|
|
17
|
+
];
|
|
18
|
+
const TEAM_MEMBER_COLUMNS = [
|
|
19
|
+
{ header: "userName", value: member => member.userName },
|
|
20
|
+
{ header: "userEmail", value: member => member.userEmail },
|
|
21
|
+
{ header: "role", value: member => member.role },
|
|
22
|
+
{ header: "userId", value: member => member.userId },
|
|
23
|
+
{ header: "createdAt", value: member => member.createdAt }
|
|
24
|
+
];
|
|
25
|
+
const TEAM_DELETE_COLUMNS = [
|
|
26
|
+
{ header: "slug", value: team => team.slug },
|
|
27
|
+
{ header: "name", value: team => team.name },
|
|
28
|
+
{ header: "deleted", value: team => team.deleted },
|
|
29
|
+
{ header: "id", value: team => team.id }
|
|
30
|
+
];
|
|
31
|
+
const TEAM_RESTORE_COLUMNS = [
|
|
32
|
+
{ header: "slug", value: team => team.slug },
|
|
33
|
+
{ header: "name", value: team => team.name },
|
|
34
|
+
{ header: "restored", value: team => team.restored },
|
|
35
|
+
{ header: "id", value: team => team.id }
|
|
36
|
+
];
|
|
37
|
+
function readTeamRole(value) {
|
|
38
|
+
const role = readRequiredText(value, "Role", "--role");
|
|
39
|
+
if (role === "admin" || role === "member")
|
|
40
|
+
return role;
|
|
41
|
+
throw new Error("Role must be admin or member.");
|
|
42
|
+
}
|
|
43
|
+
function readTeamUpdateInput(opts) {
|
|
44
|
+
if (opts.private && opts.public)
|
|
45
|
+
throw new Error("Pass either --private or --public, not both.");
|
|
46
|
+
const input = {};
|
|
47
|
+
const name = readOptionalText(opts.name, "Team name", "--name");
|
|
48
|
+
if (name !== undefined)
|
|
49
|
+
input.name = name;
|
|
50
|
+
const description = readOptionalText(opts.description, "Team description", "--description");
|
|
51
|
+
if (description !== undefined)
|
|
52
|
+
input.description = description;
|
|
53
|
+
if (opts.private)
|
|
54
|
+
input.isPrivate = true;
|
|
55
|
+
if (opts.public)
|
|
56
|
+
input.isPrivate = false;
|
|
57
|
+
if (Object.keys(input).length === 0)
|
|
58
|
+
throw new Error("At least one update flag is required.");
|
|
59
|
+
return input;
|
|
60
|
+
}
|
|
61
|
+
function printEmptyTeamList(format) {
|
|
62
|
+
if (format === "json") {
|
|
63
|
+
printJson([]);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (format === "csv") {
|
|
67
|
+
printRows([], TEAM_COLUMNS, format);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
printOutput("No teams found.");
|
|
71
|
+
}
|
|
72
|
+
function printTeamList(teams) {
|
|
73
|
+
const format = getActiveOutputFormat();
|
|
74
|
+
if (teams.length === 0) {
|
|
75
|
+
printEmptyTeamList(format);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (format !== "table") {
|
|
79
|
+
printRows(teams, TEAM_COLUMNS, format);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
for (const team of teams) {
|
|
83
|
+
const lead = team.leadName ? ` lead:${team.leadName}` : "";
|
|
84
|
+
printOutput(` ${team.slug} ${team.name} members:${team.memberCount} projects:${team.projectCount}${lead}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function printMissingTeam(slug, format) {
|
|
88
|
+
if (format === "json") {
|
|
89
|
+
printJson(null);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (format === "csv") {
|
|
93
|
+
printRows([], TEAM_COLUMNS, format);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
printOutput(`Team ${slug} not found.`);
|
|
97
|
+
}
|
|
98
|
+
function printTeamMembers(members) {
|
|
99
|
+
if (members.length === 0)
|
|
100
|
+
return;
|
|
101
|
+
printOutput("Members:");
|
|
102
|
+
for (const member of members) {
|
|
103
|
+
const email = member.userEmail ? ` <${member.userEmail}>` : "";
|
|
104
|
+
printOutput(` ${member.userName}${email} [${member.role}]`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function printTeamMembersResult(team, slug) {
|
|
108
|
+
const format = getActiveOutputFormat();
|
|
109
|
+
if (!team) {
|
|
110
|
+
if (format === "json") {
|
|
111
|
+
printJson(null);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (format === "csv") {
|
|
115
|
+
printRows([], TEAM_MEMBER_COLUMNS, format);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
printOutput(`Team ${slug} not found.`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (team.members.length === 0) {
|
|
122
|
+
if (format === "json") {
|
|
123
|
+
printJson([]);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (format === "csv") {
|
|
127
|
+
printRows([], TEAM_MEMBER_COLUMNS, format);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
printOutput("No team members found.");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (format !== "table") {
|
|
134
|
+
printRows(team.members, TEAM_MEMBER_COLUMNS, format);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
for (const member of team.members) {
|
|
138
|
+
const email = member.userEmail ? ` <${member.userEmail}>` : "";
|
|
139
|
+
printOutput(` ${member.userName}${email} [${member.role}]`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function printTeamMutationResult(team, slug, action) {
|
|
143
|
+
const format = getActiveOutputFormat();
|
|
144
|
+
if (!team) {
|
|
145
|
+
if (format === "json") {
|
|
146
|
+
printJson(null);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (format === "csv") {
|
|
150
|
+
printRows([], TEAM_COLUMNS, format);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
printOutput(`Team ${slug} not found.`);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (format === "json") {
|
|
157
|
+
printJson(team);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (format === "csv") {
|
|
161
|
+
printRows([team], TEAM_COLUMNS, format);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
printOutput(`${action} team ${team.slug}: ${team.name}`);
|
|
165
|
+
}
|
|
166
|
+
function printTeamDeleteResult(result, slug) {
|
|
167
|
+
const format = getActiveOutputFormat();
|
|
168
|
+
if (!result) {
|
|
169
|
+
if (format === "json") {
|
|
170
|
+
printJson(null);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (format === "csv") {
|
|
174
|
+
printRows([], TEAM_DELETE_COLUMNS, format);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
printOutput(`Team ${slug} not found.`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (format === "json") {
|
|
181
|
+
printJson(result);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (format === "csv") {
|
|
185
|
+
printRows([result], TEAM_DELETE_COLUMNS, format);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
printOutput(`Deleted team ${result.slug}: ${result.name}`);
|
|
189
|
+
}
|
|
190
|
+
function printTeamRestoreResult(result, slug) {
|
|
191
|
+
const format = getActiveOutputFormat();
|
|
192
|
+
if (!result) {
|
|
193
|
+
if (format === "json") {
|
|
194
|
+
printJson(null);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (format === "csv") {
|
|
198
|
+
printRows([], TEAM_RESTORE_COLUMNS, format);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
printOutput(`Team ${slug} not found.`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (format === "json") {
|
|
205
|
+
printJson(result);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
if (format === "csv") {
|
|
209
|
+
printRows([result], TEAM_RESTORE_COLUMNS, format);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
printOutput(`Restored team ${result.slug}: ${result.name}`);
|
|
213
|
+
}
|
|
214
|
+
function printTeamMemberMutationResult(result, slug, action) {
|
|
215
|
+
const format = getActiveOutputFormat();
|
|
216
|
+
if (!result) {
|
|
217
|
+
if (format === "json") {
|
|
218
|
+
printJson(null);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (format === "csv") {
|
|
222
|
+
printRows([], TEAM_MEMBER_COLUMNS, format);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
printOutput(`Team ${slug} not found.`);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (format === "json") {
|
|
229
|
+
printJson(result);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (format === "csv") {
|
|
233
|
+
printRows([result], TEAM_MEMBER_COLUMNS, format);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const email = result.userEmail ? ` <${result.userEmail}>` : "";
|
|
237
|
+
const suffix = action === "Removed" ? ` from ${result.slug}` : ` in ${result.slug}`;
|
|
238
|
+
printOutput(`${action} ${result.userName}${email}${suffix} [${result.role}]`);
|
|
239
|
+
}
|
|
240
|
+
function printTeamView(team, slug) {
|
|
241
|
+
const format = getActiveOutputFormat();
|
|
242
|
+
if (!team) {
|
|
243
|
+
printMissingTeam(slug, format);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (format === "json") {
|
|
247
|
+
printJson(team);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (format === "csv") {
|
|
251
|
+
printRows([team], TEAM_COLUMNS, format);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
printOutput(`${team.slug} ${team.name}`);
|
|
255
|
+
if (team.description)
|
|
256
|
+
printOutput(team.description);
|
|
257
|
+
if (team.leadName)
|
|
258
|
+
printOutput(`Lead: ${team.leadName}`);
|
|
259
|
+
printOutput(`Workspace: ${team.workspaceId}`);
|
|
260
|
+
printOutput(`Visibility: ${team.isPrivate ? "private" : "public"}`);
|
|
261
|
+
printOutput(`Members: ${team.memberCount}`);
|
|
262
|
+
printOutput(`Projects: ${team.projectCount}`);
|
|
263
|
+
if (team.userRole)
|
|
264
|
+
printOutput(`Your role: ${team.userRole}`);
|
|
265
|
+
printTeamMembers(team.members);
|
|
266
|
+
}
|
|
267
|
+
export function registerTeamsCommands(program) {
|
|
268
|
+
const teamsCmd = program.command("teams").description("Manage teams");
|
|
269
|
+
addOutputOptions(teamsCmd.command("list"))
|
|
270
|
+
.option("-n, --limit <number>", "Max teams", "20")
|
|
271
|
+
.description("List teams")
|
|
272
|
+
.action(async (opts) => {
|
|
273
|
+
try {
|
|
274
|
+
printTeamList(await listTeams({ limit: parsePositiveIntegerOption(opts.limit) }));
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
278
|
+
process.exit(1);
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
addOutputOptions(teamsCmd
|
|
282
|
+
.command("view")
|
|
283
|
+
.argument("<slug>", "Team slug")
|
|
284
|
+
.option("-n, --limit <number>", "Max members to show", "20")
|
|
285
|
+
.description("View team details")).action(async (slug, opts) => {
|
|
286
|
+
try {
|
|
287
|
+
printTeamView(await getTeam(slug, { memberLimit: parsePositiveIntegerOption(opts.limit) }), slug);
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
291
|
+
process.exit(1);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
addOutputOptions(teamsCmd.command("create"))
|
|
295
|
+
.requiredOption("--workspace <slug>", "Workspace slug")
|
|
296
|
+
.requiredOption("--name <name>", "Team name")
|
|
297
|
+
.option("--description <description>", "Team description")
|
|
298
|
+
.option("--private", "Make team private")
|
|
299
|
+
.description("Create a team")
|
|
300
|
+
.action(async (opts) => {
|
|
301
|
+
try {
|
|
302
|
+
const workspaceSlug = readRequiredText(opts.workspace, "Workspace slug", "--workspace");
|
|
303
|
+
const name = readRequiredText(opts.name, "Team name", "--name");
|
|
304
|
+
printTeamMutationResult(await createTeam({
|
|
305
|
+
workspaceSlug,
|
|
306
|
+
name,
|
|
307
|
+
description: readOptionalText(opts.description, "Team description", "--description"),
|
|
308
|
+
isPrivate: opts.private === true
|
|
309
|
+
}), name, "Created");
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
313
|
+
process.exit(1);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
addOutputOptions(teamsCmd.command("update"))
|
|
317
|
+
.argument("<slug>", "Team slug")
|
|
318
|
+
.option("--name <name>", "Team name")
|
|
319
|
+
.option("--description <description>", "Team description")
|
|
320
|
+
.option("--private", "Make team private")
|
|
321
|
+
.option("--public", "Make team public")
|
|
322
|
+
.description("Update a team")
|
|
323
|
+
.action(async (slug, opts) => {
|
|
324
|
+
try {
|
|
325
|
+
const teamSlug = readRequiredText(slug, "Team slug", "<slug>");
|
|
326
|
+
printTeamMutationResult(await updateTeam(teamSlug, readTeamUpdateInput(opts)), teamSlug, "Updated");
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
330
|
+
process.exit(1);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
addOutputOptions(teamsCmd.command("delete"))
|
|
334
|
+
.argument("<slug>", "Team slug")
|
|
335
|
+
.option("-y, --yes", "Confirm team deletion")
|
|
336
|
+
.description("Delete a team")
|
|
337
|
+
.action(async (slug, opts) => {
|
|
338
|
+
try {
|
|
339
|
+
const teamSlug = readRequiredText(slug, "Team slug", "<slug>");
|
|
340
|
+
await requireConfirmation(`Delete team ${teamSlug}?`, opts.yes === true);
|
|
341
|
+
printTeamDeleteResult(await deleteTeam(teamSlug), teamSlug);
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
345
|
+
process.exit(1);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
addOutputOptions(teamsCmd.command("restore"))
|
|
349
|
+
.argument("<slug>", "Team slug")
|
|
350
|
+
.description("Restore a deleted team")
|
|
351
|
+
.action(async (slug) => {
|
|
352
|
+
try {
|
|
353
|
+
const teamSlug = readRequiredText(slug, "Team slug", "<slug>");
|
|
354
|
+
printTeamRestoreResult(await restoreTeam(teamSlug), teamSlug);
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
358
|
+
process.exit(1);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
const membersCmd = teamsCmd
|
|
362
|
+
.command("members")
|
|
363
|
+
.argument("[slug]", "Team slug")
|
|
364
|
+
.option("-n, --limit <number>", "Max members to show", "20")
|
|
365
|
+
.description("List or manage team members");
|
|
366
|
+
addOutputOptions(membersCmd).action(async (slug, opts) => {
|
|
367
|
+
try {
|
|
368
|
+
const teamSlug = readRequiredText(slug, "Team slug", "<slug>");
|
|
369
|
+
printTeamMembersResult(await getTeam(teamSlug, { memberLimit: parsePositiveIntegerOption(opts.limit) }), teamSlug);
|
|
370
|
+
}
|
|
371
|
+
catch (error) {
|
|
372
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
373
|
+
process.exit(1);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
addOutputOptions(membersCmd.command("add"))
|
|
377
|
+
.argument("<slug>", "Team slug")
|
|
378
|
+
.option("--email <email>", "Member email; prompts when omitted")
|
|
379
|
+
.requiredOption("--role <role>", "Member role: admin or member")
|
|
380
|
+
.description("Add a team member")
|
|
381
|
+
.action(async (slug, opts) => {
|
|
382
|
+
try {
|
|
383
|
+
const teamSlug = readRequiredText(slug, "Team slug", "<slug>");
|
|
384
|
+
printTeamMemberMutationResult(await addTeamMember({
|
|
385
|
+
slug: teamSlug,
|
|
386
|
+
email: await resolveRequiredUserEmail(opts.email),
|
|
387
|
+
role: readTeamRole(opts.role)
|
|
388
|
+
}), teamSlug, "Added");
|
|
389
|
+
}
|
|
390
|
+
catch (error) {
|
|
391
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
392
|
+
process.exit(1);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
addOutputOptions(membersCmd.command("remove"))
|
|
396
|
+
.argument("<slug>", "Team slug")
|
|
397
|
+
.option("--email <email>", "Member email; prompts when omitted")
|
|
398
|
+
.option("-y, --yes", "Confirm team member removal")
|
|
399
|
+
.description("Remove a team member")
|
|
400
|
+
.action(async (slug, opts) => {
|
|
401
|
+
try {
|
|
402
|
+
const teamSlug = readRequiredText(slug, "Team slug", "<slug>");
|
|
403
|
+
const email = await resolveRequiredUserEmail(opts.email);
|
|
404
|
+
await requireConfirmation(`Remove ${email} from team ${teamSlug}?`, opts.yes === true);
|
|
405
|
+
printTeamMemberMutationResult(await removeTeamMember({
|
|
406
|
+
slug: teamSlug,
|
|
407
|
+
email
|
|
408
|
+
}), teamSlug, "Removed");
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
412
|
+
process.exit(1);
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
addOutputOptions(membersCmd.command("role"))
|
|
416
|
+
.argument("<slug>", "Team slug")
|
|
417
|
+
.option("--email <email>", "Member email; prompts when omitted")
|
|
418
|
+
.requiredOption("--role <role>", "Member role: admin or member")
|
|
419
|
+
.description("Update a team member role")
|
|
420
|
+
.action(async (slug, opts) => {
|
|
421
|
+
try {
|
|
422
|
+
const teamSlug = readRequiredText(slug, "Team slug", "<slug>");
|
|
423
|
+
printTeamMemberMutationResult(await updateTeamMemberRole({
|
|
424
|
+
slug: teamSlug,
|
|
425
|
+
email: await resolveRequiredUserEmail(opts.email),
|
|
426
|
+
role: readTeamRole(opts.role)
|
|
427
|
+
}), teamSlug, "Updated");
|
|
428
|
+
}
|
|
429
|
+
catch (error) {
|
|
430
|
+
printError("Failed:", error instanceof Error ? error.message : error);
|
|
431
|
+
process.exit(1);
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
//# sourceMappingURL=teams.js.map
|