@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;AA4BpC;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAehD;AAwVD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C"}
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, getManifestCreationUrl, exchangeCodeForCredentials, validateAppCredentials, getInstallationId, savePrivateKey, formatPermissionsDisplay, } from '../../lib/github-app-setup.js';
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
- console.log(chalk.bold('\nšŸ” GitHub App Authentication Setup\n'));
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: Display creation instructions
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 creationUrl = getManifestCreationUrl(manifest);
82
- console.log('Please click this URL to create your GitHub App:\n');
83
- console.log(chalk.cyan.bold(`šŸ‘‰ ${creationUrl}\n`));
84
- console.log('The app will request these permissions:');
85
- console.log(formatPermissionsDisplay(manifest));
86
- console.log();
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 when you have created the app...');
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 GitHub App creation URL
84
+ * Generate HTML content for manifest submission
85
85
  *
86
- * Note: GitHub does not support pre-filled manifests via URL parameters.
87
- * Users must manually fill in the form or use the manifest conversion API.
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":"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"}
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,CAqB7E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,iBAAiB,EAC3B,YAAY,EAAE,MAAM,GACnB,MAAM,CAiHR;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAG1E;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,0BAA0B,CAAC,CAuCrC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,0BAA0B,GAAG,IAAI,CAoBjF;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAiDjB;AA2BD;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CA4CjB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAY5E"}
@@ -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 GitHub App creation URL
35
+ * Generate HTML content for manifest submission
35
36
  *
36
- * Note: GitHub does not support pre-filled manifests via URL parameters.
37
- * Users must manually fill in the form or use the manifest conversion API.
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, '&#39;')}'>
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
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fractary/faber-cli",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "FABER CLI - Command-line interface for FABER development toolkit",
5
5
  "main": "dist/index.js",
6
6
  "bin": {