hale-commenting-system 2.0.4 → 2.1.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 +1 -1
- package/bin/detect.d.ts +9 -0
- package/bin/detect.js +72 -0
- package/bin/generators.js +2 -2
- package/bin/onboarding.js +228 -49
- package/dist/cli/detect.d.ts +9 -0
- package/dist/cli/detect.js +72 -0
- package/dist/cli/generators.js +2 -2
- package/dist/cli/onboarding.js +228 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ After installation, the onboarding flow will automatically start to help you con
|
|
|
20
20
|
|
|
21
21
|
## Requirements
|
|
22
22
|
|
|
23
|
-
- PatternFly Seed project
|
|
23
|
+
- PatternFly Seed project with PatternFly v6+ (`@patternfly/react-core` ^6.0.0)
|
|
24
24
|
- GitHub account with OAuth app
|
|
25
25
|
- Jira access (Red Hat Jira: issues.redhat.com)
|
|
26
26
|
|
package/bin/detect.d.ts
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
1
|
export declare function detectPatternFlySeed(): boolean;
|
|
2
|
+
export interface GitRemoteInfo {
|
|
3
|
+
owner?: string;
|
|
4
|
+
repo?: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
isFork?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function detectGitRemote(): GitRemoteInfo | null;
|
|
9
|
+
export type ProjectSetupType = 'forked' | 'cloned' | 'unknown' | 'none';
|
|
10
|
+
export declare function detectProjectSetup(): ProjectSetupType;
|
package/bin/detect.js
CHANGED
|
@@ -34,8 +34,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.detectPatternFlySeed = detectPatternFlySeed;
|
|
37
|
+
exports.detectGitRemote = detectGitRemote;
|
|
38
|
+
exports.detectProjectSetup = detectProjectSetup;
|
|
37
39
|
const fs = __importStar(require("fs"));
|
|
38
40
|
const path = __importStar(require("path"));
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
39
42
|
function detectPatternFlySeed() {
|
|
40
43
|
const cwd = process.cwd();
|
|
41
44
|
// Check for webpack config files
|
|
@@ -60,3 +63,72 @@ function detectPatternFlySeed() {
|
|
|
60
63
|
}
|
|
61
64
|
return hasWebpack && hasAppDir && hasPatternFly;
|
|
62
65
|
}
|
|
66
|
+
function detectGitRemote() {
|
|
67
|
+
const cwd = process.cwd();
|
|
68
|
+
// Check if .git exists
|
|
69
|
+
if (!fs.existsSync(path.join(cwd, '.git'))) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
// Get remote URL
|
|
74
|
+
const remoteUrl = (0, child_process_1.execSync)('git remote get-url origin', {
|
|
75
|
+
cwd,
|
|
76
|
+
encoding: 'utf-8',
|
|
77
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
78
|
+
}).trim();
|
|
79
|
+
if (!remoteUrl) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
// Parse GitHub URL (supports https://, git@, and ssh formats)
|
|
83
|
+
// https://github.com/owner/repo.git
|
|
84
|
+
// git@github.com:owner/repo.git
|
|
85
|
+
// ssh://git@github.com/owner/repo.git
|
|
86
|
+
const githubMatch = remoteUrl.match(/github\.com[/:]([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
87
|
+
if (githubMatch) {
|
|
88
|
+
const owner = githubMatch[1];
|
|
89
|
+
const repo = githubMatch[2].replace(/\.git$/, '');
|
|
90
|
+
// Try to detect if it's a fork by checking if upstream exists
|
|
91
|
+
let isFork = false;
|
|
92
|
+
try {
|
|
93
|
+
(0, child_process_1.execSync)('git remote get-url upstream', {
|
|
94
|
+
cwd,
|
|
95
|
+
encoding: 'utf-8',
|
|
96
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
97
|
+
});
|
|
98
|
+
isFork = true;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// No upstream remote, might still be a fork but we can't tell
|
|
102
|
+
// Check if repo name matches patternfly-react-seed (likely a fork)
|
|
103
|
+
isFork = repo.includes('patternfly-react-seed') || repo.includes('pfseed');
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
owner,
|
|
107
|
+
repo,
|
|
108
|
+
url: remoteUrl,
|
|
109
|
+
isFork
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// Git command failed or not a git repo
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
function detectProjectSetup() {
|
|
120
|
+
const gitInfo = detectGitRemote();
|
|
121
|
+
if (!gitInfo) {
|
|
122
|
+
return 'none';
|
|
123
|
+
}
|
|
124
|
+
// Check if it looks like a fork (has patternfly-react-seed in name or has upstream)
|
|
125
|
+
if (gitInfo.isFork || gitInfo.repo?.includes('patternfly-react-seed')) {
|
|
126
|
+
return 'forked';
|
|
127
|
+
}
|
|
128
|
+
// Check if it's a clone of the original
|
|
129
|
+
if (gitInfo.owner === 'patternfly' && gitInfo.repo === 'patternfly-react-seed') {
|
|
130
|
+
return 'cloned';
|
|
131
|
+
}
|
|
132
|
+
// Has git remote but unclear
|
|
133
|
+
return 'unknown';
|
|
134
|
+
}
|
package/bin/generators.js
CHANGED
|
@@ -121,8 +121,8 @@ async function integrateIntoProject() {
|
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
// Read the template
|
|
124
|
-
// In compiled output, templates
|
|
125
|
-
const packageRoot = path.resolve(__dirname, '
|
|
124
|
+
// In compiled output, templates are in the package root (same level as bin/)
|
|
125
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
126
126
|
const templatePath = path.join(packageRoot, 'templates', 'webpack-middleware.js');
|
|
127
127
|
if (!fs.existsSync(templatePath)) {
|
|
128
128
|
console.log(' ⚠️ Template file not found. Manual integration required.');
|
package/bin/onboarding.js
CHANGED
|
@@ -40,13 +40,207 @@ exports.runOnboarding = runOnboarding;
|
|
|
40
40
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
41
41
|
const validators = __importStar(require("./validators"));
|
|
42
42
|
const generators = __importStar(require("./generators"));
|
|
43
|
+
const detect_1 = require("./detect");
|
|
43
44
|
async function runOnboarding() {
|
|
44
|
-
|
|
45
|
-
console.log('
|
|
46
|
-
|
|
47
|
-
console.log('
|
|
48
|
-
console.log('
|
|
49
|
-
console.log('
|
|
45
|
+
// Welcome & Explanation
|
|
46
|
+
console.log('🚀 Welcome to Hale Commenting System!\n');
|
|
47
|
+
console.log('This commenting system allows you to:');
|
|
48
|
+
console.log(' • Add comments directly on your design pages');
|
|
49
|
+
console.log(' • Sync comments with GitHub Issues');
|
|
50
|
+
console.log(' • Link Jira tickets to pages');
|
|
51
|
+
console.log(' • Store design goals and context\n');
|
|
52
|
+
console.log('Why GitHub?');
|
|
53
|
+
console.log(' We use GitHub Issues to store and sync all comments. When you add a comment');
|
|
54
|
+
console.log(' on a page, it creates a GitHub Issue. This allows comments to persist, sync');
|
|
55
|
+
console.log(' across devices, and be managed like any other GitHub Issue.\n');
|
|
56
|
+
console.log('Why Jira?');
|
|
57
|
+
console.log(' You can link Jira tickets to specific pages or sections. This helps connect');
|
|
58
|
+
console.log(' design work to development tracking and provides context for reviewers.\n');
|
|
59
|
+
// Step 1: Project Status Check
|
|
60
|
+
console.log('📋 Step 1: Project Setup Check\n');
|
|
61
|
+
const hasProject = await inquirer_1.default.prompt([
|
|
62
|
+
{
|
|
63
|
+
type: 'list',
|
|
64
|
+
name: 'hasProject',
|
|
65
|
+
message: 'Do you have a PatternFly Seed project set up locally?',
|
|
66
|
+
choices: [
|
|
67
|
+
{ name: 'Yes, I have it set up', value: 'yes' },
|
|
68
|
+
{ name: 'No, I need help setting it up', value: 'no' }
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
]);
|
|
72
|
+
if (hasProject.hasProject === 'no') {
|
|
73
|
+
console.log('\n📚 Setting up PatternFly Seed:\n');
|
|
74
|
+
console.log('1. Fork the PatternFly Seed repository:');
|
|
75
|
+
console.log(' Visit: https://github.com/patternfly/patternfly-react-seed');
|
|
76
|
+
console.log(' Click "Fork" in the top right\n');
|
|
77
|
+
console.log('2. Clone your fork locally:');
|
|
78
|
+
console.log(' git clone https://github.com/YOUR_USERNAME/patternfly-react-seed.git');
|
|
79
|
+
console.log(' cd patternfly-react-seed\n');
|
|
80
|
+
console.log('3. Install dependencies:');
|
|
81
|
+
console.log(' npm install\n');
|
|
82
|
+
console.log('4. Run this setup again:');
|
|
83
|
+
console.log(' npx hale-commenting-system init\n');
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
// Check if it's actually a PF Seed project
|
|
87
|
+
if (!(0, detect_1.detectPatternFlySeed)()) {
|
|
88
|
+
console.error('❌ Error: This doesn\'t appear to be a PatternFly Seed project.');
|
|
89
|
+
console.error('Please run this command from a PatternFly Seed project directory.');
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
// Detect project setup type
|
|
93
|
+
const gitInfo = (0, detect_1.detectGitRemote)();
|
|
94
|
+
const setupType = (0, detect_1.detectProjectSetup)();
|
|
95
|
+
let projectSetup = 'unknown';
|
|
96
|
+
let owner = gitInfo?.owner;
|
|
97
|
+
let repo = gitInfo?.repo;
|
|
98
|
+
if (setupType === 'none' || !gitInfo) {
|
|
99
|
+
// No git remote - need to set up
|
|
100
|
+
const setupAnswer = await inquirer_1.default.prompt([
|
|
101
|
+
{
|
|
102
|
+
type: 'list',
|
|
103
|
+
name: 'setupType',
|
|
104
|
+
message: 'How did you set up your PatternFly Seed project?',
|
|
105
|
+
choices: [
|
|
106
|
+
{ name: 'I forked the PatternFly Seed repo on GitHub', value: 'forked' },
|
|
107
|
+
{ name: 'I cloned the PatternFly Seed repo locally', value: 'cloned' },
|
|
108
|
+
{ name: 'I\'m not sure', value: 'unknown' }
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
]);
|
|
112
|
+
projectSetup = setupAnswer.setupType;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
projectSetup = setupType;
|
|
116
|
+
}
|
|
117
|
+
// Handle different setup types
|
|
118
|
+
if (projectSetup === 'forked') {
|
|
119
|
+
// Ask for owner/repo if not detected
|
|
120
|
+
if (!owner || !repo) {
|
|
121
|
+
const forkAnswers = await inquirer_1.default.prompt([
|
|
122
|
+
{
|
|
123
|
+
type: 'input',
|
|
124
|
+
name: 'owner',
|
|
125
|
+
message: 'What is your GitHub username or organization name?',
|
|
126
|
+
default: owner,
|
|
127
|
+
validate: (input) => {
|
|
128
|
+
if (!input.trim())
|
|
129
|
+
return 'Owner is required';
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
type: 'input',
|
|
135
|
+
name: 'repo',
|
|
136
|
+
message: 'What is the name of your forked repository?',
|
|
137
|
+
default: repo,
|
|
138
|
+
validate: (input) => {
|
|
139
|
+
if (!input.trim())
|
|
140
|
+
return 'Repository name is required';
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]);
|
|
145
|
+
owner = forkAnswers.owner;
|
|
146
|
+
repo = forkAnswers.repo;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
console.log(`\n✅ Detected repository: ${owner}/${repo}\n`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else if (projectSetup === 'cloned') {
|
|
153
|
+
console.log('\n📝 Since you cloned the repo, you\'ll need to create your own GitHub repository.\n');
|
|
154
|
+
console.log('Steps:');
|
|
155
|
+
console.log('1. Create a new repository on GitHub');
|
|
156
|
+
console.log('2. Add it as a remote: git remote add origin <your-repo-url>');
|
|
157
|
+
console.log('3. Push your code: git push -u origin main\n');
|
|
158
|
+
const hasCreated = await inquirer_1.default.prompt([
|
|
159
|
+
{
|
|
160
|
+
type: 'confirm',
|
|
161
|
+
name: 'created',
|
|
162
|
+
message: 'Have you created and pushed to your GitHub repository?',
|
|
163
|
+
default: false
|
|
164
|
+
}
|
|
165
|
+
]);
|
|
166
|
+
if (!hasCreated.created) {
|
|
167
|
+
console.log('\nPlease complete the steps above and run this setup again.');
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
// Ask for owner/repo
|
|
171
|
+
const repoAnswers = await inquirer_1.default.prompt([
|
|
172
|
+
{
|
|
173
|
+
type: 'input',
|
|
174
|
+
name: 'owner',
|
|
175
|
+
message: 'What is your GitHub username or organization name?',
|
|
176
|
+
validate: (input) => {
|
|
177
|
+
if (!input.trim())
|
|
178
|
+
return 'Owner is required';
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
type: 'input',
|
|
184
|
+
name: 'repo',
|
|
185
|
+
message: 'What is the name of your GitHub repository?',
|
|
186
|
+
validate: (input) => {
|
|
187
|
+
if (!input.trim())
|
|
188
|
+
return 'Repository name is required';
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
]);
|
|
193
|
+
owner = repoAnswers.owner;
|
|
194
|
+
repo = repoAnswers.repo;
|
|
195
|
+
}
|
|
196
|
+
else if (projectSetup === 'unknown') {
|
|
197
|
+
// Try to detect from git
|
|
198
|
+
if (gitInfo && gitInfo.owner && gitInfo.repo) {
|
|
199
|
+
console.log(`\n✅ Detected repository: ${gitInfo.owner}/${gitInfo.repo}\n`);
|
|
200
|
+
owner = gitInfo.owner;
|
|
201
|
+
repo = gitInfo.repo;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// Ask for owner/repo
|
|
205
|
+
const repoAnswers = await inquirer_1.default.prompt([
|
|
206
|
+
{
|
|
207
|
+
type: 'input',
|
|
208
|
+
name: 'owner',
|
|
209
|
+
message: 'What is your GitHub username or organization name?',
|
|
210
|
+
validate: (input) => {
|
|
211
|
+
if (!input.trim())
|
|
212
|
+
return 'Owner is required';
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
type: 'input',
|
|
218
|
+
name: 'repo',
|
|
219
|
+
message: 'What is the name of your GitHub repository?',
|
|
220
|
+
validate: (input) => {
|
|
221
|
+
if (!input.trim())
|
|
222
|
+
return 'Repository name is required';
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
]);
|
|
227
|
+
owner = repoAnswers.owner;
|
|
228
|
+
repo = repoAnswers.repo;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// Step 2: GitHub OAuth Setup
|
|
232
|
+
console.log('\n📦 Step 2: GitHub OAuth Setup\n');
|
|
233
|
+
console.log('To sync comments with GitHub Issues, we need to authenticate with GitHub.');
|
|
234
|
+
console.log('This requires creating a GitHub OAuth App.\n');
|
|
235
|
+
console.log('Instructions:');
|
|
236
|
+
console.log('1. Visit: https://github.com/settings/developers');
|
|
237
|
+
console.log('2. Click "New OAuth App"');
|
|
238
|
+
console.log('3. Fill in the form:');
|
|
239
|
+
console.log(' - Application name: Your app name (e.g., "My Design Comments")');
|
|
240
|
+
console.log(' - Homepage URL: http://localhost:9000 (or your dev server URL)');
|
|
241
|
+
console.log(' - Authorization callback URL: http://localhost:9000/api/github-oauth-callback');
|
|
242
|
+
console.log('4. Click "Register application"');
|
|
243
|
+
console.log('5. Copy the Client ID and generate a Client Secret\n');
|
|
50
244
|
const githubAnswers = await inquirer_1.default.prompt([
|
|
51
245
|
{
|
|
52
246
|
type: 'input',
|
|
@@ -62,50 +256,39 @@ async function runOnboarding() {
|
|
|
62
256
|
type: 'password',
|
|
63
257
|
name: 'clientSecret',
|
|
64
258
|
message: 'GitHub OAuth Client Secret:',
|
|
259
|
+
mask: '*',
|
|
65
260
|
validate: (input) => {
|
|
66
261
|
if (!input.trim())
|
|
67
262
|
return 'Client Secret is required';
|
|
68
263
|
return true;
|
|
69
264
|
}
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
type: 'input',
|
|
73
|
-
name: 'owner',
|
|
74
|
-
message: 'GitHub Owner (username or org):',
|
|
75
|
-
validate: (input) => {
|
|
76
|
-
if (!input.trim())
|
|
77
|
-
return 'Owner is required';
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
type: 'input',
|
|
83
|
-
name: 'repo',
|
|
84
|
-
message: 'GitHub Repository name:',
|
|
85
|
-
validate: (input) => {
|
|
86
|
-
if (!input.trim())
|
|
87
|
-
return 'Repository name is required';
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
265
|
}
|
|
91
266
|
]);
|
|
92
267
|
// Validate GitHub credentials
|
|
93
268
|
console.log('\n🔍 Validating GitHub credentials...');
|
|
94
|
-
const githubValid = await validators.validateGitHubCredentials(githubAnswers.clientId, githubAnswers.clientSecret,
|
|
269
|
+
const githubValid = await validators.validateGitHubCredentials(githubAnswers.clientId, githubAnswers.clientSecret, owner, repo);
|
|
95
270
|
if (!githubValid) {
|
|
96
271
|
console.error('❌ GitHub validation failed. Please check your credentials and try again.');
|
|
97
272
|
process.exit(1);
|
|
98
273
|
}
|
|
99
274
|
console.log('✅ GitHub credentials validated!\n');
|
|
100
|
-
// Step
|
|
101
|
-
console.log('🎫 Step
|
|
102
|
-
console.log('
|
|
103
|
-
console.log('
|
|
275
|
+
// Step 3: Jira Setup
|
|
276
|
+
console.log('🎫 Step 3: Jira Setup\n');
|
|
277
|
+
console.log('You can link Jira tickets to pages in your design. This helps connect');
|
|
278
|
+
console.log('design work to development tracking.\n');
|
|
279
|
+
console.log('For Red Hat Jira, generate a Personal Access Token:');
|
|
280
|
+
console.log('1. Visit: https://issues.redhat.com/secure/ViewProfile.jspa');
|
|
281
|
+
console.log('2. Click "Personal Access Tokens" in the left sidebar');
|
|
282
|
+
console.log('3. Click "Create token"');
|
|
283
|
+
console.log('4. Give it a name (e.g., "Hale Commenting System")');
|
|
284
|
+
console.log('5. Remove expiration (or set a long expiration)');
|
|
285
|
+
console.log('6. Click "Create" and copy the token\n');
|
|
286
|
+
console.log('Note: We use Bearer token authentication (no email required for Red Hat Jira).\n');
|
|
104
287
|
const jiraAnswers = await inquirer_1.default.prompt([
|
|
105
288
|
{
|
|
106
289
|
type: 'input',
|
|
107
290
|
name: 'baseUrl',
|
|
108
|
-
message: 'Jira Base URL:',
|
|
291
|
+
message: 'Jira Base URL (press Enter for Red Hat Jira):',
|
|
109
292
|
default: 'https://issues.redhat.com',
|
|
110
293
|
validate: (input) => {
|
|
111
294
|
if (!input.trim())
|
|
@@ -119,16 +302,11 @@ async function runOnboarding() {
|
|
|
119
302
|
}
|
|
120
303
|
}
|
|
121
304
|
},
|
|
122
|
-
{
|
|
123
|
-
type: 'input',
|
|
124
|
-
name: 'email',
|
|
125
|
-
message: 'Jira Email (optional, leave blank if using Bearer token):',
|
|
126
|
-
default: ''
|
|
127
|
-
},
|
|
128
305
|
{
|
|
129
306
|
type: 'password',
|
|
130
307
|
name: 'apiToken',
|
|
131
308
|
message: 'Jira API Token:',
|
|
309
|
+
mask: '*',
|
|
132
310
|
validate: (input) => {
|
|
133
311
|
if (!input.trim())
|
|
134
312
|
return 'API Token is required';
|
|
@@ -138,33 +316,34 @@ async function runOnboarding() {
|
|
|
138
316
|
]);
|
|
139
317
|
// Validate Jira credentials
|
|
140
318
|
console.log('\n🔍 Validating Jira credentials...');
|
|
141
|
-
const jiraValid = await validators.validateJiraCredentials(jiraAnswers.baseUrl, jiraAnswers.apiToken,
|
|
319
|
+
const jiraValid = await validators.validateJiraCredentials(jiraAnswers.baseUrl, jiraAnswers.apiToken, undefined // No email for Bearer token
|
|
320
|
+
);
|
|
142
321
|
if (!jiraValid) {
|
|
143
322
|
console.error('❌ Jira validation failed. Please check your credentials and try again.');
|
|
144
323
|
process.exit(1);
|
|
145
324
|
}
|
|
146
325
|
console.log('✅ Jira credentials validated!\n');
|
|
147
|
-
// Step
|
|
148
|
-
console.log('📝 Step
|
|
326
|
+
// Step 4: Generate files
|
|
327
|
+
console.log('📝 Step 4: Generating configuration files...\n');
|
|
149
328
|
await generators.generateFiles({
|
|
150
329
|
github: {
|
|
151
330
|
clientId: githubAnswers.clientId,
|
|
152
331
|
clientSecret: githubAnswers.clientSecret,
|
|
153
|
-
owner:
|
|
154
|
-
repo:
|
|
332
|
+
owner: owner,
|
|
333
|
+
repo: repo
|
|
155
334
|
},
|
|
156
335
|
jira: {
|
|
157
336
|
baseUrl: jiraAnswers.baseUrl,
|
|
158
337
|
apiToken: jiraAnswers.apiToken,
|
|
159
|
-
email:
|
|
338
|
+
email: undefined // Not used for Bearer token
|
|
160
339
|
}
|
|
161
340
|
});
|
|
162
|
-
// Step
|
|
163
|
-
console.log('🔧 Step
|
|
341
|
+
// Step 5: Integrate into project
|
|
342
|
+
console.log('🔧 Step 5: Integrating into PatternFly Seed project...\n');
|
|
164
343
|
await generators.integrateIntoProject();
|
|
165
344
|
console.log('\n✅ Setup complete!');
|
|
166
345
|
console.log('\nNext steps:');
|
|
167
|
-
console.log('1.
|
|
168
|
-
console.log('
|
|
169
|
-
console.log('
|
|
346
|
+
console.log('1. Start your dev server: npm run start:dev');
|
|
347
|
+
console.log(' (If it\'s already running, restart it to load the new configuration)');
|
|
348
|
+
console.log('2. The commenting system will be available in your app!\n');
|
|
170
349
|
}
|
package/dist/cli/detect.d.ts
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
1
|
export declare function detectPatternFlySeed(): boolean;
|
|
2
|
+
export interface GitRemoteInfo {
|
|
3
|
+
owner?: string;
|
|
4
|
+
repo?: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
isFork?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function detectGitRemote(): GitRemoteInfo | null;
|
|
9
|
+
export type ProjectSetupType = 'forked' | 'cloned' | 'unknown' | 'none';
|
|
10
|
+
export declare function detectProjectSetup(): ProjectSetupType;
|
package/dist/cli/detect.js
CHANGED
|
@@ -34,8 +34,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.detectPatternFlySeed = detectPatternFlySeed;
|
|
37
|
+
exports.detectGitRemote = detectGitRemote;
|
|
38
|
+
exports.detectProjectSetup = detectProjectSetup;
|
|
37
39
|
const fs = __importStar(require("fs"));
|
|
38
40
|
const path = __importStar(require("path"));
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
39
42
|
function detectPatternFlySeed() {
|
|
40
43
|
const cwd = process.cwd();
|
|
41
44
|
// Check for webpack config files
|
|
@@ -60,3 +63,72 @@ function detectPatternFlySeed() {
|
|
|
60
63
|
}
|
|
61
64
|
return hasWebpack && hasAppDir && hasPatternFly;
|
|
62
65
|
}
|
|
66
|
+
function detectGitRemote() {
|
|
67
|
+
const cwd = process.cwd();
|
|
68
|
+
// Check if .git exists
|
|
69
|
+
if (!fs.existsSync(path.join(cwd, '.git'))) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
// Get remote URL
|
|
74
|
+
const remoteUrl = (0, child_process_1.execSync)('git remote get-url origin', {
|
|
75
|
+
cwd,
|
|
76
|
+
encoding: 'utf-8',
|
|
77
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
78
|
+
}).trim();
|
|
79
|
+
if (!remoteUrl) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
// Parse GitHub URL (supports https://, git@, and ssh formats)
|
|
83
|
+
// https://github.com/owner/repo.git
|
|
84
|
+
// git@github.com:owner/repo.git
|
|
85
|
+
// ssh://git@github.com/owner/repo.git
|
|
86
|
+
const githubMatch = remoteUrl.match(/github\.com[/:]([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
87
|
+
if (githubMatch) {
|
|
88
|
+
const owner = githubMatch[1];
|
|
89
|
+
const repo = githubMatch[2].replace(/\.git$/, '');
|
|
90
|
+
// Try to detect if it's a fork by checking if upstream exists
|
|
91
|
+
let isFork = false;
|
|
92
|
+
try {
|
|
93
|
+
(0, child_process_1.execSync)('git remote get-url upstream', {
|
|
94
|
+
cwd,
|
|
95
|
+
encoding: 'utf-8',
|
|
96
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
97
|
+
});
|
|
98
|
+
isFork = true;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// No upstream remote, might still be a fork but we can't tell
|
|
102
|
+
// Check if repo name matches patternfly-react-seed (likely a fork)
|
|
103
|
+
isFork = repo.includes('patternfly-react-seed') || repo.includes('pfseed');
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
owner,
|
|
107
|
+
repo,
|
|
108
|
+
url: remoteUrl,
|
|
109
|
+
isFork
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
// Git command failed or not a git repo
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
function detectProjectSetup() {
|
|
120
|
+
const gitInfo = detectGitRemote();
|
|
121
|
+
if (!gitInfo) {
|
|
122
|
+
return 'none';
|
|
123
|
+
}
|
|
124
|
+
// Check if it looks like a fork (has patternfly-react-seed in name or has upstream)
|
|
125
|
+
if (gitInfo.isFork || gitInfo.repo?.includes('patternfly-react-seed')) {
|
|
126
|
+
return 'forked';
|
|
127
|
+
}
|
|
128
|
+
// Check if it's a clone of the original
|
|
129
|
+
if (gitInfo.owner === 'patternfly' && gitInfo.repo === 'patternfly-react-seed') {
|
|
130
|
+
return 'cloned';
|
|
131
|
+
}
|
|
132
|
+
// Has git remote but unclear
|
|
133
|
+
return 'unknown';
|
|
134
|
+
}
|
package/dist/cli/generators.js
CHANGED
|
@@ -121,8 +121,8 @@ async function integrateIntoProject() {
|
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
// Read the template
|
|
124
|
-
// In compiled output, templates
|
|
125
|
-
const packageRoot = path.resolve(__dirname, '
|
|
124
|
+
// In compiled output, templates are in the package root (same level as bin/)
|
|
125
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
126
126
|
const templatePath = path.join(packageRoot, 'templates', 'webpack-middleware.js');
|
|
127
127
|
if (!fs.existsSync(templatePath)) {
|
|
128
128
|
console.log(' ⚠️ Template file not found. Manual integration required.');
|
package/dist/cli/onboarding.js
CHANGED
|
@@ -40,13 +40,207 @@ exports.runOnboarding = runOnboarding;
|
|
|
40
40
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
41
41
|
const validators = __importStar(require("./validators"));
|
|
42
42
|
const generators = __importStar(require("./generators"));
|
|
43
|
+
const detect_1 = require("./detect");
|
|
43
44
|
async function runOnboarding() {
|
|
44
|
-
|
|
45
|
-
console.log('
|
|
46
|
-
|
|
47
|
-
console.log('
|
|
48
|
-
console.log('
|
|
49
|
-
console.log('
|
|
45
|
+
// Welcome & Explanation
|
|
46
|
+
console.log('🚀 Welcome to Hale Commenting System!\n');
|
|
47
|
+
console.log('This commenting system allows you to:');
|
|
48
|
+
console.log(' • Add comments directly on your design pages');
|
|
49
|
+
console.log(' • Sync comments with GitHub Issues');
|
|
50
|
+
console.log(' • Link Jira tickets to pages');
|
|
51
|
+
console.log(' • Store design goals and context\n');
|
|
52
|
+
console.log('Why GitHub?');
|
|
53
|
+
console.log(' We use GitHub Issues to store and sync all comments. When you add a comment');
|
|
54
|
+
console.log(' on a page, it creates a GitHub Issue. This allows comments to persist, sync');
|
|
55
|
+
console.log(' across devices, and be managed like any other GitHub Issue.\n');
|
|
56
|
+
console.log('Why Jira?');
|
|
57
|
+
console.log(' You can link Jira tickets to specific pages or sections. This helps connect');
|
|
58
|
+
console.log(' design work to development tracking and provides context for reviewers.\n');
|
|
59
|
+
// Step 1: Project Status Check
|
|
60
|
+
console.log('📋 Step 1: Project Setup Check\n');
|
|
61
|
+
const hasProject = await inquirer_1.default.prompt([
|
|
62
|
+
{
|
|
63
|
+
type: 'list',
|
|
64
|
+
name: 'hasProject',
|
|
65
|
+
message: 'Do you have a PatternFly Seed project set up locally?',
|
|
66
|
+
choices: [
|
|
67
|
+
{ name: 'Yes, I have it set up', value: 'yes' },
|
|
68
|
+
{ name: 'No, I need help setting it up', value: 'no' }
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
]);
|
|
72
|
+
if (hasProject.hasProject === 'no') {
|
|
73
|
+
console.log('\n📚 Setting up PatternFly Seed:\n');
|
|
74
|
+
console.log('1. Fork the PatternFly Seed repository:');
|
|
75
|
+
console.log(' Visit: https://github.com/patternfly/patternfly-react-seed');
|
|
76
|
+
console.log(' Click "Fork" in the top right\n');
|
|
77
|
+
console.log('2. Clone your fork locally:');
|
|
78
|
+
console.log(' git clone https://github.com/YOUR_USERNAME/patternfly-react-seed.git');
|
|
79
|
+
console.log(' cd patternfly-react-seed\n');
|
|
80
|
+
console.log('3. Install dependencies:');
|
|
81
|
+
console.log(' npm install\n');
|
|
82
|
+
console.log('4. Run this setup again:');
|
|
83
|
+
console.log(' npx hale-commenting-system init\n');
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
// Check if it's actually a PF Seed project
|
|
87
|
+
if (!(0, detect_1.detectPatternFlySeed)()) {
|
|
88
|
+
console.error('❌ Error: This doesn\'t appear to be a PatternFly Seed project.');
|
|
89
|
+
console.error('Please run this command from a PatternFly Seed project directory.');
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
// Detect project setup type
|
|
93
|
+
const gitInfo = (0, detect_1.detectGitRemote)();
|
|
94
|
+
const setupType = (0, detect_1.detectProjectSetup)();
|
|
95
|
+
let projectSetup = 'unknown';
|
|
96
|
+
let owner = gitInfo?.owner;
|
|
97
|
+
let repo = gitInfo?.repo;
|
|
98
|
+
if (setupType === 'none' || !gitInfo) {
|
|
99
|
+
// No git remote - need to set up
|
|
100
|
+
const setupAnswer = await inquirer_1.default.prompt([
|
|
101
|
+
{
|
|
102
|
+
type: 'list',
|
|
103
|
+
name: 'setupType',
|
|
104
|
+
message: 'How did you set up your PatternFly Seed project?',
|
|
105
|
+
choices: [
|
|
106
|
+
{ name: 'I forked the PatternFly Seed repo on GitHub', value: 'forked' },
|
|
107
|
+
{ name: 'I cloned the PatternFly Seed repo locally', value: 'cloned' },
|
|
108
|
+
{ name: 'I\'m not sure', value: 'unknown' }
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
]);
|
|
112
|
+
projectSetup = setupAnswer.setupType;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
projectSetup = setupType;
|
|
116
|
+
}
|
|
117
|
+
// Handle different setup types
|
|
118
|
+
if (projectSetup === 'forked') {
|
|
119
|
+
// Ask for owner/repo if not detected
|
|
120
|
+
if (!owner || !repo) {
|
|
121
|
+
const forkAnswers = await inquirer_1.default.prompt([
|
|
122
|
+
{
|
|
123
|
+
type: 'input',
|
|
124
|
+
name: 'owner',
|
|
125
|
+
message: 'What is your GitHub username or organization name?',
|
|
126
|
+
default: owner,
|
|
127
|
+
validate: (input) => {
|
|
128
|
+
if (!input.trim())
|
|
129
|
+
return 'Owner is required';
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
type: 'input',
|
|
135
|
+
name: 'repo',
|
|
136
|
+
message: 'What is the name of your forked repository?',
|
|
137
|
+
default: repo,
|
|
138
|
+
validate: (input) => {
|
|
139
|
+
if (!input.trim())
|
|
140
|
+
return 'Repository name is required';
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]);
|
|
145
|
+
owner = forkAnswers.owner;
|
|
146
|
+
repo = forkAnswers.repo;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
console.log(`\n✅ Detected repository: ${owner}/${repo}\n`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else if (projectSetup === 'cloned') {
|
|
153
|
+
console.log('\n📝 Since you cloned the repo, you\'ll need to create your own GitHub repository.\n');
|
|
154
|
+
console.log('Steps:');
|
|
155
|
+
console.log('1. Create a new repository on GitHub');
|
|
156
|
+
console.log('2. Add it as a remote: git remote add origin <your-repo-url>');
|
|
157
|
+
console.log('3. Push your code: git push -u origin main\n');
|
|
158
|
+
const hasCreated = await inquirer_1.default.prompt([
|
|
159
|
+
{
|
|
160
|
+
type: 'confirm',
|
|
161
|
+
name: 'created',
|
|
162
|
+
message: 'Have you created and pushed to your GitHub repository?',
|
|
163
|
+
default: false
|
|
164
|
+
}
|
|
165
|
+
]);
|
|
166
|
+
if (!hasCreated.created) {
|
|
167
|
+
console.log('\nPlease complete the steps above and run this setup again.');
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
// Ask for owner/repo
|
|
171
|
+
const repoAnswers = await inquirer_1.default.prompt([
|
|
172
|
+
{
|
|
173
|
+
type: 'input',
|
|
174
|
+
name: 'owner',
|
|
175
|
+
message: 'What is your GitHub username or organization name?',
|
|
176
|
+
validate: (input) => {
|
|
177
|
+
if (!input.trim())
|
|
178
|
+
return 'Owner is required';
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
type: 'input',
|
|
184
|
+
name: 'repo',
|
|
185
|
+
message: 'What is the name of your GitHub repository?',
|
|
186
|
+
validate: (input) => {
|
|
187
|
+
if (!input.trim())
|
|
188
|
+
return 'Repository name is required';
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
]);
|
|
193
|
+
owner = repoAnswers.owner;
|
|
194
|
+
repo = repoAnswers.repo;
|
|
195
|
+
}
|
|
196
|
+
else if (projectSetup === 'unknown') {
|
|
197
|
+
// Try to detect from git
|
|
198
|
+
if (gitInfo && gitInfo.owner && gitInfo.repo) {
|
|
199
|
+
console.log(`\n✅ Detected repository: ${gitInfo.owner}/${gitInfo.repo}\n`);
|
|
200
|
+
owner = gitInfo.owner;
|
|
201
|
+
repo = gitInfo.repo;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// Ask for owner/repo
|
|
205
|
+
const repoAnswers = await inquirer_1.default.prompt([
|
|
206
|
+
{
|
|
207
|
+
type: 'input',
|
|
208
|
+
name: 'owner',
|
|
209
|
+
message: 'What is your GitHub username or organization name?',
|
|
210
|
+
validate: (input) => {
|
|
211
|
+
if (!input.trim())
|
|
212
|
+
return 'Owner is required';
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
type: 'input',
|
|
218
|
+
name: 'repo',
|
|
219
|
+
message: 'What is the name of your GitHub repository?',
|
|
220
|
+
validate: (input) => {
|
|
221
|
+
if (!input.trim())
|
|
222
|
+
return 'Repository name is required';
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
]);
|
|
227
|
+
owner = repoAnswers.owner;
|
|
228
|
+
repo = repoAnswers.repo;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// Step 2: GitHub OAuth Setup
|
|
232
|
+
console.log('\n📦 Step 2: GitHub OAuth Setup\n');
|
|
233
|
+
console.log('To sync comments with GitHub Issues, we need to authenticate with GitHub.');
|
|
234
|
+
console.log('This requires creating a GitHub OAuth App.\n');
|
|
235
|
+
console.log('Instructions:');
|
|
236
|
+
console.log('1. Visit: https://github.com/settings/developers');
|
|
237
|
+
console.log('2. Click "New OAuth App"');
|
|
238
|
+
console.log('3. Fill in the form:');
|
|
239
|
+
console.log(' - Application name: Your app name (e.g., "My Design Comments")');
|
|
240
|
+
console.log(' - Homepage URL: http://localhost:9000 (or your dev server URL)');
|
|
241
|
+
console.log(' - Authorization callback URL: http://localhost:9000/api/github-oauth-callback');
|
|
242
|
+
console.log('4. Click "Register application"');
|
|
243
|
+
console.log('5. Copy the Client ID and generate a Client Secret\n');
|
|
50
244
|
const githubAnswers = await inquirer_1.default.prompt([
|
|
51
245
|
{
|
|
52
246
|
type: 'input',
|
|
@@ -62,50 +256,39 @@ async function runOnboarding() {
|
|
|
62
256
|
type: 'password',
|
|
63
257
|
name: 'clientSecret',
|
|
64
258
|
message: 'GitHub OAuth Client Secret:',
|
|
259
|
+
mask: '*',
|
|
65
260
|
validate: (input) => {
|
|
66
261
|
if (!input.trim())
|
|
67
262
|
return 'Client Secret is required';
|
|
68
263
|
return true;
|
|
69
264
|
}
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
type: 'input',
|
|
73
|
-
name: 'owner',
|
|
74
|
-
message: 'GitHub Owner (username or org):',
|
|
75
|
-
validate: (input) => {
|
|
76
|
-
if (!input.trim())
|
|
77
|
-
return 'Owner is required';
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
type: 'input',
|
|
83
|
-
name: 'repo',
|
|
84
|
-
message: 'GitHub Repository name:',
|
|
85
|
-
validate: (input) => {
|
|
86
|
-
if (!input.trim())
|
|
87
|
-
return 'Repository name is required';
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
265
|
}
|
|
91
266
|
]);
|
|
92
267
|
// Validate GitHub credentials
|
|
93
268
|
console.log('\n🔍 Validating GitHub credentials...');
|
|
94
|
-
const githubValid = await validators.validateGitHubCredentials(githubAnswers.clientId, githubAnswers.clientSecret,
|
|
269
|
+
const githubValid = await validators.validateGitHubCredentials(githubAnswers.clientId, githubAnswers.clientSecret, owner, repo);
|
|
95
270
|
if (!githubValid) {
|
|
96
271
|
console.error('❌ GitHub validation failed. Please check your credentials and try again.');
|
|
97
272
|
process.exit(1);
|
|
98
273
|
}
|
|
99
274
|
console.log('✅ GitHub credentials validated!\n');
|
|
100
|
-
// Step
|
|
101
|
-
console.log('🎫 Step
|
|
102
|
-
console.log('
|
|
103
|
-
console.log('
|
|
275
|
+
// Step 3: Jira Setup
|
|
276
|
+
console.log('🎫 Step 3: Jira Setup\n');
|
|
277
|
+
console.log('You can link Jira tickets to pages in your design. This helps connect');
|
|
278
|
+
console.log('design work to development tracking.\n');
|
|
279
|
+
console.log('For Red Hat Jira, generate a Personal Access Token:');
|
|
280
|
+
console.log('1. Visit: https://issues.redhat.com/secure/ViewProfile.jspa');
|
|
281
|
+
console.log('2. Click "Personal Access Tokens" in the left sidebar');
|
|
282
|
+
console.log('3. Click "Create token"');
|
|
283
|
+
console.log('4. Give it a name (e.g., "Hale Commenting System")');
|
|
284
|
+
console.log('5. Remove expiration (or set a long expiration)');
|
|
285
|
+
console.log('6. Click "Create" and copy the token\n');
|
|
286
|
+
console.log('Note: We use Bearer token authentication (no email required for Red Hat Jira).\n');
|
|
104
287
|
const jiraAnswers = await inquirer_1.default.prompt([
|
|
105
288
|
{
|
|
106
289
|
type: 'input',
|
|
107
290
|
name: 'baseUrl',
|
|
108
|
-
message: 'Jira Base URL:',
|
|
291
|
+
message: 'Jira Base URL (press Enter for Red Hat Jira):',
|
|
109
292
|
default: 'https://issues.redhat.com',
|
|
110
293
|
validate: (input) => {
|
|
111
294
|
if (!input.trim())
|
|
@@ -119,16 +302,11 @@ async function runOnboarding() {
|
|
|
119
302
|
}
|
|
120
303
|
}
|
|
121
304
|
},
|
|
122
|
-
{
|
|
123
|
-
type: 'input',
|
|
124
|
-
name: 'email',
|
|
125
|
-
message: 'Jira Email (optional, leave blank if using Bearer token):',
|
|
126
|
-
default: ''
|
|
127
|
-
},
|
|
128
305
|
{
|
|
129
306
|
type: 'password',
|
|
130
307
|
name: 'apiToken',
|
|
131
308
|
message: 'Jira API Token:',
|
|
309
|
+
mask: '*',
|
|
132
310
|
validate: (input) => {
|
|
133
311
|
if (!input.trim())
|
|
134
312
|
return 'API Token is required';
|
|
@@ -138,33 +316,34 @@ async function runOnboarding() {
|
|
|
138
316
|
]);
|
|
139
317
|
// Validate Jira credentials
|
|
140
318
|
console.log('\n🔍 Validating Jira credentials...');
|
|
141
|
-
const jiraValid = await validators.validateJiraCredentials(jiraAnswers.baseUrl, jiraAnswers.apiToken,
|
|
319
|
+
const jiraValid = await validators.validateJiraCredentials(jiraAnswers.baseUrl, jiraAnswers.apiToken, undefined // No email for Bearer token
|
|
320
|
+
);
|
|
142
321
|
if (!jiraValid) {
|
|
143
322
|
console.error('❌ Jira validation failed. Please check your credentials and try again.');
|
|
144
323
|
process.exit(1);
|
|
145
324
|
}
|
|
146
325
|
console.log('✅ Jira credentials validated!\n');
|
|
147
|
-
// Step
|
|
148
|
-
console.log('📝 Step
|
|
326
|
+
// Step 4: Generate files
|
|
327
|
+
console.log('📝 Step 4: Generating configuration files...\n');
|
|
149
328
|
await generators.generateFiles({
|
|
150
329
|
github: {
|
|
151
330
|
clientId: githubAnswers.clientId,
|
|
152
331
|
clientSecret: githubAnswers.clientSecret,
|
|
153
|
-
owner:
|
|
154
|
-
repo:
|
|
332
|
+
owner: owner,
|
|
333
|
+
repo: repo
|
|
155
334
|
},
|
|
156
335
|
jira: {
|
|
157
336
|
baseUrl: jiraAnswers.baseUrl,
|
|
158
337
|
apiToken: jiraAnswers.apiToken,
|
|
159
|
-
email:
|
|
338
|
+
email: undefined // Not used for Bearer token
|
|
160
339
|
}
|
|
161
340
|
});
|
|
162
|
-
// Step
|
|
163
|
-
console.log('🔧 Step
|
|
341
|
+
// Step 5: Integrate into project
|
|
342
|
+
console.log('🔧 Step 5: Integrating into PatternFly Seed project...\n');
|
|
164
343
|
await generators.integrateIntoProject();
|
|
165
344
|
console.log('\n✅ Setup complete!');
|
|
166
345
|
console.log('\nNext steps:');
|
|
167
|
-
console.log('1.
|
|
168
|
-
console.log('
|
|
169
|
-
console.log('
|
|
346
|
+
console.log('1. Start your dev server: npm run start:dev');
|
|
347
|
+
console.log(' (If it\'s already running, restart it to load the new configuration)');
|
|
348
|
+
console.log('2. The commenting system will be available in your app!\n');
|
|
170
349
|
}
|