@fractary/faber-cli 1.3.2 → 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.
package/README.md CHANGED
@@ -16,7 +16,40 @@ npx @fractary/faber-cli --help
16
16
 
17
17
  ## Quick Start
18
18
 
19
- ### Initialize a FABER project
19
+ ### 1. Install
20
+
21
+ ```bash
22
+ npm install -g @fractary/faber-cli
23
+ ```
24
+
25
+ Or use directly with `npx`:
26
+
27
+ ```bash
28
+ npx @fractary/faber-cli --help
29
+ ```
30
+
31
+ ### 2. Authenticate with GitHub
32
+
33
+ **Option A: Automated Setup (Recommended)**
34
+
35
+ ```bash
36
+ cd your-project
37
+ fractary-faber auth setup
38
+ ```
39
+
40
+ This command will:
41
+ 1. Detect your GitHub organization and repository
42
+ 2. Show you a URL to create a GitHub App
43
+ 3. Guide you through copying the authorization code
44
+ 4. Automatically configure FABER CLI
45
+
46
+ All in ~30 seconds!
47
+
48
+ **Option B: Manual Setup**
49
+
50
+ See [GitHub App Setup Guide](../docs/github-app-setup.md) for detailed manual instructions.
51
+
52
+ ### 3. Initialize a FABER project
20
53
 
21
54
  ```bash
22
55
  fractary-faber init
@@ -191,14 +224,78 @@ All commands support:
191
224
  - `--debug` - Enable debug output
192
225
  - `--help` - Show command help
193
226
 
194
- ## Environment Variables
227
+ ## Authentication
228
+
229
+ ### GitHub App Authentication (Recommended)
195
230
 
196
- Configure providers via environment variables:
231
+ For enhanced security, audit trails, and enterprise readiness, use GitHub App authentication instead of Personal Access Tokens.
232
+
233
+ **Quick Setup (Automated):**
234
+
235
+ ```bash
236
+ fractary-faber auth setup
237
+ ```
238
+
239
+ This command will guide you through creating and configuring a GitHub App in ~30 seconds.
240
+
241
+ **Manual Configuration (`.fractary/settings.json`):**
242
+ ```json
243
+ {
244
+ "github": {
245
+ "organization": "your-org",
246
+ "project": "your-repo",
247
+ "app": {
248
+ "id": "123456",
249
+ "installation_id": "12345678",
250
+ "private_key_path": "~/.github/faber-app.pem"
251
+ }
252
+ }
253
+ }
254
+ ```
255
+
256
+ **For CI/CD (environment variable):**
257
+ ```json
258
+ {
259
+ "github": {
260
+ "organization": "your-org",
261
+ "project": "your-repo",
262
+ "app": {
263
+ "id": "123456",
264
+ "installation_id": "12345678",
265
+ "private_key_env_var": "GITHUB_APP_PRIVATE_KEY"
266
+ }
267
+ }
268
+ }
269
+ ```
270
+
271
+ ```bash
272
+ export GITHUB_APP_PRIVATE_KEY=$(cat ~/.github/faber-app.pem | base64)
273
+ ```
274
+
275
+ **See detailed setup guide:** [docs/github-app-setup.md](../docs/github-app-setup.md)
276
+
277
+ ### Personal Access Token (Legacy)
278
+
279
+ Still supported for backward compatibility:
197
280
 
198
281
  ```bash
199
- # GitHub
200
282
  export GITHUB_TOKEN=<token>
283
+ ```
201
284
 
285
+ Or in `.fractary/settings.json`:
286
+ ```json
287
+ {
288
+ "github": {
289
+ "token": "ghp_xxxxxxxxxxxx",
290
+ "organization": "your-org",
291
+ "project": "your-repo"
292
+ }
293
+ }
294
+ ```
295
+
296
+ ### Other Providers
297
+
298
+ ```bash
202
299
  # Jira
203
300
  export JIRA_BASE_URL=<url>
204
301
  export JIRA_USERNAME=<username>
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Authentication setup command
3
+ */
4
+ import { Command } from 'commander';
5
+ /**
6
+ * Create the auth setup command
7
+ */
8
+ export declare function createAuthSetupCommand(): Command;
9
+ /**
10
+ * Create the main auth command
11
+ */
12
+ export declare function createAuthCommand(): Command;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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;AA6BpC;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAehD;AAwYD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C"}
@@ -0,0 +1,336 @@
1
+ /**
2
+ * Authentication setup command
3
+ */
4
+ import { Command } from 'commander';
5
+ import * as readline from 'readline/promises';
6
+ import chalk from 'chalk';
7
+ import fs from 'fs/promises';
8
+ import { generateAppManifest, generateManifestHtml, exchangeCodeForCredentials, validateAppCredentials, getInstallationId, savePrivateKey, } from '../../lib/github-app-setup.js';
9
+ import { parseCodeFromUrl, validateManifestCode, detectGitHubContext, isGitRepository, } from '../../utils/github-manifest.js';
10
+ /**
11
+ * Create the auth setup command
12
+ */
13
+ export function createAuthSetupCommand() {
14
+ return new Command('setup')
15
+ .description('Set up GitHub App authentication for FABER CLI')
16
+ .option('--org <name>', 'GitHub organization name')
17
+ .option('--repo <name>', 'GitHub repository name')
18
+ .option('--config-path <path>', 'Path to config file', '.fractary/settings.json')
19
+ .option('--show-manifest', 'Display manifest JSON before setup')
20
+ .option('--no-save', 'Display credentials without saving')
21
+ .action(async (options) => {
22
+ await runSetup(options);
23
+ });
24
+ }
25
+ /**
26
+ * Run the setup flow
27
+ */
28
+ async function runSetup(options) {
29
+ // Force output to flush immediately
30
+ process.stdout.write('\n🔐 GitHub App Authentication Setup\n\n');
31
+ process.stdout.write('Initializing...\n');
32
+ // Step 1: Detect or prompt for GitHub context
33
+ let org = options.org;
34
+ let repo = options.repo;
35
+ if (!org || !repo) {
36
+ if (!isGitRepository()) {
37
+ console.error(chalk.red('❌ Error: Not a git repository\n') +
38
+ 'Run this command from a git repository or provide --org and --repo flags.');
39
+ process.exit(1);
40
+ }
41
+ const context = detectGitHubContext();
42
+ if (!context) {
43
+ console.error(chalk.red('❌ Error: Could not detect GitHub organization/repository\n') +
44
+ 'Please provide --org and --repo flags.');
45
+ process.exit(1);
46
+ }
47
+ org = context.org;
48
+ repo = context.repo;
49
+ }
50
+ console.log('Detected GitHub context:');
51
+ console.log(` Organization: ${chalk.cyan(org)}`);
52
+ console.log(` Repository: ${chalk.cyan(repo)}\n`);
53
+ // Step 2: Check if already configured
54
+ const configPath = options.configPath || '.fractary/settings.json';
55
+ const existingConfig = await checkExistingConfig(configPath);
56
+ if (existingConfig) {
57
+ console.log(chalk.yellow('⚠️ GitHub App already configured in ' + configPath));
58
+ console.log('This will create a new app and replace the existing configuration.\n');
59
+ const rl = readline.createInterface({
60
+ input: process.stdin,
61
+ output: process.stdout,
62
+ });
63
+ const answer = await rl.question('Continue? (y/N): ');
64
+ rl.close();
65
+ if (answer.toLowerCase() !== 'y') {
66
+ console.log('Setup cancelled.');
67
+ return;
68
+ }
69
+ console.log();
70
+ }
71
+ // Step 3: Generate manifest
72
+ const manifest = generateAppManifest({ organization: org, repository: repo });
73
+ if (options.showManifest) {
74
+ console.log(chalk.bold('\n📋 App Manifest:\n'));
75
+ console.log(JSON.stringify(manifest, null, 2));
76
+ console.log();
77
+ }
78
+ // Step 4: Generate and open manifest HTML
79
+ console.log(chalk.bold('━'.repeat(60)));
80
+ console.log(chalk.bold('📋 STEP 1: Create the GitHub App'));
81
+ console.log(chalk.bold('━'.repeat(60)));
82
+ 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');
132
+ const rl1 = readline.createInterface({
133
+ input: process.stdin,
134
+ output: process.stdout,
135
+ });
136
+ await rl1.question('Press Enter after you have clicked the Create button in your browser...');
137
+ rl1.close();
138
+ // Step 5: Prompt for code
139
+ console.log();
140
+ console.log(chalk.bold('━'.repeat(60)));
141
+ console.log(chalk.bold('📋 STEP 2: Copy the code from the redirect URL'));
142
+ console.log(chalk.bold('━'.repeat(60)));
143
+ console.log();
144
+ console.log('After creating the app, GitHub will redirect you to a URL like:');
145
+ console.log(chalk.gray('https://github.com/settings/apps/your-app?code=XXXXXXXXXXXXX'));
146
+ console.log();
147
+ console.log('Copy the entire code from the URL bar and paste it below:\n');
148
+ let code = null;
149
+ let attempts = 0;
150
+ const maxAttempts = 3;
151
+ const rl2 = readline.createInterface({
152
+ input: process.stdin,
153
+ output: process.stdout,
154
+ });
155
+ while (!code && attempts < maxAttempts) {
156
+ const input = await rl2.question(chalk.bold('Code: '));
157
+ // Try to parse code from URL or use directly
158
+ code = parseCodeFromUrl(input);
159
+ if (!code || !validateManifestCode(code)) {
160
+ attempts++;
161
+ if (attempts < maxAttempts) {
162
+ console.log(chalk.red(`\n❌ Invalid code format. Please try again (${maxAttempts - attempts} attempts remaining).\n`));
163
+ code = null;
164
+ }
165
+ }
166
+ }
167
+ rl2.close();
168
+ if (!code) {
169
+ console.error(chalk.red('\n❌ Error: Could not validate code after multiple attempts.\n'));
170
+ console.log('Please run the command again and ensure you copy the complete code.');
171
+ process.exit(1);
172
+ }
173
+ // Step 6: Exchange code for credentials
174
+ console.log(chalk.gray('\nExchanging code for credentials...'));
175
+ let conversionResponse;
176
+ try {
177
+ conversionResponse = await exchangeCodeForCredentials(code);
178
+ validateAppCredentials(conversionResponse);
179
+ }
180
+ catch (error) {
181
+ if (error instanceof Error) {
182
+ console.error(chalk.red('\n❌ Error: ' + error.message + '\n'));
183
+ }
184
+ else {
185
+ console.error(chalk.red('\n❌ Unknown error occurred\n'));
186
+ }
187
+ process.exit(1);
188
+ }
189
+ console.log(chalk.green('✓ App created successfully!'));
190
+ console.log(` App ID: ${chalk.cyan(conversionResponse.id)}`);
191
+ console.log(` App Name: ${chalk.cyan(conversionResponse.name)}\n`);
192
+ // Step 7: Fetch installation ID
193
+ console.log(chalk.gray('Fetching installation ID...'));
194
+ let installationId;
195
+ try {
196
+ installationId = await getInstallationId(conversionResponse.id.toString(), conversionResponse.pem, org);
197
+ }
198
+ catch (error) {
199
+ if (error instanceof Error) {
200
+ console.error(chalk.red('\n❌ Error: ' + error.message + '\n'));
201
+ }
202
+ else {
203
+ console.error(chalk.red('\n❌ Unknown error occurred\n'));
204
+ }
205
+ console.log('The app was created but could not find the installation.');
206
+ console.log(`Please install the app on your organization: ${chalk.cyan(`https://github.com/apps/${conversionResponse.slug}/installations/new`)}`);
207
+ process.exit(1);
208
+ }
209
+ console.log(chalk.green(`✓ Installation ID: ${chalk.cyan(installationId)}\n`));
210
+ // Step 8: Save private key
211
+ if (!options.noSave) {
212
+ console.log(chalk.gray(`Saving private key to ~/.github/faber-${org}.pem...`));
213
+ let keyPath;
214
+ try {
215
+ keyPath = await savePrivateKey(conversionResponse.pem, org);
216
+ }
217
+ catch (error) {
218
+ if (error instanceof Error) {
219
+ console.error(chalk.red('\n❌ Error saving private key: ' + error.message + '\n'));
220
+ }
221
+ else {
222
+ console.error(chalk.red('\n❌ Unknown error saving private key\n'));
223
+ }
224
+ console.log('You can manually save the private key to ~/.github/ directory.');
225
+ process.exit(1);
226
+ }
227
+ console.log(chalk.green(`✓ Private key saved (permissions: 0600)\n`));
228
+ // Step 9: Update configuration
229
+ console.log(chalk.gray('Updating configuration...'));
230
+ try {
231
+ await updateConfig(configPath, {
232
+ id: conversionResponse.id.toString(),
233
+ installation_id: installationId,
234
+ private_key_path: keyPath.replace(process.env.HOME || '', '~'),
235
+ org,
236
+ repo,
237
+ });
238
+ }
239
+ catch (error) {
240
+ if (error instanceof Error) {
241
+ console.error(chalk.red('\n❌ Error updating config: ' + error.message + '\n'));
242
+ }
243
+ else {
244
+ console.error(chalk.red('\n❌ Unknown error updating config\n'));
245
+ }
246
+ console.log('You can manually update .fractary/settings.json with:');
247
+ console.log(JSON.stringify({
248
+ github: {
249
+ organization: org,
250
+ project: repo,
251
+ app: {
252
+ id: conversionResponse.id.toString(),
253
+ installation_id: installationId,
254
+ private_key_path: `~/.github/faber-${org}.pem`,
255
+ },
256
+ },
257
+ }, null, 2));
258
+ process.exit(1);
259
+ }
260
+ console.log(chalk.green(`✓ Configuration saved to ${configPath}\n`));
261
+ }
262
+ else {
263
+ // Display credentials without saving
264
+ console.log(chalk.bold('\n📋 App Credentials:\n'));
265
+ console.log(JSON.stringify({
266
+ app_id: conversionResponse.id,
267
+ installation_id: installationId,
268
+ app_slug: conversionResponse.slug,
269
+ private_key: '[PEM key not shown]',
270
+ }, null, 2));
271
+ }
272
+ // Step 10: Success message
273
+ console.log(chalk.bold('━'.repeat(60)));
274
+ console.log(chalk.bold.green('✨ Setup Complete!'));
275
+ console.log(chalk.bold('━'.repeat(60)));
276
+ console.log();
277
+ console.log('Test your configuration:');
278
+ console.log(chalk.cyan(' fractary-faber work issue fetch 1'));
279
+ console.log();
280
+ console.log('View your app:');
281
+ console.log(chalk.cyan(` https://github.com/organizations/${org}/settings/apps/${conversionResponse.slug}`));
282
+ console.log();
283
+ }
284
+ /**
285
+ * Check if configuration already exists
286
+ */
287
+ async function checkExistingConfig(configPath) {
288
+ try {
289
+ const content = await fs.readFile(configPath, 'utf-8');
290
+ const config = JSON.parse(content);
291
+ return !!(config.github?.app);
292
+ }
293
+ catch {
294
+ return false;
295
+ }
296
+ }
297
+ /**
298
+ * Update configuration file
299
+ */
300
+ async function updateConfig(configPath, appConfig) {
301
+ let config = {};
302
+ try {
303
+ const content = await fs.readFile(configPath, 'utf-8');
304
+ config = JSON.parse(content);
305
+ }
306
+ catch {
307
+ // File doesn't exist, start with empty config
308
+ }
309
+ // Update GitHub config
310
+ config.github = config.github || {};
311
+ config.github.organization = appConfig.org;
312
+ config.github.project = appConfig.repo;
313
+ config.github.app = {
314
+ id: appConfig.id,
315
+ installation_id: appConfig.installation_id,
316
+ private_key_path: appConfig.private_key_path,
317
+ created_via: 'manifest-flow',
318
+ created_at: new Date().toISOString(),
319
+ };
320
+ // Ensure directory exists
321
+ const lastSlash = configPath.lastIndexOf('/');
322
+ if (lastSlash > 0) {
323
+ const dir = configPath.substring(0, lastSlash);
324
+ await fs.mkdir(dir, { recursive: true });
325
+ }
326
+ // Write config
327
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2) + '\n');
328
+ }
329
+ /**
330
+ * Create the main auth command
331
+ */
332
+ export function createAuthCommand() {
333
+ const command = new Command('auth').description('Authentication management');
334
+ command.addCommand(createAuthSetupCommand());
335
+ return command;
336
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CA2IxC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CA4IxC"}
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ import { createSpecCommand } from './commands/spec/index.js';
14
14
  import { createLogsCommand } from './commands/logs/index.js';
15
15
  import { createInitCommand } from './commands/init.js';
16
16
  import { createPlanCommand } from './commands/plan/index.js';
17
+ import { createAuthCommand } from './commands/auth/index.js';
17
18
  const version = '1.3.2';
18
19
  /**
19
20
  * Create and configure the main CLI program
@@ -21,7 +22,7 @@ const version = '1.3.2';
21
22
  export function createFaberCLI() {
22
23
  const program = new Command('fractary-faber');
23
24
  program
24
- .description('FABER development toolkit (workflow, work, repo, spec, logs)')
25
+ .description('FABER development toolkit (workflow, work, repo, spec, logs, auth)')
25
26
  .version(version)
26
27
  .enablePositionalOptions();
27
28
  // Global options
@@ -116,6 +117,7 @@ export function createFaberCLI() {
116
117
  cleanupCmd.parse(['', '', ...Object.entries(options).flatMap(([k, v]) => typeof v === 'boolean' && v ? [`--${k}`] : typeof v === 'string' ? [`--${k}`, v] : [])], { from: 'user' });
117
118
  });
118
119
  // Subcommand trees
120
+ program.addCommand(createAuthCommand());
119
121
  program.addCommand(createWorkCommand());
120
122
  program.addCommand(createRepoCommand());
121
123
  program.addCommand(createSpecCommand());
@@ -0,0 +1,122 @@
1
+ /**
2
+ * GitHub App Authentication Module
3
+ *
4
+ * Provides JWT generation, installation token exchange, and token caching
5
+ * for GitHub App authentication in FABER CLI.
6
+ */
7
+ import type { GitHubAppConfig } from '../types/config.js';
8
+ /**
9
+ * Private Key Loader
10
+ *
11
+ * Loads private keys from file path or environment variable
12
+ */
13
+ export declare class PrivateKeyLoader {
14
+ /**
15
+ * Load private key from configured sources.
16
+ * Priority: env var > file path
17
+ *
18
+ * @param config - GitHub App configuration
19
+ * @returns The private key content
20
+ * @throws Error if private key cannot be loaded
21
+ */
22
+ static load(config: GitHubAppConfig): Promise<string>;
23
+ /**
24
+ * Validate private key format.
25
+ *
26
+ * @param key - The private key content
27
+ * @returns true if valid PEM format
28
+ */
29
+ static validate(key: string): boolean;
30
+ }
31
+ /**
32
+ * GitHub App Authentication
33
+ *
34
+ * Handles JWT generation, installation token exchange, and caching
35
+ */
36
+ export declare class GitHubAppAuth {
37
+ private cache;
38
+ private config;
39
+ private refreshPromise;
40
+ private static readonly REFRESH_THRESHOLD_MS;
41
+ private static readonly JWT_EXPIRY_SECONDS;
42
+ private static readonly GITHUB_API_URL;
43
+ constructor(config: GitHubAppConfig);
44
+ /**
45
+ * Get a valid installation token.
46
+ * Returns cached token if still valid, otherwise generates new one.
47
+ *
48
+ * @returns Installation access token
49
+ */
50
+ getToken(): Promise<string>;
51
+ /**
52
+ * Force refresh the token.
53
+ *
54
+ * @returns New installation access token
55
+ */
56
+ refreshToken(): Promise<string>;
57
+ /**
58
+ * Check if token needs refresh (within 5 minutes of expiration).
59
+ *
60
+ * @returns true if token should be refreshed
61
+ */
62
+ isTokenExpiringSoon(): boolean;
63
+ /**
64
+ * Validate the configuration and private key.
65
+ *
66
+ * @throws Error if configuration is invalid
67
+ */
68
+ validate(): Promise<void>;
69
+ /**
70
+ * Perform the actual token refresh
71
+ */
72
+ private doRefresh;
73
+ /**
74
+ * Generate a JWT for GitHub App authentication
75
+ */
76
+ private generateJWT;
77
+ /**
78
+ * Exchange JWT for installation access token
79
+ */
80
+ private exchangeForInstallationToken;
81
+ /**
82
+ * Check if token is expired
83
+ */
84
+ private isExpired;
85
+ /**
86
+ * Check if token is expiring soon
87
+ */
88
+ private isExpiringSoon;
89
+ /**
90
+ * Trigger background token refresh (non-blocking)
91
+ */
92
+ private triggerBackgroundRefresh;
93
+ }
94
+ /**
95
+ * Token Provider Interface
96
+ *
97
+ * Abstract interface for getting tokens, supporting both PAT and GitHub App
98
+ */
99
+ export interface TokenProvider {
100
+ getToken(): Promise<string>;
101
+ }
102
+ /**
103
+ * Static Token Provider
104
+ *
105
+ * Simple provider for static PAT tokens
106
+ */
107
+ export declare class StaticTokenProvider implements TokenProvider {
108
+ private token;
109
+ constructor(token: string);
110
+ getToken(): Promise<string>;
111
+ }
112
+ /**
113
+ * GitHub App Token Provider
114
+ *
115
+ * Provider that uses GitHubAppAuth for dynamic token generation
116
+ */
117
+ export declare class GitHubAppTokenProvider implements TokenProvider {
118
+ private auth;
119
+ constructor(auth: GitHubAppAuth);
120
+ getToken(): Promise<string>;
121
+ }
122
+ //# sourceMappingURL=github-app-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app-auth.d.ts","sourceRoot":"","sources":["../../src/lib/github-app-auth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAqB1D;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B;;;;;;;OAOG;WACU,IAAI,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAiD3D;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;CAUtC;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,cAAc,CAAgC;IAGtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAiB;IAE7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAEjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAA4B;gBAEtD,MAAM,EAAE,eAAe;IAInC;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAkBjC;;;;OAIG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAerC;;;;OAIG;IACH,mBAAmB,IAAI,OAAO;IAK9B;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB/B;;OAEG;YACW,SAAS;IAcvB;;OAEG;YACW,WAAW;IAoBzB;;OAEG;YACW,4BAA4B;IAwD1C;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAUjC;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IAC3C,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,MAAM;IAE3B,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;CAGlC;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,YAAW,aAAa;IAC9C,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,aAAa;IAEjC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;CAGlC"}