@prodbeam/mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/CLAUDE.md +7 -0
- package/dist/adapters/github-mcp.d.ts +25 -0
- package/dist/adapters/github-mcp.d.ts.map +1 -0
- package/dist/adapters/github-mcp.js +307 -0
- package/dist/adapters/github-mcp.js.map +1 -0
- package/dist/adapters/jira-mcp.d.ts +14 -0
- package/dist/adapters/jira-mcp.d.ts.map +1 -0
- package/dist/adapters/jira-mcp.js +159 -0
- package/dist/adapters/jira-mcp.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +256 -0
- package/dist/cli.js.map +1 -0
- package/dist/clients/github-client.d.ts +29 -0
- package/dist/clients/github-client.d.ts.map +1 -0
- package/dist/clients/github-client.js +116 -0
- package/dist/clients/github-client.js.map +1 -0
- package/dist/clients/jira-client.d.ts +30 -0
- package/dist/clients/jira-client.d.ts.map +1 -0
- package/dist/clients/jira-client.js +115 -0
- package/dist/clients/jira-client.js.map +1 -0
- package/dist/clients/types.d.ts +155 -0
- package/dist/clients/types.d.ts.map +1 -0
- package/dist/clients/types.js +2 -0
- package/dist/clients/types.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +426 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/prompt.d.ts +18 -0
- package/dist/commands/prompt.d.ts.map +1 -0
- package/dist/commands/prompt.js +122 -0
- package/dist/commands/prompt.js.map +1 -0
- package/dist/config/credentials.d.ts +9 -0
- package/dist/config/credentials.d.ts.map +1 -0
- package/dist/config/credentials.js +87 -0
- package/dist/config/credentials.js.map +1 -0
- package/dist/config/paths.d.ts +6 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +31 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/team-config.d.ts +204 -0
- package/dist/config/team-config.d.ts.map +1 -0
- package/dist/config/team-config.js +86 -0
- package/dist/config/team-config.js.map +1 -0
- package/dist/config/thresholds.d.ts +15 -0
- package/dist/config/thresholds.d.ts.map +1 -0
- package/dist/config/thresholds.js +18 -0
- package/dist/config/thresholds.js.map +1 -0
- package/dist/config/types.d.ts +42 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/discovery/github-discovery.d.ts +4 -0
- package/dist/discovery/github-discovery.d.ts.map +1 -0
- package/dist/discovery/github-discovery.js +46 -0
- package/dist/discovery/github-discovery.js.map +1 -0
- package/dist/discovery/jira-discovery.d.ts +4 -0
- package/dist/discovery/jira-discovery.d.ts.map +1 -0
- package/dist/discovery/jira-discovery.js +68 -0
- package/dist/discovery/jira-discovery.js.map +1 -0
- package/dist/discovery/types.d.ts +40 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +2 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/generators/metrics-calculator.d.ts +5 -0
- package/dist/generators/metrics-calculator.d.ts.map +1 -0
- package/dist/generators/metrics-calculator.js +101 -0
- package/dist/generators/metrics-calculator.js.map +1 -0
- package/dist/generators/report-generator.d.ts +25 -0
- package/dist/generators/report-generator.d.ts.map +1 -0
- package/dist/generators/report-generator.js +375 -0
- package/dist/generators/report-generator.js.map +1 -0
- package/dist/generators/sprint-analyzer.d.ts +5 -0
- package/dist/generators/sprint-analyzer.d.ts.map +1 -0
- package/dist/generators/sprint-analyzer.js +88 -0
- package/dist/generators/sprint-analyzer.js.map +1 -0
- package/dist/history/history-store.d.ts +15 -0
- package/dist/history/history-store.d.ts.map +1 -0
- package/dist/history/history-store.js +197 -0
- package/dist/history/history-store.js.map +1 -0
- package/dist/history/snapshot-builder.d.ts +15 -0
- package/dist/history/snapshot-builder.d.ts.map +1 -0
- package/dist/history/snapshot-builder.js +45 -0
- package/dist/history/snapshot-builder.js.map +1 -0
- package/dist/history/types.d.ts +33 -0
- package/dist/history/types.d.ts.map +1 -0
- package/dist/history/types.js +2 -0
- package/dist/history/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +797 -0
- package/dist/index.js.map +1 -0
- package/dist/insights/anomaly-detector.d.ts +28 -0
- package/dist/insights/anomaly-detector.d.ts.map +1 -0
- package/dist/insights/anomaly-detector.js +154 -0
- package/dist/insights/anomaly-detector.js.map +1 -0
- package/dist/insights/team-health.d.ts +24 -0
- package/dist/insights/team-health.d.ts.map +1 -0
- package/dist/insights/team-health.js +151 -0
- package/dist/insights/team-health.js.map +1 -0
- package/dist/insights/trend-analyzer.d.ts +5 -0
- package/dist/insights/trend-analyzer.d.ts.map +1 -0
- package/dist/insights/trend-analyzer.js +79 -0
- package/dist/insights/trend-analyzer.js.map +1 -0
- package/dist/insights/types.d.ts +10 -0
- package/dist/insights/types.d.ts.map +1 -0
- package/dist/insights/types.js +2 -0
- package/dist/insights/types.js.map +1 -0
- package/dist/orchestrator/data-fetcher.d.ts +16 -0
- package/dist/orchestrator/data-fetcher.d.ts.map +1 -0
- package/dist/orchestrator/data-fetcher.js +169 -0
- package/dist/orchestrator/data-fetcher.js.map +1 -0
- package/dist/orchestrator/time-range.d.ts +8 -0
- package/dist/orchestrator/time-range.d.ts.map +1 -0
- package/dist/orchestrator/time-range.js +27 -0
- package/dist/orchestrator/time-range.js.map +1 -0
- package/dist/types/github.d.ts +40 -0
- package/dist/types/github.d.ts.map +1 -0
- package/dist/types/github.js +2 -0
- package/dist/types/github.js.map +1 -0
- package/dist/types/jira.d.ts +18 -0
- package/dist/types/jira.d.ts.map +1 -0
- package/dist/types/jira.js +2 -0
- package/dist/types/jira.js.map +1 -0
- package/dist/types/retrospective.d.ts +38 -0
- package/dist/types/retrospective.d.ts.map +1 -0
- package/dist/types/retrospective.js +2 -0
- package/dist/types/retrospective.js.map +1 -0
- package/dist/types/weekly.d.ts +41 -0
- package/dist/types/weekly.d.ts.map +1 -0
- package/dist/types/weekly.js +2 -0
- package/dist/types/weekly.js.map +1 -0
- package/dist/validators.d.ts +236 -0
- package/dist/validators.d.ts.map +1 -0
- package/dist/validators.js +62 -0
- package/dist/validators.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { resolveGitHubCredentials, resolveJiraCredentials, mergeCredentials, } from '../config/credentials.js';
|
|
7
|
+
import { teamConfigExists, writeTeamConfig, createDefaultConfig } from '../config/team-config.js';
|
|
8
|
+
import { resolveConfigDir } from '../config/paths.js';
|
|
9
|
+
import { GitHubClient, GitHubClientError } from '../clients/github-client.js';
|
|
10
|
+
import { JiraClient, JiraClientError } from '../clients/jira-client.js';
|
|
11
|
+
import { discoverJiraTeam } from '../discovery/jira-discovery.js';
|
|
12
|
+
import { createPrompt, ask, askSecret, askConfirm, printHeader, printSuccess, printWarning, printInfo, printStep, } from './prompt.js';
|
|
13
|
+
const MAX_AUTH_RETRIES = 3;
|
|
14
|
+
const TOTAL_STEPS = 6;
|
|
15
|
+
export async function runInit() {
|
|
16
|
+
printHeader('prodbeam init');
|
|
17
|
+
printInfo('Interactive setup for Prodbeam engineering intelligence.\n');
|
|
18
|
+
const rl = createPrompt();
|
|
19
|
+
try {
|
|
20
|
+
printStep(1, TOTAL_STEPS, 'GitHub credentials');
|
|
21
|
+
const { creds: ghCreds, source: ghSource } = await resolveOrPromptGitHub(rl);
|
|
22
|
+
printStep(2, TOTAL_STEPS, 'Jira credentials');
|
|
23
|
+
const { creds: jiraCreds, source: jiraSource } = await resolveOrPromptJira(rl);
|
|
24
|
+
printStep(3, TOTAL_STEPS, 'Validating credentials');
|
|
25
|
+
const ghUser = await validateGitHub(rl, ghCreds, ghSource);
|
|
26
|
+
const jiraUser = await validateJira(rl, jiraCreds, jiraSource);
|
|
27
|
+
printStep(4, TOTAL_STEPS, 'Team setup');
|
|
28
|
+
if (teamConfigExists()) {
|
|
29
|
+
const overwrite = await askConfirm(rl, 'Team config already exists. Overwrite?', false);
|
|
30
|
+
if (!overwrite) {
|
|
31
|
+
printInfo('Keeping existing team config.');
|
|
32
|
+
rl.close();
|
|
33
|
+
printSummary(ghUser, jiraUser, null);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const teamName = await ask(rl, 'Team name', { required: true });
|
|
38
|
+
const members = await askTeamMembers(rl, ghUser);
|
|
39
|
+
printStep(5, TOTAL_STEPS, 'Running auto-discovery');
|
|
40
|
+
const config = await runDiscovery(ghCreds, jiraCreds, teamName, members);
|
|
41
|
+
if (ghSource === 'prompt' || jiraSource === 'prompt') {
|
|
42
|
+
const credsToSave = {};
|
|
43
|
+
if (ghSource === 'prompt')
|
|
44
|
+
credsToSave.github = ghCreds;
|
|
45
|
+
if (jiraSource === 'prompt')
|
|
46
|
+
credsToSave.jira = jiraCreds;
|
|
47
|
+
mergeCredentials(credsToSave);
|
|
48
|
+
printSuccess(`Credentials saved to ${resolveConfigDir()}/credentials.json`);
|
|
49
|
+
}
|
|
50
|
+
writeTeamConfig(config);
|
|
51
|
+
printSuccess(`Team config saved to ${resolveConfigDir()}/team.json`);
|
|
52
|
+
printStep(6, TOTAL_STEPS, 'MCP server registration');
|
|
53
|
+
registerMcpServer(ghCreds, jiraCreds);
|
|
54
|
+
rl.close();
|
|
55
|
+
printSummary(ghUser, jiraUser, config);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
rl.close();
|
|
59
|
+
if (error instanceof Error && error.message === 'readline was closed') {
|
|
60
|
+
console.log('\nSetup cancelled.');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function askTeamMembers(rl, ghUser) {
|
|
67
|
+
printInfo('Add team members (GitHub username + email). Empty username to finish.\n');
|
|
68
|
+
const members = [];
|
|
69
|
+
let memberNum = 1;
|
|
70
|
+
for (;;) {
|
|
71
|
+
const isFirst = memberNum === 1;
|
|
72
|
+
const ghDefault = isFirst ? ghUser.login : undefined;
|
|
73
|
+
const github = await ask(rl, ` Member ${memberNum} — GitHub username`, {
|
|
74
|
+
defaultValue: ghDefault,
|
|
75
|
+
});
|
|
76
|
+
if (!github) {
|
|
77
|
+
if (members.length === 0) {
|
|
78
|
+
printWarning('At least one team member is required.');
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
const email = await ask(rl, ` Member ${memberNum} — Email`, {
|
|
84
|
+
required: true,
|
|
85
|
+
validate: (v) => (v.includes('@') ? null : 'Must be a valid email address'),
|
|
86
|
+
});
|
|
87
|
+
members.push({ github, email });
|
|
88
|
+
printSuccess(` Added @${github} (${email})`);
|
|
89
|
+
memberNum++;
|
|
90
|
+
console.log('');
|
|
91
|
+
}
|
|
92
|
+
return members;
|
|
93
|
+
}
|
|
94
|
+
const GITHUB_TOKEN_KEYS = ['GITHUB_TOKEN', 'GITHUB_PERSONAL_ACCESS_TOKEN'];
|
|
95
|
+
const JIRA_HOST_KEYS = ['JIRA_HOST', 'JIRA_BASE_URL', 'ATLASSIAN_SITE_URL'];
|
|
96
|
+
const JIRA_EMAIL_KEYS = ['JIRA_EMAIL', 'ATLASSIAN_EMAIL'];
|
|
97
|
+
const JIRA_TOKEN_KEYS = ['JIRA_API_TOKEN', 'ATLASSIAN_API_TOKEN'];
|
|
98
|
+
function scanMcpConfigEnvVars() {
|
|
99
|
+
const configPath = join(homedir(), '.claude', 'mcp.json');
|
|
100
|
+
if (!existsSync(configPath)) {
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const raw = readFileSync(configPath, 'utf-8');
|
|
105
|
+
const config = JSON.parse(raw);
|
|
106
|
+
if (!config.mcpServers || typeof config.mcpServers !== 'object') {
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
109
|
+
const merged = {};
|
|
110
|
+
for (const server of Object.values(config.mcpServers)) {
|
|
111
|
+
if (server.env && typeof server.env === 'object') {
|
|
112
|
+
for (const [key, value] of Object.entries(server.env)) {
|
|
113
|
+
if (typeof value === 'string' && value) {
|
|
114
|
+
merged[key] = value;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return merged;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return {};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function findEnvVar(envVars, keys) {
|
|
126
|
+
for (const key of keys) {
|
|
127
|
+
if (envVars[key])
|
|
128
|
+
return envVars[key];
|
|
129
|
+
}
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
async function resolveOrPromptGitHub(rl) {
|
|
133
|
+
const envToken = process.env['GITHUB_TOKEN'];
|
|
134
|
+
if (envToken) {
|
|
135
|
+
printSuccess('Found GITHUB_TOKEN in environment.');
|
|
136
|
+
return { creds: { token: envToken }, source: 'env' };
|
|
137
|
+
}
|
|
138
|
+
const fileCreds = resolveGitHubCredentials();
|
|
139
|
+
if (fileCreds) {
|
|
140
|
+
printSuccess('Found GitHub token in credentials file.');
|
|
141
|
+
return { creds: fileCreds, source: 'file' };
|
|
142
|
+
}
|
|
143
|
+
const mcpEnv = scanMcpConfigEnvVars();
|
|
144
|
+
const mcpToken = findEnvVar(mcpEnv, GITHUB_TOKEN_KEYS);
|
|
145
|
+
if (mcpToken) {
|
|
146
|
+
printSuccess('Found GitHub token in Claude MCP config (~/.claude/mcp.json).');
|
|
147
|
+
return { creds: { token: mcpToken }, source: 'file' };
|
|
148
|
+
}
|
|
149
|
+
printInfo('No GitHub token found. Create one at https://github.com/settings/tokens');
|
|
150
|
+
printInfo('Required scopes: repo, read:org, read:user');
|
|
151
|
+
const token = await askSecret(rl, 'GitHub personal access token');
|
|
152
|
+
if (!token) {
|
|
153
|
+
throw new Error('GitHub token is required.');
|
|
154
|
+
}
|
|
155
|
+
return { creds: { token }, source: 'prompt' };
|
|
156
|
+
}
|
|
157
|
+
async function resolveOrPromptJira(rl) {
|
|
158
|
+
const envToken = process.env['JIRA_API_TOKEN'];
|
|
159
|
+
const envEmail = process.env['JIRA_EMAIL'];
|
|
160
|
+
const envHost = process.env['JIRA_HOST'];
|
|
161
|
+
if (envToken && envEmail && envHost) {
|
|
162
|
+
printSuccess('Found Jira credentials in environment.');
|
|
163
|
+
return { creds: { host: envHost, email: envEmail, apiToken: envToken }, source: 'env' };
|
|
164
|
+
}
|
|
165
|
+
const fileCreds = resolveJiraCredentials();
|
|
166
|
+
if (fileCreds) {
|
|
167
|
+
printSuccess('Found Jira credentials in credentials file.');
|
|
168
|
+
return { creds: fileCreds, source: 'file' };
|
|
169
|
+
}
|
|
170
|
+
const mcpEnv = scanMcpConfigEnvVars();
|
|
171
|
+
const mcpToken = findEnvVar(mcpEnv, JIRA_TOKEN_KEYS);
|
|
172
|
+
const mcpEmail = findEnvVar(mcpEnv, JIRA_EMAIL_KEYS);
|
|
173
|
+
const mcpHost = findEnvVar(mcpEnv, JIRA_HOST_KEYS);
|
|
174
|
+
if (mcpToken && mcpEmail && mcpHost) {
|
|
175
|
+
printSuccess('Found Jira credentials in Claude MCP config (~/.claude/mcp.json).');
|
|
176
|
+
return { creds: { host: mcpHost, email: mcpEmail, apiToken: mcpToken }, source: 'file' };
|
|
177
|
+
}
|
|
178
|
+
printInfo('No Jira credentials found.');
|
|
179
|
+
printInfo('Create an API token at https://id.atlassian.com/manage-profile/security/api-tokens');
|
|
180
|
+
const host = await ask(rl, 'Jira Cloud hostname (e.g., company.atlassian.net)', {
|
|
181
|
+
required: true,
|
|
182
|
+
defaultValue: mcpHost,
|
|
183
|
+
validate: (v) => v.includes('.') ? null : 'Must be a valid hostname (e.g., company.atlassian.net)',
|
|
184
|
+
});
|
|
185
|
+
const email = await ask(rl, 'Jira account email', {
|
|
186
|
+
required: true,
|
|
187
|
+
defaultValue: mcpEmail,
|
|
188
|
+
validate: (v) => (v.includes('@') ? null : 'Must be a valid email address'),
|
|
189
|
+
});
|
|
190
|
+
const apiToken = await askSecret(rl, 'Jira API token');
|
|
191
|
+
if (!apiToken) {
|
|
192
|
+
throw new Error('Jira API token is required.');
|
|
193
|
+
}
|
|
194
|
+
return { creds: { host, email, apiToken }, source: 'prompt' };
|
|
195
|
+
}
|
|
196
|
+
async function validateGitHub(rl, creds, source) {
|
|
197
|
+
for (let attempt = 1; attempt <= MAX_AUTH_RETRIES; attempt++) {
|
|
198
|
+
try {
|
|
199
|
+
const client = new GitHubClient(creds.token);
|
|
200
|
+
const user = await client.getAuthenticatedUser();
|
|
201
|
+
printSuccess(`GitHub: authenticated as @${user.login}${user.name ? ` (${user.name})` : ''}`);
|
|
202
|
+
return user;
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
if (error instanceof GitHubClientError && error.statusCode === 401) {
|
|
206
|
+
if (source !== 'prompt' || attempt >= MAX_AUTH_RETRIES) {
|
|
207
|
+
throw new Error(`GitHub authentication failed (${error.statusCode}). Check your token.`);
|
|
208
|
+
}
|
|
209
|
+
printWarning(`Invalid token (attempt ${attempt}/${MAX_AUTH_RETRIES}). Try again.`);
|
|
210
|
+
const token = await askSecret(rl, 'GitHub personal access token');
|
|
211
|
+
if (!token)
|
|
212
|
+
throw new Error('GitHub token is required.');
|
|
213
|
+
creds.token = token;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const skip = await askConfirm(rl, `GitHub API unreachable: ${error instanceof Error ? error.message : 'unknown error'}. Skip validation?`, false);
|
|
217
|
+
if (skip) {
|
|
218
|
+
printWarning('Skipping GitHub validation. Credentials saved as-is.');
|
|
219
|
+
return { login: 'unknown', name: null };
|
|
220
|
+
}
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
throw new Error('GitHub authentication failed after maximum retries.');
|
|
225
|
+
}
|
|
226
|
+
async function validateJira(rl, creds, source) {
|
|
227
|
+
for (let attempt = 1; attempt <= MAX_AUTH_RETRIES; attempt++) {
|
|
228
|
+
try {
|
|
229
|
+
const client = new JiraClient(creds.host, creds.email, creds.apiToken);
|
|
230
|
+
const user = await client.getMyself();
|
|
231
|
+
printSuccess(`Jira: authenticated as ${user.displayName}`);
|
|
232
|
+
return user;
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
if (error instanceof JiraClientError &&
|
|
236
|
+
(error.statusCode === 401 || error.statusCode === 403)) {
|
|
237
|
+
if (source !== 'prompt' || attempt >= MAX_AUTH_RETRIES) {
|
|
238
|
+
throw new Error(`Jira authentication failed (${error.statusCode}). Check your credentials.`);
|
|
239
|
+
}
|
|
240
|
+
printWarning(`Invalid credentials (attempt ${attempt}/${MAX_AUTH_RETRIES}). Try again.`);
|
|
241
|
+
const host = await ask(rl, 'Jira Cloud hostname', {
|
|
242
|
+
required: true,
|
|
243
|
+
defaultValue: creds.host,
|
|
244
|
+
});
|
|
245
|
+
const email = await ask(rl, 'Jira account email', {
|
|
246
|
+
required: true,
|
|
247
|
+
defaultValue: creds.email,
|
|
248
|
+
});
|
|
249
|
+
const apiToken = await askSecret(rl, 'Jira API token');
|
|
250
|
+
if (!apiToken)
|
|
251
|
+
throw new Error('Jira API token is required.');
|
|
252
|
+
creds.host = host;
|
|
253
|
+
creds.email = email;
|
|
254
|
+
creds.apiToken = apiToken;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
const skip = await askConfirm(rl, `Jira API unreachable: ${error instanceof Error ? error.message : 'unknown error'}. Skip validation?`, false);
|
|
258
|
+
if (skip) {
|
|
259
|
+
printWarning('Skipping Jira validation. Credentials saved as-is.');
|
|
260
|
+
return { accountId: 'unknown', displayName: 'unknown' };
|
|
261
|
+
}
|
|
262
|
+
throw error;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
throw new Error('Jira authentication failed after maximum retries.');
|
|
266
|
+
}
|
|
267
|
+
async function runDiscovery(ghCreds, jiraCreds, teamName, members) {
|
|
268
|
+
const emails = members.map((m) => m.email);
|
|
269
|
+
const config = createDefaultConfig(teamName, emails);
|
|
270
|
+
for (const input of members) {
|
|
271
|
+
const configMember = config.team.members.find((m) => m.email.toLowerCase() === input.email.toLowerCase());
|
|
272
|
+
if (configMember) {
|
|
273
|
+
configMember.github = input.github;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const ghClient = new GitHubClient(ghCreds.token);
|
|
277
|
+
const jiraClient = new JiraClient(jiraCreds.host, jiraCreds.email, jiraCreds.apiToken);
|
|
278
|
+
const usernames = members.map((m) => m.github);
|
|
279
|
+
const [ghRepoResults, jiraDiscovery] = await Promise.all([
|
|
280
|
+
discoverGitHubReposAndOrgs(ghClient, usernames),
|
|
281
|
+
discoverJiraTeam(jiraClient, emails, jiraCreds.host).catch((error) => {
|
|
282
|
+
printWarning(`Jira discovery failed: ${error instanceof Error ? error.message : 'unknown error'}`);
|
|
283
|
+
return null;
|
|
284
|
+
}),
|
|
285
|
+
]);
|
|
286
|
+
config.github.repos = ghRepoResults.repos;
|
|
287
|
+
if (ghRepoResults.orgs.length > 0) {
|
|
288
|
+
config.github.org = ghRepoResults.orgs[0];
|
|
289
|
+
}
|
|
290
|
+
printInfo(`Found ${ghRepoResults.repos.length} active repos, ${ghRepoResults.orgs.length} orgs`);
|
|
291
|
+
if (jiraDiscovery) {
|
|
292
|
+
config.jira.host = jiraDiscovery.host;
|
|
293
|
+
config.jira.projects = jiraDiscovery.projects.map((p) => p.key);
|
|
294
|
+
for (const jiraMember of jiraDiscovery.members) {
|
|
295
|
+
const configMember = config.team.members.find((m) => m.email.toLowerCase() === jiraMember.email.toLowerCase());
|
|
296
|
+
if (configMember && jiraMember.accountId) {
|
|
297
|
+
configMember.jiraAccountId = jiraMember.accountId;
|
|
298
|
+
configMember.name = configMember.name ?? jiraMember.displayName ?? undefined;
|
|
299
|
+
printSuccess(` ${jiraMember.email} -> ${jiraMember.displayName} (Jira)`);
|
|
300
|
+
}
|
|
301
|
+
else if (jiraMember.error) {
|
|
302
|
+
printWarning(` ${jiraMember.email}: ${jiraMember.error}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
printInfo(`Found ${jiraDiscovery.projects.length} projects`);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
config.jira.host = jiraCreds.host;
|
|
309
|
+
}
|
|
310
|
+
return config;
|
|
311
|
+
}
|
|
312
|
+
async function discoverGitHubReposAndOrgs(client, usernames) {
|
|
313
|
+
const repoSet = new Set();
|
|
314
|
+
const orgSet = new Set();
|
|
315
|
+
const results = await Promise.all(usernames.map(async (username) => {
|
|
316
|
+
const [repos, orgs] = await Promise.all([
|
|
317
|
+
client.getRecentRepos(username).catch(() => []),
|
|
318
|
+
client.getUserOrgs(username).catch(() => []),
|
|
319
|
+
]);
|
|
320
|
+
return { username, repos, orgs };
|
|
321
|
+
}));
|
|
322
|
+
for (const { username, repos, orgs } of results) {
|
|
323
|
+
for (const repo of repos)
|
|
324
|
+
repoSet.add(repo);
|
|
325
|
+
for (const org of orgs)
|
|
326
|
+
orgSet.add(org);
|
|
327
|
+
if (repos.length > 0 || orgs.length > 0) {
|
|
328
|
+
printSuccess(` @${username}: ${repos.length} repos, ${orgs.length} orgs`);
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
printWarning(` @${username}: no recent repos found`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
repos: Array.from(repoSet).sort(),
|
|
336
|
+
orgs: Array.from(orgSet).sort(),
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
function registerMcpServer(ghCreds, jiraCreds) {
|
|
340
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
341
|
+
const projectRoot = dirname(dirname(thisFile));
|
|
342
|
+
const serverPath = join(projectRoot, 'index.js');
|
|
343
|
+
const args = [
|
|
344
|
+
'mcp',
|
|
345
|
+
'add',
|
|
346
|
+
'prodbeam',
|
|
347
|
+
'-e',
|
|
348
|
+
`GITHUB_TOKEN=${ghCreds.token}`,
|
|
349
|
+
'-e',
|
|
350
|
+
`JIRA_HOST=${jiraCreds.host}`,
|
|
351
|
+
'-e',
|
|
352
|
+
`JIRA_EMAIL=${jiraCreds.email}`,
|
|
353
|
+
'-e',
|
|
354
|
+
`JIRA_API_TOKEN=${jiraCreds.apiToken}`,
|
|
355
|
+
'--',
|
|
356
|
+
'node',
|
|
357
|
+
serverPath,
|
|
358
|
+
];
|
|
359
|
+
const claudePath = resolveClaudeCli();
|
|
360
|
+
if (!claudePath) {
|
|
361
|
+
printWarning('Claude CLI not found in PATH.');
|
|
362
|
+
printManualMcpInstructions(serverPath, ghCreds, jiraCreds);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
try {
|
|
366
|
+
try {
|
|
367
|
+
execFileSync(claudePath, ['mcp', 'remove', 'prodbeam'], { stdio: 'pipe' });
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
}
|
|
371
|
+
execFileSync(claudePath, args, { stdio: 'pipe' });
|
|
372
|
+
printSuccess('MCP server registered with Claude Code.');
|
|
373
|
+
printInfo('Start a new Claude Code session to use prodbeam tools.');
|
|
374
|
+
}
|
|
375
|
+
catch (error) {
|
|
376
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
377
|
+
printWarning(`MCP registration failed: ${message}`);
|
|
378
|
+
printManualMcpInstructions(serverPath, ghCreds, jiraCreds);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
function resolveClaudeCli() {
|
|
382
|
+
const candidates = [
|
|
383
|
+
'claude',
|
|
384
|
+
join(homedir(), '.local', 'bin', 'claude'),
|
|
385
|
+
'/usr/local/bin/claude',
|
|
386
|
+
];
|
|
387
|
+
for (const candidate of candidates) {
|
|
388
|
+
try {
|
|
389
|
+
execFileSync(candidate, ['--version'], { stdio: 'pipe' });
|
|
390
|
+
return candidate;
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
function printManualMcpInstructions(serverPath, _ghCreds, jiraCreds) {
|
|
399
|
+
printInfo('Register manually by running:\n');
|
|
400
|
+
const cmd = [
|
|
401
|
+
'claude mcp add prodbeam',
|
|
402
|
+
' -e GITHUB_TOKEN=<your-github-token>',
|
|
403
|
+
` -e JIRA_HOST=${jiraCreds.host}`,
|
|
404
|
+
` -e JIRA_EMAIL=${jiraCreds.email}`,
|
|
405
|
+
' -e JIRA_API_TOKEN=<your-jira-api-token>',
|
|
406
|
+
` -- node ${serverPath}`,
|
|
407
|
+
].join(' \\\n');
|
|
408
|
+
console.log(` ${cmd}\n`);
|
|
409
|
+
printInfo('Replace <your-github-token> and <your-jira-api-token> with your actual tokens.');
|
|
410
|
+
}
|
|
411
|
+
function printSummary(ghUser, jiraUser, config) {
|
|
412
|
+
printHeader('Setup Complete');
|
|
413
|
+
console.log(` GitHub: @${ghUser.login}`);
|
|
414
|
+
console.log(` Jira: ${jiraUser.displayName}`);
|
|
415
|
+
console.log(` Config: ${resolveConfigDir()}`);
|
|
416
|
+
if (config) {
|
|
417
|
+
console.log(` Team: ${config.team.name} (${config.team.members.length} members)`);
|
|
418
|
+
console.log(` Repos: ${config.github.repos.length}`);
|
|
419
|
+
console.log(` Projects: ${config.jira.projects.join(', ') || 'none'}`);
|
|
420
|
+
}
|
|
421
|
+
console.log('\nNext steps:');
|
|
422
|
+
console.log(' 1. Start a new Claude Code session');
|
|
423
|
+
console.log(' 2. Try: "Give me today\'s standup"');
|
|
424
|
+
console.log(' 3. Run `prodbeam status` to verify config\n');
|
|
425
|
+
}
|
|
426
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Interface } from 'node:readline/promises';
|
|
2
|
+
export declare function createPrompt(): Interface;
|
|
3
|
+
export interface AskOptions {
|
|
4
|
+
required?: boolean;
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
validate?: (value: string) => string | null;
|
|
7
|
+
}
|
|
8
|
+
export declare function ask(rl: Interface, question: string, opts?: AskOptions): Promise<string>;
|
|
9
|
+
export declare function askSecret(rl: Interface, question: string): Promise<string>;
|
|
10
|
+
export declare function askEmails(rl: Interface, question: string): Promise<string[]>;
|
|
11
|
+
export declare function askConfirm(rl: Interface, question: string, defaultYes?: boolean): Promise<boolean>;
|
|
12
|
+
export declare function printHeader(text: string): void;
|
|
13
|
+
export declare function printSuccess(text: string): void;
|
|
14
|
+
export declare function printWarning(text: string): void;
|
|
15
|
+
export declare function printInfo(text: string): void;
|
|
16
|
+
export declare function printError(text: string): void;
|
|
17
|
+
export declare function printStep(step: number, total: number, text: string): void;
|
|
18
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/commands/prompt.ts"],"names":[],"mappings":"AAOA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKzE,wBAAgB,YAAY,IAAI,SAAS,CAExC;AAID,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CAC7C;AAMD,wBAAsB,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBjG;AAMD,wBAAsB,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDhF;AAMD,wBAAsB,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqBlF;AAKD,wBAAsB,UAAU,CAC9B,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,EAChB,UAAU,UAAO,GAChB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAYD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG9C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEzE"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { stdin, stdout } from 'node:process';
|
|
3
|
+
export function createPrompt() {
|
|
4
|
+
return createInterface({ input: stdin, output: stdout });
|
|
5
|
+
}
|
|
6
|
+
export async function ask(rl, question, opts = {}) {
|
|
7
|
+
const { required = false, defaultValue, validate } = opts;
|
|
8
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : '';
|
|
9
|
+
for (;;) {
|
|
10
|
+
const raw = await rl.question(`${question}${suffix}: `);
|
|
11
|
+
const value = raw.trim() || defaultValue || '';
|
|
12
|
+
if (required && !value) {
|
|
13
|
+
printWarning('This field is required. Please enter a value.');
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (validate) {
|
|
17
|
+
const error = validate(value);
|
|
18
|
+
if (error) {
|
|
19
|
+
printWarning(error);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function askSecret(rl, question) {
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
const input = rl.terminal ? stdin : stdin;
|
|
29
|
+
stdout.write(`${question}: `);
|
|
30
|
+
if (!stdin.isTTY) {
|
|
31
|
+
void rl.question('').then((answer) => resolve(answer.trim()));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
stdin.setRawMode(true);
|
|
35
|
+
stdin.resume();
|
|
36
|
+
let secret = '';
|
|
37
|
+
const onData = (data) => {
|
|
38
|
+
const char = data.toString();
|
|
39
|
+
if (char === '\n' || char === '\r' || char === '\u0004') {
|
|
40
|
+
stdin.setRawMode(false);
|
|
41
|
+
stdin.pause();
|
|
42
|
+
stdin.removeListener('data', onData);
|
|
43
|
+
stdout.write('\n');
|
|
44
|
+
resolve(secret.trim());
|
|
45
|
+
}
|
|
46
|
+
else if (char === '\u0003') {
|
|
47
|
+
stdin.setRawMode(false);
|
|
48
|
+
stdin.pause();
|
|
49
|
+
stdin.removeListener('data', onData);
|
|
50
|
+
stdout.write('\n');
|
|
51
|
+
rl.close();
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
else if (char === '\u007F' || char === '\b') {
|
|
55
|
+
if (secret.length > 0) {
|
|
56
|
+
secret = secret.slice(0, -1);
|
|
57
|
+
stdout.write('\b \b');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (char.charCodeAt(0) >= 32) {
|
|
61
|
+
secret += char;
|
|
62
|
+
stdout.write('*');
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
void input;
|
|
66
|
+
stdin.on('data', onData);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export async function askEmails(rl, question) {
|
|
70
|
+
for (;;) {
|
|
71
|
+
const raw = await rl.question(`${question}: `);
|
|
72
|
+
const emails = raw
|
|
73
|
+
.split(',')
|
|
74
|
+
.map((e) => e.trim())
|
|
75
|
+
.filter(Boolean);
|
|
76
|
+
if (emails.length === 0) {
|
|
77
|
+
printWarning('Please enter at least one email address.');
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const invalid = emails.filter((e) => !e.includes('@'));
|
|
81
|
+
if (invalid.length > 0) {
|
|
82
|
+
printWarning(`Invalid email(s): ${invalid.join(', ')}`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
return emails;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export async function askConfirm(rl, question, defaultYes = true) {
|
|
89
|
+
const hint = defaultYes ? '[Y/n]' : '[y/N]';
|
|
90
|
+
const raw = await rl.question(`${question} ${hint}: `);
|
|
91
|
+
const answer = raw.trim().toLowerCase();
|
|
92
|
+
if (!answer)
|
|
93
|
+
return defaultYes;
|
|
94
|
+
return answer === 'y' || answer === 'yes';
|
|
95
|
+
}
|
|
96
|
+
const BOLD = '\x1b[1m';
|
|
97
|
+
const GREEN = '\x1b[32m';
|
|
98
|
+
const YELLOW = '\x1b[33m';
|
|
99
|
+
const RED = '\x1b[31m';
|
|
100
|
+
const CYAN = '\x1b[36m';
|
|
101
|
+
const DIM = '\x1b[2m';
|
|
102
|
+
const RESET = '\x1b[0m';
|
|
103
|
+
export function printHeader(text) {
|
|
104
|
+
console.log(`\n${BOLD}${CYAN}${text}${RESET}`);
|
|
105
|
+
console.log(`${DIM}${'─'.repeat(text.length)}${RESET}`);
|
|
106
|
+
}
|
|
107
|
+
export function printSuccess(text) {
|
|
108
|
+
console.log(`${GREEN}[ok]${RESET} ${text}`);
|
|
109
|
+
}
|
|
110
|
+
export function printWarning(text) {
|
|
111
|
+
console.log(`${YELLOW}[!]${RESET} ${text}`);
|
|
112
|
+
}
|
|
113
|
+
export function printInfo(text) {
|
|
114
|
+
console.log(`${DIM}[i]${RESET} ${text}`);
|
|
115
|
+
}
|
|
116
|
+
export function printError(text) {
|
|
117
|
+
console.log(`${RED}[error]${RESET} ${text}`);
|
|
118
|
+
}
|
|
119
|
+
export function printStep(step, total, text) {
|
|
120
|
+
console.log(`\n${BOLD}[${step}/${total}]${RESET} ${text}`);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/commands/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CredentialsConfig, GitHubCredentials, JiraCredentials } from './types.js';
|
|
2
|
+
export declare function resolveGitHubCredentials(): GitHubCredentials | null;
|
|
3
|
+
export declare function resolveJiraCredentials(): JiraCredentials | null;
|
|
4
|
+
export declare function resolveCredentials(): CredentialsConfig;
|
|
5
|
+
export declare function writeCredentials(config: CredentialsConfig): void;
|
|
6
|
+
export declare function mergeCredentials(newCreds: CredentialsConfig): void;
|
|
7
|
+
export declare function hasGitHubCredentials(): boolean;
|
|
8
|
+
export declare function hasJiraCredentials(): boolean;
|
|
9
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/config/credentials.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAiCxF,wBAAgB,wBAAwB,IAAI,iBAAiB,GAAG,IAAI,CAcnE;AAMD,wBAAgB,sBAAsB,IAAI,eAAe,GAAG,IAAI,CAiB/D;AAKD,wBAAgB,kBAAkB,IAAI,iBAAiB,CAItD;AA0BD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAKhE;AAOD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAYlE;AAKD,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C"}
|