@fractary/faber 2.2.0 → 2.3.0

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.
@@ -0,0 +1,155 @@
1
+ /**
2
+ * @fractary/faber - GitHub App Authentication
3
+ *
4
+ * Provides JWT generation, installation token exchange, and token caching
5
+ * for GitHub App authentication.
6
+ *
7
+ * This module is used by both the SDK and CLI for GitHub App auth.
8
+ */
9
+ /**
10
+ * GitHub App configuration
11
+ */
12
+ export interface GitHubAppConfig {
13
+ /** GitHub App ID */
14
+ id: string;
15
+ /** Installation ID for the target org/repo */
16
+ installation_id: string;
17
+ /** Path to PEM file (optional if env var used) */
18
+ private_key_path?: string;
19
+ /** Env var name containing base64-encoded key */
20
+ private_key_env_var?: string;
21
+ /** How the app was created */
22
+ created_via?: 'manifest-flow' | 'manual';
23
+ /** ISO 8601 timestamp of creation */
24
+ created_at?: string;
25
+ }
26
+ /**
27
+ * Private Key Loader
28
+ *
29
+ * Loads private keys from file path or environment variable
30
+ */
31
+ export declare class PrivateKeyLoader {
32
+ /**
33
+ * Load private key from configured sources.
34
+ * Priority: env var > file path
35
+ *
36
+ * @param config - GitHub App configuration
37
+ * @returns The private key content
38
+ * @throws Error if private key cannot be loaded
39
+ */
40
+ static load(config: GitHubAppConfig): Promise<string>;
41
+ /**
42
+ * Validate private key format.
43
+ *
44
+ * @param key - The private key content
45
+ * @returns true if valid PEM format
46
+ */
47
+ static validate(key: string): boolean;
48
+ }
49
+ /**
50
+ * GitHub App Authentication
51
+ *
52
+ * Handles JWT generation, installation token exchange, and caching
53
+ */
54
+ export declare class GitHubAppAuth {
55
+ private cache;
56
+ private config;
57
+ private refreshPromise;
58
+ private static readonly REFRESH_THRESHOLD_MS;
59
+ private static readonly JWT_EXPIRY_SECONDS;
60
+ private static readonly GITHUB_API_URL;
61
+ constructor(config: GitHubAppConfig);
62
+ /**
63
+ * Get the configuration
64
+ */
65
+ getConfig(): GitHubAppConfig;
66
+ /**
67
+ * Get a valid installation token.
68
+ * Returns cached token if still valid, otherwise generates new one.
69
+ *
70
+ * @returns Installation access token
71
+ */
72
+ getToken(): Promise<string>;
73
+ /**
74
+ * Force refresh the token.
75
+ *
76
+ * @returns New installation access token
77
+ */
78
+ refreshToken(): Promise<string>;
79
+ /**
80
+ * Check if token needs refresh (within 5 minutes of expiration).
81
+ *
82
+ * @returns true if token should be refreshed
83
+ */
84
+ isTokenExpiringSoon(): boolean;
85
+ /**
86
+ * Validate the configuration and private key.
87
+ *
88
+ * @throws Error if configuration is invalid
89
+ */
90
+ validate(): Promise<void>;
91
+ /**
92
+ * Perform the actual token refresh
93
+ */
94
+ private doRefresh;
95
+ /**
96
+ * Generate a JWT for GitHub App authentication
97
+ */
98
+ private generateJWT;
99
+ /**
100
+ * Exchange JWT for installation access token
101
+ */
102
+ private exchangeForInstallationToken;
103
+ /**
104
+ * Check if token is expired
105
+ */
106
+ private isExpired;
107
+ /**
108
+ * Check if token is expiring soon
109
+ */
110
+ private isExpiringSoon;
111
+ /**
112
+ * Trigger background token refresh with retry (non-blocking)
113
+ */
114
+ private triggerBackgroundRefresh;
115
+ /**
116
+ * Refresh token with exponential backoff retry
117
+ *
118
+ * @param maxRetries - Maximum number of retry attempts
119
+ * @param baseDelayMs - Base delay in milliseconds (doubles each retry)
120
+ */
121
+ private refreshWithRetry;
122
+ /**
123
+ * Sleep helper for retry delays
124
+ */
125
+ private sleep;
126
+ }
127
+ /**
128
+ * Token Provider Interface
129
+ *
130
+ * Abstract interface for getting tokens, supporting both PAT and GitHub App
131
+ */
132
+ export interface TokenProvider {
133
+ getToken(): Promise<string>;
134
+ }
135
+ /**
136
+ * Static Token Provider
137
+ *
138
+ * Simple provider for static PAT tokens
139
+ */
140
+ export declare class StaticTokenProvider implements TokenProvider {
141
+ private token;
142
+ constructor(token: string);
143
+ getToken(): Promise<string>;
144
+ }
145
+ /**
146
+ * GitHub App Token Provider
147
+ *
148
+ * Provider that uses GitHubAppAuth for dynamic token generation
149
+ */
150
+ export declare class GitHubAppTokenProvider implements TokenProvider {
151
+ private auth;
152
+ constructor(auth: GitHubAppAuth);
153
+ getToken(): Promise<string>;
154
+ }
155
+ //# sourceMappingURL=github-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app.d.ts","sourceRoot":"","sources":["../../src/auth/github-app.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oBAAoB;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iDAAiD;IACjD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,8BAA8B;IAC9B,WAAW,CAAC,EAAE,eAAe,GAAG,QAAQ,CAAC;IACzC,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAqBD;;;;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;;OAEG;IACH,SAAS,IAAI,eAAe;IAI5B;;;;;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;IA2D1C;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAWhC;;;;;OAKG;YACW,gBAAgB;IAmC9B;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd;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"}
@@ -0,0 +1,348 @@
1
+ /**
2
+ * @fractary/faber - GitHub App Authentication
3
+ *
4
+ * Provides JWT generation, installation token exchange, and token caching
5
+ * for GitHub App authentication.
6
+ *
7
+ * This module is used by both the SDK and CLI for GitHub App auth.
8
+ */
9
+ import jwt from 'jsonwebtoken';
10
+ import fs from 'fs/promises';
11
+ import path from 'path';
12
+ import os from 'os';
13
+ /**
14
+ * Private Key Loader
15
+ *
16
+ * Loads private keys from file path or environment variable
17
+ */
18
+ export class PrivateKeyLoader {
19
+ /**
20
+ * Load private key from configured sources.
21
+ * Priority: env var > file path
22
+ *
23
+ * @param config - GitHub App configuration
24
+ * @returns The private key content
25
+ * @throws Error if private key cannot be loaded
26
+ */
27
+ static async load(config) {
28
+ // Try environment variable first (priority)
29
+ if (config.private_key_env_var) {
30
+ const envValue = process.env[config.private_key_env_var];
31
+ if (envValue) {
32
+ try {
33
+ // Decode base64-encoded key
34
+ const decoded = Buffer.from(envValue, 'base64').toString('utf-8');
35
+ if (PrivateKeyLoader.validate(decoded)) {
36
+ return decoded;
37
+ }
38
+ }
39
+ catch {
40
+ // Invalid base64, fall through to file path
41
+ }
42
+ }
43
+ }
44
+ // Try file path
45
+ if (config.private_key_path) {
46
+ try {
47
+ // Expand ~ to home directory
48
+ const expandedPath = config.private_key_path.startsWith('~')
49
+ ? config.private_key_path.replace('~', os.homedir())
50
+ : config.private_key_path;
51
+ const resolvedPath = path.resolve(expandedPath);
52
+ const key = await fs.readFile(resolvedPath, 'utf-8');
53
+ if (PrivateKeyLoader.validate(key)) {
54
+ return key;
55
+ }
56
+ throw new Error('Invalid private key format. Expected PEM-encoded RSA private key');
57
+ }
58
+ catch (error) {
59
+ if (error instanceof Error && error.message.includes('ENOENT')) {
60
+ throw new Error(`GitHub App private key not found at '${config.private_key_path}'. ` +
61
+ `Check 'private_key_path' in config or set ${config.private_key_env_var || 'GITHUB_APP_PRIVATE_KEY'} env var`);
62
+ }
63
+ throw error;
64
+ }
65
+ }
66
+ throw new Error('GitHub App private key not found. ' +
67
+ "Configure 'private_key_path' in .fractary/config.yaml or set GITHUB_APP_PRIVATE_KEY env var");
68
+ }
69
+ /**
70
+ * Validate private key format.
71
+ *
72
+ * @param key - The private key content
73
+ * @returns true if valid PEM format
74
+ */
75
+ static validate(key) {
76
+ // Check for PEM format (RSA or PKCS#8)
77
+ const trimmed = key.trim();
78
+ return ((trimmed.startsWith('-----BEGIN RSA PRIVATE KEY-----') &&
79
+ trimmed.endsWith('-----END RSA PRIVATE KEY-----')) ||
80
+ (trimmed.startsWith('-----BEGIN PRIVATE KEY-----') &&
81
+ trimmed.endsWith('-----END PRIVATE KEY-----')));
82
+ }
83
+ }
84
+ /**
85
+ * GitHub App Authentication
86
+ *
87
+ * Handles JWT generation, installation token exchange, and caching
88
+ */
89
+ export class GitHubAppAuth {
90
+ cache = new Map();
91
+ config;
92
+ refreshPromise = null;
93
+ // Token refresh threshold (5 minutes before expiration)
94
+ static REFRESH_THRESHOLD_MS = 5 * 60 * 1000;
95
+ // JWT validity period (reduced to 5 minutes to handle clock skew)
96
+ static JWT_EXPIRY_SECONDS = 300;
97
+ // GitHub API base URL
98
+ static GITHUB_API_URL = 'https://api.github.com';
99
+ constructor(config) {
100
+ this.config = config;
101
+ }
102
+ /**
103
+ * Get the configuration
104
+ */
105
+ getConfig() {
106
+ return this.config;
107
+ }
108
+ /**
109
+ * Get a valid installation token.
110
+ * Returns cached token if still valid, otherwise generates new one.
111
+ *
112
+ * @returns Installation access token
113
+ */
114
+ async getToken() {
115
+ const cacheKey = this.config.installation_id;
116
+ const cached = this.cache.get(cacheKey);
117
+ if (cached && !this.isExpired(cached) && !this.isExpiringSoon(cached)) {
118
+ return cached.token;
119
+ }
120
+ // If token is expiring soon but still valid, trigger background refresh
121
+ if (cached && !this.isExpired(cached) && this.isExpiringSoon(cached)) {
122
+ this.triggerBackgroundRefresh();
123
+ return cached.token;
124
+ }
125
+ // Token expired or missing, must refresh synchronously
126
+ return this.refreshToken();
127
+ }
128
+ /**
129
+ * Force refresh the token.
130
+ *
131
+ * @returns New installation access token
132
+ */
133
+ async refreshToken() {
134
+ // Deduplicate concurrent refresh requests
135
+ if (this.refreshPromise) {
136
+ return this.refreshPromise;
137
+ }
138
+ this.refreshPromise = this.doRefresh();
139
+ try {
140
+ return await this.refreshPromise;
141
+ }
142
+ finally {
143
+ this.refreshPromise = null;
144
+ }
145
+ }
146
+ /**
147
+ * Check if token needs refresh (within 5 minutes of expiration).
148
+ *
149
+ * @returns true if token should be refreshed
150
+ */
151
+ isTokenExpiringSoon() {
152
+ const cached = this.cache.get(this.config.installation_id);
153
+ return cached ? this.isExpiringSoon(cached) : true;
154
+ }
155
+ /**
156
+ * Validate the configuration and private key.
157
+ *
158
+ * @throws Error if configuration is invalid
159
+ */
160
+ async validate() {
161
+ // Validate required fields
162
+ if (!this.config.id) {
163
+ throw new Error("GitHub App ID is required. Configure 'app.id' in .fractary/config.yaml");
164
+ }
165
+ if (!this.config.installation_id) {
166
+ throw new Error("GitHub App Installation ID is required. Configure 'app.installation_id' in .fractary/config.yaml");
167
+ }
168
+ // Validate private key can be loaded
169
+ await PrivateKeyLoader.load(this.config);
170
+ // Attempt to generate JWT to validate key
171
+ await this.generateJWT();
172
+ }
173
+ /**
174
+ * Perform the actual token refresh
175
+ */
176
+ async doRefresh() {
177
+ const jwtToken = await this.generateJWT();
178
+ const installationToken = await this.exchangeForInstallationToken(jwtToken);
179
+ // Cache the token
180
+ this.cache.set(this.config.installation_id, {
181
+ token: installationToken.token,
182
+ expires_at: new Date(installationToken.expires_at),
183
+ installation_id: this.config.installation_id,
184
+ });
185
+ return installationToken.token;
186
+ }
187
+ /**
188
+ * Generate a JWT for GitHub App authentication
189
+ */
190
+ async generateJWT() {
191
+ const privateKey = await PrivateKeyLoader.load(this.config);
192
+ const now = Math.floor(Date.now() / 1000);
193
+ const payload = {
194
+ iat: now - 60, // Issued 60 seconds ago to allow for clock drift
195
+ exp: now + GitHubAppAuth.JWT_EXPIRY_SECONDS,
196
+ iss: this.config.id,
197
+ };
198
+ try {
199
+ return jwt.sign(payload, privateKey, { algorithm: 'RS256' });
200
+ }
201
+ catch (error) {
202
+ if (error instanceof Error) {
203
+ throw new Error(`Failed to generate JWT: ${error.message}`);
204
+ }
205
+ throw error;
206
+ }
207
+ }
208
+ /**
209
+ * Exchange JWT for installation access token
210
+ */
211
+ async exchangeForInstallationToken(jwtToken) {
212
+ const url = `${GitHubAppAuth.GITHUB_API_URL}/app/installations/${this.config.installation_id}/access_tokens`;
213
+ let response;
214
+ try {
215
+ response = await fetch(url, {
216
+ method: 'POST',
217
+ headers: {
218
+ Accept: 'application/vnd.github+json',
219
+ Authorization: `Bearer ${jwtToken}`,
220
+ 'X-GitHub-Api-Version': '2022-11-28',
221
+ },
222
+ });
223
+ }
224
+ catch (error) {
225
+ if (error instanceof Error) {
226
+ throw new Error(`Failed to connect to GitHub API: ${error.message}`);
227
+ }
228
+ throw error;
229
+ }
230
+ if (!response.ok) {
231
+ const errorBody = await response.text().catch(() => 'Unknown error');
232
+ if (response.status === 401) {
233
+ throw new Error(`Failed to authenticate with GitHub App. Status: ${response.status}, Response: ${errorBody}`);
234
+ }
235
+ if (response.status === 404) {
236
+ throw new Error(`GitHub App installation not found (ID: ${this.config.installation_id}). ` +
237
+ 'Verify the Installation ID is correct and the app is installed.');
238
+ }
239
+ if (response.status === 403) {
240
+ // Check for rate limiting
241
+ const rateLimitRemaining = response.headers.get('x-ratelimit-remaining');
242
+ const rateLimitReset = response.headers.get('x-ratelimit-reset');
243
+ if (rateLimitRemaining === '0' && rateLimitReset) {
244
+ const resetValue = parseInt(rateLimitReset, 10);
245
+ if (!isNaN(resetValue)) {
246
+ const resetTime = new Date(resetValue * 1000);
247
+ const secondsUntilReset = Math.ceil((resetTime.getTime() - Date.now()) / 1000);
248
+ throw new Error(`GitHub API rate limited. Retry after ${secondsUntilReset} seconds.`);
249
+ }
250
+ }
251
+ }
252
+ throw new Error(`Failed to get installation token: ${response.status} ${errorBody}`);
253
+ }
254
+ return response.json();
255
+ }
256
+ /**
257
+ * Check if token is expired
258
+ */
259
+ isExpired(cached) {
260
+ return cached.expires_at.getTime() <= Date.now();
261
+ }
262
+ /**
263
+ * Check if token is expiring soon
264
+ */
265
+ isExpiringSoon(cached) {
266
+ return cached.expires_at.getTime() - Date.now() < GitHubAppAuth.REFRESH_THRESHOLD_MS;
267
+ }
268
+ /**
269
+ * Trigger background token refresh with retry (non-blocking)
270
+ */
271
+ triggerBackgroundRefresh() {
272
+ if (this.refreshPromise) {
273
+ return; // Already refreshing
274
+ }
275
+ // Retry with exponential backoff for transient failures
276
+ this.refreshWithRetry(3, 1000).catch(error => {
277
+ console.error('[GitHubAppAuth] Background token refresh failed after retries:', error.message);
278
+ });
279
+ }
280
+ /**
281
+ * Refresh token with exponential backoff retry
282
+ *
283
+ * @param maxRetries - Maximum number of retry attempts
284
+ * @param baseDelayMs - Base delay in milliseconds (doubles each retry)
285
+ */
286
+ async refreshWithRetry(maxRetries, baseDelayMs) {
287
+ let lastError = null;
288
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
289
+ try {
290
+ return await this.refreshToken();
291
+ }
292
+ catch (error) {
293
+ lastError = error instanceof Error ? error : new Error(String(error));
294
+ // Don't retry auth errors (invalid credentials, wrong installation ID)
295
+ const errorMessage = lastError.message.toLowerCase();
296
+ if (errorMessage.includes('401') ||
297
+ errorMessage.includes('404') ||
298
+ errorMessage.includes('invalid') ||
299
+ errorMessage.includes('not found')) {
300
+ throw lastError;
301
+ }
302
+ // If we have retries left, wait with exponential backoff
303
+ if (attempt < maxRetries) {
304
+ const delay = baseDelayMs * Math.pow(2, attempt);
305
+ console.error(`[GitHubAppAuth] Token refresh failed (attempt ${attempt + 1}/${maxRetries + 1}), ` +
306
+ `retrying in ${delay}ms: ${lastError.message}`);
307
+ await this.sleep(delay);
308
+ }
309
+ }
310
+ }
311
+ throw lastError || new Error('Token refresh failed after retries');
312
+ }
313
+ /**
314
+ * Sleep helper for retry delays
315
+ */
316
+ sleep(ms) {
317
+ return new Promise(resolve => setTimeout(resolve, ms));
318
+ }
319
+ }
320
+ /**
321
+ * Static Token Provider
322
+ *
323
+ * Simple provider for static PAT tokens
324
+ */
325
+ export class StaticTokenProvider {
326
+ token;
327
+ constructor(token) {
328
+ this.token = token;
329
+ }
330
+ async getToken() {
331
+ return this.token;
332
+ }
333
+ }
334
+ /**
335
+ * GitHub App Token Provider
336
+ *
337
+ * Provider that uses GitHubAppAuth for dynamic token generation
338
+ */
339
+ export class GitHubAppTokenProvider {
340
+ auth;
341
+ constructor(auth) {
342
+ this.auth = auth;
343
+ }
344
+ async getToken() {
345
+ return this.auth.getToken();
346
+ }
347
+ }
348
+ //# sourceMappingURL=github-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app.js","sourceRoot":"","sources":["../../src/auth/github-app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fractary/faber - Auth Module
3
+ *
4
+ * Authentication utilities for GitHub App and PAT authentication.
5
+ */
6
+ export { GitHubAppAuth, GitHubAppConfig, PrivateKeyLoader, TokenProvider, StaticTokenProvider, GitHubAppTokenProvider, } from './github-app.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fractary/faber - Auth Module
3
+ *
4
+ * Authentication utilities for GitHub App and PAT authentication.
5
+ */
6
+ export { GitHubAppAuth, PrivateKeyLoader, StaticTokenProvider, GitHubAppTokenProvider, } from './github-app.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,aAAa,EAEb,gBAAgB,EAEhB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -24,4 +24,5 @@ export * from './state/index.js';
24
24
  export * from './workflow/index.js';
25
25
  export * from './storage/index.js';
26
26
  export * from './agents/index.js';
27
+ export * from './auth/index.js';
27
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAG5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAG5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -26,4 +26,6 @@ export * from './state/index.js';
26
26
  export * from './workflow/index.js';
27
27
  export * from './storage/index.js';
28
28
  export * from './agents/index.js';
29
+ // Auth module
30
+ export * from './auth/index.js';
29
31
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAe;AACf,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAE5B,iBAAiB;AACjB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAe;AACf,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAE5B,iBAAiB;AACjB,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAElC,cAAc;AACd,cAAc,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fractary/faber",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "FABER SDK - Development toolkit for AI-assisted workflows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -41,6 +41,10 @@
41
41
  "./agents": {
42
42
  "types": "./dist/agents/index.d.ts",
43
43
  "default": "./dist/agents/index.js"
44
+ },
45
+ "./auth": {
46
+ "types": "./dist/auth/index.d.ts",
47
+ "default": "./dist/auth/index.js"
44
48
  }
45
49
  },
46
50
  "files": [
@@ -78,11 +82,13 @@
78
82
  "@fractary/forge": "^1.1.4",
79
83
  "commander": "^12.0.0",
80
84
  "js-yaml": "^4.1.1",
85
+ "jsonwebtoken": "^9.0.0",
81
86
  "zod": "^3.22.4"
82
87
  },
83
88
  "devDependencies": {
84
89
  "@types/jest": "^30.0.0",
85
90
  "@types/js-yaml": "^4.0.9",
91
+ "@types/jsonwebtoken": "^9.0.0",
86
92
  "@types/node": "^20.19.26",
87
93
  "@typescript-eslint/eslint-plugin": "^6.19.0",
88
94
  "@typescript-eslint/parser": "^6.19.0",