@fractary/faber-cli 1.3.1 → 1.3.3
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 +101 -4
- package/dist/commands/auth/index.d.ts +13 -0
- package/dist/commands/auth/index.d.ts.map +1 -0
- package/dist/commands/auth/index.js +291 -0
- package/dist/commands/init.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/lib/anthropic-client.js +1 -1
- package/dist/lib/github-app-auth.d.ts +122 -0
- package/dist/lib/github-app-auth.d.ts.map +1 -0
- package/dist/lib/github-app-auth.js +294 -0
- package/dist/lib/github-app-setup.d.ts +131 -0
- package/dist/lib/github-app-setup.d.ts.map +1 -0
- package/dist/lib/github-app-setup.js +241 -0
- package/dist/lib/repo-client.d.ts +22 -2
- package/dist/lib/repo-client.d.ts.map +1 -1
- package/dist/lib/repo-client.js +52 -8
- package/dist/lib/sdk-config-adapter.d.ts +52 -0
- package/dist/lib/sdk-config-adapter.d.ts.map +1 -1
- package/dist/lib/sdk-config-adapter.js +167 -6
- package/dist/types/config.d.ts +12 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/github-manifest.d.ts +39 -0
- package/dist/utils/github-manifest.d.ts.map +1 -0
- package/dist/utils/github-manifest.js +84 -0
- package/package.json +5 -2
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* Repo Client
|
|
3
3
|
*
|
|
4
4
|
* Integrates with @fractary/core SDK for repository and work tracking operations
|
|
5
|
+
* Supports both PAT and GitHub App authentication methods.
|
|
5
6
|
*/
|
|
7
|
+
import { WorkManager, RepoManager } from '@fractary/core';
|
|
8
|
+
import type { FaberConfig } from '../types/config.js';
|
|
6
9
|
interface Issue {
|
|
7
10
|
id: string;
|
|
8
11
|
number: number;
|
|
@@ -31,7 +34,7 @@ interface IssueUpdateOptions {
|
|
|
31
34
|
* Repo Client - integrates with @fractary/core SDK
|
|
32
35
|
*
|
|
33
36
|
* Provides repository and work tracking operations using WorkManager and RepoManager
|
|
34
|
-
* from the @fractary/core SDK.
|
|
37
|
+
* from the @fractary/core SDK. Supports both PAT and GitHub App authentication.
|
|
35
38
|
*/
|
|
36
39
|
export declare class RepoClient {
|
|
37
40
|
private config;
|
|
@@ -39,7 +42,24 @@ export declare class RepoClient {
|
|
|
39
42
|
private repoManager;
|
|
40
43
|
private organization;
|
|
41
44
|
private project;
|
|
42
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Create a RepoClient instance (async factory method)
|
|
47
|
+
*
|
|
48
|
+
* Use this method to create RepoClient instances as it supports
|
|
49
|
+
* both PAT and GitHub App authentication.
|
|
50
|
+
*
|
|
51
|
+
* @param config - FABER CLI configuration
|
|
52
|
+
* @returns Promise resolving to RepoClient instance
|
|
53
|
+
*/
|
|
54
|
+
static create(config: FaberConfig): Promise<RepoClient>;
|
|
55
|
+
/**
|
|
56
|
+
* Create a RepoClient instance
|
|
57
|
+
*
|
|
58
|
+
* @param config - FABER CLI configuration
|
|
59
|
+
* @param workManager - Optional pre-initialized WorkManager (for async factory)
|
|
60
|
+
* @param repoManager - Optional pre-initialized RepoManager (for async factory)
|
|
61
|
+
*/
|
|
62
|
+
constructor(config: FaberConfig, workManager?: WorkManager, repoManager?: RepoManager);
|
|
43
63
|
/**
|
|
44
64
|
* Fetch specific issues by ID
|
|
45
65
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo-client.d.ts","sourceRoot":"","sources":["../../src/lib/repo-client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"repo-client.d.ts","sourceRoot":"","sources":["../../src/lib/repo-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAS1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,kBAAkB;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAS;IAExB;;;;;;;;OAQG;WACU,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAmB7D;;;;;;OAMG;gBACS,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,WAAW;IA0CrF;;;;OAIG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAclD;;;;OAIG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAetD;;;;OAIG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrD;;;;OAIG;IACG,cAAc,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IA+BzF;;;;OAIG;IACG,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CA0B9D"}
|
package/dist/lib/repo-client.js
CHANGED
|
@@ -2,29 +2,73 @@
|
|
|
2
2
|
* Repo Client
|
|
3
3
|
*
|
|
4
4
|
* Integrates with @fractary/core SDK for repository and work tracking operations
|
|
5
|
+
* Supports both PAT and GitHub App authentication methods.
|
|
5
6
|
*/
|
|
6
7
|
import { WorkManager, RepoManager } from '@fractary/core';
|
|
7
|
-
import { createWorkConfig, createRepoConfig } from './sdk-config-adapter.js';
|
|
8
|
+
import { createWorkConfig, createRepoConfig, createWorkConfigAsync, createRepoConfigAsync, isGitHubAppConfigured, } from './sdk-config-adapter.js';
|
|
8
9
|
import { sdkIssueToCLIIssue, sdkWorktreeToCLIWorktreeResult } from './sdk-type-adapter.js';
|
|
9
10
|
import os from 'os';
|
|
10
11
|
/**
|
|
11
12
|
* Repo Client - integrates with @fractary/core SDK
|
|
12
13
|
*
|
|
13
14
|
* Provides repository and work tracking operations using WorkManager and RepoManager
|
|
14
|
-
* from the @fractary/core SDK.
|
|
15
|
+
* from the @fractary/core SDK. Supports both PAT and GitHub App authentication.
|
|
15
16
|
*/
|
|
16
17
|
export class RepoClient {
|
|
17
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Create a RepoClient instance (async factory method)
|
|
20
|
+
*
|
|
21
|
+
* Use this method to create RepoClient instances as it supports
|
|
22
|
+
* both PAT and GitHub App authentication.
|
|
23
|
+
*
|
|
24
|
+
* @param config - FABER CLI configuration
|
|
25
|
+
* @returns Promise resolving to RepoClient instance
|
|
26
|
+
*/
|
|
27
|
+
static async create(config) {
|
|
28
|
+
// Use async config methods for GitHub App support
|
|
29
|
+
const workConfig = await createWorkConfigAsync(config);
|
|
30
|
+
const repoConfig = await createRepoConfigAsync(config);
|
|
31
|
+
try {
|
|
32
|
+
const workManager = new WorkManager(workConfig);
|
|
33
|
+
const repoManager = new RepoManager(repoConfig);
|
|
34
|
+
// Create client with pre-initialized managers
|
|
35
|
+
return new RepoClient(config, workManager, repoManager);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error instanceof Error) {
|
|
39
|
+
throw new Error(`Failed to initialize SDK managers: ${error.message}`);
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a RepoClient instance
|
|
46
|
+
*
|
|
47
|
+
* @param config - FABER CLI configuration
|
|
48
|
+
* @param workManager - Optional pre-initialized WorkManager (for async factory)
|
|
49
|
+
* @param repoManager - Optional pre-initialized RepoManager (for async factory)
|
|
50
|
+
*/
|
|
51
|
+
constructor(config, workManager, repoManager) {
|
|
18
52
|
this.config = config;
|
|
19
|
-
|
|
53
|
+
this.organization = config.github?.organization || 'unknown';
|
|
54
|
+
this.project = config.github?.project || 'unknown';
|
|
55
|
+
// If managers are provided (from static create), use them
|
|
56
|
+
if (workManager && repoManager) {
|
|
57
|
+
this.workManager = workManager;
|
|
58
|
+
this.repoManager = repoManager;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Synchronous initialization - only works with PAT
|
|
62
|
+
if (isGitHubAppConfigured(config)) {
|
|
63
|
+
throw new Error('GitHub App authentication requires async initialization. ' +
|
|
64
|
+
'Use RepoClient.create() instead of new RepoClient().');
|
|
65
|
+
}
|
|
66
|
+
// Validate GitHub token for PAT auth
|
|
20
67
|
const token = config.github?.token;
|
|
21
68
|
if (!token) {
|
|
22
69
|
throw new Error('GitHub token not found. Set GITHUB_TOKEN environment variable.');
|
|
23
70
|
}
|
|
24
|
-
//
|
|
25
|
-
this.organization = config.github?.organization || 'unknown';
|
|
26
|
-
this.project = config.github?.project || 'unknown';
|
|
27
|
-
// Create SDK configurations
|
|
71
|
+
// Create SDK configurations (PAT only)
|
|
28
72
|
const workConfig = createWorkConfig(config);
|
|
29
73
|
const repoConfig = createRepoConfig(config);
|
|
30
74
|
// Initialize SDK managers
|
|
@@ -2,9 +2,41 @@
|
|
|
2
2
|
* SDK Configuration Adapter
|
|
3
3
|
*
|
|
4
4
|
* Converts FABER CLI configuration to @fractary/core SDK configuration format
|
|
5
|
+
* Supports both PAT and GitHub App authentication methods.
|
|
5
6
|
*/
|
|
6
7
|
import type { FaberConfig } from '../types/config.js';
|
|
7
8
|
import type { WorkConfig, RepoConfig } from '@fractary/core';
|
|
9
|
+
import { TokenProvider } from './github-app-auth.js';
|
|
10
|
+
/**
|
|
11
|
+
* Get the current token from the provider
|
|
12
|
+
* Used internally and for SDK configuration
|
|
13
|
+
*
|
|
14
|
+
* @param faberConfig - FABER CLI configuration
|
|
15
|
+
* @returns Promise resolving to the current token
|
|
16
|
+
*/
|
|
17
|
+
export declare function getToken(faberConfig: FaberConfig): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Get the token provider for dynamic token refresh
|
|
20
|
+
* Useful for long-running operations that need fresh tokens
|
|
21
|
+
*
|
|
22
|
+
* @param faberConfig - FABER CLI configuration
|
|
23
|
+
* @returns TokenProvider instance
|
|
24
|
+
*/
|
|
25
|
+
export declare function getTokenProviderInstance(faberConfig: FaberConfig): TokenProvider;
|
|
26
|
+
/**
|
|
27
|
+
* Validate GitHub authentication configuration
|
|
28
|
+
*
|
|
29
|
+
* @param faberConfig - FABER CLI configuration
|
|
30
|
+
* @throws Error if configuration is invalid
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateGitHubAuth(faberConfig: FaberConfig): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Check if GitHub App authentication is configured
|
|
35
|
+
*
|
|
36
|
+
* @param faberConfig - FABER CLI configuration
|
|
37
|
+
* @returns true if GitHub App is configured
|
|
38
|
+
*/
|
|
39
|
+
export declare function isGitHubAppConfigured(faberConfig: FaberConfig): boolean;
|
|
8
40
|
/**
|
|
9
41
|
* Create WorkConfig for WorkManager from FaberConfig
|
|
10
42
|
*
|
|
@@ -13,6 +45,16 @@ import type { WorkConfig, RepoConfig } from '@fractary/core';
|
|
|
13
45
|
* @throws Error if required fields are missing
|
|
14
46
|
*/
|
|
15
47
|
export declare function createWorkConfig(faberConfig: FaberConfig): WorkConfig;
|
|
48
|
+
/**
|
|
49
|
+
* Create WorkConfig for WorkManager from FaberConfig (async version)
|
|
50
|
+
*
|
|
51
|
+
* This version supports both PAT and GitHub App authentication.
|
|
52
|
+
*
|
|
53
|
+
* @param faberConfig - FABER CLI configuration
|
|
54
|
+
* @returns Promise resolving to WorkConfig for @fractary/core WorkManager
|
|
55
|
+
* @throws Error if required fields are missing
|
|
56
|
+
*/
|
|
57
|
+
export declare function createWorkConfigAsync(faberConfig: FaberConfig): Promise<WorkConfig>;
|
|
16
58
|
/**
|
|
17
59
|
* Create RepoConfig for RepoManager from FaberConfig
|
|
18
60
|
*
|
|
@@ -21,4 +63,14 @@ export declare function createWorkConfig(faberConfig: FaberConfig): WorkConfig;
|
|
|
21
63
|
* @throws Error if required fields are missing
|
|
22
64
|
*/
|
|
23
65
|
export declare function createRepoConfig(faberConfig: FaberConfig): RepoConfig;
|
|
66
|
+
/**
|
|
67
|
+
* Create RepoConfig for RepoManager from FaberConfig (async version)
|
|
68
|
+
*
|
|
69
|
+
* This version supports both PAT and GitHub App authentication.
|
|
70
|
+
*
|
|
71
|
+
* @param faberConfig - FABER CLI configuration
|
|
72
|
+
* @returns Promise resolving to RepoConfig for @fractary/core RepoManager
|
|
73
|
+
* @throws Error if required fields are missing
|
|
74
|
+
*/
|
|
75
|
+
export declare function createRepoConfigAsync(faberConfig: FaberConfig): Promise<RepoConfig>;
|
|
24
76
|
//# sourceMappingURL=sdk-config-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-config-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/sdk-config-adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"sdk-config-adapter.d.ts","sourceRoot":"","sources":["../../src/lib/sdk-config-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAEL,aAAa,EAGd,MAAM,sBAAsB,CAAC;AA2D9B;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxE;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,CAEhF;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAGvE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,UAAU,CAmCrE;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBzF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,UAAU,CAyBrE;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAYzF"}
|
|
@@ -2,7 +2,107 @@
|
|
|
2
2
|
* SDK Configuration Adapter
|
|
3
3
|
*
|
|
4
4
|
* Converts FABER CLI configuration to @fractary/core SDK configuration format
|
|
5
|
+
* Supports both PAT and GitHub App authentication methods.
|
|
5
6
|
*/
|
|
7
|
+
import { GitHubAppAuth, StaticTokenProvider, GitHubAppTokenProvider, } from './github-app-auth.js';
|
|
8
|
+
// Singleton token provider for reuse across SDK instances
|
|
9
|
+
let tokenProvider = null;
|
|
10
|
+
let tokenProviderConfig = null;
|
|
11
|
+
/**
|
|
12
|
+
* Get or create a token provider based on configuration
|
|
13
|
+
*
|
|
14
|
+
* @param faberConfig - FABER CLI configuration
|
|
15
|
+
* @returns TokenProvider instance
|
|
16
|
+
*/
|
|
17
|
+
function getTokenProvider(faberConfig) {
|
|
18
|
+
const appConfig = faberConfig.github?.app;
|
|
19
|
+
const patToken = faberConfig.github?.token;
|
|
20
|
+
// Determine which auth method to use
|
|
21
|
+
// GitHub App takes precedence over PAT if configured
|
|
22
|
+
if (appConfig?.id && appConfig?.installation_id) {
|
|
23
|
+
// Check if we can reuse existing provider
|
|
24
|
+
if (tokenProvider && tokenProviderConfig === appConfig) {
|
|
25
|
+
return tokenProvider;
|
|
26
|
+
}
|
|
27
|
+
// Create new GitHub App token provider
|
|
28
|
+
const auth = new GitHubAppAuth(appConfig);
|
|
29
|
+
tokenProvider = new GitHubAppTokenProvider(auth);
|
|
30
|
+
tokenProviderConfig = appConfig;
|
|
31
|
+
return tokenProvider;
|
|
32
|
+
}
|
|
33
|
+
// Fall back to PAT
|
|
34
|
+
if (patToken) {
|
|
35
|
+
// Check if we can reuse existing provider
|
|
36
|
+
if (tokenProvider && tokenProviderConfig === patToken) {
|
|
37
|
+
return tokenProvider;
|
|
38
|
+
}
|
|
39
|
+
tokenProvider = new StaticTokenProvider(patToken);
|
|
40
|
+
tokenProviderConfig = patToken;
|
|
41
|
+
return tokenProvider;
|
|
42
|
+
}
|
|
43
|
+
throw new Error('GitHub authentication not configured. Either:\n' +
|
|
44
|
+
' 1. Set GITHUB_TOKEN environment variable, or\n' +
|
|
45
|
+
' 2. Configure GitHub App in .fractary/settings.json:\n' +
|
|
46
|
+
' {\n' +
|
|
47
|
+
' "github": {\n' +
|
|
48
|
+
' "app": {\n' +
|
|
49
|
+
' "id": "<app-id>",\n' +
|
|
50
|
+
' "installation_id": "<installation-id>",\n' +
|
|
51
|
+
' "private_key_path": "~/.github/your-app.pem"\n' +
|
|
52
|
+
' }\n' +
|
|
53
|
+
' }\n' +
|
|
54
|
+
' }');
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the current token from the provider
|
|
58
|
+
* Used internally and for SDK configuration
|
|
59
|
+
*
|
|
60
|
+
* @param faberConfig - FABER CLI configuration
|
|
61
|
+
* @returns Promise resolving to the current token
|
|
62
|
+
*/
|
|
63
|
+
export async function getToken(faberConfig) {
|
|
64
|
+
const provider = getTokenProvider(faberConfig);
|
|
65
|
+
return provider.getToken();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the token provider for dynamic token refresh
|
|
69
|
+
* Useful for long-running operations that need fresh tokens
|
|
70
|
+
*
|
|
71
|
+
* @param faberConfig - FABER CLI configuration
|
|
72
|
+
* @returns TokenProvider instance
|
|
73
|
+
*/
|
|
74
|
+
export function getTokenProviderInstance(faberConfig) {
|
|
75
|
+
return getTokenProvider(faberConfig);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Validate GitHub authentication configuration
|
|
79
|
+
*
|
|
80
|
+
* @param faberConfig - FABER CLI configuration
|
|
81
|
+
* @throws Error if configuration is invalid
|
|
82
|
+
*/
|
|
83
|
+
export async function validateGitHubAuth(faberConfig) {
|
|
84
|
+
const appConfig = faberConfig.github?.app;
|
|
85
|
+
if (appConfig?.id && appConfig?.installation_id) {
|
|
86
|
+
// Validate GitHub App configuration
|
|
87
|
+
const auth = new GitHubAppAuth(appConfig);
|
|
88
|
+
await auth.validate();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// Validate PAT
|
|
92
|
+
if (!faberConfig.github?.token) {
|
|
93
|
+
throw new Error('GitHub token not found. Set GITHUB_TOKEN environment variable or configure in .fractary/settings.json');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if GitHub App authentication is configured
|
|
98
|
+
*
|
|
99
|
+
* @param faberConfig - FABER CLI configuration
|
|
100
|
+
* @returns true if GitHub App is configured
|
|
101
|
+
*/
|
|
102
|
+
export function isGitHubAppConfigured(faberConfig) {
|
|
103
|
+
const appConfig = faberConfig.github?.app;
|
|
104
|
+
return !!(appConfig?.id && appConfig?.installation_id);
|
|
105
|
+
}
|
|
6
106
|
/**
|
|
7
107
|
* Create WorkConfig for WorkManager from FaberConfig
|
|
8
108
|
*
|
|
@@ -11,15 +111,49 @@
|
|
|
11
111
|
* @throws Error if required fields are missing
|
|
12
112
|
*/
|
|
13
113
|
export function createWorkConfig(faberConfig) {
|
|
14
|
-
const token = faberConfig.github?.token;
|
|
15
114
|
const owner = faberConfig.github?.organization;
|
|
16
115
|
const repo = faberConfig.github?.project;
|
|
17
|
-
if (!
|
|
18
|
-
throw new Error('GitHub
|
|
116
|
+
if (!owner || !repo) {
|
|
117
|
+
throw new Error('GitHub organization and project must be configured in .fractary/settings.json');
|
|
118
|
+
}
|
|
119
|
+
// Get token provider (validates auth config)
|
|
120
|
+
const provider = getTokenProvider(faberConfig);
|
|
121
|
+
// For SDK config, we need a synchronous token
|
|
122
|
+
// The SDK will use this initially; for long-running operations,
|
|
123
|
+
// use createWorkConfigAsync or the token provider directly
|
|
124
|
+
let token;
|
|
125
|
+
if (provider instanceof StaticTokenProvider) {
|
|
126
|
+
// For PAT, we can get token synchronously via internal access
|
|
127
|
+
token = faberConfig.github?.token || '';
|
|
19
128
|
}
|
|
129
|
+
else {
|
|
130
|
+
// For GitHub App, throw helpful error - use async version
|
|
131
|
+
throw new Error('GitHub App authentication requires async initialization. ' +
|
|
132
|
+
'Use createWorkConfigAsync() instead of createWorkConfig().');
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
platform: 'github',
|
|
136
|
+
owner,
|
|
137
|
+
repo,
|
|
138
|
+
token,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Create WorkConfig for WorkManager from FaberConfig (async version)
|
|
143
|
+
*
|
|
144
|
+
* This version supports both PAT and GitHub App authentication.
|
|
145
|
+
*
|
|
146
|
+
* @param faberConfig - FABER CLI configuration
|
|
147
|
+
* @returns Promise resolving to WorkConfig for @fractary/core WorkManager
|
|
148
|
+
* @throws Error if required fields are missing
|
|
149
|
+
*/
|
|
150
|
+
export async function createWorkConfigAsync(faberConfig) {
|
|
151
|
+
const owner = faberConfig.github?.organization;
|
|
152
|
+
const repo = faberConfig.github?.project;
|
|
20
153
|
if (!owner || !repo) {
|
|
21
154
|
throw new Error('GitHub organization and project must be configured in .fractary/settings.json');
|
|
22
155
|
}
|
|
156
|
+
const token = await getToken(faberConfig);
|
|
23
157
|
return {
|
|
24
158
|
platform: 'github',
|
|
25
159
|
owner,
|
|
@@ -35,12 +169,39 @@ export function createWorkConfig(faberConfig) {
|
|
|
35
169
|
* @throws Error if required fields are missing
|
|
36
170
|
*/
|
|
37
171
|
export function createRepoConfig(faberConfig) {
|
|
38
|
-
const token = faberConfig.github?.token;
|
|
39
172
|
const owner = faberConfig.github?.organization;
|
|
40
173
|
const repo = faberConfig.github?.project;
|
|
41
|
-
|
|
42
|
-
|
|
174
|
+
// Get token provider (validates auth config)
|
|
175
|
+
const provider = getTokenProvider(faberConfig);
|
|
176
|
+
// For SDK config, we need a synchronous token
|
|
177
|
+
let token;
|
|
178
|
+
if (provider instanceof StaticTokenProvider) {
|
|
179
|
+
token = faberConfig.github?.token || '';
|
|
43
180
|
}
|
|
181
|
+
else {
|
|
182
|
+
throw new Error('GitHub App authentication requires async initialization. ' +
|
|
183
|
+
'Use createRepoConfigAsync() instead of createRepoConfig().');
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
platform: 'github',
|
|
187
|
+
owner,
|
|
188
|
+
repo,
|
|
189
|
+
token,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Create RepoConfig for RepoManager from FaberConfig (async version)
|
|
194
|
+
*
|
|
195
|
+
* This version supports both PAT and GitHub App authentication.
|
|
196
|
+
*
|
|
197
|
+
* @param faberConfig - FABER CLI configuration
|
|
198
|
+
* @returns Promise resolving to RepoConfig for @fractary/core RepoManager
|
|
199
|
+
* @throws Error if required fields are missing
|
|
200
|
+
*/
|
|
201
|
+
export async function createRepoConfigAsync(faberConfig) {
|
|
202
|
+
const owner = faberConfig.github?.organization;
|
|
203
|
+
const repo = faberConfig.github?.project;
|
|
204
|
+
const token = await getToken(faberConfig);
|
|
44
205
|
return {
|
|
45
206
|
platform: 'github',
|
|
46
207
|
owner,
|
package/dist/types/config.d.ts
CHANGED
|
@@ -6,11 +6,23 @@
|
|
|
6
6
|
export interface AnthropicConfig {
|
|
7
7
|
api_key?: string;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* GitHub App authentication configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface GitHubAppConfig {
|
|
13
|
+
id: string;
|
|
14
|
+
installation_id: string;
|
|
15
|
+
private_key_path?: string;
|
|
16
|
+
private_key_env_var?: string;
|
|
17
|
+
created_via?: 'manifest-flow' | 'manual';
|
|
18
|
+
created_at?: string;
|
|
19
|
+
}
|
|
9
20
|
export interface GitHubConfig {
|
|
10
21
|
token?: string;
|
|
11
22
|
organization?: string;
|
|
12
23
|
project?: string;
|
|
13
24
|
repo?: string;
|
|
25
|
+
app?: GitHubAppConfig;
|
|
14
26
|
}
|
|
15
27
|
export interface WorktreeConfig {
|
|
16
28
|
location?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,eAAe,GAAG,QAAQ,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper utilities for GitHub App Manifest flow
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Parse code parameter from GitHub redirect URL or direct code input
|
|
6
|
+
*
|
|
7
|
+
* @param input - Either a full GitHub URL or just the code
|
|
8
|
+
* @returns The extracted code, or null if invalid
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseCodeFromUrl(input: string): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Validate manifest code format
|
|
13
|
+
*
|
|
14
|
+
* GitHub manifest codes are typically long alphanumeric strings
|
|
15
|
+
* with underscores and hyphens, at least 20 characters long.
|
|
16
|
+
*
|
|
17
|
+
* @param code - The code to validate
|
|
18
|
+
* @returns true if code appears valid
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateManifestCode(code: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Detect GitHub context from git remote
|
|
23
|
+
*
|
|
24
|
+
* Parses the git remote URL to extract organization and repository names.
|
|
25
|
+
* Supports both HTTPS and SSH URL formats.
|
|
26
|
+
*
|
|
27
|
+
* @returns Object with org and repo, or null if not detectable
|
|
28
|
+
*/
|
|
29
|
+
export declare function detectGitHubContext(): {
|
|
30
|
+
org: string;
|
|
31
|
+
repo: string;
|
|
32
|
+
} | null;
|
|
33
|
+
/**
|
|
34
|
+
* Validate if current directory is a git repository
|
|
35
|
+
*
|
|
36
|
+
* @returns true if current directory is a git repository
|
|
37
|
+
*/
|
|
38
|
+
export declare function isGitRepository(): boolean;
|
|
39
|
+
//# sourceMappingURL=github-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-manifest.d.ts","sourceRoot":"","sources":["../../src/utils/github-manifest.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoB7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB1E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAQzC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper utilities for GitHub App Manifest flow
|
|
3
|
+
*/
|
|
4
|
+
import { Git } from '@fractary/faber';
|
|
5
|
+
/**
|
|
6
|
+
* Parse code parameter from GitHub redirect URL or direct code input
|
|
7
|
+
*
|
|
8
|
+
* @param input - Either a full GitHub URL or just the code
|
|
9
|
+
* @returns The extracted code, or null if invalid
|
|
10
|
+
*/
|
|
11
|
+
export function parseCodeFromUrl(input) {
|
|
12
|
+
const trimmed = input.trim();
|
|
13
|
+
// Try to parse as URL first
|
|
14
|
+
try {
|
|
15
|
+
const url = new URL(trimmed);
|
|
16
|
+
const code = url.searchParams.get('code');
|
|
17
|
+
if (code) {
|
|
18
|
+
return code;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Not a valid URL, check if it's just the code itself
|
|
23
|
+
}
|
|
24
|
+
// Check if input looks like a code (alphanumeric, underscores, hyphens)
|
|
25
|
+
if (/^[a-zA-Z0-9_-]+$/.test(trimmed)) {
|
|
26
|
+
return trimmed;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validate manifest code format
|
|
32
|
+
*
|
|
33
|
+
* GitHub manifest codes are typically long alphanumeric strings
|
|
34
|
+
* with underscores and hyphens, at least 20 characters long.
|
|
35
|
+
*
|
|
36
|
+
* @param code - The code to validate
|
|
37
|
+
* @returns true if code appears valid
|
|
38
|
+
*/
|
|
39
|
+
export function validateManifestCode(code) {
|
|
40
|
+
return /^[a-zA-Z0-9_-]{20,}$/.test(code);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Detect GitHub context from git remote
|
|
44
|
+
*
|
|
45
|
+
* Parses the git remote URL to extract organization and repository names.
|
|
46
|
+
* Supports both HTTPS and SSH URL formats.
|
|
47
|
+
*
|
|
48
|
+
* @returns Object with org and repo, or null if not detectable
|
|
49
|
+
*/
|
|
50
|
+
export function detectGitHubContext() {
|
|
51
|
+
try {
|
|
52
|
+
const git = new Git();
|
|
53
|
+
const remoteUrl = git.exec('remote get-url origin').trim();
|
|
54
|
+
// Parse various GitHub URL formats
|
|
55
|
+
// HTTPS: https://github.com/org/repo.git
|
|
56
|
+
// SSH: git@github.com:org/repo.git
|
|
57
|
+
const match = remoteUrl.match(/github\.com[/:]([^/]+)\/([^/]+?)(\.git)?$/);
|
|
58
|
+
if (match) {
|
|
59
|
+
const org = match[1];
|
|
60
|
+
const repo = match[2].replace(/\.git$/, '');
|
|
61
|
+
return { org, repo };
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Not a git repository or no origin remote
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Validate if current directory is a git repository
|
|
72
|
+
*
|
|
73
|
+
* @returns true if current directory is a git repository
|
|
74
|
+
*/
|
|
75
|
+
export function isGitRepository() {
|
|
76
|
+
try {
|
|
77
|
+
const git = new Git();
|
|
78
|
+
git.exec('rev-parse --git-dir');
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fractary/faber-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "FABER CLI - Command-line interface for FABER development toolkit",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -38,11 +38,14 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@fractary/core": "^0.2.0",
|
|
40
40
|
"@fractary/faber": "^2.1.1",
|
|
41
|
+
"ajv": "^8.12.0",
|
|
41
42
|
"chalk": "^5.0.0",
|
|
42
|
-
"commander": "^12.0.0"
|
|
43
|
+
"commander": "^12.0.0",
|
|
44
|
+
"jsonwebtoken": "^9.0.0"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
|
45
47
|
"@types/jest": "^30.0.0",
|
|
48
|
+
"@types/jsonwebtoken": "^9.0.0",
|
|
46
49
|
"@types/node": "^20.19.26",
|
|
47
50
|
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
48
51
|
"@typescript-eslint/parser": "^6.19.0",
|