@bragduck/cli 2.2.0 → 2.2.1

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/dist/index.js CHANGED
@@ -1031,11 +1031,19 @@ var init_api_service = __esm({
1031
1031
  * Refine brags using AI
1032
1032
  */
1033
1033
  async refineBrags(request) {
1034
- logger.debug(`Refining ${request.brags.length} brags`);
1034
+ const MAX_TEXT_LENGTH = 1e4;
1035
+ const trimmedRequest = {
1036
+ ...request,
1037
+ brags: request.brags.map((brag) => ({
1038
+ ...brag,
1039
+ text: brag.text && brag.text.length > MAX_TEXT_LENGTH ? brag.text.substring(0, MAX_TEXT_LENGTH) : brag.text
1040
+ }))
1041
+ };
1042
+ logger.debug(`Refining ${trimmedRequest.brags.length} brags`);
1035
1043
  try {
1036
1044
  const response = await this.makeRequest(API_ENDPOINTS.BRAGS.REFINE, {
1037
1045
  method: "POST",
1038
- body: request
1046
+ body: trimmedRequest
1039
1047
  });
1040
1048
  logger.debug(`Successfully refined ${response.refined_brags.length} brags`);
1041
1049
  return response;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/constants.ts","../src/services/storage.service.ts","../src/utils/errors.ts","../src/utils/logger.ts","../src/utils/oauth-server.ts","../src/utils/browser.ts","../src/services/auth.service.ts","../src/services/api.service.ts","../src/utils/version.ts","../src/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","// Load environment variables\nimport { config } from 'dotenv';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\n\n// Get the directory of this file\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Load .env from the project root (silently)\n// In production, this file is bundled into dist/bin/bragduck.js, so we need to go up 2 levels\n// In development (src/), we'd need to go up 1 level, but the build is what matters\nconfig({ path: join(__dirname, '..', '..', '.env'), debug: false, quiet: true } as any);\n\n// App-wide constants for Bragduck CLI\n\n/**\n * Application name used for storage and configuration\n */\nexport const APP_NAME = 'bragduck';\n\n/**\n * Storage keys for credentials and configuration\n */\nexport const STORAGE_KEYS = {\n ACCESS_TOKEN: 'access_token',\n REFRESH_TOKEN: 'refresh_token',\n USER_INFO: 'user_info',\n OAUTH_STATE: 'oauth_state',\n} as const;\n\n/**\n * Configuration keys\n */\nexport const CONFIG_KEYS = {\n DEFAULT_COMMIT_DAYS: 'defaultCommitDays',\n AUTO_VERSION_CHECK: 'autoVersionCheck',\n} as const;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG = {\n defaultCommitDays: 30,\n autoVersionCheck: true,\n} as const;\n\n/**\n * OAuth configuration\n */\nexport const OAUTH_CONFIG = {\n CLIENT_ID: 'bragduck-cli',\n CALLBACK_PATH: '/callback',\n TIMEOUT_MS: 120000, // 2 minutes\n MIN_PORT: 8000,\n MAX_PORT: 9000,\n} as const;\n\n/**\n * API endpoints\n */\nexport const API_ENDPOINTS = {\n AUTH: {\n INITIATE: '/v1/auth/cli/initiate',\n TOKEN: '/v1/auth/cli/token',\n },\n BRAGS: {\n CREATE: '/v1/brags',\n LIST: '/v1/brags',\n REFINE: '/v1/brags/refine',\n },\n SUBSCRIPTION: {\n STATUS: '/v1/subscriptions/status',\n },\n VERSION: '/v1/cli/version',\n /**\n * @deprecated Use BRAGS.REFINE instead\n */\n COMMITS: {\n REFINE: '/v1/commits/refine',\n },\n} as const;\n\n/**\n * Encryption configuration for file-based credential storage\n */\nexport const ENCRYPTION_CONFIG = {\n ALGORITHM: 'aes-256-gcm',\n KEY_LENGTH: 32,\n IV_LENGTH: 16,\n AUTH_TAG_LENGTH: 16,\n SALT_LENGTH: 32,\n} as const;\n\n/**\n * File paths for credential storage fallback\n */\nexport const STORAGE_PATHS = {\n CREDENTIALS_DIR: '.bragduck',\n CREDENTIALS_FILE: 'credentials.enc',\n CONFIG_FILE: 'config.json',\n} as const;\n\n/**\n * Error codes\n */\nexport const ERROR_CODES = {\n AUTH_FAILED: 'AUTH_FAILED',\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n NETWORK_ERROR: 'NETWORK_ERROR',\n GIT_ERROR: 'GIT_ERROR',\n API_ERROR: 'API_ERROR',\n STORAGE_ERROR: 'STORAGE_ERROR',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n} as const;\n\n/**\n * HTTP status codes\n */\nexport const HTTP_STATUS = {\n OK: 200,\n CREATED: 201,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n INTERNAL_SERVER_ERROR: 500,\n} as const;\n\n/**\n * GitHub configuration\n */\nexport const GITHUB_CONFIG = {\n MIN_GH_VERSION: '2.0.0',\n PR_SEARCH_FIELDS: 'number,title,body,author,mergedAt,additions,deletions,changedFiles,url,labels',\n MAX_BODY_LENGTH: 5000,\n} as const;\n","import Conf from 'conf';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { APP_NAME, ENCRYPTION_CONFIG, STORAGE_PATHS, DEFAULT_CONFIG } from '../constants.js';\nimport type {\n StoredCredentials,\n UserInfo,\n OAuthState,\n StorageBackend,\n EncryptedData,\n BragduckConfig,\n} from '../types/config.types.js';\n\n/**\n * Storage service for managing credentials and configuration\n * Uses encrypted file storage for credentials\n *\n * NOTE: OS keychain support (via cross-keychain or similar) can be added in the future.\n * For now, we use secure encrypted file storage with machine-specific keys.\n */\nexport class StorageService {\n private config: Conf<BragduckConfig>;\n private storageBackend: StorageBackend;\n private credentialsDir: string;\n private credentialsFilePath: string;\n\n constructor() {\n // Initialize config management\n this.config = new Conf<BragduckConfig>({\n projectName: APP_NAME,\n defaults: DEFAULT_CONFIG,\n });\n\n // Set up credentials directory and file path\n this.credentialsDir = join(homedir(), STORAGE_PATHS.CREDENTIALS_DIR);\n this.credentialsFilePath = join(this.credentialsDir, STORAGE_PATHS.CREDENTIALS_FILE);\n\n // Use file storage for now (keychain support can be added later)\n this.storageBackend = 'file';\n this.ensureCredentialsDir();\n }\n\n /**\n * Ensure credentials directory exists\n */\n private ensureCredentialsDir(): void {\n if (!existsSync(this.credentialsDir)) {\n mkdirSync(this.credentialsDir, { recursive: true, mode: 0o700 });\n }\n }\n\n /**\n * Encrypt data for file storage\n */\n private encrypt(data: string, key: Buffer): EncryptedData {\n const iv = randomBytes(ENCRYPTION_CONFIG.IV_LENGTH);\n const cipher = createCipheriv(ENCRYPTION_CONFIG.ALGORITHM, key, iv, {\n authTagLength: ENCRYPTION_CONFIG.AUTH_TAG_LENGTH,\n });\n\n let encrypted = cipher.update(data, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n\n const authTag = cipher.getAuthTag();\n\n return {\n encrypted,\n iv: iv.toString('hex'),\n authTag: authTag.toString('hex'),\n salt: '', // Salt is stored separately\n };\n }\n\n /**\n * Decrypt data from file storage\n */\n private decrypt(encryptedData: EncryptedData, key: Buffer): string {\n const decipher = createDecipheriv(\n ENCRYPTION_CONFIG.ALGORITHM,\n key,\n Buffer.from(encryptedData.iv, 'hex'),\n {\n authTagLength: ENCRYPTION_CONFIG.AUTH_TAG_LENGTH,\n }\n );\n\n decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));\n\n let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n\n return decrypted;\n }\n\n /**\n * Derive encryption key from machine-specific data\n */\n private deriveEncryptionKey(salt: Buffer): Buffer {\n // Use machine ID and app name as password\n const password = `${APP_NAME}-${homedir()}-${process.platform}`;\n return scryptSync(password, salt, ENCRYPTION_CONFIG.KEY_LENGTH);\n }\n\n /**\n * Store credentials using encrypted file storage\n */\n async setCredentials(credentials: StoredCredentials): Promise<void> {\n const data = JSON.stringify(credentials);\n\n // Encrypt and store credentials\n const salt = randomBytes(ENCRYPTION_CONFIG.SALT_LENGTH);\n const key = this.deriveEncryptionKey(salt);\n const encrypted = this.encrypt(data, key);\n encrypted.salt = salt.toString('hex');\n\n writeFileSync(this.credentialsFilePath, JSON.stringify(encrypted), {\n mode: 0o600,\n encoding: 'utf8',\n });\n }\n\n /**\n * Retrieve credentials from encrypted file storage\n */\n async getCredentials(): Promise<StoredCredentials | null> {\n if (!existsSync(this.credentialsFilePath)) {\n return null;\n }\n\n try {\n const encryptedData: EncryptedData = JSON.parse(\n readFileSync(this.credentialsFilePath, 'utf8')\n );\n const salt = Buffer.from(encryptedData.salt, 'hex');\n const key = this.deriveEncryptionKey(salt);\n const decrypted = this.decrypt(encryptedData, key);\n return JSON.parse(decrypted);\n } catch (error) {\n console.error('Failed to decrypt credentials:', error);\n return null;\n }\n }\n\n /**\n * Delete credentials from file storage\n */\n async deleteCredentials(): Promise<void> {\n // Delete file if it exists\n if (existsSync(this.credentialsFilePath)) {\n try {\n unlinkSync(this.credentialsFilePath);\n } catch (error) {\n console.error('Failed to delete credentials file:', error);\n }\n }\n }\n\n /**\n * Check if user is authenticated\n */\n async isAuthenticated(): Promise<boolean> {\n const credentials = await this.getCredentials();\n if (!credentials || !credentials.accessToken) {\n return false;\n }\n\n // Check if token is expired\n if (credentials.expiresAt && credentials.expiresAt < Date.now()) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Store user information\n */\n setUserInfo(userInfo: UserInfo): void {\n this.config.set('userInfo' as keyof BragduckConfig, userInfo as any);\n }\n\n /**\n * Get user information\n */\n getUserInfo(): UserInfo | null {\n return (this.config.get('userInfo' as keyof BragduckConfig) as any) || null;\n }\n\n /**\n * Delete user information\n */\n deleteUserInfo(): void {\n this.config.delete('userInfo' as keyof BragduckConfig);\n }\n\n /**\n * Store OAuth state for CSRF protection\n */\n setOAuthState(state: OAuthState): void {\n this.config.set('oauthState' as keyof BragduckConfig, state as any);\n }\n\n /**\n * Get OAuth state\n */\n getOAuthState(): OAuthState | null {\n return (this.config.get('oauthState' as keyof BragduckConfig) as any) || null;\n }\n\n /**\n * Delete OAuth state\n */\n deleteOAuthState(): void {\n this.config.delete('oauthState' as keyof BragduckConfig);\n }\n\n /**\n * Get configuration value\n */\n getConfig<K extends keyof BragduckConfig>(key: K): BragduckConfig[K] {\n return this.config.get(key);\n }\n\n /**\n * Set configuration value\n */\n setConfig<K extends keyof BragduckConfig>(key: K, value: BragduckConfig[K]): void {\n this.config.set(key, value);\n }\n\n /**\n * Get all configuration\n */\n getAllConfig(): BragduckConfig {\n return this.config.store;\n }\n\n /**\n * Reset configuration to defaults\n */\n resetConfig(): void {\n this.config.clear();\n // Re-apply defaults\n Object.entries(DEFAULT_CONFIG).forEach(([key, value]) => {\n this.config.set(key as keyof BragduckConfig, value as any);\n });\n }\n\n /**\n * Get current storage backend\n */\n getStorageBackend(): StorageBackend {\n return this.storageBackend;\n }\n\n /**\n * Clear all stored data (credentials + config)\n */\n async clearAll(): Promise<void> {\n await this.deleteCredentials();\n this.deleteUserInfo();\n this.deleteOAuthState();\n this.resetConfig();\n }\n}\n\n// Export singleton instance\nexport const storageService = new StorageService();\n","// Custom error classes for Bragduck CLI\n\n/**\n * Base error class for all Bragduck errors\n */\nexport class BragduckError extends Error {\n public code: string;\n public details?: Record<string, any>;\n\n constructor(message: string, code: string, details?: Record<string, any>) {\n super(message);\n this.name = 'BragduckError';\n this.code = code;\n this.details = details;\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Authentication-related errors\n */\nexport class AuthenticationError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'AUTH_ERROR', details);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Git operation errors\n */\nexport class GitError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GIT_ERROR', details);\n this.name = 'GitError';\n }\n}\n\n/**\n * API communication errors\n */\nexport class ApiError extends BragduckError {\n public statusCode?: number;\n\n constructor(message: string, statusCode?: number, details?: Record<string, any>) {\n super(message, 'API_ERROR', details);\n this.name = 'ApiError';\n this.statusCode = statusCode;\n }\n}\n\n/**\n * Network-related errors\n */\nexport class NetworkError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'NETWORK_ERROR', details);\n this.name = 'NetworkError';\n }\n}\n\n/**\n * Storage-related errors\n */\nexport class StorageError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'STORAGE_ERROR', details);\n this.name = 'StorageError';\n }\n}\n\n/**\n * Validation errors\n */\nexport class ValidationError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * OAuth-specific errors\n */\nexport class OAuthError extends AuthenticationError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, details);\n this.name = 'OAuthError';\n }\n}\n\n/**\n * Token expiration error\n */\nexport class TokenExpiredError extends AuthenticationError {\n constructor(message = 'Authentication token has expired') {\n super(message);\n this.name = 'TokenExpiredError';\n this.code = 'TOKEN_EXPIRED';\n }\n}\n\n/**\n * GitHub-related errors\n */\nexport class GitHubError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GITHUB_ERROR', details);\n this.name = 'GitHubError';\n }\n}\n","import chalk from 'chalk';\n\n/**\n * Logger utility for consistent console output\n */\nexport const logger = {\n /**\n * Debug message (only shown when DEBUG env var is set)\n */\n debug: (message: string, ...args: any[]): void => {\n if (process.env.DEBUG) {\n console.log(chalk.gray(`[DEBUG] ${message}`), ...args);\n }\n },\n\n /**\n * Info message\n */\n info: (message: string): void => {\n console.log(chalk.blue(`ℹ ${message}`));\n },\n\n /**\n * Success message\n */\n success: (message: string): void => {\n console.log(chalk.green(`✓ ${message}`));\n },\n\n /**\n * Warning message\n */\n warning: (message: string): void => {\n console.warn(chalk.yellow(`⚠ ${message}`));\n },\n\n /**\n * Error message\n */\n error: (message: string): void => {\n console.error(chalk.red(`✗ ${message}`));\n },\n\n /**\n * Plain log without formatting\n */\n log: (message: string): void => {\n console.log(message);\n },\n};\n","import { createServer, type Server, type IncomingMessage, type ServerResponse } from 'http';\nimport { parse } from 'url';\nimport { OAUTH_CONFIG } from '../constants.js';\nimport { OAuthError } from './errors.js';\nimport { logger } from './logger.js';\n\n/**\n * OAuth callback result\n */\nexport interface OAuthCallbackResult {\n code: string;\n state: string;\n port: number;\n}\n\n/**\n * Find an available port in the configured range\n */\nasync function findAvailablePort(): Promise<number> {\n const { MIN_PORT, MAX_PORT } = OAUTH_CONFIG;\n\n for (let port = MIN_PORT; port <= MAX_PORT; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n const testServer = createServer();\n testServer.once('error', reject);\n testServer.once('listening', () => {\n testServer.close(() => resolve());\n });\n testServer.listen(port, '127.0.0.1');\n });\n return port;\n } catch {\n // Port is in use, try next one\n continue;\n }\n }\n\n throw new OAuthError(`No available ports found in range ${MIN_PORT}-${MAX_PORT}`);\n}\n\n/**\n * Success HTML page to show after authentication\n */\nconst SUCCESS_HTML = `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bragduck - Authentication Successful</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n }\n .container {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 1rem;\n backdrop-filter: blur(10px);\n box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);\n max-width: 500px;\n }\n h1 {\n font-size: 2.5rem;\n margin: 0 0 1rem 0;\n }\n .checkmark {\n font-size: 4rem;\n animation: scale-in 0.3s ease-out;\n }\n p {\n font-size: 1.2rem;\n margin: 1rem 0;\n opacity: 0.9;\n }\n @keyframes scale-in {\n from { transform: scale(0); }\n to { transform: scale(1); }\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"checkmark\">✓</div>\n <h1>Authentication Successful!</h1>\n <p>You can now close this window and return to your terminal.</p>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Error HTML page to show on authentication failure\n */\nconst ERROR_HTML = (error: string) => `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bragduck - Authentication Failed</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n }\n .container {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 1rem;\n backdrop-filter: blur(10px);\n box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);\n max-width: 500px;\n }\n h1 {\n font-size: 2.5rem;\n margin: 0 0 1rem 0;\n }\n .error-icon {\n font-size: 4rem;\n }\n p {\n font-size: 1.2rem;\n margin: 1rem 0;\n opacity: 0.9;\n }\n .error-details {\n background: rgba(0, 0, 0, 0.2);\n padding: 1rem;\n border-radius: 0.5rem;\n font-family: monospace;\n font-size: 0.9rem;\n margin-top: 1rem;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"error-icon\">✗</div>\n <h1>Authentication Failed</h1>\n <p>Please return to your terminal and try again.</p>\n <div class=\"error-details\">${error}</div>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Start OAuth callback server and wait for callback\n */\nexport async function startOAuthCallbackServer(\n expectedState: string\n): Promise<OAuthCallbackResult> {\n const port = await findAvailablePort();\n const timeout = OAUTH_CONFIG.TIMEOUT_MS;\n\n return new Promise<OAuthCallbackResult>((resolve, reject) => {\n let server: Server | null = null;\n let timeoutId: ReturnType<typeof globalThis.setTimeout> | null = null;\n\n const cleanup = () => {\n if (timeoutId) {\n globalThis.clearTimeout(timeoutId);\n }\n if (server) {\n // Close all connections immediately (Node.js 18+)\n if (typeof (server as any).closeAllConnections === 'function') {\n (server as any).closeAllConnections();\n }\n server.close(() => {\n logger.debug('OAuth server closed');\n });\n server.unref(); // Allow process to exit even if server is still running\n }\n };\n\n const handleRequest = (req: IncomingMessage, res: ServerResponse) => {\n const parsedUrl = parse(req.url || '', true);\n\n logger.debug(`OAuth callback received: ${req.url}`);\n\n // Handle callback request\n if (parsedUrl.pathname === OAUTH_CONFIG.CALLBACK_PATH) {\n const { code, state, error, error_description } = parsedUrl.query;\n\n // Check for OAuth errors\n if (error) {\n const errorMsg = error_description || error;\n logger.debug(`OAuth error: ${errorMsg}`);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(String(errorMsg)));\n\n cleanup();\n reject(new OAuthError(`OAuth error: ${errorMsg}`));\n return;\n }\n\n // Validate required parameters\n if (!code || !state) {\n const errorMsg = 'Missing code or state parameter';\n logger.debug(errorMsg);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(errorMsg));\n\n cleanup();\n reject(new OAuthError(errorMsg));\n return;\n }\n\n // Verify state matches (CSRF protection)\n if (state !== expectedState) {\n const errorMsg = 'Invalid state parameter (possible CSRF attack)';\n logger.debug(errorMsg);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(errorMsg));\n\n cleanup();\n reject(new OAuthError(errorMsg));\n return;\n }\n\n // Success!\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(SUCCESS_HTML);\n\n // Give the response time to be sent before closing\n globalThis.setTimeout(() => {\n cleanup();\n resolve({\n code: String(code),\n state: String(state),\n port,\n });\n }, 100);\n return;\n }\n\n // Handle other requests (404)\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n };\n\n // Create server\n server = createServer(handleRequest);\n\n // Handle server errors\n server.on('error', (error) => {\n logger.debug(`OAuth server error: ${error.message}`);\n cleanup();\n reject(new OAuthError(`OAuth server error: ${error.message}`));\n });\n\n // Start server\n server.listen(port, '127.0.0.1', () => {\n logger.debug(\n `OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`\n );\n });\n\n // Set timeout\n timeoutId = globalThis.setTimeout(() => {\n logger.debug('OAuth callback timeout');\n cleanup();\n reject(new OAuthError('Authentication timeout - no callback received within 2 minutes'));\n }, timeout);\n });\n}\n\n/**\n * Get the callback URL for the OAuth flow\n */\nexport async function getCallbackUrl(): Promise<string> {\n const port = await findAvailablePort();\n return `http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`;\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { logger } from './logger.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Open a URL in the default browser\n */\nexport async function openBrowser(url: string): Promise<void> {\n const platform = process.platform;\n let command: string;\n\n // Determine the command based on the platform\n switch (platform) {\n case 'darwin': // macOS\n command = `open \"${url}\"`;\n break;\n case 'win32': // Windows\n command = `start \"\" \"${url}\"`;\n break;\n default: // Linux and others\n command = `xdg-open \"${url}\"`;\n break;\n }\n\n try {\n logger.debug(`Opening browser with command: ${command}`);\n await execAsync(command);\n logger.debug('Browser opened successfully');\n } catch (error) {\n logger.debug(`Failed to open browser: ${error}`);\n throw new Error(`Failed to open browser automatically. Please open this URL manually:\\n${url}`);\n }\n}\n","import { randomBytes } from 'crypto';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath, URLSearchParams } from 'url';\nimport { dirname, join } from 'path';\nimport { ofetch } from 'ofetch';\nimport { OAUTH_CONFIG, API_ENDPOINTS } from '../constants.js';\nimport { storageService } from './storage.service.js';\nimport { startOAuthCallbackServer, getCallbackUrl } from '../utils/oauth-server.js';\nimport { openBrowser } from '../utils/browser.js';\nimport { AuthenticationError, NetworkError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type { StoredCredentials, UserInfo } from '../types/config.types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get CLI version and User-Agent string\n */\nfunction getUserAgent(): string {\n try {\n // In production (dist/services/auth.service.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const version = packageJson.version;\n const platform = process.platform;\n const arch = process.arch;\n return `BragDuck-CLI/${version} (${platform}-${arch})`;\n } catch {\n logger.debug('Failed to read package.json version');\n return 'BragDuck-CLI/2.0.0';\n }\n}\n\n/**\n * Token exchange response from the backend\n */\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type: string;\n user?: UserInfo;\n}\n\n/**\n * Authentication service for managing OAuth flow and tokens\n */\nexport class AuthService {\n private apiBaseUrl: string;\n\n constructor() {\n // Use environment variable or default API URL\n this.apiBaseUrl = process.env.API_BASE_URL || 'https://api.bragduck.com';\n }\n\n /**\n * Generate a random state string for CSRF protection\n */\n private generateState(): string {\n return randomBytes(32).toString('hex');\n }\n\n /**\n * Build the OAuth authorization URL\n */\n private async buildAuthUrl(state: string, callbackUrl: string): Promise<string> {\n const params = new URLSearchParams({\n client_id: OAUTH_CONFIG.CLIENT_ID,\n redirect_uri: callbackUrl,\n state,\n });\n\n return `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.INITIATE}?${params.toString()}`;\n }\n\n /**\n * Exchange authorization code for access token\n */\n private async exchangeCodeForToken(code: string, callbackUrl: string): Promise<TokenResponse> {\n try {\n logger.debug('Exchanging authorization code for token');\n\n const response = await ofetch<TokenResponse>(\n `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.TOKEN}`,\n {\n method: 'POST',\n body: {\n code,\n redirect_uri: callbackUrl,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n grant_type: 'authorization_code',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': getUserAgent(),\n },\n }\n );\n\n logger.debug('Token exchange successful');\n return response;\n } catch (error: any) {\n logger.debug(`Token exchange failed: ${error.message}`);\n\n if (error.response) {\n throw new AuthenticationError(\n `Token exchange failed: ${error.response.statusText || 'Unknown error'}`,\n {\n statusCode: error.response.status,\n body: error.response._data,\n }\n );\n }\n\n throw new NetworkError('Failed to connect to authentication server', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Complete OAuth flow: start server, open browser, wait for callback, exchange token\n */\n async login(): Promise<UserInfo> {\n logger.debug('Starting OAuth login flow');\n\n // Generate state for CSRF protection\n const state = this.generateState();\n const callbackUrl = await getCallbackUrl();\n\n // Store state temporarily\n storageService.setOAuthState({\n state,\n createdAt: Date.now(),\n });\n\n logger.debug(`OAuth state: ${state}`);\n logger.debug(`Callback URL: ${callbackUrl}`);\n\n // Build authorization URL\n const authUrl = await this.buildAuthUrl(state, callbackUrl);\n logger.debug(`Authorization URL: ${authUrl}`);\n\n // Start callback server (this will wait for the callback)\n const serverPromise = startOAuthCallbackServer(state);\n\n // Open browser\n try {\n await openBrowser(authUrl);\n } catch {\n // If browser opening fails, show the URL for manual opening\n logger.warning('Could not open browser automatically');\n logger.info(`Please open this URL in your browser:`);\n logger.log(authUrl);\n }\n\n // Wait for callback\n let callbackResult;\n try {\n callbackResult = await serverPromise;\n } catch (error: any) {\n storageService.deleteOAuthState();\n throw error;\n }\n\n // Clear OAuth state\n storageService.deleteOAuthState();\n\n // Exchange code for token\n const tokenResponse = await this.exchangeCodeForToken(callbackResult.code, callbackUrl);\n\n // Calculate expiration time\n const expiresAt = tokenResponse.expires_in\n ? Date.now() + tokenResponse.expires_in * 1000\n : undefined;\n\n // Store credentials\n const credentials: StoredCredentials = {\n accessToken: tokenResponse.access_token,\n refreshToken: tokenResponse.refresh_token,\n expiresAt,\n };\n await storageService.setCredentials(credentials);\n\n // Store user info if provided\n if (tokenResponse.user) {\n storageService.setUserInfo(tokenResponse.user);\n }\n\n logger.debug('Login successful');\n\n return tokenResponse.user || { id: 'unknown', email: 'unknown', name: 'Unknown User' };\n }\n\n /**\n * Logout: clear all stored credentials and user info\n */\n async logout(): Promise<void> {\n logger.debug('Logging out');\n\n await storageService.deleteCredentials();\n storageService.deleteUserInfo();\n storageService.deleteOAuthState();\n\n logger.debug('Logout complete');\n }\n\n /**\n * Check if user is authenticated\n */\n async isAuthenticated(): Promise<boolean> {\n return storageService.isAuthenticated();\n }\n\n /**\n * Get current access token\n */\n async getAccessToken(): Promise<string | null> {\n const credentials = await storageService.getCredentials();\n return credentials?.accessToken || null;\n }\n\n /**\n * Get current user info\n */\n getUserInfo(): UserInfo | null {\n return storageService.getUserInfo();\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refreshToken(): Promise<void> {\n logger.debug('Refreshing access token');\n\n const credentials = await storageService.getCredentials();\n if (!credentials?.refreshToken) {\n throw new AuthenticationError('No refresh token available');\n }\n\n try {\n const response = await ofetch<TokenResponse>(\n `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.TOKEN}`,\n {\n method: 'POST',\n body: {\n refresh_token: credentials.refreshToken,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n grant_type: 'refresh_token',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': getUserAgent(),\n },\n }\n );\n\n // Calculate expiration time\n const expiresAt = response.expires_in ? Date.now() + response.expires_in * 1000 : undefined;\n\n // Update stored credentials\n const newCredentials: StoredCredentials = {\n accessToken: response.access_token,\n refreshToken: response.refresh_token || credentials.refreshToken,\n expiresAt,\n };\n await storageService.setCredentials(newCredentials);\n\n logger.debug('Token refresh successful');\n } catch (error: any) {\n logger.debug(`Token refresh failed: ${error.message}`);\n\n // If refresh fails, user needs to re-authenticate\n await this.logout();\n throw new AuthenticationError('Token refresh failed. Please log in again.');\n }\n }\n}\n\n// Export singleton instance\nexport const authService = new AuthService();\n","import { ofetch, type FetchOptions } from 'ofetch';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { URLSearchParams } from 'url';\nimport { dirname, join } from 'path';\nimport { authService } from './auth.service.js';\nimport { API_ENDPOINTS, HTTP_STATUS } from '../constants.js';\nimport { ApiError, NetworkError, TokenExpiredError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type {\n RefineCommitsRequest,\n RefineCommitsResponse,\n RefineBragsRequest,\n RefineBragsResponse,\n CreateBragsRequest,\n CreateBragsResponse,\n ListBragsParams,\n ListBragsResponse,\n GetSubscriptionStatusResponse,\n VersionCheckResponse,\n ApiErrorResponse,\n} from '../types/api.types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get CLI version from package.json\n */\nfunction getCliVersion(): string {\n try {\n // In production (dist/services/api.service.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version;\n } catch {\n logger.debug('Failed to read package.json version');\n return '2.0.0'; // Fallback version\n }\n}\n\n/**\n * Get platform information for User-Agent\n */\nfunction getPlatformInfo(): string {\n const platform = process.platform; // darwin, linux, win32, etc.\n const arch = process.arch; // arm64, x64, etc.\n return `${platform}-${arch}`;\n}\n\n/**\n * API service for communicating with the Bragduck backend\n */\nexport class ApiService {\n private baseURL: string;\n private client: typeof ofetch;\n\n constructor() {\n // Use environment variable or default API URL\n this.baseURL = process.env.API_BASE_URL || 'https://api.bragduck.com';\n\n // Create ofetch client with interceptors\n this.client = ofetch.create({\n baseURL: this.baseURL,\n\n // Request interceptor\n onRequest: async ({ request, options }) => {\n logger.debug(`API Request: ${options.method || 'GET'} ${request}`);\n\n // Add User-Agent header for CLI identification\n const cliVersion = getCliVersion();\n const platform = getPlatformInfo();\n const userAgent = `BragDuck-CLI/${cliVersion} (${platform})`;\n\n // Add authentication header\n const token = await authService.getAccessToken();\n\n // Create new headers object\n const newHeaders: Record<string, string> = {\n 'User-Agent': userAgent,\n };\n\n // Copy existing headers if any\n if (options.headers) {\n if (typeof options.headers === 'object' && !Array.isArray(options.headers)) {\n Object.entries(options.headers).forEach(([key, value]) => {\n if (typeof value === 'string') {\n newHeaders[key] = value;\n }\n });\n }\n }\n\n if (token) {\n newHeaders.Authorization = `Bearer ${token}`;\n }\n\n // Ensure Content-Type is set for POST/PUT requests\n if (options.method && ['POST', 'PUT', 'PATCH'].includes(options.method)) {\n newHeaders['Content-Type'] = 'application/json';\n }\n\n options.headers = newHeaders as any;\n },\n\n // Response interceptor for success\n onResponse: ({ response }) => {\n logger.debug(`API Response: ${response.status} ${response.statusText}`);\n },\n\n // Response interceptor for errors\n onResponseError: async ({ request, response }) => {\n const status = response.status;\n\n logger.debug(`API Error: ${status} ${response.statusText} - ${request}`);\n\n // Handle 401 Unauthorized - token expired\n if (status === HTTP_STATUS.UNAUTHORIZED) {\n logger.debug('Token expired, attempting refresh');\n\n try {\n // Try to refresh the token\n await authService.refreshToken();\n\n // Retry the request once with the new token\n logger.debug('Token refreshed, retrying request');\n throw new Error('RETRY_WITH_NEW_TOKEN');\n } catch (error: any) {\n if (error.message === 'RETRY_WITH_NEW_TOKEN') {\n throw error;\n }\n // If refresh fails, throw TokenExpiredError\n throw new TokenExpiredError(\n 'Your session has expired. Please run \"bragduck init\" to login again.'\n );\n }\n }\n\n // Parse error response\n let errorMessage = 'An unexpected error occurred';\n let errorDetails: Record<string, any> | undefined;\n\n try {\n const errorData = response._data as ApiErrorResponse;\n if (errorData && errorData.message) {\n errorMessage = errorData.message;\n errorDetails = errorData.details;\n }\n } catch {\n // If we can't parse error, use status text\n errorMessage = response.statusText || errorMessage;\n }\n\n throw new ApiError(errorMessage, status, errorDetails);\n },\n\n // Retry configuration\n retry: 2,\n retryDelay: 1000,\n retryStatusCodes: [408, 409, 425, 429, 500, 502, 503, 504],\n\n // Timeout\n timeout: 30000, // 30 seconds\n });\n }\n\n /**\n * Make API request with retry for token refresh\n */\n private async makeRequest<T>(url: string, options: FetchOptions = {}): Promise<T> {\n try {\n return (await this.client(url, options)) as Promise<T>;\n } catch (error: any) {\n // If we got the special retry signal, retry the request once\n if (error.message === 'RETRY_WITH_NEW_TOKEN') {\n logger.debug('Retrying request with refreshed token');\n return (await this.client(url, options)) as Promise<T>;\n }\n\n // Handle network errors\n if (error.name === 'FetchError' || error.code === 'ECONNREFUSED') {\n throw new NetworkError('Failed to connect to Bragduck API', {\n originalError: error.message,\n baseURL: this.baseURL,\n });\n }\n\n throw error;\n }\n }\n\n /**\n * Refine brags using AI\n */\n async refineBrags(request: RefineBragsRequest): Promise<RefineBragsResponse> {\n logger.debug(`Refining ${request.brags.length} brags`);\n\n try {\n const response = await this.makeRequest<RefineBragsResponse>(API_ENDPOINTS.BRAGS.REFINE, {\n method: 'POST',\n body: request,\n });\n\n logger.debug(`Successfully refined ${response.refined_brags.length} brags`);\n return response;\n } catch (_error) {\n logger.debug('Failed to refine brags');\n throw _error;\n }\n }\n\n /**\n * @deprecated Use refineBrags() instead. Will be removed in v3.0.0\n * Refine commits using AI (legacy endpoint)\n */\n async refineCommits(request: RefineCommitsRequest): Promise<RefineCommitsResponse> {\n logger.debug(`[DEPRECATED] Using legacy refineCommits - migrate to refineBrags`);\n logger.debug(`Refining ${request.commits.length} commits`);\n\n try {\n const response = await this.makeRequest<RefineCommitsResponse>(API_ENDPOINTS.COMMITS.REFINE, {\n method: 'POST',\n body: request,\n });\n\n logger.debug(`Successfully refined ${response.refined_commits.length} commits`);\n return response;\n } catch (_error) {\n logger.debug('Failed to refine commits');\n throw _error;\n }\n }\n\n /**\n * Create brags from refined commits\n */\n async createBrags(request: CreateBragsRequest): Promise<CreateBragsResponse> {\n logger.debug(`Creating ${request.brags.length} brags`);\n\n try {\n const response = await this.makeRequest<CreateBragsResponse>(API_ENDPOINTS.BRAGS.CREATE, {\n method: 'POST',\n body: request,\n });\n\n logger.debug(`Successfully created ${response.created} brags`);\n return response;\n } catch (_error) {\n logger.debug('Failed to create brags');\n throw _error;\n }\n }\n\n /**\n * List existing brags\n */\n async listBrags(params: ListBragsParams = {}): Promise<ListBragsResponse> {\n const { limit = 50, offset = 0, tags, search } = params;\n\n logger.debug(`Listing brags: limit=${limit}, offset=${offset}`);\n\n try {\n // Build query parameters\n const queryParams = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (search) {\n queryParams.append('search', search);\n }\n\n if (tags && tags.length > 0) {\n tags.forEach((tag) => queryParams.append('tags[]', tag));\n }\n\n const url = `${API_ENDPOINTS.BRAGS.LIST}?${queryParams.toString()}`;\n\n const response = await this.makeRequest<ListBragsResponse>(url, {\n method: 'GET',\n });\n\n logger.debug(\n `Successfully fetched ${response.brags.length} brags (total: ${response.total})`\n );\n return response;\n } catch (_error) {\n logger.debug('Failed to list brags');\n throw _error;\n }\n }\n\n /**\n * Get user's subscription status\n */\n async getSubscriptionStatus(): Promise<GetSubscriptionStatusResponse> {\n logger.debug(`Fetching subscription status from ${API_ENDPOINTS.SUBSCRIPTION.STATUS}`);\n\n try {\n const response = await this.makeRequest<{\n status: string;\n data: GetSubscriptionStatusResponse;\n }>(API_ENDPOINTS.SUBSCRIPTION.STATUS, {\n method: 'GET',\n });\n\n logger.debug(`Subscription API response: ${JSON.stringify(response)}`);\n\n // Unwrap the response - API returns { status: \"success\", data: {...} }\n const subscriptionData = response.data;\n\n logger.debug(\n `Subscription tier: ${subscriptionData.tier}, status: ${subscriptionData.status}`\n );\n return subscriptionData;\n } catch (error) {\n logger.debug(`Failed to fetch subscription status: ${error}`);\n logger.debug(`Error details: ${JSON.stringify(error, null, 2)}`);\n throw error;\n }\n }\n\n /**\n * Check for CLI updates\n */\n async checkVersion(): Promise<VersionCheckResponse> {\n logger.debug('Checking for CLI updates');\n\n try {\n const response = await this.makeRequest<VersionCheckResponse>(API_ENDPOINTS.VERSION, {\n method: 'GET',\n });\n\n logger.debug(`Latest version: ${response.latest_version}`);\n return response;\n } catch {\n logger.debug('Failed to check version');\n // Don't throw error for version check failures\n // Return current version as fallback\n const { version } = await import('../utils/version.js');\n return {\n latest_version: version,\n critical_update: false,\n };\n }\n }\n\n /**\n * Test API connectivity\n */\n async testConnection(): Promise<boolean> {\n try {\n await this.checkVersion();\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Update base URL\n */\n setBaseURL(url: string): void {\n this.baseURL = url;\n // Recreate client with new base URL\n this.client = ofetch.create({\n baseURL: url,\n });\n }\n\n /**\n * Get current base URL\n */\n getBaseURL(): string {\n return this.baseURL;\n }\n}\n\n// Export singleton instance\nexport const apiService = new ApiService();\n","import { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport chalk from 'chalk';\nimport boxen from 'boxen';\nimport { apiService } from '../services/api.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { logger } from './logger.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get current CLI version from package.json\n */\nexport function getCurrentVersion(): string {\n try {\n // In production (dist/utils/version.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version;\n } catch {\n logger.debug('Failed to read package.json version');\n return '1.0.0'; // Fallback version\n }\n}\n\n/**\n * Export current version\n */\nexport const version = getCurrentVersion();\n\n/**\n * Compare two semantic versions\n * Returns:\n * 1 if v1 > v2\n * 0 if v1 === v2\n * -1 if v1 < v2\n */\nexport function compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map((p) => parseInt(p, 10));\n const parts2 = v2.split('.').map((p) => parseInt(p, 10));\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 > part2) return 1;\n if (part1 < part2) return -1;\n }\n\n return 0;\n}\n\n/**\n * Check if a newer version is available\n */\nexport async function checkForUpdates(\n options: {\n silent?: boolean;\n force?: boolean;\n } = {}\n): Promise<{ updateAvailable: boolean; latestVersion: string; currentVersion: string }> {\n const { silent = false, force = false } = options;\n\n try {\n // Skip version check if disabled in config (unless forced)\n if (!force) {\n const autoVersionCheck = storageService.getConfig('autoVersionCheck');\n if (!autoVersionCheck) {\n logger.debug('Version check disabled in config');\n return {\n updateAvailable: false,\n latestVersion: version,\n currentVersion: version,\n };\n }\n }\n\n logger.debug('Checking for CLI updates...');\n\n // Check via API service\n const response = await apiService.checkVersion();\n const latestVersion = response.latest_version;\n const currentVersion = version;\n\n logger.debug(`Current version: ${currentVersion}, Latest version: ${latestVersion}`);\n\n const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;\n\n // Display update notification if not silent and update is available\n if (!silent && updateAvailable) {\n displayUpdateNotification(currentVersion, latestVersion, response.critical_update);\n }\n\n return {\n updateAvailable,\n latestVersion,\n currentVersion,\n };\n } catch (error: any) {\n logger.debug(`Version check failed: ${error.message}`);\n // Don't throw error - version check is non-critical\n return {\n updateAvailable: false,\n latestVersion: version,\n currentVersion: version,\n };\n }\n}\n\n/**\n * Display update notification\n */\nfunction displayUpdateNotification(\n currentVersion: string,\n latestVersion: string,\n critical: boolean = false\n): void {\n const urgency = critical\n ? chalk.red.bold('CRITICAL UPDATE')\n : chalk.yellow.bold('Update Available');\n const message =\n `${urgency}\\n\\n` +\n `Current version: ${chalk.dim(currentVersion)}\\n` +\n `Latest version: ${chalk.green(latestVersion)}\\n\\n` +\n `Update with: ${chalk.cyan('npm install -g @bragduck/cli@latest')}`;\n\n console.log('');\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 0, right: 1, bottom: 0, left: 1 },\n borderStyle: 'round',\n borderColor: critical ? 'red' : 'yellow',\n })\n );\n console.log('');\n\n if (critical) {\n logger.warning('This is a critical update. Please update as soon as possible.');\n console.log('');\n }\n}\n\n/**\n * Format version for display\n */\nexport function formatVersion(includePrefix: boolean = true): string {\n const prefix = includePrefix ? 'v' : '';\n return `${prefix}${version}`;\n}\n","// Main entry point for the Bragduck CLI package\n// This file exports the public API for programmatic usage\n\nexport { version } from './utils/version.js';\n\n// Future exports will be added here as we implement services and utilities\n// Example:\n// export { AuthService } from './services/auth.service.js';\n// export { GitService } from './services/git.service.js';\n// export { ApiService } from './services/api.service.js';\n"],"mappings":"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","names":["fileURLToPath","join","randomBytes","readFileSync","fileURLToPath","dirname","join","__dirname","version","__filename","ofetch","readFileSync","fileURLToPath","URLSearchParams","dirname","join","__dirname","__filename","version","readFileSync","fileURLToPath","dirname","join","chalk","__dirname","__filename"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/constants.ts","../src/services/storage.service.ts","../src/utils/errors.ts","../src/utils/logger.ts","../src/utils/oauth-server.ts","../src/utils/browser.ts","../src/services/auth.service.ts","../src/services/api.service.ts","../src/utils/version.ts","../src/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","// Load environment variables\nimport { config } from 'dotenv';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\n\n// Get the directory of this file\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Load .env from the project root (silently)\n// In production, this file is bundled into dist/bin/bragduck.js, so we need to go up 2 levels\n// In development (src/), we'd need to go up 1 level, but the build is what matters\nconfig({ path: join(__dirname, '..', '..', '.env'), debug: false, quiet: true } as any);\n\n// App-wide constants for Bragduck CLI\n\n/**\n * Application name used for storage and configuration\n */\nexport const APP_NAME = 'bragduck';\n\n/**\n * Storage keys for credentials and configuration\n */\nexport const STORAGE_KEYS = {\n ACCESS_TOKEN: 'access_token',\n REFRESH_TOKEN: 'refresh_token',\n USER_INFO: 'user_info',\n OAUTH_STATE: 'oauth_state',\n} as const;\n\n/**\n * Configuration keys\n */\nexport const CONFIG_KEYS = {\n DEFAULT_COMMIT_DAYS: 'defaultCommitDays',\n AUTO_VERSION_CHECK: 'autoVersionCheck',\n} as const;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG = {\n defaultCommitDays: 30,\n autoVersionCheck: true,\n} as const;\n\n/**\n * OAuth configuration\n */\nexport const OAUTH_CONFIG = {\n CLIENT_ID: 'bragduck-cli',\n CALLBACK_PATH: '/callback',\n TIMEOUT_MS: 120000, // 2 minutes\n MIN_PORT: 8000,\n MAX_PORT: 9000,\n} as const;\n\n/**\n * API endpoints\n */\nexport const API_ENDPOINTS = {\n AUTH: {\n INITIATE: '/v1/auth/cli/initiate',\n TOKEN: '/v1/auth/cli/token',\n },\n BRAGS: {\n CREATE: '/v1/brags',\n LIST: '/v1/brags',\n REFINE: '/v1/brags/refine',\n },\n SUBSCRIPTION: {\n STATUS: '/v1/subscriptions/status',\n },\n VERSION: '/v1/cli/version',\n /**\n * @deprecated Use BRAGS.REFINE instead\n */\n COMMITS: {\n REFINE: '/v1/commits/refine',\n },\n} as const;\n\n/**\n * Encryption configuration for file-based credential storage\n */\nexport const ENCRYPTION_CONFIG = {\n ALGORITHM: 'aes-256-gcm',\n KEY_LENGTH: 32,\n IV_LENGTH: 16,\n AUTH_TAG_LENGTH: 16,\n SALT_LENGTH: 32,\n} as const;\n\n/**\n * File paths for credential storage fallback\n */\nexport const STORAGE_PATHS = {\n CREDENTIALS_DIR: '.bragduck',\n CREDENTIALS_FILE: 'credentials.enc',\n CONFIG_FILE: 'config.json',\n} as const;\n\n/**\n * Error codes\n */\nexport const ERROR_CODES = {\n AUTH_FAILED: 'AUTH_FAILED',\n TOKEN_EXPIRED: 'TOKEN_EXPIRED',\n NETWORK_ERROR: 'NETWORK_ERROR',\n GIT_ERROR: 'GIT_ERROR',\n API_ERROR: 'API_ERROR',\n STORAGE_ERROR: 'STORAGE_ERROR',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n} as const;\n\n/**\n * HTTP status codes\n */\nexport const HTTP_STATUS = {\n OK: 200,\n CREATED: 201,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n INTERNAL_SERVER_ERROR: 500,\n} as const;\n\n/**\n * GitHub configuration\n */\nexport const GITHUB_CONFIG = {\n MIN_GH_VERSION: '2.0.0',\n PR_SEARCH_FIELDS: 'number,title,body,author,mergedAt,additions,deletions,changedFiles,url,labels',\n MAX_BODY_LENGTH: 5000,\n} as const;\n","import Conf from 'conf';\nimport { createCipheriv, createDecipheriv, randomBytes, scryptSync } from 'crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport { APP_NAME, ENCRYPTION_CONFIG, STORAGE_PATHS, DEFAULT_CONFIG } from '../constants.js';\nimport type {\n StoredCredentials,\n UserInfo,\n OAuthState,\n StorageBackend,\n EncryptedData,\n BragduckConfig,\n} from '../types/config.types.js';\n\n/**\n * Storage service for managing credentials and configuration\n * Uses encrypted file storage for credentials\n *\n * NOTE: OS keychain support (via cross-keychain or similar) can be added in the future.\n * For now, we use secure encrypted file storage with machine-specific keys.\n */\nexport class StorageService {\n private config: Conf<BragduckConfig>;\n private storageBackend: StorageBackend;\n private credentialsDir: string;\n private credentialsFilePath: string;\n\n constructor() {\n // Initialize config management\n this.config = new Conf<BragduckConfig>({\n projectName: APP_NAME,\n defaults: DEFAULT_CONFIG,\n });\n\n // Set up credentials directory and file path\n this.credentialsDir = join(homedir(), STORAGE_PATHS.CREDENTIALS_DIR);\n this.credentialsFilePath = join(this.credentialsDir, STORAGE_PATHS.CREDENTIALS_FILE);\n\n // Use file storage for now (keychain support can be added later)\n this.storageBackend = 'file';\n this.ensureCredentialsDir();\n }\n\n /**\n * Ensure credentials directory exists\n */\n private ensureCredentialsDir(): void {\n if (!existsSync(this.credentialsDir)) {\n mkdirSync(this.credentialsDir, { recursive: true, mode: 0o700 });\n }\n }\n\n /**\n * Encrypt data for file storage\n */\n private encrypt(data: string, key: Buffer): EncryptedData {\n const iv = randomBytes(ENCRYPTION_CONFIG.IV_LENGTH);\n const cipher = createCipheriv(ENCRYPTION_CONFIG.ALGORITHM, key, iv, {\n authTagLength: ENCRYPTION_CONFIG.AUTH_TAG_LENGTH,\n });\n\n let encrypted = cipher.update(data, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n\n const authTag = cipher.getAuthTag();\n\n return {\n encrypted,\n iv: iv.toString('hex'),\n authTag: authTag.toString('hex'),\n salt: '', // Salt is stored separately\n };\n }\n\n /**\n * Decrypt data from file storage\n */\n private decrypt(encryptedData: EncryptedData, key: Buffer): string {\n const decipher = createDecipheriv(\n ENCRYPTION_CONFIG.ALGORITHM,\n key,\n Buffer.from(encryptedData.iv, 'hex'),\n {\n authTagLength: ENCRYPTION_CONFIG.AUTH_TAG_LENGTH,\n }\n );\n\n decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));\n\n let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n\n return decrypted;\n }\n\n /**\n * Derive encryption key from machine-specific data\n */\n private deriveEncryptionKey(salt: Buffer): Buffer {\n // Use machine ID and app name as password\n const password = `${APP_NAME}-${homedir()}-${process.platform}`;\n return scryptSync(password, salt, ENCRYPTION_CONFIG.KEY_LENGTH);\n }\n\n /**\n * Store credentials using encrypted file storage\n */\n async setCredentials(credentials: StoredCredentials): Promise<void> {\n const data = JSON.stringify(credentials);\n\n // Encrypt and store credentials\n const salt = randomBytes(ENCRYPTION_CONFIG.SALT_LENGTH);\n const key = this.deriveEncryptionKey(salt);\n const encrypted = this.encrypt(data, key);\n encrypted.salt = salt.toString('hex');\n\n writeFileSync(this.credentialsFilePath, JSON.stringify(encrypted), {\n mode: 0o600,\n encoding: 'utf8',\n });\n }\n\n /**\n * Retrieve credentials from encrypted file storage\n */\n async getCredentials(): Promise<StoredCredentials | null> {\n if (!existsSync(this.credentialsFilePath)) {\n return null;\n }\n\n try {\n const encryptedData: EncryptedData = JSON.parse(\n readFileSync(this.credentialsFilePath, 'utf8')\n );\n const salt = Buffer.from(encryptedData.salt, 'hex');\n const key = this.deriveEncryptionKey(salt);\n const decrypted = this.decrypt(encryptedData, key);\n return JSON.parse(decrypted);\n } catch (error) {\n console.error('Failed to decrypt credentials:', error);\n return null;\n }\n }\n\n /**\n * Delete credentials from file storage\n */\n async deleteCredentials(): Promise<void> {\n // Delete file if it exists\n if (existsSync(this.credentialsFilePath)) {\n try {\n unlinkSync(this.credentialsFilePath);\n } catch (error) {\n console.error('Failed to delete credentials file:', error);\n }\n }\n }\n\n /**\n * Check if user is authenticated\n */\n async isAuthenticated(): Promise<boolean> {\n const credentials = await this.getCredentials();\n if (!credentials || !credentials.accessToken) {\n return false;\n }\n\n // Check if token is expired\n if (credentials.expiresAt && credentials.expiresAt < Date.now()) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Store user information\n */\n setUserInfo(userInfo: UserInfo): void {\n this.config.set('userInfo' as keyof BragduckConfig, userInfo as any);\n }\n\n /**\n * Get user information\n */\n getUserInfo(): UserInfo | null {\n return (this.config.get('userInfo' as keyof BragduckConfig) as any) || null;\n }\n\n /**\n * Delete user information\n */\n deleteUserInfo(): void {\n this.config.delete('userInfo' as keyof BragduckConfig);\n }\n\n /**\n * Store OAuth state for CSRF protection\n */\n setOAuthState(state: OAuthState): void {\n this.config.set('oauthState' as keyof BragduckConfig, state as any);\n }\n\n /**\n * Get OAuth state\n */\n getOAuthState(): OAuthState | null {\n return (this.config.get('oauthState' as keyof BragduckConfig) as any) || null;\n }\n\n /**\n * Delete OAuth state\n */\n deleteOAuthState(): void {\n this.config.delete('oauthState' as keyof BragduckConfig);\n }\n\n /**\n * Get configuration value\n */\n getConfig<K extends keyof BragduckConfig>(key: K): BragduckConfig[K] {\n return this.config.get(key);\n }\n\n /**\n * Set configuration value\n */\n setConfig<K extends keyof BragduckConfig>(key: K, value: BragduckConfig[K]): void {\n this.config.set(key, value);\n }\n\n /**\n * Get all configuration\n */\n getAllConfig(): BragduckConfig {\n return this.config.store;\n }\n\n /**\n * Reset configuration to defaults\n */\n resetConfig(): void {\n this.config.clear();\n // Re-apply defaults\n Object.entries(DEFAULT_CONFIG).forEach(([key, value]) => {\n this.config.set(key as keyof BragduckConfig, value as any);\n });\n }\n\n /**\n * Get current storage backend\n */\n getStorageBackend(): StorageBackend {\n return this.storageBackend;\n }\n\n /**\n * Clear all stored data (credentials + config)\n */\n async clearAll(): Promise<void> {\n await this.deleteCredentials();\n this.deleteUserInfo();\n this.deleteOAuthState();\n this.resetConfig();\n }\n}\n\n// Export singleton instance\nexport const storageService = new StorageService();\n","// Custom error classes for Bragduck CLI\n\n/**\n * Base error class for all Bragduck errors\n */\nexport class BragduckError extends Error {\n public code: string;\n public details?: Record<string, any>;\n\n constructor(message: string, code: string, details?: Record<string, any>) {\n super(message);\n this.name = 'BragduckError';\n this.code = code;\n this.details = details;\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Authentication-related errors\n */\nexport class AuthenticationError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'AUTH_ERROR', details);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Git operation errors\n */\nexport class GitError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GIT_ERROR', details);\n this.name = 'GitError';\n }\n}\n\n/**\n * API communication errors\n */\nexport class ApiError extends BragduckError {\n public statusCode?: number;\n\n constructor(message: string, statusCode?: number, details?: Record<string, any>) {\n super(message, 'API_ERROR', details);\n this.name = 'ApiError';\n this.statusCode = statusCode;\n }\n}\n\n/**\n * Network-related errors\n */\nexport class NetworkError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'NETWORK_ERROR', details);\n this.name = 'NetworkError';\n }\n}\n\n/**\n * Storage-related errors\n */\nexport class StorageError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'STORAGE_ERROR', details);\n this.name = 'StorageError';\n }\n}\n\n/**\n * Validation errors\n */\nexport class ValidationError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * OAuth-specific errors\n */\nexport class OAuthError extends AuthenticationError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, details);\n this.name = 'OAuthError';\n }\n}\n\n/**\n * Token expiration error\n */\nexport class TokenExpiredError extends AuthenticationError {\n constructor(message = 'Authentication token has expired') {\n super(message);\n this.name = 'TokenExpiredError';\n this.code = 'TOKEN_EXPIRED';\n }\n}\n\n/**\n * GitHub-related errors\n */\nexport class GitHubError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GITHUB_ERROR', details);\n this.name = 'GitHubError';\n }\n}\n","import chalk from 'chalk';\n\n/**\n * Logger utility for consistent console output\n */\nexport const logger = {\n /**\n * Debug message (only shown when DEBUG env var is set)\n */\n debug: (message: string, ...args: any[]): void => {\n if (process.env.DEBUG) {\n console.log(chalk.gray(`[DEBUG] ${message}`), ...args);\n }\n },\n\n /**\n * Info message\n */\n info: (message: string): void => {\n console.log(chalk.blue(`ℹ ${message}`));\n },\n\n /**\n * Success message\n */\n success: (message: string): void => {\n console.log(chalk.green(`✓ ${message}`));\n },\n\n /**\n * Warning message\n */\n warning: (message: string): void => {\n console.warn(chalk.yellow(`⚠ ${message}`));\n },\n\n /**\n * Error message\n */\n error: (message: string): void => {\n console.error(chalk.red(`✗ ${message}`));\n },\n\n /**\n * Plain log without formatting\n */\n log: (message: string): void => {\n console.log(message);\n },\n};\n","import { createServer, type Server, type IncomingMessage, type ServerResponse } from 'http';\nimport { parse } from 'url';\nimport { OAUTH_CONFIG } from '../constants.js';\nimport { OAuthError } from './errors.js';\nimport { logger } from './logger.js';\n\n/**\n * OAuth callback result\n */\nexport interface OAuthCallbackResult {\n code: string;\n state: string;\n port: number;\n}\n\n/**\n * Find an available port in the configured range\n */\nasync function findAvailablePort(): Promise<number> {\n const { MIN_PORT, MAX_PORT } = OAUTH_CONFIG;\n\n for (let port = MIN_PORT; port <= MAX_PORT; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n const testServer = createServer();\n testServer.once('error', reject);\n testServer.once('listening', () => {\n testServer.close(() => resolve());\n });\n testServer.listen(port, '127.0.0.1');\n });\n return port;\n } catch {\n // Port is in use, try next one\n continue;\n }\n }\n\n throw new OAuthError(`No available ports found in range ${MIN_PORT}-${MAX_PORT}`);\n}\n\n/**\n * Success HTML page to show after authentication\n */\nconst SUCCESS_HTML = `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bragduck - Authentication Successful</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n }\n .container {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 1rem;\n backdrop-filter: blur(10px);\n box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);\n max-width: 500px;\n }\n h1 {\n font-size: 2.5rem;\n margin: 0 0 1rem 0;\n }\n .checkmark {\n font-size: 4rem;\n animation: scale-in 0.3s ease-out;\n }\n p {\n font-size: 1.2rem;\n margin: 1rem 0;\n opacity: 0.9;\n }\n @keyframes scale-in {\n from { transform: scale(0); }\n to { transform: scale(1); }\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"checkmark\">✓</div>\n <h1>Authentication Successful!</h1>\n <p>You can now close this window and return to your terminal.</p>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Error HTML page to show on authentication failure\n */\nconst ERROR_HTML = (error: string) => `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Bragduck - Authentication Failed</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n }\n .container {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 1rem;\n backdrop-filter: blur(10px);\n box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);\n max-width: 500px;\n }\n h1 {\n font-size: 2.5rem;\n margin: 0 0 1rem 0;\n }\n .error-icon {\n font-size: 4rem;\n }\n p {\n font-size: 1.2rem;\n margin: 1rem 0;\n opacity: 0.9;\n }\n .error-details {\n background: rgba(0, 0, 0, 0.2);\n padding: 1rem;\n border-radius: 0.5rem;\n font-family: monospace;\n font-size: 0.9rem;\n margin-top: 1rem;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"error-icon\">✗</div>\n <h1>Authentication Failed</h1>\n <p>Please return to your terminal and try again.</p>\n <div class=\"error-details\">${error}</div>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Start OAuth callback server and wait for callback\n */\nexport async function startOAuthCallbackServer(\n expectedState: string\n): Promise<OAuthCallbackResult> {\n const port = await findAvailablePort();\n const timeout = OAUTH_CONFIG.TIMEOUT_MS;\n\n return new Promise<OAuthCallbackResult>((resolve, reject) => {\n let server: Server | null = null;\n let timeoutId: ReturnType<typeof globalThis.setTimeout> | null = null;\n\n const cleanup = () => {\n if (timeoutId) {\n globalThis.clearTimeout(timeoutId);\n }\n if (server) {\n // Close all connections immediately (Node.js 18+)\n if (typeof (server as any).closeAllConnections === 'function') {\n (server as any).closeAllConnections();\n }\n server.close(() => {\n logger.debug('OAuth server closed');\n });\n server.unref(); // Allow process to exit even if server is still running\n }\n };\n\n const handleRequest = (req: IncomingMessage, res: ServerResponse) => {\n const parsedUrl = parse(req.url || '', true);\n\n logger.debug(`OAuth callback received: ${req.url}`);\n\n // Handle callback request\n if (parsedUrl.pathname === OAUTH_CONFIG.CALLBACK_PATH) {\n const { code, state, error, error_description } = parsedUrl.query;\n\n // Check for OAuth errors\n if (error) {\n const errorMsg = error_description || error;\n logger.debug(`OAuth error: ${errorMsg}`);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(String(errorMsg)));\n\n cleanup();\n reject(new OAuthError(`OAuth error: ${errorMsg}`));\n return;\n }\n\n // Validate required parameters\n if (!code || !state) {\n const errorMsg = 'Missing code or state parameter';\n logger.debug(errorMsg);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(errorMsg));\n\n cleanup();\n reject(new OAuthError(errorMsg));\n return;\n }\n\n // Verify state matches (CSRF protection)\n if (state !== expectedState) {\n const errorMsg = 'Invalid state parameter (possible CSRF attack)';\n logger.debug(errorMsg);\n\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(errorMsg));\n\n cleanup();\n reject(new OAuthError(errorMsg));\n return;\n }\n\n // Success!\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(SUCCESS_HTML);\n\n // Give the response time to be sent before closing\n globalThis.setTimeout(() => {\n cleanup();\n resolve({\n code: String(code),\n state: String(state),\n port,\n });\n }, 100);\n return;\n }\n\n // Handle other requests (404)\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n };\n\n // Create server\n server = createServer(handleRequest);\n\n // Handle server errors\n server.on('error', (error) => {\n logger.debug(`OAuth server error: ${error.message}`);\n cleanup();\n reject(new OAuthError(`OAuth server error: ${error.message}`));\n });\n\n // Start server\n server.listen(port, '127.0.0.1', () => {\n logger.debug(\n `OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`\n );\n });\n\n // Set timeout\n timeoutId = globalThis.setTimeout(() => {\n logger.debug('OAuth callback timeout');\n cleanup();\n reject(new OAuthError('Authentication timeout - no callback received within 2 minutes'));\n }, timeout);\n });\n}\n\n/**\n * Get the callback URL for the OAuth flow\n */\nexport async function getCallbackUrl(): Promise<string> {\n const port = await findAvailablePort();\n return `http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`;\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { logger } from './logger.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Open a URL in the default browser\n */\nexport async function openBrowser(url: string): Promise<void> {\n const platform = process.platform;\n let command: string;\n\n // Determine the command based on the platform\n switch (platform) {\n case 'darwin': // macOS\n command = `open \"${url}\"`;\n break;\n case 'win32': // Windows\n command = `start \"\" \"${url}\"`;\n break;\n default: // Linux and others\n command = `xdg-open \"${url}\"`;\n break;\n }\n\n try {\n logger.debug(`Opening browser with command: ${command}`);\n await execAsync(command);\n logger.debug('Browser opened successfully');\n } catch (error) {\n logger.debug(`Failed to open browser: ${error}`);\n throw new Error(`Failed to open browser automatically. Please open this URL manually:\\n${url}`);\n }\n}\n","import { randomBytes } from 'crypto';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath, URLSearchParams } from 'url';\nimport { dirname, join } from 'path';\nimport { ofetch } from 'ofetch';\nimport { OAUTH_CONFIG, API_ENDPOINTS } from '../constants.js';\nimport { storageService } from './storage.service.js';\nimport { startOAuthCallbackServer, getCallbackUrl } from '../utils/oauth-server.js';\nimport { openBrowser } from '../utils/browser.js';\nimport { AuthenticationError, NetworkError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type { StoredCredentials, UserInfo } from '../types/config.types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get CLI version and User-Agent string\n */\nfunction getUserAgent(): string {\n try {\n // In production (dist/services/auth.service.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const version = packageJson.version;\n const platform = process.platform;\n const arch = process.arch;\n return `BragDuck-CLI/${version} (${platform}-${arch})`;\n } catch {\n logger.debug('Failed to read package.json version');\n return 'BragDuck-CLI/2.0.0';\n }\n}\n\n/**\n * Token exchange response from the backend\n */\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type: string;\n user?: UserInfo;\n}\n\n/**\n * Authentication service for managing OAuth flow and tokens\n */\nexport class AuthService {\n private apiBaseUrl: string;\n\n constructor() {\n // Use environment variable or default API URL\n this.apiBaseUrl = process.env.API_BASE_URL || 'https://api.bragduck.com';\n }\n\n /**\n * Generate a random state string for CSRF protection\n */\n private generateState(): string {\n return randomBytes(32).toString('hex');\n }\n\n /**\n * Build the OAuth authorization URL\n */\n private async buildAuthUrl(state: string, callbackUrl: string): Promise<string> {\n const params = new URLSearchParams({\n client_id: OAUTH_CONFIG.CLIENT_ID,\n redirect_uri: callbackUrl,\n state,\n });\n\n return `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.INITIATE}?${params.toString()}`;\n }\n\n /**\n * Exchange authorization code for access token\n */\n private async exchangeCodeForToken(code: string, callbackUrl: string): Promise<TokenResponse> {\n try {\n logger.debug('Exchanging authorization code for token');\n\n const response = await ofetch<TokenResponse>(\n `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.TOKEN}`,\n {\n method: 'POST',\n body: {\n code,\n redirect_uri: callbackUrl,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n grant_type: 'authorization_code',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': getUserAgent(),\n },\n }\n );\n\n logger.debug('Token exchange successful');\n return response;\n } catch (error: any) {\n logger.debug(`Token exchange failed: ${error.message}`);\n\n if (error.response) {\n throw new AuthenticationError(\n `Token exchange failed: ${error.response.statusText || 'Unknown error'}`,\n {\n statusCode: error.response.status,\n body: error.response._data,\n }\n );\n }\n\n throw new NetworkError('Failed to connect to authentication server', {\n originalError: error.message,\n });\n }\n }\n\n /**\n * Complete OAuth flow: start server, open browser, wait for callback, exchange token\n */\n async login(): Promise<UserInfo> {\n logger.debug('Starting OAuth login flow');\n\n // Generate state for CSRF protection\n const state = this.generateState();\n const callbackUrl = await getCallbackUrl();\n\n // Store state temporarily\n storageService.setOAuthState({\n state,\n createdAt: Date.now(),\n });\n\n logger.debug(`OAuth state: ${state}`);\n logger.debug(`Callback URL: ${callbackUrl}`);\n\n // Build authorization URL\n const authUrl = await this.buildAuthUrl(state, callbackUrl);\n logger.debug(`Authorization URL: ${authUrl}`);\n\n // Start callback server (this will wait for the callback)\n const serverPromise = startOAuthCallbackServer(state);\n\n // Open browser\n try {\n await openBrowser(authUrl);\n } catch {\n // If browser opening fails, show the URL for manual opening\n logger.warning('Could not open browser automatically');\n logger.info(`Please open this URL in your browser:`);\n logger.log(authUrl);\n }\n\n // Wait for callback\n let callbackResult;\n try {\n callbackResult = await serverPromise;\n } catch (error: any) {\n storageService.deleteOAuthState();\n throw error;\n }\n\n // Clear OAuth state\n storageService.deleteOAuthState();\n\n // Exchange code for token\n const tokenResponse = await this.exchangeCodeForToken(callbackResult.code, callbackUrl);\n\n // Calculate expiration time\n const expiresAt = tokenResponse.expires_in\n ? Date.now() + tokenResponse.expires_in * 1000\n : undefined;\n\n // Store credentials\n const credentials: StoredCredentials = {\n accessToken: tokenResponse.access_token,\n refreshToken: tokenResponse.refresh_token,\n expiresAt,\n };\n await storageService.setCredentials(credentials);\n\n // Store user info if provided\n if (tokenResponse.user) {\n storageService.setUserInfo(tokenResponse.user);\n }\n\n logger.debug('Login successful');\n\n return tokenResponse.user || { id: 'unknown', email: 'unknown', name: 'Unknown User' };\n }\n\n /**\n * Logout: clear all stored credentials and user info\n */\n async logout(): Promise<void> {\n logger.debug('Logging out');\n\n await storageService.deleteCredentials();\n storageService.deleteUserInfo();\n storageService.deleteOAuthState();\n\n logger.debug('Logout complete');\n }\n\n /**\n * Check if user is authenticated\n */\n async isAuthenticated(): Promise<boolean> {\n return storageService.isAuthenticated();\n }\n\n /**\n * Get current access token\n */\n async getAccessToken(): Promise<string | null> {\n const credentials = await storageService.getCredentials();\n return credentials?.accessToken || null;\n }\n\n /**\n * Get current user info\n */\n getUserInfo(): UserInfo | null {\n return storageService.getUserInfo();\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refreshToken(): Promise<void> {\n logger.debug('Refreshing access token');\n\n const credentials = await storageService.getCredentials();\n if (!credentials?.refreshToken) {\n throw new AuthenticationError('No refresh token available');\n }\n\n try {\n const response = await ofetch<TokenResponse>(\n `${this.apiBaseUrl}${API_ENDPOINTS.AUTH.TOKEN}`,\n {\n method: 'POST',\n body: {\n refresh_token: credentials.refreshToken,\n client_id: OAUTH_CONFIG.CLIENT_ID,\n grant_type: 'refresh_token',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': getUserAgent(),\n },\n }\n );\n\n // Calculate expiration time\n const expiresAt = response.expires_in ? Date.now() + response.expires_in * 1000 : undefined;\n\n // Update stored credentials\n const newCredentials: StoredCredentials = {\n accessToken: response.access_token,\n refreshToken: response.refresh_token || credentials.refreshToken,\n expiresAt,\n };\n await storageService.setCredentials(newCredentials);\n\n logger.debug('Token refresh successful');\n } catch (error: any) {\n logger.debug(`Token refresh failed: ${error.message}`);\n\n // If refresh fails, user needs to re-authenticate\n await this.logout();\n throw new AuthenticationError('Token refresh failed. Please log in again.');\n }\n }\n}\n\n// Export singleton instance\nexport const authService = new AuthService();\n","import { ofetch, type FetchOptions } from 'ofetch';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { URLSearchParams } from 'url';\nimport { dirname, join } from 'path';\nimport { authService } from './auth.service.js';\nimport { API_ENDPOINTS, HTTP_STATUS } from '../constants.js';\nimport { ApiError, NetworkError, TokenExpiredError } from '../utils/errors.js';\nimport { logger } from '../utils/logger.js';\nimport type {\n RefineCommitsRequest,\n RefineCommitsResponse,\n RefineBragsRequest,\n RefineBragsResponse,\n CreateBragsRequest,\n CreateBragsResponse,\n ListBragsParams,\n ListBragsResponse,\n GetSubscriptionStatusResponse,\n VersionCheckResponse,\n ApiErrorResponse,\n} from '../types/api.types.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get CLI version from package.json\n */\nfunction getCliVersion(): string {\n try {\n // In production (dist/services/api.service.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version;\n } catch {\n logger.debug('Failed to read package.json version');\n return '2.0.0'; // Fallback version\n }\n}\n\n/**\n * Get platform information for User-Agent\n */\nfunction getPlatformInfo(): string {\n const platform = process.platform; // darwin, linux, win32, etc.\n const arch = process.arch; // arm64, x64, etc.\n return `${platform}-${arch}`;\n}\n\n/**\n * API service for communicating with the Bragduck backend\n */\nexport class ApiService {\n private baseURL: string;\n private client: typeof ofetch;\n\n constructor() {\n // Use environment variable or default API URL\n this.baseURL = process.env.API_BASE_URL || 'https://api.bragduck.com';\n\n // Create ofetch client with interceptors\n this.client = ofetch.create({\n baseURL: this.baseURL,\n\n // Request interceptor\n onRequest: async ({ request, options }) => {\n logger.debug(`API Request: ${options.method || 'GET'} ${request}`);\n\n // Add User-Agent header for CLI identification\n const cliVersion = getCliVersion();\n const platform = getPlatformInfo();\n const userAgent = `BragDuck-CLI/${cliVersion} (${platform})`;\n\n // Add authentication header\n const token = await authService.getAccessToken();\n\n // Create new headers object\n const newHeaders: Record<string, string> = {\n 'User-Agent': userAgent,\n };\n\n // Copy existing headers if any\n if (options.headers) {\n if (typeof options.headers === 'object' && !Array.isArray(options.headers)) {\n Object.entries(options.headers).forEach(([key, value]) => {\n if (typeof value === 'string') {\n newHeaders[key] = value;\n }\n });\n }\n }\n\n if (token) {\n newHeaders.Authorization = `Bearer ${token}`;\n }\n\n // Ensure Content-Type is set for POST/PUT requests\n if (options.method && ['POST', 'PUT', 'PATCH'].includes(options.method)) {\n newHeaders['Content-Type'] = 'application/json';\n }\n\n options.headers = newHeaders as any;\n },\n\n // Response interceptor for success\n onResponse: ({ response }) => {\n logger.debug(`API Response: ${response.status} ${response.statusText}`);\n },\n\n // Response interceptor for errors\n onResponseError: async ({ request, response }) => {\n const status = response.status;\n\n logger.debug(`API Error: ${status} ${response.statusText} - ${request}`);\n\n // Handle 401 Unauthorized - token expired\n if (status === HTTP_STATUS.UNAUTHORIZED) {\n logger.debug('Token expired, attempting refresh');\n\n try {\n // Try to refresh the token\n await authService.refreshToken();\n\n // Retry the request once with the new token\n logger.debug('Token refreshed, retrying request');\n throw new Error('RETRY_WITH_NEW_TOKEN');\n } catch (error: any) {\n if (error.message === 'RETRY_WITH_NEW_TOKEN') {\n throw error;\n }\n // If refresh fails, throw TokenExpiredError\n throw new TokenExpiredError(\n 'Your session has expired. Please run \"bragduck init\" to login again.'\n );\n }\n }\n\n // Parse error response\n let errorMessage = 'An unexpected error occurred';\n let errorDetails: Record<string, any> | undefined;\n\n try {\n const errorData = response._data as ApiErrorResponse;\n if (errorData && errorData.message) {\n errorMessage = errorData.message;\n errorDetails = errorData.details;\n }\n } catch {\n // If we can't parse error, use status text\n errorMessage = response.statusText || errorMessage;\n }\n\n throw new ApiError(errorMessage, status, errorDetails);\n },\n\n // Retry configuration\n retry: 2,\n retryDelay: 1000,\n retryStatusCodes: [408, 409, 425, 429, 500, 502, 503, 504],\n\n // Timeout\n timeout: 30000, // 30 seconds\n });\n }\n\n /**\n * Make API request with retry for token refresh\n */\n private async makeRequest<T>(url: string, options: FetchOptions = {}): Promise<T> {\n try {\n return (await this.client(url, options)) as Promise<T>;\n } catch (error: any) {\n // If we got the special retry signal, retry the request once\n if (error.message === 'RETRY_WITH_NEW_TOKEN') {\n logger.debug('Retrying request with refreshed token');\n return (await this.client(url, options)) as Promise<T>;\n }\n\n // Handle network errors\n if (error.name === 'FetchError' || error.code === 'ECONNREFUSED') {\n throw new NetworkError('Failed to connect to Bragduck API', {\n originalError: error.message,\n baseURL: this.baseURL,\n });\n }\n\n throw error;\n }\n }\n\n /**\n * Refine brags using AI\n */\n async refineBrags(request: RefineBragsRequest): Promise<RefineBragsResponse> {\n const MAX_TEXT_LENGTH = 10000;\n\n const trimmedRequest = {\n ...request,\n brags: request.brags.map((brag: RefineBragsRequest['brags'][number]) => ({\n ...brag,\n text:\n brag.text && brag.text.length > MAX_TEXT_LENGTH\n ? brag.text.substring(0, MAX_TEXT_LENGTH)\n : brag.text,\n })),\n };\n\n logger.debug(`Refining ${trimmedRequest.brags.length} brags`);\n\n try {\n const response = await this.makeRequest<RefineBragsResponse>(API_ENDPOINTS.BRAGS.REFINE, {\n method: 'POST',\n body: trimmedRequest,\n });\n\n logger.debug(`Successfully refined ${response.refined_brags.length} brags`);\n return response;\n } catch (_error) {\n logger.debug('Failed to refine brags');\n throw _error;\n }\n }\n\n /**\n * @deprecated Use refineBrags() instead. Will be removed in v3.0.0\n * Refine commits using AI (legacy endpoint)\n */\n async refineCommits(request: RefineCommitsRequest): Promise<RefineCommitsResponse> {\n logger.debug(`[DEPRECATED] Using legacy refineCommits - migrate to refineBrags`);\n logger.debug(`Refining ${request.commits.length} commits`);\n\n try {\n const response = await this.makeRequest<RefineCommitsResponse>(API_ENDPOINTS.COMMITS.REFINE, {\n method: 'POST',\n body: request,\n });\n\n logger.debug(`Successfully refined ${response.refined_commits.length} commits`);\n return response;\n } catch (_error) {\n logger.debug('Failed to refine commits');\n throw _error;\n }\n }\n\n /**\n * Create brags from refined commits\n */\n async createBrags(request: CreateBragsRequest): Promise<CreateBragsResponse> {\n logger.debug(`Creating ${request.brags.length} brags`);\n\n try {\n const response = await this.makeRequest<CreateBragsResponse>(API_ENDPOINTS.BRAGS.CREATE, {\n method: 'POST',\n body: request,\n });\n\n logger.debug(`Successfully created ${response.created} brags`);\n return response;\n } catch (_error) {\n logger.debug('Failed to create brags');\n throw _error;\n }\n }\n\n /**\n * List existing brags\n */\n async listBrags(params: ListBragsParams = {}): Promise<ListBragsResponse> {\n const { limit = 50, offset = 0, tags, search } = params;\n\n logger.debug(`Listing brags: limit=${limit}, offset=${offset}`);\n\n try {\n // Build query parameters\n const queryParams = new URLSearchParams({\n limit: limit.toString(),\n offset: offset.toString(),\n });\n\n if (search) {\n queryParams.append('search', search);\n }\n\n if (tags && tags.length > 0) {\n tags.forEach((tag) => queryParams.append('tags[]', tag));\n }\n\n const url = `${API_ENDPOINTS.BRAGS.LIST}?${queryParams.toString()}`;\n\n const response = await this.makeRequest<ListBragsResponse>(url, {\n method: 'GET',\n });\n\n logger.debug(\n `Successfully fetched ${response.brags.length} brags (total: ${response.total})`\n );\n return response;\n } catch (_error) {\n logger.debug('Failed to list brags');\n throw _error;\n }\n }\n\n /**\n * Get user's subscription status\n */\n async getSubscriptionStatus(): Promise<GetSubscriptionStatusResponse> {\n logger.debug(`Fetching subscription status from ${API_ENDPOINTS.SUBSCRIPTION.STATUS}`);\n\n try {\n const response = await this.makeRequest<{\n status: string;\n data: GetSubscriptionStatusResponse;\n }>(API_ENDPOINTS.SUBSCRIPTION.STATUS, {\n method: 'GET',\n });\n\n logger.debug(`Subscription API response: ${JSON.stringify(response)}`);\n\n // Unwrap the response - API returns { status: \"success\", data: {...} }\n const subscriptionData = response.data;\n\n logger.debug(\n `Subscription tier: ${subscriptionData.tier}, status: ${subscriptionData.status}`\n );\n return subscriptionData;\n } catch (error) {\n logger.debug(`Failed to fetch subscription status: ${error}`);\n logger.debug(`Error details: ${JSON.stringify(error, null, 2)}`);\n throw error;\n }\n }\n\n /**\n * Check for CLI updates\n */\n async checkVersion(): Promise<VersionCheckResponse> {\n logger.debug('Checking for CLI updates');\n\n try {\n const response = await this.makeRequest<VersionCheckResponse>(API_ENDPOINTS.VERSION, {\n method: 'GET',\n });\n\n logger.debug(`Latest version: ${response.latest_version}`);\n return response;\n } catch {\n logger.debug('Failed to check version');\n // Don't throw error for version check failures\n // Return current version as fallback\n const { version } = await import('../utils/version.js');\n return {\n latest_version: version,\n critical_update: false,\n };\n }\n }\n\n /**\n * Test API connectivity\n */\n async testConnection(): Promise<boolean> {\n try {\n await this.checkVersion();\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Update base URL\n */\n setBaseURL(url: string): void {\n this.baseURL = url;\n // Recreate client with new base URL\n this.client = ofetch.create({\n baseURL: url,\n });\n }\n\n /**\n * Get current base URL\n */\n getBaseURL(): string {\n return this.baseURL;\n }\n}\n\n// Export singleton instance\nexport const apiService = new ApiService();\n","import { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport chalk from 'chalk';\nimport boxen from 'boxen';\nimport { apiService } from '../services/api.service.js';\nimport { storageService } from '../services/storage.service.js';\nimport { logger } from './logger.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get current CLI version from package.json\n */\nexport function getCurrentVersion(): string {\n try {\n // In production (dist/utils/version.js), package.json is 2 levels up\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return packageJson.version;\n } catch {\n logger.debug('Failed to read package.json version');\n return '1.0.0'; // Fallback version\n }\n}\n\n/**\n * Export current version\n */\nexport const version = getCurrentVersion();\n\n/**\n * Compare two semantic versions\n * Returns:\n * 1 if v1 > v2\n * 0 if v1 === v2\n * -1 if v1 < v2\n */\nexport function compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map((p) => parseInt(p, 10));\n const parts2 = v2.split('.').map((p) => parseInt(p, 10));\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 > part2) return 1;\n if (part1 < part2) return -1;\n }\n\n return 0;\n}\n\n/**\n * Check if a newer version is available\n */\nexport async function checkForUpdates(\n options: {\n silent?: boolean;\n force?: boolean;\n } = {}\n): Promise<{ updateAvailable: boolean; latestVersion: string; currentVersion: string }> {\n const { silent = false, force = false } = options;\n\n try {\n // Skip version check if disabled in config (unless forced)\n if (!force) {\n const autoVersionCheck = storageService.getConfig('autoVersionCheck');\n if (!autoVersionCheck) {\n logger.debug('Version check disabled in config');\n return {\n updateAvailable: false,\n latestVersion: version,\n currentVersion: version,\n };\n }\n }\n\n logger.debug('Checking for CLI updates...');\n\n // Check via API service\n const response = await apiService.checkVersion();\n const latestVersion = response.latest_version;\n const currentVersion = version;\n\n logger.debug(`Current version: ${currentVersion}, Latest version: ${latestVersion}`);\n\n const updateAvailable = compareVersions(latestVersion, currentVersion) > 0;\n\n // Display update notification if not silent and update is available\n if (!silent && updateAvailable) {\n displayUpdateNotification(currentVersion, latestVersion, response.critical_update);\n }\n\n return {\n updateAvailable,\n latestVersion,\n currentVersion,\n };\n } catch (error: any) {\n logger.debug(`Version check failed: ${error.message}`);\n // Don't throw error - version check is non-critical\n return {\n updateAvailable: false,\n latestVersion: version,\n currentVersion: version,\n };\n }\n}\n\n/**\n * Display update notification\n */\nfunction displayUpdateNotification(\n currentVersion: string,\n latestVersion: string,\n critical: boolean = false\n): void {\n const urgency = critical\n ? chalk.red.bold('CRITICAL UPDATE')\n : chalk.yellow.bold('Update Available');\n const message =\n `${urgency}\\n\\n` +\n `Current version: ${chalk.dim(currentVersion)}\\n` +\n `Latest version: ${chalk.green(latestVersion)}\\n\\n` +\n `Update with: ${chalk.cyan('npm install -g @bragduck/cli@latest')}`;\n\n console.log('');\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 0, right: 1, bottom: 0, left: 1 },\n borderStyle: 'round',\n borderColor: critical ? 'red' : 'yellow',\n })\n );\n console.log('');\n\n if (critical) {\n logger.warning('This is a critical update. Please update as soon as possible.');\n console.log('');\n }\n}\n\n/**\n * Format version for display\n */\nexport function formatVersion(includePrefix: boolean = true): string {\n const prefix = includePrefix ? 'v' : '';\n return `${prefix}${version}`;\n}\n","// Main entry point for the Bragduck CLI package\n// This file exports the public API for programmatic usage\n\nexport { version } from './utils/version.js';\n\n// Future exports will be added here as we implement services and utilities\n// Example:\n// export { AuthService } from './services/auth.service.js';\n// export { GitService } from './services/git.service.js';\n// export { ApiService } from './services/api.service.js';\n"],"mappings":"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","names":["fileURLToPath","join","randomBytes","readFileSync","fileURLToPath","dirname","join","__dirname","version","__filename","ofetch","readFileSync","fileURLToPath","URLSearchParams","dirname","join","__dirname","__filename","version","readFileSync","fileURLToPath","dirname","join","chalk","__dirname","__filename"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bragduck/cli",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "CLI tool for managing developer achievements and brags",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",