@fractary/faber-cli 1.3.3 ā 1.3.4
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BpC;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAehD;AAwYD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C"}
|
|
@@ -5,7 +5,7 @@ import { Command } from 'commander';
|
|
|
5
5
|
import * as readline from 'readline/promises';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import fs from 'fs/promises';
|
|
8
|
-
import { generateAppManifest,
|
|
8
|
+
import { generateAppManifest, generateManifestHtml, exchangeCodeForCredentials, validateAppCredentials, getInstallationId, savePrivateKey, } from '../../lib/github-app-setup.js';
|
|
9
9
|
import { parseCodeFromUrl, validateManifestCode, detectGitHubContext, isGitRepository, } from '../../utils/github-manifest.js';
|
|
10
10
|
/**
|
|
11
11
|
* Create the auth setup command
|
|
@@ -26,7 +26,9 @@ export function createAuthSetupCommand() {
|
|
|
26
26
|
* Run the setup flow
|
|
27
27
|
*/
|
|
28
28
|
async function runSetup(options) {
|
|
29
|
-
|
|
29
|
+
// Force output to flush immediately
|
|
30
|
+
process.stdout.write('\nš GitHub App Authentication Setup\n\n');
|
|
31
|
+
process.stdout.write('Initializing...\n');
|
|
30
32
|
// Step 1: Detect or prompt for GitHub context
|
|
31
33
|
let org = options.org;
|
|
32
34
|
let repo = options.repo;
|
|
@@ -73,22 +75,65 @@ async function runSetup(options) {
|
|
|
73
75
|
console.log(JSON.stringify(manifest, null, 2));
|
|
74
76
|
console.log();
|
|
75
77
|
}
|
|
76
|
-
// Step 4:
|
|
78
|
+
// Step 4: Generate and open manifest HTML
|
|
77
79
|
console.log(chalk.bold('ā'.repeat(60)));
|
|
78
80
|
console.log(chalk.bold('š STEP 1: Create the GitHub App'));
|
|
79
81
|
console.log(chalk.bold('ā'.repeat(60)));
|
|
80
82
|
console.log();
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
const htmlContent = generateManifestHtml(manifest, org);
|
|
84
|
+
const os = await import('os');
|
|
85
|
+
const path = await import('path');
|
|
86
|
+
// Detect WSL and use Windows-accessible temp directory
|
|
87
|
+
let tmpDir = os.tmpdir();
|
|
88
|
+
const isWsl = process.platform === 'linux' && os.release().toLowerCase().includes('microsoft');
|
|
89
|
+
if (isWsl) {
|
|
90
|
+
// Use current working directory for WSL (it's usually in /mnt/c which is Windows-accessible)
|
|
91
|
+
tmpDir = process.cwd();
|
|
92
|
+
}
|
|
93
|
+
const htmlPath = path.join(tmpDir, `faber-github-app-${Date.now()}.html`);
|
|
94
|
+
try {
|
|
95
|
+
await fs.writeFile(htmlPath, htmlContent, 'utf-8');
|
|
96
|
+
console.log(chalk.gray(`ā Generated manifest form\n`));
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error(chalk.red('Failed to create manifest file'));
|
|
100
|
+
if (error instanceof Error) {
|
|
101
|
+
console.error(chalk.red(error.message));
|
|
102
|
+
}
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
console.log('Opening GitHub App creation page in your browser...\n');
|
|
106
|
+
// Open HTML file in default browser (safe - we control the path)
|
|
107
|
+
const { execFile } = await import('child_process');
|
|
108
|
+
const { promisify } = await import('util');
|
|
109
|
+
const execFileAsync = promisify(execFile);
|
|
110
|
+
try {
|
|
111
|
+
if (process.platform === 'darwin') {
|
|
112
|
+
await execFileAsync('open', [htmlPath]);
|
|
113
|
+
}
|
|
114
|
+
else if (process.platform === 'win32') {
|
|
115
|
+
// Windows requires cmd /c start for file associations
|
|
116
|
+
await execFileAsync('cmd', ['/c', 'start', '', htmlPath]);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Linux/Unix
|
|
120
|
+
await execFileAsync('xdg-open', [htmlPath]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.log(chalk.yellow('\nā ļø Could not open browser automatically.'));
|
|
125
|
+
console.log(chalk.yellow(`Please open this file manually:\n ${htmlPath}\n`));
|
|
126
|
+
}
|
|
127
|
+
console.log(chalk.bold('In your browser:'));
|
|
128
|
+
console.log(' 1. Review the app permissions');
|
|
129
|
+
console.log(' 2. Click the green "Create GitHub App ā" button');
|
|
130
|
+
console.log(' 3. GitHub will ask you to confirm - click "Create GitHub App" again');
|
|
131
|
+
console.log(' 4. After creation, look at the browser URL bar\n');
|
|
87
132
|
const rl1 = readline.createInterface({
|
|
88
133
|
input: process.stdin,
|
|
89
134
|
output: process.stdout,
|
|
90
135
|
});
|
|
91
|
-
await rl1.question('Press Enter
|
|
136
|
+
await rl1.question('Press Enter after you have clicked the Create button in your browser...');
|
|
92
137
|
rl1.close();
|
|
93
138
|
// Step 5: Prompt for code
|
|
94
139
|
console.log();
|
|
@@ -81,10 +81,21 @@ export interface AppCredentials {
|
|
|
81
81
|
*/
|
|
82
82
|
export declare function generateAppManifest(config: ManifestConfig): GitHubAppManifest;
|
|
83
83
|
/**
|
|
84
|
-
* Generate
|
|
84
|
+
* Generate HTML content for manifest submission
|
|
85
85
|
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
86
|
+
* The GitHub App Manifest flow requires POSTing a form to GitHub.
|
|
87
|
+
* Since CLI cannot POST directly, we generate an HTML file that the user
|
|
88
|
+
* opens in their browser and clicks to submit.
|
|
89
|
+
*
|
|
90
|
+
* @param manifest - The app manifest to submit
|
|
91
|
+
* @param organization - GitHub organization name
|
|
92
|
+
* @returns HTML content ready to save to file
|
|
93
|
+
*/
|
|
94
|
+
export declare function generateManifestHtml(manifest: GitHubAppManifest, organization: string): string;
|
|
95
|
+
/**
|
|
96
|
+
* Generate GitHub App creation URL (legacy - prefer generateManifestHtml)
|
|
97
|
+
*
|
|
98
|
+
* @deprecated Use generateManifestHtml() instead for proper manifest flow
|
|
88
99
|
*/
|
|
89
100
|
export declare function getManifestCreationUrl(manifest: GitHubAppManifest): string;
|
|
90
101
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-app-setup.d.ts","sourceRoot":"","sources":["../../src/lib/github-app-setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,mBAAmB,EAAE;QACnB,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAC3B,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QACzB,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;QAChC,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE;QACX,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAqBD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"github-app-setup.d.ts","sourceRoot":"","sources":["../../src/lib/github-app-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ export function generateAppManifest(config) {
|
|
|
19
19
|
hook_attributes: {
|
|
20
20
|
url: 'https://example.com/webhook', // Required but not used
|
|
21
21
|
},
|
|
22
|
+
redirect_url: 'https://example.com', // Required by GitHub for manifest flow
|
|
22
23
|
description: 'FABER CLI for automated workflow management, issue tracking, and repository operations.',
|
|
23
24
|
public: false,
|
|
24
25
|
default_permissions: {
|
|
@@ -31,13 +32,136 @@ export function generateAppManifest(config) {
|
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
34
|
-
* Generate
|
|
35
|
+
* Generate HTML content for manifest submission
|
|
35
36
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
37
|
+
* The GitHub App Manifest flow requires POSTing a form to GitHub.
|
|
38
|
+
* Since CLI cannot POST directly, we generate an HTML file that the user
|
|
39
|
+
* opens in their browser and clicks to submit.
|
|
40
|
+
*
|
|
41
|
+
* @param manifest - The app manifest to submit
|
|
42
|
+
* @param organization - GitHub organization name
|
|
43
|
+
* @returns HTML content ready to save to file
|
|
44
|
+
*/
|
|
45
|
+
export function generateManifestHtml(manifest, organization) {
|
|
46
|
+
const manifestJson = JSON.stringify(manifest, null, 2);
|
|
47
|
+
const targetUrl = organization
|
|
48
|
+
? `https://github.com/organizations/${organization}/settings/apps/new`
|
|
49
|
+
: 'https://github.com/settings/apps/new';
|
|
50
|
+
return `<!DOCTYPE html>
|
|
51
|
+
<html lang="en">
|
|
52
|
+
<head>
|
|
53
|
+
<meta charset="UTF-8">
|
|
54
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
55
|
+
<title>FABER CLI - Create GitHub App</title>
|
|
56
|
+
<style>
|
|
57
|
+
body {
|
|
58
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
59
|
+
max-width: 600px;
|
|
60
|
+
margin: 50px auto;
|
|
61
|
+
padding: 20px;
|
|
62
|
+
background: #f6f8fa;
|
|
63
|
+
}
|
|
64
|
+
.container {
|
|
65
|
+
background: white;
|
|
66
|
+
border-radius: 8px;
|
|
67
|
+
padding: 30px;
|
|
68
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
69
|
+
}
|
|
70
|
+
h1 {
|
|
71
|
+
margin-top: 0;
|
|
72
|
+
color: #24292f;
|
|
73
|
+
}
|
|
74
|
+
.info {
|
|
75
|
+
background: #dff6ff;
|
|
76
|
+
border-left: 4px solid #0969da;
|
|
77
|
+
padding: 12px 16px;
|
|
78
|
+
margin: 20px 0;
|
|
79
|
+
border-radius: 4px;
|
|
80
|
+
}
|
|
81
|
+
button {
|
|
82
|
+
background: #2da44e;
|
|
83
|
+
color: white;
|
|
84
|
+
border: none;
|
|
85
|
+
padding: 12px 24px;
|
|
86
|
+
font-size: 16px;
|
|
87
|
+
border-radius: 6px;
|
|
88
|
+
cursor: pointer;
|
|
89
|
+
width: 100%;
|
|
90
|
+
margin-top: 20px;
|
|
91
|
+
}
|
|
92
|
+
button:hover {
|
|
93
|
+
background: #2c974b;
|
|
94
|
+
}
|
|
95
|
+
.manifest {
|
|
96
|
+
background: #f6f8fa;
|
|
97
|
+
border: 1px solid #d0d7de;
|
|
98
|
+
border-radius: 6px;
|
|
99
|
+
padding: 16px;
|
|
100
|
+
margin: 16px 0;
|
|
101
|
+
overflow-x: auto;
|
|
102
|
+
}
|
|
103
|
+
.manifest pre {
|
|
104
|
+
margin: 0;
|
|
105
|
+
font-family: 'SF Mono', Monaco, monospace;
|
|
106
|
+
font-size: 12px;
|
|
107
|
+
}
|
|
108
|
+
.instructions {
|
|
109
|
+
color: #57606a;
|
|
110
|
+
margin: 16px 0;
|
|
111
|
+
line-height: 1.6;
|
|
112
|
+
}
|
|
113
|
+
</style>
|
|
114
|
+
</head>
|
|
115
|
+
<body>
|
|
116
|
+
<div class="container">
|
|
117
|
+
<h1>š Create FABER GitHub App</h1>
|
|
118
|
+
|
|
119
|
+
<div class="info">
|
|
120
|
+
<strong>Step 1 of 2:</strong> Click the button below to create your GitHub App
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div class="instructions">
|
|
124
|
+
<p>This will create a GitHub App for <strong>${organization}</strong> with the following permissions:</p>
|
|
125
|
+
<ul>
|
|
126
|
+
<li>Contents: Write</li>
|
|
127
|
+
<li>Issues: Write</li>
|
|
128
|
+
<li>Pull Requests: Write</li>
|
|
129
|
+
<li>Metadata: Read</li>
|
|
130
|
+
</ul>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<details>
|
|
134
|
+
<summary style="cursor: pointer; color: #0969da;">Show manifest JSON</summary>
|
|
135
|
+
<div class="manifest">
|
|
136
|
+
<pre>${manifestJson}</pre>
|
|
137
|
+
</div>
|
|
138
|
+
</details>
|
|
139
|
+
|
|
140
|
+
<form action="${targetUrl}" method="post" id="manifestForm">
|
|
141
|
+
<input type="hidden" name="manifest" value='${manifestJson.replace(/'/g, ''')}'>
|
|
142
|
+
<button type="submit">Create GitHub App ā</button>
|
|
143
|
+
</form>
|
|
144
|
+
|
|
145
|
+
<div class="instructions" style="margin-top: 20px; font-size: 14px;">
|
|
146
|
+
<p><strong>What happens next:</strong></p>
|
|
147
|
+
<ol>
|
|
148
|
+
<li>GitHub will show you the app details for review</li>
|
|
149
|
+
<li>Click "Create GitHub App" to confirm</li>
|
|
150
|
+
<li>GitHub will redirect you to a URL with a code</li>
|
|
151
|
+
<li>Copy the code and paste it into the CLI</li>
|
|
152
|
+
</ol>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</body>
|
|
156
|
+
</html>`;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Generate GitHub App creation URL (legacy - prefer generateManifestHtml)
|
|
160
|
+
*
|
|
161
|
+
* @deprecated Use generateManifestHtml() instead for proper manifest flow
|
|
38
162
|
*/
|
|
39
163
|
export function getManifestCreationUrl(manifest) {
|
|
40
|
-
// GitHub App creation page
|
|
164
|
+
// For backward compatibility, return the basic GitHub App creation page
|
|
41
165
|
return 'https://github.com/settings/apps/new';
|
|
42
166
|
}
|
|
43
167
|
/**
|