@releasehub/cli 1.0.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/dist/commands/ai.d.ts +3 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +215 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +130 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/generate.d.ts +12 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +105 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/ai.d.ts +15 -0
- package/dist/lib/ai.d.ts.map +1 -0
- package/dist/lib/ai.js +128 -0
- package/dist/lib/ai.js.map +1 -0
- package/dist/lib/config.d.ts +21 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +69 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/errors.d.ts +15 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +49 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/formatters.d.ts +12 -0
- package/dist/lib/formatters.d.ts.map +1 -0
- package/dist/lib/formatters.js +121 -0
- package/dist/lib/formatters.js.map +1 -0
- package/dist/lib/git.d.ts +13 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +52 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/github.d.ts +34 -0
- package/dist/lib/github.d.ts.map +1 -0
- package/dist/lib/github.js +166 -0
- package/dist/lib/github.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAuFnC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiJzD"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import * as readline from 'readline';
|
|
4
|
+
import { readConfig, updateConfig, writeConfig, getKeyForProvider, getActiveProvider, AI_PROVIDERS, AI_PROVIDER_LABELS, AI_PROVIDER_KEY_URLS, } from '../lib/config.js';
|
|
5
|
+
import { handleError } from '../lib/errors.js';
|
|
6
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
7
|
+
function prompt(question) {
|
|
8
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
9
|
+
return new Promise(resolve => {
|
|
10
|
+
rl.question(question, answer => { rl.close(); resolve(answer.trim()); });
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function promptSelect(question, options) {
|
|
14
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
15
|
+
return new Promise(resolve => {
|
|
16
|
+
console.log('');
|
|
17
|
+
console.log(chalk.bold(` ${question}`));
|
|
18
|
+
options.forEach((opt, i) => {
|
|
19
|
+
console.log(` ${chalk.dim(`${i + 1}.`)} ${opt}`);
|
|
20
|
+
});
|
|
21
|
+
console.log('');
|
|
22
|
+
rl.question(chalk.bold(' Enter number: '), answer => {
|
|
23
|
+
rl.close();
|
|
24
|
+
const n = parseInt(answer.trim(), 10);
|
|
25
|
+
resolve(isNaN(n) ? 0 : n - 1);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function validateKey(provider, key) {
|
|
30
|
+
try {
|
|
31
|
+
if (provider === 'anthropic') {
|
|
32
|
+
const res = await fetch('https://api.anthropic.com/v1/models', {
|
|
33
|
+
headers: { 'x-api-key': key, 'anthropic-version': '2023-06-01' },
|
|
34
|
+
});
|
|
35
|
+
return res.ok;
|
|
36
|
+
}
|
|
37
|
+
if (provider === 'openai') {
|
|
38
|
+
const res = await fetch('https://api.openai.com/v1/models', {
|
|
39
|
+
headers: { Authorization: `Bearer ${key}` },
|
|
40
|
+
});
|
|
41
|
+
return res.ok;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function addKeyForProvider(provider) {
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(chalk.dim(` Get your key at: ${AI_PROVIDER_KEY_URLS[provider]}`));
|
|
52
|
+
console.log('');
|
|
53
|
+
const key = await prompt(chalk.bold(` ${AI_PROVIDER_LABELS[provider]} API key: `));
|
|
54
|
+
if (!key) {
|
|
55
|
+
console.log(chalk.red(' ✖ No key provided.'));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const spinner = ora('Validating key...').start();
|
|
59
|
+
const valid = await validateKey(provider, key);
|
|
60
|
+
if (!valid) {
|
|
61
|
+
spinner.fail(chalk.red('Key validation failed. Check your key and try again.'));
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const configKey = provider === 'anthropic' ? 'anthropic_key' : 'openai_key';
|
|
65
|
+
updateConfig({ [configKey]: key, ai_provider: provider });
|
|
66
|
+
spinner.succeed(`${AI_PROVIDER_LABELS[provider]} key saved and set as active provider.`);
|
|
67
|
+
console.log('');
|
|
68
|
+
console.log(chalk.dim(' Next: releasehub generate --from <tag> --to <tag>'));
|
|
69
|
+
console.log('');
|
|
70
|
+
}
|
|
71
|
+
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
72
|
+
export function registerAICommands(program) {
|
|
73
|
+
const ai = program
|
|
74
|
+
.command('ai')
|
|
75
|
+
.description('Manage AI provider and keys')
|
|
76
|
+
.addHelpText('after', `
|
|
77
|
+
${chalk.bold('Commands:')}
|
|
78
|
+
${chalk.cyan('releasehub ai add-key')} ${chalk.dim('Add an Anthropic or OpenAI key')}
|
|
79
|
+
${chalk.cyan('releasehub ai switch')} ${chalk.dim('Switch active AI provider')}
|
|
80
|
+
${chalk.cyan('releasehub ai remove-key')} ${chalk.dim('Remove a saved key')}
|
|
81
|
+
${chalk.cyan('releasehub ai status')} ${chalk.dim('Show provider status and validate keys')}
|
|
82
|
+
`);
|
|
83
|
+
// ── add-key ───────────────────────────────────────────────────────────────
|
|
84
|
+
ai
|
|
85
|
+
.command('add-key')
|
|
86
|
+
.description('Add an AI provider key (select provider interactively)')
|
|
87
|
+
.action(async () => {
|
|
88
|
+
try {
|
|
89
|
+
const idx = await promptSelect('Which AI provider?', AI_PROVIDERS.map(p => AI_PROVIDER_LABELS[p]));
|
|
90
|
+
const provider = AI_PROVIDERS[idx];
|
|
91
|
+
if (!provider) {
|
|
92
|
+
console.log(chalk.red(' ✖ Invalid selection.'));
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
await addKeyForProvider(provider);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
handleError(err);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
// ── switch ────────────────────────────────────────────────────────────────
|
|
102
|
+
ai
|
|
103
|
+
.command('switch')
|
|
104
|
+
.description('Switch active AI provider')
|
|
105
|
+
.action(async () => {
|
|
106
|
+
try {
|
|
107
|
+
const current = getActiveProvider();
|
|
108
|
+
console.log('');
|
|
109
|
+
console.log(chalk.dim(` Current provider: ${AI_PROVIDER_LABELS[current]}`));
|
|
110
|
+
const idx = await promptSelect('Switch to which provider?', AI_PROVIDERS.map(p => {
|
|
111
|
+
const hasKey = !!getKeyForProvider(p);
|
|
112
|
+
const active = p === current ? chalk.dim(' (current)') : '';
|
|
113
|
+
const missing = !hasKey ? chalk.red(' (no key)') : '';
|
|
114
|
+
return `${AI_PROVIDER_LABELS[p]}${active}${missing}`;
|
|
115
|
+
}));
|
|
116
|
+
const provider = AI_PROVIDERS[idx];
|
|
117
|
+
if (!provider) {
|
|
118
|
+
console.log(chalk.red(' ✖ Invalid selection.'));
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
if (provider === current) {
|
|
122
|
+
console.log(chalk.yellow(` Already using ${AI_PROVIDER_LABELS[provider]}.`));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!getKeyForProvider(provider)) {
|
|
126
|
+
console.log(chalk.yellow(` No key saved for ${AI_PROVIDER_LABELS[provider]}.`));
|
|
127
|
+
const answer = await prompt(chalk.bold(' Add key now? (y/n): '));
|
|
128
|
+
if (answer.toLowerCase() === 'y') {
|
|
129
|
+
await addKeyForProvider(provider);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
console.log(chalk.dim(' Cancelled.'));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
updateConfig({ ai_provider: provider });
|
|
136
|
+
console.log(chalk.green(`✔ Switched to ${AI_PROVIDER_LABELS[provider]}.`));
|
|
137
|
+
console.log('');
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
handleError(err);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// ── remove-key ────────────────────────────────────────────────────────────
|
|
144
|
+
ai
|
|
145
|
+
.command('remove-key')
|
|
146
|
+
.description('Remove a saved AI key')
|
|
147
|
+
.action(async () => {
|
|
148
|
+
try {
|
|
149
|
+
const config = readConfig();
|
|
150
|
+
const available = AI_PROVIDERS.filter(p => !!getKeyForProvider(p));
|
|
151
|
+
if (available.length === 0) {
|
|
152
|
+
console.log(chalk.yellow('No AI keys saved.'));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const idx = await promptSelect('Remove key for which provider?', available.map(p => AI_PROVIDER_LABELS[p]));
|
|
156
|
+
const provider = available[idx];
|
|
157
|
+
if (!provider) {
|
|
158
|
+
console.log(chalk.red(' ✖ Invalid selection.'));
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
const configKey = provider === 'anthropic' ? 'anthropic_key' : 'openai_key';
|
|
162
|
+
delete config[configKey];
|
|
163
|
+
if (config.ai_provider === provider) {
|
|
164
|
+
const other = AI_PROVIDERS.find(p => p !== provider && !!getKeyForProvider(p));
|
|
165
|
+
config.ai_provider = other;
|
|
166
|
+
}
|
|
167
|
+
writeConfig(config);
|
|
168
|
+
console.log(chalk.green(`✔ ${AI_PROVIDER_LABELS[provider]} key removed.`));
|
|
169
|
+
console.log('');
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
handleError(err);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
// ── status ────────────────────────────────────────────────────────────────
|
|
176
|
+
ai
|
|
177
|
+
.command('status')
|
|
178
|
+
.description('Show active provider and validate saved keys')
|
|
179
|
+
.action(async () => {
|
|
180
|
+
try {
|
|
181
|
+
console.log('');
|
|
182
|
+
const active = getActiveProvider();
|
|
183
|
+
console.log(chalk.bold(' AI provider status'));
|
|
184
|
+
console.log('');
|
|
185
|
+
for (const provider of AI_PROVIDERS) {
|
|
186
|
+
const key = getKeyForProvider(provider);
|
|
187
|
+
const isActive = provider === active;
|
|
188
|
+
const activeTag = isActive ? chalk.bgBlue.white(' active ') + ' ' : ' ';
|
|
189
|
+
if (key) {
|
|
190
|
+
const spinner = ora({ text: `Checking ${AI_PROVIDER_LABELS[provider]}...` }).start();
|
|
191
|
+
const valid = await validateKey(provider, key);
|
|
192
|
+
const source = ((provider === 'anthropic' && process.env['RELEASEHUB_ANTHROPIC_KEY']) ||
|
|
193
|
+
(provider === 'openai' && process.env['RELEASEHUB_OPENAI_KEY'])) ? 'env var' : 'config';
|
|
194
|
+
if (valid) {
|
|
195
|
+
spinner.succeed(`${activeTag}${chalk.green(AI_PROVIDER_LABELS[provider])} — valid ${chalk.dim(`(${source}, ${key.slice(0, 10)}...)`)}`);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
spinner.fail(`${activeTag}${chalk.red(AI_PROVIDER_LABELS[provider])} — invalid or expired`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
console.log(` ${activeTag}${chalk.dim(AI_PROVIDER_LABELS[provider])} — ${chalk.yellow('no key saved')}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
console.log('');
|
|
206
|
+
console.log(chalk.dim(' releasehub ai add-key — add a key'));
|
|
207
|
+
console.log(chalk.dim(' releasehub ai switch — switch provider'));
|
|
208
|
+
console.log('');
|
|
209
|
+
}
|
|
210
|
+
catch (err) {
|
|
211
|
+
handleError(err);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=ai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAsFnC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkE3D"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { updateConfig, writeConfig, readConfig } from '../lib/config.js';
|
|
4
|
+
import { handleError, ApiError } from '../lib/errors.js';
|
|
5
|
+
// GitHub OAuth device flow
|
|
6
|
+
const GITHUB_CLIENT_ID = process.env.RELEASEHUB_GITHUB_CLIENT_ID ?? 'Ov23lilDl2r3neGz7d7P';
|
|
7
|
+
async function requestDeviceCode() {
|
|
8
|
+
const res = await fetch('https://github.com/login/device/code', {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
headers: {
|
|
11
|
+
'Accept': 'application/json',
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify({
|
|
15
|
+
client_id: GITHUB_CLIENT_ID,
|
|
16
|
+
scope: 'repo read:user',
|
|
17
|
+
}),
|
|
18
|
+
});
|
|
19
|
+
if (!res.ok)
|
|
20
|
+
throw new ApiError('Failed to connect to GitHub. Check your internet connection and try again.', res.status);
|
|
21
|
+
return res.json();
|
|
22
|
+
}
|
|
23
|
+
async function pollForToken(deviceCode, interval) {
|
|
24
|
+
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
25
|
+
while (true) {
|
|
26
|
+
await delay(interval * 1000);
|
|
27
|
+
const res = await fetch('https://github.com/login/oauth/access_token', {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: {
|
|
30
|
+
'Accept': 'application/json',
|
|
31
|
+
'Content-Type': 'application/json',
|
|
32
|
+
},
|
|
33
|
+
body: JSON.stringify({
|
|
34
|
+
client_id: GITHUB_CLIENT_ID,
|
|
35
|
+
device_code: deviceCode,
|
|
36
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
39
|
+
const data = await res.json();
|
|
40
|
+
if (data.access_token)
|
|
41
|
+
return data.access_token;
|
|
42
|
+
if (data.error === 'authorization_pending')
|
|
43
|
+
continue;
|
|
44
|
+
if (data.error === 'slow_down') {
|
|
45
|
+
await delay(5000);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (data.error === 'expired_token')
|
|
49
|
+
throw new ApiError('The code expired. Run releasehub auth login again.');
|
|
50
|
+
if (data.error === 'access_denied')
|
|
51
|
+
throw new ApiError('Authorization was cancelled.');
|
|
52
|
+
throw new ApiError(data.error_description ?? 'GitHub authorization failed.');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function getGitHubUser(token) {
|
|
56
|
+
const res = await fetch('https://api.github.com/user', {
|
|
57
|
+
headers: {
|
|
58
|
+
Authorization: `Bearer ${token}`,
|
|
59
|
+
'User-Agent': '@releasehub/cli',
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
if (!res.ok)
|
|
63
|
+
throw new ApiError('Failed to fetch your GitHub profile.', res.status);
|
|
64
|
+
return res.json();
|
|
65
|
+
}
|
|
66
|
+
export function registerAuthCommands(program) {
|
|
67
|
+
const auth = program
|
|
68
|
+
.command('auth')
|
|
69
|
+
.description('Manage GitHub authentication')
|
|
70
|
+
.addHelpText('after', `
|
|
71
|
+
${chalk.bold('Commands:')}
|
|
72
|
+
${chalk.cyan('releasehub auth login')} ${chalk.dim('Connect your GitHub account')}
|
|
73
|
+
${chalk.cyan('releasehub auth logout')} ${chalk.dim('Disconnect and remove saved token')}
|
|
74
|
+
`);
|
|
75
|
+
auth
|
|
76
|
+
.command('login')
|
|
77
|
+
.description('Connect your GitHub account via OAuth')
|
|
78
|
+
.addHelpText('after', `
|
|
79
|
+
${chalk.dim('Opens a GitHub device authorization flow in your browser.')}
|
|
80
|
+
${chalk.dim('Your token is stored locally in ~/.releasehub/config.json')}
|
|
81
|
+
`)
|
|
82
|
+
.action(async () => {
|
|
83
|
+
try {
|
|
84
|
+
console.log('');
|
|
85
|
+
const spinner = ora('Connecting to GitHub...').start();
|
|
86
|
+
const { device_code, user_code, verification_uri, interval } = await requestDeviceCode();
|
|
87
|
+
spinner.stop();
|
|
88
|
+
console.log(chalk.bold(' Open this URL in your browser:'));
|
|
89
|
+
console.log(` ${chalk.cyan(verification_uri)}`);
|
|
90
|
+
console.log('');
|
|
91
|
+
console.log(chalk.bold(' Enter this code when prompted:'));
|
|
92
|
+
console.log(` ${chalk.yellow.bold(user_code)}`);
|
|
93
|
+
console.log('');
|
|
94
|
+
const waiting = ora('Waiting for authorization...').start();
|
|
95
|
+
const token = await pollForToken(device_code, interval);
|
|
96
|
+
const user = await getGitHubUser(token);
|
|
97
|
+
updateConfig({ github_token: token });
|
|
98
|
+
waiting.succeed(`Authenticated as ${chalk.bold('@' + user.login)}`);
|
|
99
|
+
console.log('');
|
|
100
|
+
console.log(chalk.dim(' Next: releasehub ai add-key'));
|
|
101
|
+
console.log('');
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
handleError(err);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
auth
|
|
108
|
+
.command('logout')
|
|
109
|
+
.description('Disconnect your GitHub account and remove saved token')
|
|
110
|
+
.action(() => {
|
|
111
|
+
try {
|
|
112
|
+
const config = readConfig();
|
|
113
|
+
if (!config.github_token) {
|
|
114
|
+
console.log('');
|
|
115
|
+
console.log(chalk.yellow(' You are not logged in.'));
|
|
116
|
+
console.log('');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
delete config.github_token;
|
|
120
|
+
writeConfig(config);
|
|
121
|
+
console.log('');
|
|
122
|
+
console.log(chalk.green(' ✔ Logged out successfully.'));
|
|
123
|
+
console.log('');
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
handleError(err);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export interface GenerateOptions {
|
|
3
|
+
from: string;
|
|
4
|
+
to: string;
|
|
5
|
+
repo?: string;
|
|
6
|
+
format: string;
|
|
7
|
+
output?: string;
|
|
8
|
+
publish?: boolean;
|
|
9
|
+
quiet?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function registerGenerateCommand(program: Command): void;
|
|
12
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWnC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyG9D"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { writeFileSync } from 'fs';
|
|
4
|
+
import { detectRepo, parseRepo } from '../lib/git.js';
|
|
5
|
+
import { fetchPullRequests, publishGitHubRelease } from '../lib/github.js';
|
|
6
|
+
import { analyzePullRequests } from '../lib/ai.js';
|
|
7
|
+
import { getActiveAIKey, getActiveProvider, AI_PROVIDER_LABELS } from '../lib/config.js';
|
|
8
|
+
import { handleError, AuthError } from '../lib/errors.js';
|
|
9
|
+
import { formatOutput } from '../lib/formatters.js';
|
|
10
|
+
export function registerGenerateCommand(program) {
|
|
11
|
+
program
|
|
12
|
+
.command('generate')
|
|
13
|
+
.description('Generate release notes from merged pull requests')
|
|
14
|
+
.addHelpText('after', `
|
|
15
|
+
${chalk.bold('Formats:')}
|
|
16
|
+
${chalk.cyan('github-release')} ${chalk.dim('Markdown for a GitHub Release page (default)')}
|
|
17
|
+
${chalk.cyan('changelog')} ${chalk.dim('Keep a Changelog format, with date')}
|
|
18
|
+
${chalk.cyan('slack')} ${chalk.dim('Compact Slack message with emoji')}
|
|
19
|
+
|
|
20
|
+
${chalk.bold('Examples:')}
|
|
21
|
+
${chalk.cyan('releasehub generate --from v1.0.0 --to v1.1.0')}
|
|
22
|
+
${chalk.cyan('releasehub generate --from v1.0.0 --to v1.1.0 --format slack')}
|
|
23
|
+
${chalk.cyan('releasehub generate --from v1.0.0 --to v1.1.0 --output release.md')}
|
|
24
|
+
${chalk.cyan('releasehub generate --from v1.0.0 --to v1.1.0 --publish')}
|
|
25
|
+
${chalk.cyan('releasehub generate --from v1.0.0 --to v1.1.0 --quiet')} ${chalk.dim('(CI mode — stdout only)')}
|
|
26
|
+
`)
|
|
27
|
+
.requiredOption('--from <tag>', 'Start tag (e.g. v1.0.0)')
|
|
28
|
+
.requiredOption('--to <tag>', 'End tag (e.g. v1.1.0)')
|
|
29
|
+
.option('--repo <repo>', 'Repository in owner/name format (auto-detected from git remote if omitted)')
|
|
30
|
+
.option('--format <format>', 'Output format: github-release | changelog | slack', 'github-release')
|
|
31
|
+
.option('--output <file>', 'Write output to a file instead of printing to stdout')
|
|
32
|
+
.option('--publish', 'Publish directly as a GitHub Release via the API')
|
|
33
|
+
.option('--quiet', 'Suppress progress output — prints only the final result (useful in CI)')
|
|
34
|
+
.action(async (options) => {
|
|
35
|
+
try {
|
|
36
|
+
const log = (msg) => { if (!options.quiet)
|
|
37
|
+
process.stderr.write(msg + '\n'); };
|
|
38
|
+
log('');
|
|
39
|
+
// 1. Resolve repo
|
|
40
|
+
const repo = options.repo ? parseRepo(options.repo) : detectRepo();
|
|
41
|
+
log(chalk.dim(` repo : ${repo.owner}/${repo.name}`));
|
|
42
|
+
log(chalk.dim(` range : ${options.from} → ${options.to}`));
|
|
43
|
+
log(chalk.dim(` format : ${options.format}`));
|
|
44
|
+
log(chalk.dim(` provider : ${AI_PROVIDER_LABELS[getActiveProvider()]}`));
|
|
45
|
+
log('');
|
|
46
|
+
// 2. Check AI key
|
|
47
|
+
if (!getActiveAIKey()) {
|
|
48
|
+
throw new AuthError('No AI key found. Run: releasehub ai add-key');
|
|
49
|
+
}
|
|
50
|
+
// 3. Fetch PRs
|
|
51
|
+
const prSpinner = ora({ text: 'Fetching pull requests...', isSilent: options.quiet }).start();
|
|
52
|
+
const prs = await fetchPullRequests(repo, options.from, options.to);
|
|
53
|
+
if (prs.length === 0) {
|
|
54
|
+
prSpinner.warn(chalk.yellow('No merged pull requests found in this range.'));
|
|
55
|
+
log(chalk.dim(' Make sure the tags exist and there are merged PRs between them.'));
|
|
56
|
+
log(chalk.dim(` Try: git tag --list to see available tags.`));
|
|
57
|
+
log('');
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
prSpinner.succeed(`Fetched ${chalk.bold(prs.length)} pull requests`);
|
|
61
|
+
// 4. AI analysis
|
|
62
|
+
const aiSpinner = ora({ text: 'Analyzing with AI...', isSilent: options.quiet }).start();
|
|
63
|
+
const { changes } = await analyzePullRequests(prs);
|
|
64
|
+
const visible = changes.filter(c => c.visible);
|
|
65
|
+
const hidden = changes.filter(c => !c.visible);
|
|
66
|
+
aiSpinner.succeed(`Analyzed — ${chalk.bold(visible.length)} user-facing, ${chalk.dim(`${hidden.length} hidden`)}`);
|
|
67
|
+
if (visible.length === 0) {
|
|
68
|
+
log('');
|
|
69
|
+
log(chalk.yellow(' No user-facing changes found.'));
|
|
70
|
+
log(chalk.dim(' All pull requests were classified as internal (refactors, CI, dependencies).'));
|
|
71
|
+
log(chalk.dim(' Nothing to publish for this release range.'));
|
|
72
|
+
log('');
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
// 5. Format output
|
|
76
|
+
const output = formatOutput(options.format, { version: options.to, changes });
|
|
77
|
+
// 6. Write or print
|
|
78
|
+
if (options.output) {
|
|
79
|
+
writeFileSync(options.output, output, 'utf8');
|
|
80
|
+
log('');
|
|
81
|
+
log(chalk.green(` ✓ Written to ${options.output}`));
|
|
82
|
+
log('');
|
|
83
|
+
}
|
|
84
|
+
else if (!options.publish) {
|
|
85
|
+
// Only print to stdout if not publishing (publish prints the URL instead)
|
|
86
|
+
process.stdout.write(output);
|
|
87
|
+
}
|
|
88
|
+
// 7. Publish as GitHub Release
|
|
89
|
+
if (options.publish) {
|
|
90
|
+
const publishSpinner = ora({ text: 'Publishing GitHub Release...', isSilent: options.quiet }).start();
|
|
91
|
+
// --publish only makes sense with github-release format
|
|
92
|
+
const releaseBody = options.format === 'github-release'
|
|
93
|
+
? output
|
|
94
|
+
: formatOutput('github-release', { version: options.to, changes });
|
|
95
|
+
const release = await publishGitHubRelease(repo, options.to, releaseBody);
|
|
96
|
+
publishSpinner.succeed(`Published: ${chalk.cyan(release.html_url)}`);
|
|
97
|
+
log('');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
handleError(err);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
import { registerAuthCommands } from './commands/auth.js';
|
|
6
|
+
import { registerAICommands } from './commands/ai.js';
|
|
7
|
+
import { registerGenerateCommand } from './commands/generate.js';
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const { version } = require('../package.json');
|
|
10
|
+
const program = new Command();
|
|
11
|
+
program
|
|
12
|
+
.name('releasehub')
|
|
13
|
+
.description('AI-powered release notes from your terminal')
|
|
14
|
+
.version(version, '-v, --version', 'Print version')
|
|
15
|
+
.addHelpText('after', `
|
|
16
|
+
${chalk.bold('Getting started:')}
|
|
17
|
+
${chalk.dim('1.')} ${chalk.cyan('releasehub auth login')} ${chalk.dim('Connect your GitHub account')}
|
|
18
|
+
${chalk.dim('2.')} ${chalk.cyan('releasehub ai add-key')} ${chalk.dim('Add your AI provider key')}
|
|
19
|
+
${chalk.dim('3.')} ${chalk.cyan('releasehub generate ...')} ${chalk.dim('Generate release notes')}
|
|
20
|
+
|
|
21
|
+
${chalk.bold('Examples:')}
|
|
22
|
+
${chalk.cyan('releasehub generate --from v2.3.0 --to v2.4.0')}
|
|
23
|
+
${chalk.cyan('releasehub generate --from v2.3.0 --to v2.4.0 --format slack')}
|
|
24
|
+
${chalk.cyan('releasehub generate --from v2.3.0 --to v2.4.0 --output release.md')}
|
|
25
|
+
${chalk.cyan('releasehub generate --from v2.3.0 --to v2.4.0 --publish')}
|
|
26
|
+
|
|
27
|
+
${chalk.dim('Docs: https://berat.app/releasehub/docs')}
|
|
28
|
+
`);
|
|
29
|
+
registerAuthCommands(program);
|
|
30
|
+
registerAICommands(program);
|
|
31
|
+
registerGenerateCommand(program);
|
|
32
|
+
program.parse();
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAEhE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC9C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAA;AAErE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,eAAe,CAAC;KAClD,WAAW,CAAC,OAAO,EAAE;EACtB,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC;IAC5B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC;IACvG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACpG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC;;EAEpG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;IACrB,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,8DAA8D,CAAC;IAC1E,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,yDAAyD,CAAC;;EAEvE,KAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC;GACnD,CAAC,CAAA;AAEJ,oBAAoB,CAAC,OAAO,CAAC,CAAA;AAC7B,kBAAkB,CAAC,OAAO,CAAC,CAAA;AAC3B,uBAAuB,CAAC,OAAO,CAAC,CAAA;AAEhC,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
package/dist/lib/ai.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PullRequest } from './github.js';
|
|
2
|
+
export type ChangeCategory = 'feature' | 'improvement' | 'bugfix' | 'breaking' | 'internal';
|
|
3
|
+
export interface AnalyzedChange {
|
|
4
|
+
original_title: string;
|
|
5
|
+
rewritten_title: string;
|
|
6
|
+
category: ChangeCategory;
|
|
7
|
+
visible: boolean;
|
|
8
|
+
confidence: number;
|
|
9
|
+
reasoning: string;
|
|
10
|
+
}
|
|
11
|
+
export interface AnalysisResult {
|
|
12
|
+
changes: AnalyzedChange[];
|
|
13
|
+
}
|
|
14
|
+
export declare function analyzePullRequests(prs: PullRequest[]): Promise<AnalysisResult>;
|
|
15
|
+
//# sourceMappingURL=ai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/lib/ai.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAI9C,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAA;AAE3F,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,cAAc,CAAA;IACxB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,EAAE,CAAA;CAC1B;AAsHD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAgBrF"}
|