@bragduck/cli 2.8.3 → 2.9.2
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/bin/bragduck.js +903 -868
- package/dist/bin/bragduck.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1105,7 +1105,7 @@ var init_auth_service = __esm({
|
|
|
1105
1105
|
refreshToken: tokenResponse.refresh_token,
|
|
1106
1106
|
expiresAt
|
|
1107
1107
|
};
|
|
1108
|
-
await storageService.
|
|
1108
|
+
await storageService.setServiceCredentials("bragduck", credentials);
|
|
1109
1109
|
if (tokenResponse.user) {
|
|
1110
1110
|
storageService.setUserInfo(tokenResponse.user);
|
|
1111
1111
|
}
|
|
@@ -1132,7 +1132,7 @@ var init_auth_service = __esm({
|
|
|
1132
1132
|
* Get current access token
|
|
1133
1133
|
*/
|
|
1134
1134
|
async getAccessToken() {
|
|
1135
|
-
const credentials = await storageService.
|
|
1135
|
+
const credentials = await storageService.getServiceCredentials("bragduck");
|
|
1136
1136
|
return credentials?.accessToken || null;
|
|
1137
1137
|
}
|
|
1138
1138
|
/**
|
|
@@ -1146,7 +1146,7 @@ var init_auth_service = __esm({
|
|
|
1146
1146
|
*/
|
|
1147
1147
|
async refreshToken() {
|
|
1148
1148
|
logger.debug("Refreshing access token");
|
|
1149
|
-
const credentials = await storageService.
|
|
1149
|
+
const credentials = await storageService.getServiceCredentials("bragduck");
|
|
1150
1150
|
if (!credentials?.refreshToken) {
|
|
1151
1151
|
throw new AuthenticationError("No refresh token available");
|
|
1152
1152
|
}
|
|
@@ -1172,7 +1172,7 @@ var init_auth_service = __esm({
|
|
|
1172
1172
|
refreshToken: response.refresh_token || credentials.refreshToken,
|
|
1173
1173
|
expiresAt
|
|
1174
1174
|
};
|
|
1175
|
-
await storageService.
|
|
1175
|
+
await storageService.setServiceCredentials("bragduck", newCredentials);
|
|
1176
1176
|
logger.debug("Token refresh successful");
|
|
1177
1177
|
} catch (error) {
|
|
1178
1178
|
logger.debug(`Token refresh failed: ${error.message}`);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/constants.ts","../src/utils/env-loader.ts","../src/utils/errors.ts","../src/utils/config-loader.ts","../src/services/storage.service.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 DEFAULT_SOURCE: 'defaultSource',\n SOURCE_PRIORITY: 'sourcePriority',\n JIRA_INSTANCE: 'jiraInstance',\n CONFLUENCE_INSTANCE: 'confluenceInstance',\n GITLAB_INSTANCE: 'gitlabInstance',\n} as const;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG = {\n defaultCommitDays: 30,\n autoVersionCheck: true,\n defaultSource: undefined,\n sourcePriority: undefined,\n jiraInstance: undefined,\n confluenceInstance: undefined,\n gitlabInstance: undefined,\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 ORGANISATIONS: {\n LIST: '/v1/users/{userId}/organisations',\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\n/**\n * Environment variable names for configuration\n */\nexport const ENV_VARS = {\n SOURCE: 'BRAGDUCK_SOURCE',\n JIRA_INSTANCE: 'BRAGDUCK_JIRA_INSTANCE',\n CONFLUENCE_INSTANCE: 'BRAGDUCK_CONFLUENCE_INSTANCE',\n GITLAB_INSTANCE: 'BRAGDUCK_GITLAB_INSTANCE',\n DEFAULT_COMMIT_DAYS: 'BRAGDUCK_DEFAULT_COMMIT_DAYS',\n AUTO_VERSION_CHECK: 'BRAGDUCK_AUTO_VERSION_CHECK',\n SOURCE_PRIORITY: 'BRAGDUCK_SOURCE_PRIORITY',\n\n // Credentials (for CI/CD)\n JIRA_TOKEN: 'BRAGDUCK_JIRA_TOKEN',\n CONFLUENCE_TOKEN: 'BRAGDUCK_CONFLUENCE_TOKEN',\n GITLAB_TOKEN: 'BRAGDUCK_GITLAB_TOKEN',\n} as const;\n\n/**\n * Project config file names to search for (in order of priority)\n */\nexport const CONFIG_FILES = ['.bragduckrc', '.bragduck/config.json', '.bragduckrc.json'] as const;\n","import type { SourceType } from '../types/source.types.js';\nimport type { EnvironmentConfig } from '../types/config.types.js';\n\n/**\n * Parse a number from environment variable\n */\nfunction parseEnvNumber(key: string): number | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Parse a boolean from environment variable\n * Accepts: true/false, yes/no, 1/0 (case-insensitive)\n */\nfunction parseEnvBoolean(key: string): boolean | undefined {\n const value = process.env[key]?.toLowerCase();\n if (!value) return undefined;\n\n if (['true', 'yes', '1'].includes(value)) return true;\n if (['false', 'no', '0'].includes(value)) return false;\n return undefined;\n}\n\n/**\n * Parse an array from environment variable (comma-separated)\n */\nfunction parseEnvArray(key: string): SourceType[] | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const items = value\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n return items.length > 0 ? (items as SourceType[]) : undefined;\n}\n\n/**\n * Validate source type from environment variable\n */\nfunction parseEnvSource(key: string): SourceType | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n return validSources.includes(value as SourceType) ? (value as SourceType) : undefined;\n}\n\n/**\n * Load configuration from environment variables\n * Environment variables follow the pattern: BRAGDUCK_*\n */\nexport function loadEnvConfig(): EnvironmentConfig {\n return {\n // Source configuration\n source: parseEnvSource('BRAGDUCK_SOURCE'),\n jiraInstance: process.env.BRAGDUCK_JIRA_INSTANCE,\n confluenceInstance: process.env.BRAGDUCK_CONFLUENCE_INSTANCE,\n gitlabInstance: process.env.BRAGDUCK_GITLAB_INSTANCE,\n\n // Behavior configuration\n defaultCommitDays: parseEnvNumber('BRAGDUCK_DEFAULT_COMMIT_DAYS'),\n autoVersionCheck: parseEnvBoolean('BRAGDUCK_AUTO_VERSION_CHECK'),\n sourcePriority: parseEnvArray('BRAGDUCK_SOURCE_PRIORITY'),\n\n // Credential overrides (for CI/CD)\n jiraToken: process.env.BRAGDUCK_JIRA_TOKEN,\n confluenceToken: process.env.BRAGDUCK_CONFLUENCE_TOKEN,\n gitlabToken: process.env.BRAGDUCK_GITLAB_TOKEN,\n };\n}\n\n/**\n * Get a specific environment config value\n */\nexport function getEnvConfigValue<K extends keyof EnvironmentConfig>(key: K): EnvironmentConfig[K] {\n const config = loadEnvConfig();\n return config[key];\n}\n\n/**\n * Check if any environment configuration is set\n */\nexport function hasEnvConfig(): boolean {\n const config = loadEnvConfig();\n return Object.values(config).some((value) => value !== undefined);\n}\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\n/**\n * Bitbucket-related errors\n */\nexport class BitbucketError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'BITBUCKET_ERROR', details);\n this.name = 'BitbucketError';\n }\n}\n\n/**\n * GitLab-related errors\n */\nexport class GitLabError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GITLAB_ERROR', details);\n this.name = 'GitLabError';\n }\n}\n\n/**\n * Jira-related errors\n */\nexport class JiraError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'JIRA_ERROR', details);\n this.name = 'JiraError';\n }\n}\n\n/**\n * Confluence-related errors\n */\nexport class ConfluenceError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'CONFLUENCE_ERROR', details);\n this.name = 'ConfluenceError';\n }\n}\n\n/**\n * Atlassian-related errors (for shared Atlassian services)\n */\nexport class AtlassianError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'ATLASSIAN_ERROR', details);\n this.name = 'AtlassianError';\n }\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { CONFIG_FILES } from '../constants.js';\nimport { ValidationError } from './errors.js';\nimport type { SourceType } from '../types/source.types.js';\nimport type { ProjectConfig } from '../types/config.types.js';\n\n/**\n * Cache for project config to avoid repeated file system reads\n */\nlet configCache: Map<string, ProjectConfig | null> = new Map();\n\n/**\n * Find and load project config file in the current directory\n */\nexport async function findProjectConfig(): Promise<ProjectConfig | null> {\n const cwd = process.cwd();\n\n // Check cache first\n if (configCache.has(cwd)) {\n return configCache.get(cwd) || null;\n }\n\n // Search for config files in order of priority\n for (const filename of CONFIG_FILES) {\n const configPath = path.join(cwd, filename);\n\n try {\n await fs.access(configPath);\n const config = await loadAndValidateConfig(configPath);\n configCache.set(cwd, config);\n return config;\n } catch {\n // File doesn't exist or is not readable, continue to next\n continue;\n }\n }\n\n // No config file found\n configCache.set(cwd, null);\n return null;\n}\n\n/**\n * Load and validate a project config file\n */\nexport async function loadAndValidateConfig(configPath: string): Promise<ProjectConfig> {\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n const config = JSON.parse(content);\n\n // Validate the config structure\n validateProjectConfig(config);\n\n return config as ProjectConfig;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ValidationError(`Invalid JSON in config file: ${configPath}`, {\n originalError: error.message,\n });\n }\n throw error;\n }\n}\n\n/**\n * Validate project config structure\n */\nfunction validateProjectConfig(config: unknown): void {\n if (typeof config !== 'object' || config === null) {\n throw new ValidationError('Config must be a JSON object');\n }\n\n const cfg = config as Record<string, unknown>;\n\n // Validate defaultCommitDays\n if (cfg.defaultCommitDays !== undefined) {\n if (typeof cfg.defaultCommitDays !== 'number') {\n throw new ValidationError('defaultCommitDays must be a number');\n }\n if (cfg.defaultCommitDays < 1 || cfg.defaultCommitDays > 365) {\n throw new ValidationError('defaultCommitDays must be between 1 and 365');\n }\n }\n\n // Validate autoVersionCheck\n if (cfg.autoVersionCheck !== undefined) {\n if (typeof cfg.autoVersionCheck !== 'boolean') {\n throw new ValidationError('autoVersionCheck must be a boolean');\n }\n }\n\n // Validate defaultSource\n if (cfg.defaultSource !== undefined) {\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n if (!validSources.includes(cfg.defaultSource as SourceType)) {\n throw new ValidationError(\n `Invalid defaultSource: ${cfg.defaultSource}. Must be one of: ${validSources.join(', ')}`\n );\n }\n }\n\n // Validate sourcePriority\n if (cfg.sourcePriority !== undefined) {\n if (!Array.isArray(cfg.sourcePriority)) {\n throw new ValidationError('sourcePriority must be an array');\n }\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n for (const source of cfg.sourcePriority) {\n if (!validSources.includes(source)) {\n throw new ValidationError(\n `Invalid source in sourcePriority: ${source}. Must be one of: ${validSources.join(', ')}`\n );\n }\n }\n }\n\n // Validate instance URLs\n const instanceFields = ['jiraInstance', 'confluenceInstance', 'gitlabInstance'];\n for (const field of instanceFields) {\n if (cfg[field] !== undefined) {\n if (typeof cfg[field] !== 'string') {\n throw new ValidationError(`${field} must be a string`);\n }\n // Basic hostname/URL validation\n const value = cfg[field] as string;\n if (!value.match(/^[a-zA-Z0-9.-]+(:[0-9]+)?(\\/.*)?$/)) {\n throw new ValidationError(`Invalid ${field}: ${value}`);\n }\n }\n }\n\n // Validate boolean flags\n const booleanFields = ['requireAuthentication', 'skipSourceDetection'];\n for (const field of booleanFields) {\n if (cfg[field] !== undefined && typeof cfg[field] !== 'boolean') {\n throw new ValidationError(`${field} must be a boolean`);\n }\n }\n}\n\n/**\n * Clear the config cache (useful for testing)\n */\nexport function clearConfigCache(): void {\n configCache.clear();\n}\n\n/**\n * Get config value from project config\n */\nexport async function getProjectConfigValue<K extends keyof ProjectConfig>(\n key: K\n): Promise<ProjectConfig[K] | undefined> {\n const config = await findProjectConfig();\n return config?.[key];\n}\n\n/**\n * Check if a project config file exists\n */\nexport async function hasProjectConfig(): Promise<boolean> {\n const config = await findProjectConfig();\n return config !== null;\n}\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 { loadEnvConfig } from '../utils/env-loader.js';\nimport { findProjectConfig } from '../utils/config-loader.js';\nimport type {\n StoredCredentials,\n ServiceCredentials,\n ServiceType,\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 (checks bragduck service)\n */\n async isAuthenticated(): Promise<boolean> {\n // Use the service-aware authentication check to support both legacy and multi-service formats\n return this.isServiceAuthenticated('bragduck');\n }\n\n /**\n * Get credentials for a specific service\n */\n async getServiceCredentials(service: ServiceType): Promise<ServiceCredentials | null> {\n const credentials = await this.getCredentials();\n if (!credentials) return null;\n\n // Handle legacy format for bragduck service\n if (service === 'bragduck' && credentials.accessToken && !credentials.services) {\n return {\n accessToken: credentials.accessToken,\n refreshToken: credentials.refreshToken,\n expiresAt: credentials.expiresAt,\n };\n }\n\n return credentials.services?.[service] || null;\n }\n\n /**\n * Set credentials for a specific service\n */\n async setServiceCredentials(service: ServiceType, creds: ServiceCredentials): Promise<void> {\n let existing = await this.getCredentials();\n\n // Migrate legacy format on first new service addition\n if (existing && existing.accessToken && !existing.services) {\n existing = {\n services: {\n bragduck: {\n accessToken: existing.accessToken,\n refreshToken: existing.refreshToken,\n expiresAt: existing.expiresAt,\n },\n },\n };\n }\n\n const updated: StoredCredentials = {\n ...existing,\n services: {\n ...existing?.services,\n [service]: creds,\n },\n };\n\n await this.setCredentials(updated);\n }\n\n /**\n * Delete credentials for a specific service\n */\n async deleteServiceCredentials(service: ServiceType): Promise<void> {\n const existing = await this.getCredentials();\n if (!existing?.services?.[service]) return;\n\n delete existing.services[service];\n await this.setCredentials(existing);\n }\n\n /**\n * Check if a specific service is authenticated\n */\n async isServiceAuthenticated(service: ServiceType): Promise<boolean> {\n const creds = await this.getServiceCredentials(service);\n if (!creds?.accessToken) return false;\n\n // Check expiration\n if (creds.expiresAt && creds.expiresAt < Date.now()) return false;\n\n return true;\n }\n\n /**\n * List all authenticated services\n */\n async getAuthenticatedServices(): Promise<ServiceType[]> {\n const credentials = await this.getCredentials();\n if (!credentials) return [];\n\n // Handle legacy format\n if (credentials.accessToken && !credentials.services) {\n return ['bragduck'];\n }\n\n if (!credentials.services) return [];\n\n const services: ServiceType[] = [];\n for (const [service, creds] of Object.entries(credentials.services)) {\n if (creds?.accessToken) {\n services.push(service as ServiceType);\n }\n }\n\n return services;\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 with hierarchy resolution\n * Priority: env vars > project config > user config > defaults\n */\n async getConfigWithHierarchy<K extends keyof BragduckConfig>(key: K): Promise<BragduckConfig[K]> {\n // 1. Check environment variable\n const envConfig = loadEnvConfig();\n const envKey = key === 'defaultSource' ? 'source' : key;\n if (envConfig[envKey as keyof typeof envConfig] !== undefined) {\n return envConfig[envKey as keyof typeof envConfig] as BragduckConfig[K];\n }\n\n // 2. Check project config\n const projectConfig = await findProjectConfig();\n if (projectConfig && projectConfig[key] !== undefined) {\n return projectConfig[key] as BragduckConfig[K];\n }\n\n // 3. Check user config\n const userValue = this.config.get(key);\n if (userValue !== undefined) {\n return userValue;\n }\n\n // 4. Return default\n return DEFAULT_CONFIG[key] as BragduckConfig[K];\n }\n\n /**\n * Get configuration value (uses hierarchy resolution)\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 (merges all layers)\n * Priority: env vars > project config > user config > defaults\n */\n async getAllConfigWithHierarchy(): Promise<BragduckConfig> {\n const envConfig = loadEnvConfig();\n const projectConfig = await findProjectConfig();\n const userConfig = this.config.store;\n\n // Merge all layers with proper priority\n return {\n ...DEFAULT_CONFIG,\n ...userConfig,\n ...projectConfig,\n ...(envConfig.source && { defaultSource: envConfig.source }),\n ...(envConfig.jiraInstance && { jiraInstance: envConfig.jiraInstance }),\n ...(envConfig.confluenceInstance && { confluenceInstance: envConfig.confluenceInstance }),\n ...(envConfig.gitlabInstance && { gitlabInstance: envConfig.gitlabInstance }),\n ...(envConfig.defaultCommitDays !== undefined && {\n defaultCommitDays: envConfig.defaultCommitDays,\n }),\n ...(envConfig.autoVersionCheck !== undefined && {\n autoVersionCheck: envConfig.autoVersionCheck,\n }),\n ...(envConfig.sourcePriority && { sourcePriority: envConfig.sourcePriority }),\n };\n }\n\n /**\n * Get all configuration (user config only)\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 (skip undefined values)\n Object.entries(DEFAULT_CONFIG).forEach(([key, value]) => {\n if (value !== undefined) {\n this.config.set(key as keyof BragduckConfig, value as any);\n }\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","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(\n 'Bragduck platform token refresh failed. Please run \"bragduck auth login\" to re-authenticate.'\n );\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 ListOrganisationsResponse,\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 Bragduck platform session has expired. Please run \"bragduck auth login\" to re-authenticate.'\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 logger.debug(`Request body: ${JSON.stringify(request, null, 2)}`);\n\n try {\n const response = await this.makeRequest<CreateBragsResponse>(API_ENDPOINTS.BRAGS.CREATE, {\n method: 'POST',\n body: request,\n });\n logger.debug(`Response: ${JSON.stringify(response, null, 2)}`);\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 * List user's organisations\n */\n async listUserOrganisations(userId: string): Promise<ListOrganisationsResponse> {\n logger.debug(`Listing organisations for user: ${userId}`);\n\n try {\n const url = API_ENDPOINTS.ORGANISATIONS.LIST.replace('{userId}', userId);\n\n const response = await this.makeRequest<ListOrganisationsResponse>(url, {\n method: 'GET',\n });\n\n logger.debug(`Successfully fetched ${response.items.length} organisations`);\n return response;\n } catch (_error) {\n logger.debug('Failed to list organisations');\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","path","config","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/utils/env-loader.ts","../src/utils/errors.ts","../src/utils/config-loader.ts","../src/services/storage.service.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 DEFAULT_SOURCE: 'defaultSource',\n SOURCE_PRIORITY: 'sourcePriority',\n JIRA_INSTANCE: 'jiraInstance',\n CONFLUENCE_INSTANCE: 'confluenceInstance',\n GITLAB_INSTANCE: 'gitlabInstance',\n} as const;\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG = {\n defaultCommitDays: 30,\n autoVersionCheck: true,\n defaultSource: undefined,\n sourcePriority: undefined,\n jiraInstance: undefined,\n confluenceInstance: undefined,\n gitlabInstance: undefined,\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 ORGANISATIONS: {\n LIST: '/v1/users/{userId}/organisations',\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\n/**\n * Environment variable names for configuration\n */\nexport const ENV_VARS = {\n SOURCE: 'BRAGDUCK_SOURCE',\n JIRA_INSTANCE: 'BRAGDUCK_JIRA_INSTANCE',\n CONFLUENCE_INSTANCE: 'BRAGDUCK_CONFLUENCE_INSTANCE',\n GITLAB_INSTANCE: 'BRAGDUCK_GITLAB_INSTANCE',\n DEFAULT_COMMIT_DAYS: 'BRAGDUCK_DEFAULT_COMMIT_DAYS',\n AUTO_VERSION_CHECK: 'BRAGDUCK_AUTO_VERSION_CHECK',\n SOURCE_PRIORITY: 'BRAGDUCK_SOURCE_PRIORITY',\n\n // Credentials (for CI/CD)\n JIRA_TOKEN: 'BRAGDUCK_JIRA_TOKEN',\n CONFLUENCE_TOKEN: 'BRAGDUCK_CONFLUENCE_TOKEN',\n GITLAB_TOKEN: 'BRAGDUCK_GITLAB_TOKEN',\n} as const;\n\n/**\n * Project config file names to search for (in order of priority)\n */\nexport const CONFIG_FILES = ['.bragduckrc', '.bragduck/config.json', '.bragduckrc.json'] as const;\n","import type { SourceType } from '../types/source.types.js';\nimport type { EnvironmentConfig } from '../types/config.types.js';\n\n/**\n * Parse a number from environment variable\n */\nfunction parseEnvNumber(key: string): number | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Parse a boolean from environment variable\n * Accepts: true/false, yes/no, 1/0 (case-insensitive)\n */\nfunction parseEnvBoolean(key: string): boolean | undefined {\n const value = process.env[key]?.toLowerCase();\n if (!value) return undefined;\n\n if (['true', 'yes', '1'].includes(value)) return true;\n if (['false', 'no', '0'].includes(value)) return false;\n return undefined;\n}\n\n/**\n * Parse an array from environment variable (comma-separated)\n */\nfunction parseEnvArray(key: string): SourceType[] | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const items = value\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n return items.length > 0 ? (items as SourceType[]) : undefined;\n}\n\n/**\n * Validate source type from environment variable\n */\nfunction parseEnvSource(key: string): SourceType | undefined {\n const value = process.env[key];\n if (!value) return undefined;\n\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n return validSources.includes(value as SourceType) ? (value as SourceType) : undefined;\n}\n\n/**\n * Load configuration from environment variables\n * Environment variables follow the pattern: BRAGDUCK_*\n */\nexport function loadEnvConfig(): EnvironmentConfig {\n return {\n // Source configuration\n source: parseEnvSource('BRAGDUCK_SOURCE'),\n jiraInstance: process.env.BRAGDUCK_JIRA_INSTANCE,\n confluenceInstance: process.env.BRAGDUCK_CONFLUENCE_INSTANCE,\n gitlabInstance: process.env.BRAGDUCK_GITLAB_INSTANCE,\n\n // Behavior configuration\n defaultCommitDays: parseEnvNumber('BRAGDUCK_DEFAULT_COMMIT_DAYS'),\n autoVersionCheck: parseEnvBoolean('BRAGDUCK_AUTO_VERSION_CHECK'),\n sourcePriority: parseEnvArray('BRAGDUCK_SOURCE_PRIORITY'),\n\n // Credential overrides (for CI/CD)\n jiraToken: process.env.BRAGDUCK_JIRA_TOKEN,\n confluenceToken: process.env.BRAGDUCK_CONFLUENCE_TOKEN,\n gitlabToken: process.env.BRAGDUCK_GITLAB_TOKEN,\n };\n}\n\n/**\n * Get a specific environment config value\n */\nexport function getEnvConfigValue<K extends keyof EnvironmentConfig>(key: K): EnvironmentConfig[K] {\n const config = loadEnvConfig();\n return config[key];\n}\n\n/**\n * Check if any environment configuration is set\n */\nexport function hasEnvConfig(): boolean {\n const config = loadEnvConfig();\n return Object.values(config).some((value) => value !== undefined);\n}\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\n/**\n * Bitbucket-related errors\n */\nexport class BitbucketError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'BITBUCKET_ERROR', details);\n this.name = 'BitbucketError';\n }\n}\n\n/**\n * GitLab-related errors\n */\nexport class GitLabError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'GITLAB_ERROR', details);\n this.name = 'GitLabError';\n }\n}\n\n/**\n * Jira-related errors\n */\nexport class JiraError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'JIRA_ERROR', details);\n this.name = 'JiraError';\n }\n}\n\n/**\n * Confluence-related errors\n */\nexport class ConfluenceError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'CONFLUENCE_ERROR', details);\n this.name = 'ConfluenceError';\n }\n}\n\n/**\n * Atlassian-related errors (for shared Atlassian services)\n */\nexport class AtlassianError extends BragduckError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'ATLASSIAN_ERROR', details);\n this.name = 'AtlassianError';\n }\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { CONFIG_FILES } from '../constants.js';\nimport { ValidationError } from './errors.js';\nimport type { SourceType } from '../types/source.types.js';\nimport type { ProjectConfig } from '../types/config.types.js';\n\n/**\n * Cache for project config to avoid repeated file system reads\n */\nlet configCache: Map<string, ProjectConfig | null> = new Map();\n\n/**\n * Find and load project config file in the current directory\n */\nexport async function findProjectConfig(): Promise<ProjectConfig | null> {\n const cwd = process.cwd();\n\n // Check cache first\n if (configCache.has(cwd)) {\n return configCache.get(cwd) || null;\n }\n\n // Search for config files in order of priority\n for (const filename of CONFIG_FILES) {\n const configPath = path.join(cwd, filename);\n\n try {\n await fs.access(configPath);\n const config = await loadAndValidateConfig(configPath);\n configCache.set(cwd, config);\n return config;\n } catch {\n // File doesn't exist or is not readable, continue to next\n continue;\n }\n }\n\n // No config file found\n configCache.set(cwd, null);\n return null;\n}\n\n/**\n * Load and validate a project config file\n */\nexport async function loadAndValidateConfig(configPath: string): Promise<ProjectConfig> {\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n const config = JSON.parse(content);\n\n // Validate the config structure\n validateProjectConfig(config);\n\n return config as ProjectConfig;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new ValidationError(`Invalid JSON in config file: ${configPath}`, {\n originalError: error.message,\n });\n }\n throw error;\n }\n}\n\n/**\n * Validate project config structure\n */\nfunction validateProjectConfig(config: unknown): void {\n if (typeof config !== 'object' || config === null) {\n throw new ValidationError('Config must be a JSON object');\n }\n\n const cfg = config as Record<string, unknown>;\n\n // Validate defaultCommitDays\n if (cfg.defaultCommitDays !== undefined) {\n if (typeof cfg.defaultCommitDays !== 'number') {\n throw new ValidationError('defaultCommitDays must be a number');\n }\n if (cfg.defaultCommitDays < 1 || cfg.defaultCommitDays > 365) {\n throw new ValidationError('defaultCommitDays must be between 1 and 365');\n }\n }\n\n // Validate autoVersionCheck\n if (cfg.autoVersionCheck !== undefined) {\n if (typeof cfg.autoVersionCheck !== 'boolean') {\n throw new ValidationError('autoVersionCheck must be a boolean');\n }\n }\n\n // Validate defaultSource\n if (cfg.defaultSource !== undefined) {\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n if (!validSources.includes(cfg.defaultSource as SourceType)) {\n throw new ValidationError(\n `Invalid defaultSource: ${cfg.defaultSource}. Must be one of: ${validSources.join(', ')}`\n );\n }\n }\n\n // Validate sourcePriority\n if (cfg.sourcePriority !== undefined) {\n if (!Array.isArray(cfg.sourcePriority)) {\n throw new ValidationError('sourcePriority must be an array');\n }\n const validSources: SourceType[] = ['github', 'gitlab', 'bitbucket', 'jira', 'confluence'];\n for (const source of cfg.sourcePriority) {\n if (!validSources.includes(source)) {\n throw new ValidationError(\n `Invalid source in sourcePriority: ${source}. Must be one of: ${validSources.join(', ')}`\n );\n }\n }\n }\n\n // Validate instance URLs\n const instanceFields = ['jiraInstance', 'confluenceInstance', 'gitlabInstance'];\n for (const field of instanceFields) {\n if (cfg[field] !== undefined) {\n if (typeof cfg[field] !== 'string') {\n throw new ValidationError(`${field} must be a string`);\n }\n // Basic hostname/URL validation\n const value = cfg[field] as string;\n if (!value.match(/^[a-zA-Z0-9.-]+(:[0-9]+)?(\\/.*)?$/)) {\n throw new ValidationError(`Invalid ${field}: ${value}`);\n }\n }\n }\n\n // Validate boolean flags\n const booleanFields = ['requireAuthentication', 'skipSourceDetection'];\n for (const field of booleanFields) {\n if (cfg[field] !== undefined && typeof cfg[field] !== 'boolean') {\n throw new ValidationError(`${field} must be a boolean`);\n }\n }\n}\n\n/**\n * Clear the config cache (useful for testing)\n */\nexport function clearConfigCache(): void {\n configCache.clear();\n}\n\n/**\n * Get config value from project config\n */\nexport async function getProjectConfigValue<K extends keyof ProjectConfig>(\n key: K\n): Promise<ProjectConfig[K] | undefined> {\n const config = await findProjectConfig();\n return config?.[key];\n}\n\n/**\n * Check if a project config file exists\n */\nexport async function hasProjectConfig(): Promise<boolean> {\n const config = await findProjectConfig();\n return config !== null;\n}\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 { loadEnvConfig } from '../utils/env-loader.js';\nimport { findProjectConfig } from '../utils/config-loader.js';\nimport type {\n StoredCredentials,\n ServiceCredentials,\n ServiceType,\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 (checks bragduck service)\n */\n async isAuthenticated(): Promise<boolean> {\n // Use the service-aware authentication check to support both legacy and multi-service formats\n return this.isServiceAuthenticated('bragduck');\n }\n\n /**\n * Get credentials for a specific service\n */\n async getServiceCredentials(service: ServiceType): Promise<ServiceCredentials | null> {\n const credentials = await this.getCredentials();\n if (!credentials) return null;\n\n // Handle legacy format for bragduck service\n if (service === 'bragduck' && credentials.accessToken && !credentials.services) {\n return {\n accessToken: credentials.accessToken,\n refreshToken: credentials.refreshToken,\n expiresAt: credentials.expiresAt,\n };\n }\n\n return credentials.services?.[service] || null;\n }\n\n /**\n * Set credentials for a specific service\n */\n async setServiceCredentials(service: ServiceType, creds: ServiceCredentials): Promise<void> {\n let existing = await this.getCredentials();\n\n // Migrate legacy format on first new service addition\n if (existing && existing.accessToken && !existing.services) {\n existing = {\n services: {\n bragduck: {\n accessToken: existing.accessToken,\n refreshToken: existing.refreshToken,\n expiresAt: existing.expiresAt,\n },\n },\n };\n }\n\n const updated: StoredCredentials = {\n ...existing,\n services: {\n ...existing?.services,\n [service]: creds,\n },\n };\n\n await this.setCredentials(updated);\n }\n\n /**\n * Delete credentials for a specific service\n */\n async deleteServiceCredentials(service: ServiceType): Promise<void> {\n const existing = await this.getCredentials();\n if (!existing?.services?.[service]) return;\n\n delete existing.services[service];\n await this.setCredentials(existing);\n }\n\n /**\n * Check if a specific service is authenticated\n */\n async isServiceAuthenticated(service: ServiceType): Promise<boolean> {\n const creds = await this.getServiceCredentials(service);\n if (!creds?.accessToken) return false;\n\n // Check expiration\n if (creds.expiresAt && creds.expiresAt < Date.now()) return false;\n\n return true;\n }\n\n /**\n * List all authenticated services\n */\n async getAuthenticatedServices(): Promise<ServiceType[]> {\n const credentials = await this.getCredentials();\n if (!credentials) return [];\n\n // Handle legacy format\n if (credentials.accessToken && !credentials.services) {\n return ['bragduck'];\n }\n\n if (!credentials.services) return [];\n\n const services: ServiceType[] = [];\n for (const [service, creds] of Object.entries(credentials.services)) {\n if (creds?.accessToken) {\n services.push(service as ServiceType);\n }\n }\n\n return services;\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 with hierarchy resolution\n * Priority: env vars > project config > user config > defaults\n */\n async getConfigWithHierarchy<K extends keyof BragduckConfig>(key: K): Promise<BragduckConfig[K]> {\n // 1. Check environment variable\n const envConfig = loadEnvConfig();\n const envKey = key === 'defaultSource' ? 'source' : key;\n if (envConfig[envKey as keyof typeof envConfig] !== undefined) {\n return envConfig[envKey as keyof typeof envConfig] as BragduckConfig[K];\n }\n\n // 2. Check project config\n const projectConfig = await findProjectConfig();\n if (projectConfig && projectConfig[key] !== undefined) {\n return projectConfig[key] as BragduckConfig[K];\n }\n\n // 3. Check user config\n const userValue = this.config.get(key);\n if (userValue !== undefined) {\n return userValue;\n }\n\n // 4. Return default\n return DEFAULT_CONFIG[key] as BragduckConfig[K];\n }\n\n /**\n * Get configuration value (uses hierarchy resolution)\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 (merges all layers)\n * Priority: env vars > project config > user config > defaults\n */\n async getAllConfigWithHierarchy(): Promise<BragduckConfig> {\n const envConfig = loadEnvConfig();\n const projectConfig = await findProjectConfig();\n const userConfig = this.config.store;\n\n // Merge all layers with proper priority\n return {\n ...DEFAULT_CONFIG,\n ...userConfig,\n ...projectConfig,\n ...(envConfig.source && { defaultSource: envConfig.source }),\n ...(envConfig.jiraInstance && { jiraInstance: envConfig.jiraInstance }),\n ...(envConfig.confluenceInstance && { confluenceInstance: envConfig.confluenceInstance }),\n ...(envConfig.gitlabInstance && { gitlabInstance: envConfig.gitlabInstance }),\n ...(envConfig.defaultCommitDays !== undefined && {\n defaultCommitDays: envConfig.defaultCommitDays,\n }),\n ...(envConfig.autoVersionCheck !== undefined && {\n autoVersionCheck: envConfig.autoVersionCheck,\n }),\n ...(envConfig.sourcePriority && { sourcePriority: envConfig.sourcePriority }),\n };\n }\n\n /**\n * Get all configuration (user config only)\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 (skip undefined values)\n Object.entries(DEFAULT_CONFIG).forEach(([key, value]) => {\n if (value !== undefined) {\n this.config.set(key as keyof BragduckConfig, value as any);\n }\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","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 { ServiceCredentials, 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 for bragduck service\n const credentials: ServiceCredentials = {\n accessToken: tokenResponse.access_token,\n refreshToken: tokenResponse.refresh_token,\n expiresAt,\n };\n await storageService.setServiceCredentials('bragduck', 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.getServiceCredentials('bragduck');\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.getServiceCredentials('bragduck');\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 for bragduck service\n const newCredentials: ServiceCredentials = {\n accessToken: response.access_token,\n refreshToken: response.refresh_token || credentials.refreshToken,\n expiresAt,\n };\n await storageService.setServiceCredentials('bragduck', 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(\n 'Bragduck platform token refresh failed. Please run \"bragduck auth login\" to re-authenticate.'\n );\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 ListOrganisationsResponse,\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 Bragduck platform session has expired. Please run \"bragduck auth login\" to re-authenticate.'\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 logger.debug(`Request body: ${JSON.stringify(request, null, 2)}`);\n\n try {\n const response = await this.makeRequest<CreateBragsResponse>(API_ENDPOINTS.BRAGS.CREATE, {\n method: 'POST',\n body: request,\n });\n logger.debug(`Response: ${JSON.stringify(response, null, 2)}`);\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 * List user's organisations\n */\n async listUserOrganisations(userId: string): Promise<ListOrganisationsResponse> {\n logger.debug(`Listing organisations for user: ${userId}`);\n\n try {\n const url = API_ENDPOINTS.ORGANISATIONS.LIST.replace('{userId}', userId);\n\n const response = await this.makeRequest<ListOrganisationsResponse>(url, {\n method: 'GET',\n });\n\n logger.debug(`Successfully fetched ${response.items.length} organisations`);\n return response;\n } catch (_error) {\n logger.debug('Failed to list organisations');\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":";;;;;;;;;;;;AACA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAF9B;AAAA;AAAA;AAAA;AAAA;;;ACCA,SAAS,cAAc;AACvB,SAAS,iBAAAA,sBAAqB;AAC9B,SAAS,SAAS,YAAY;AAH9B,IAMM,YACA,WAYO,UA4BA,gBAaA,cAWA,eA4BA,mBAWA,eAsBA,aAwCA;AA5Kb;AAAA;AAAA;AAAA;AAMA,IAAM,aAAaA,eAAc,YAAY,GAAG;AAChD,IAAM,YAAY,QAAQ,UAAU;AAKpC,WAAO,EAAE,MAAM,KAAK,WAAW,MAAM,MAAM,MAAM,GAAG,OAAO,OAAO,OAAO,KAAK,CAAQ;AAO/E,IAAM,WAAW;AA4BjB,IAAM,iBAAiB;AAAA,MAC5B,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,MAClB,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,IAClB;AAKO,IAAM,eAAe;AAAA,MAC1B,WAAW;AAAA,MACX,eAAe;AAAA,MACf,YAAY;AAAA;AAAA,MACZ,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAKO,IAAM,gBAAgB;AAAA,MAC3B,MAAM;AAAA,QACJ,UAAU;AAAA,QACV,OAAO;AAAA,MACT;AAAA,MACA,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AAAA,MACA,cAAc;AAAA,QACZ,QAAQ;AAAA,MACV;AAAA,MACA,eAAe;AAAA,QACb,MAAM;AAAA,MACR;AAAA,MACA,SAAS;AAAA;AAAA;AAAA;AAAA,MAIT,SAAS;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,IACF;AAKO,IAAM,oBAAoB;AAAA,MAC/B,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,iBAAiB;AAAA,MACjB,aAAa;AAAA,IACf;AAKO,IAAM,gBAAgB;AAAA,MAC3B,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,aAAa;AAAA,IACf;AAkBO,IAAM,cAAc;AAAA,MACzB,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,aAAa;AAAA,MACb,cAAc;AAAA,MACd,WAAW;AAAA,MACX,WAAW;AAAA,MACX,uBAAuB;AAAA,IACzB;AAgCO,IAAM,eAAe,CAAC,eAAe,yBAAyB,kBAAkB;AAAA;AAAA;;;ACtKvF,SAAS,eAAe,KAAiC;AACvD,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAAS,SAAS,OAAO,EAAE;AACjC,SAAO,MAAM,MAAM,IAAI,SAAY;AACrC;AAMA,SAAS,gBAAgB,KAAkC;AACzD,QAAM,QAAQ,QAAQ,IAAI,GAAG,GAAG,YAAY;AAC5C,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,CAAC,QAAQ,OAAO,GAAG,EAAE,SAAS,KAAK,EAAG,QAAO;AACjD,MAAI,CAAC,SAAS,MAAM,GAAG,EAAE,SAAS,KAAK,EAAG,QAAO;AACjD,SAAO;AACT;AAKA,SAAS,cAAc,KAAuC;AAC5D,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,QAAQ,MACX,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAE7B,SAAO,MAAM,SAAS,IAAK,QAAyB;AACtD;AAKA,SAAS,eAAe,KAAqC;AAC3D,QAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,eAA6B,CAAC,UAAU,UAAU,aAAa,QAAQ,YAAY;AACzF,SAAO,aAAa,SAAS,KAAmB,IAAK,QAAuB;AAC9E;AAMO,SAAS,gBAAmC;AACjD,SAAO;AAAA;AAAA,IAEL,QAAQ,eAAe,iBAAiB;AAAA,IACxC,cAAc,QAAQ,IAAI;AAAA,IAC1B,oBAAoB,QAAQ,IAAI;AAAA,IAChC,gBAAgB,QAAQ,IAAI;AAAA;AAAA,IAG5B,mBAAmB,eAAe,8BAA8B;AAAA,IAChE,kBAAkB,gBAAgB,6BAA6B;AAAA,IAC/D,gBAAgB,cAAc,0BAA0B;AAAA;AAAA,IAGxD,WAAW,QAAQ,IAAI;AAAA,IACvB,iBAAiB,QAAQ,IAAI;AAAA,IAC7B,aAAa,QAAQ,IAAI;AAAA,EAC3B;AACF;AA3EA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAKa,eAgBA,qBAoBA,UAaA,cAoBA,iBAUA,YAUA;AA9Fb;AAAA;AAAA;AAAA;AAKO,IAAM,gBAAN,cAA4B,MAAM;AAAA,MAChC;AAAA,MACA;AAAA,MAEP,YAAY,SAAiB,MAAc,SAA+B;AACxE,cAAM,OAAO;AACb,aAAK,OAAO;AACZ,aAAK,OAAO;AACZ,aAAK,UAAU;AACf,cAAM,kBAAkB,MAAM,KAAK,WAAW;AAAA,MAChD;AAAA,IACF;AAKO,IAAM,sBAAN,cAAkC,cAAc;AAAA,MACrD,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,cAAc,OAAO;AACpC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAeO,IAAM,WAAN,cAAuB,cAAc;AAAA,MACnC;AAAA,MAEP,YAAY,SAAiB,YAAqB,SAA+B;AAC/E,cAAM,SAAS,aAAa,OAAO;AACnC,aAAK,OAAO;AACZ,aAAK,aAAa;AAAA,MACpB;AAAA,IACF;AAKO,IAAM,eAAN,cAA2B,cAAc;AAAA,MAC9C,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,iBAAiB,OAAO;AACvC,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAeO,IAAM,kBAAN,cAA8B,cAAc;AAAA,MACjD,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,oBAAoB,OAAO;AAC1C,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,aAAN,cAAyB,oBAAoB;AAAA,MAClD,YAAY,SAAiB,SAA+B;AAC1D,cAAM,SAAS,OAAO;AACtB,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAKO,IAAM,oBAAN,cAAgC,oBAAoB;AAAA,MACzD,YAAY,UAAU,oCAAoC;AACxD,cAAM,OAAO;AACb,aAAK,OAAO;AACZ,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;ACpGA,SAAS,YAAY,UAAU;AAC/B,OAAOC,WAAU;AAcjB,eAAsB,oBAAmD;AACvE,QAAM,MAAM,QAAQ,IAAI;AAGxB,MAAI,YAAY,IAAI,GAAG,GAAG;AACxB,WAAO,YAAY,IAAI,GAAG,KAAK;AAAA,EACjC;AAGA,aAAW,YAAY,cAAc;AACnC,UAAM,aAAaA,MAAK,KAAK,KAAK,QAAQ;AAE1C,QAAI;AACF,YAAM,GAAG,OAAO,UAAU;AAC1B,YAAMC,UAAS,MAAM,sBAAsB,UAAU;AACrD,kBAAY,IAAI,KAAKA,OAAM;AAC3B,aAAOA;AAAA,IACT,QAAQ;AAEN;AAAA,IACF;AAAA,EACF;AAGA,cAAY,IAAI,KAAK,IAAI;AACzB,SAAO;AACT;AAKA,eAAsB,sBAAsB,YAA4C;AACtF,MAAI;AACF,UAAM,UAAU,MAAM,GAAG,SAAS,YAAY,OAAO;AACrD,UAAMA,UAAS,KAAK,MAAM,OAAO;AAGjC,0BAAsBA,OAAM;AAE5B,WAAOA;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,aAAa;AAChC,YAAM,IAAI,gBAAgB,gCAAgC,UAAU,IAAI;AAAA,QACtE,eAAe,MAAM;AAAA,MACvB,CAAC;AAAA,IACH;AACA,UAAM;AAAA,EACR;AACF;AAKA,SAAS,sBAAsBA,SAAuB;AACpD,MAAI,OAAOA,YAAW,YAAYA,YAAW,MAAM;AACjD,UAAM,IAAI,gBAAgB,8BAA8B;AAAA,EAC1D;AAEA,QAAM,MAAMA;AAGZ,MAAI,IAAI,sBAAsB,QAAW;AACvC,QAAI,OAAO,IAAI,sBAAsB,UAAU;AAC7C,YAAM,IAAI,gBAAgB,oCAAoC;AAAA,IAChE;AACA,QAAI,IAAI,oBAAoB,KAAK,IAAI,oBAAoB,KAAK;AAC5D,YAAM,IAAI,gBAAgB,6CAA6C;AAAA,IACzE;AAAA,EACF;AAGA,MAAI,IAAI,qBAAqB,QAAW;AACtC,QAAI,OAAO,IAAI,qBAAqB,WAAW;AAC7C,YAAM,IAAI,gBAAgB,oCAAoC;AAAA,IAChE;AAAA,EACF;AAGA,MAAI,IAAI,kBAAkB,QAAW;AACnC,UAAM,eAA6B,CAAC,UAAU,UAAU,aAAa,QAAQ,YAAY;AACzF,QAAI,CAAC,aAAa,SAAS,IAAI,aAA2B,GAAG;AAC3D,YAAM,IAAI;AAAA,QACR,0BAA0B,IAAI,aAAa,qBAAqB,aAAa,KAAK,IAAI,CAAC;AAAA,MACzF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,IAAI,mBAAmB,QAAW;AACpC,QAAI,CAAC,MAAM,QAAQ,IAAI,cAAc,GAAG;AACtC,YAAM,IAAI,gBAAgB,iCAAiC;AAAA,IAC7D;AACA,UAAM,eAA6B,CAAC,UAAU,UAAU,aAAa,QAAQ,YAAY;AACzF,eAAW,UAAU,IAAI,gBAAgB;AACvC,UAAI,CAAC,aAAa,SAAS,MAAM,GAAG;AAClC,cAAM,IAAI;AAAA,UACR,qCAAqC,MAAM,qBAAqB,aAAa,KAAK,IAAI,CAAC;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,iBAAiB,CAAC,gBAAgB,sBAAsB,gBAAgB;AAC9E,aAAW,SAAS,gBAAgB;AAClC,QAAI,IAAI,KAAK,MAAM,QAAW;AAC5B,UAAI,OAAO,IAAI,KAAK,MAAM,UAAU;AAClC,cAAM,IAAI,gBAAgB,GAAG,KAAK,mBAAmB;AAAA,MACvD;AAEA,YAAM,QAAQ,IAAI,KAAK;AACvB,UAAI,CAAC,MAAM,MAAM,mCAAmC,GAAG;AACrD,cAAM,IAAI,gBAAgB,WAAW,KAAK,KAAK,KAAK,EAAE;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,CAAC,yBAAyB,qBAAqB;AACrE,aAAW,SAAS,eAAe;AACjC,QAAI,IAAI,KAAK,MAAM,UAAa,OAAO,IAAI,KAAK,MAAM,WAAW;AAC/D,YAAM,IAAI,gBAAgB,GAAG,KAAK,oBAAoB;AAAA,IACxD;AAAA,EACF;AACF;AA3IA,IAUI;AAVJ;AAAA;AAAA;AAAA;AAEA;AACA;AAOA,IAAI,cAAiD,oBAAI,IAAI;AAAA;AAAA;;;ACV7D,OAAO,UAAU;AACjB,SAAS,gBAAgB,kBAAkB,aAAa,kBAAkB;AAC1E,SAAS,YAAY,WAAW,cAAc,eAAe,kBAAkB;AAC/E,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AAJrB,IA0Ba,gBAyYA;AAnab;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AAmBO,IAAM,iBAAN,MAAqB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAER,cAAc;AAEZ,aAAK,SAAS,IAAI,KAAqB;AAAA,UACrC,aAAa;AAAA,UACb,UAAU;AAAA,QACZ,CAAC;AAGD,aAAK,iBAAiBA,MAAK,QAAQ,GAAG,cAAc,eAAe;AACnE,aAAK,sBAAsBA,MAAK,KAAK,gBAAgB,cAAc,gBAAgB;AAGnF,aAAK,iBAAiB;AACtB,aAAK,qBAAqB;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA,MAKQ,uBAA6B;AACnC,YAAI,CAAC,WAAW,KAAK,cAAc,GAAG;AACpC,oBAAU,KAAK,gBAAgB,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAAA,QACjE;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,QAAQ,MAAc,KAA4B;AACxD,cAAM,KAAK,YAAY,kBAAkB,SAAS;AAClD,cAAM,SAAS,eAAe,kBAAkB,WAAW,KAAK,IAAI;AAAA,UAClE,eAAe,kBAAkB;AAAA,QACnC,CAAC;AAED,YAAI,YAAY,OAAO,OAAO,MAAM,QAAQ,KAAK;AACjD,qBAAa,OAAO,MAAM,KAAK;AAE/B,cAAM,UAAU,OAAO,WAAW;AAElC,eAAO;AAAA,UACL;AAAA,UACA,IAAI,GAAG,SAAS,KAAK;AAAA,UACrB,SAAS,QAAQ,SAAS,KAAK;AAAA,UAC/B,MAAM;AAAA;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,QAAQ,eAA8B,KAAqB;AACjE,cAAM,WAAW;AAAA,UACf,kBAAkB;AAAA,UAClB;AAAA,UACA,OAAO,KAAK,cAAc,IAAI,KAAK;AAAA,UACnC;AAAA,YACE,eAAe,kBAAkB;AAAA,UACnC;AAAA,QACF;AAEA,iBAAS,WAAW,OAAO,KAAK,cAAc,SAAS,KAAK,CAAC;AAE7D,YAAI,YAAY,SAAS,OAAO,cAAc,WAAW,OAAO,MAAM;AACtE,qBAAa,SAAS,MAAM,MAAM;AAElC,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKQ,oBAAoB,MAAsB;AAEhD,cAAM,WAAW,GAAG,QAAQ,IAAI,QAAQ,CAAC,IAAI,QAAQ,QAAQ;AAC7D,eAAO,WAAW,UAAU,MAAM,kBAAkB,UAAU;AAAA,MAChE;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAAe,aAA+C;AAClE,cAAM,OAAO,KAAK,UAAU,WAAW;AAGvC,cAAM,OAAO,YAAY,kBAAkB,WAAW;AACtD,cAAM,MAAM,KAAK,oBAAoB,IAAI;AACzC,cAAM,YAAY,KAAK,QAAQ,MAAM,GAAG;AACxC,kBAAU,OAAO,KAAK,SAAS,KAAK;AAEpC,sBAAc,KAAK,qBAAqB,KAAK,UAAU,SAAS,GAAG;AAAA,UACjE,MAAM;AAAA,UACN,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAoD;AACxD,YAAI,CAAC,WAAW,KAAK,mBAAmB,GAAG;AACzC,iBAAO;AAAA,QACT;AAEA,YAAI;AACF,gBAAM,gBAA+B,KAAK;AAAA,YACxC,aAAa,KAAK,qBAAqB,MAAM;AAAA,UAC/C;AACA,gBAAM,OAAO,OAAO,KAAK,cAAc,MAAM,KAAK;AAClD,gBAAM,MAAM,KAAK,oBAAoB,IAAI;AACzC,gBAAM,YAAY,KAAK,QAAQ,eAAe,GAAG;AACjD,iBAAO,KAAK,MAAM,SAAS;AAAA,QAC7B,SAAS,OAAO;AACd,kBAAQ,MAAM,kCAAkC,KAAK;AACrD,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,oBAAmC;AAEvC,YAAI,WAAW,KAAK,mBAAmB,GAAG;AACxC,cAAI;AACF,uBAAW,KAAK,mBAAmB;AAAA,UACrC,SAAS,OAAO;AACd,oBAAQ,MAAM,sCAAsC,KAAK;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAAoC;AAExC,eAAO,KAAK,uBAAuB,UAAU;AAAA,MAC/C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,sBAAsB,SAA0D;AACpF,cAAM,cAAc,MAAM,KAAK,eAAe;AAC9C,YAAI,CAAC,YAAa,QAAO;AAGzB,YAAI,YAAY,cAAc,YAAY,eAAe,CAAC,YAAY,UAAU;AAC9E,iBAAO;AAAA,YACL,aAAa,YAAY;AAAA,YACzB,cAAc,YAAY;AAAA,YAC1B,WAAW,YAAY;AAAA,UACzB;AAAA,QACF;AAEA,eAAO,YAAY,WAAW,OAAO,KAAK;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,sBAAsB,SAAsB,OAA0C;AAC1F,YAAI,WAAW,MAAM,KAAK,eAAe;AAGzC,YAAI,YAAY,SAAS,eAAe,CAAC,SAAS,UAAU;AAC1D,qBAAW;AAAA,YACT,UAAU;AAAA,cACR,UAAU;AAAA,gBACR,aAAa,SAAS;AAAA,gBACtB,cAAc,SAAS;AAAA,gBACvB,WAAW,SAAS;AAAA,cACtB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,cAAM,UAA6B;AAAA,UACjC,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAG,UAAU;AAAA,YACb,CAAC,OAAO,GAAG;AAAA,UACb;AAAA,QACF;AAEA,cAAM,KAAK,eAAe,OAAO;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,yBAAyB,SAAqC;AAClE,cAAM,WAAW,MAAM,KAAK,eAAe;AAC3C,YAAI,CAAC,UAAU,WAAW,OAAO,EAAG;AAEpC,eAAO,SAAS,SAAS,OAAO;AAChC,cAAM,KAAK,eAAe,QAAQ;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,uBAAuB,SAAwC;AACnE,cAAM,QAAQ,MAAM,KAAK,sBAAsB,OAAO;AACtD,YAAI,CAAC,OAAO,YAAa,QAAO;AAGhC,YAAI,MAAM,aAAa,MAAM,YAAY,KAAK,IAAI,EAAG,QAAO;AAE5D,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,2BAAmD;AACvD,cAAM,cAAc,MAAM,KAAK,eAAe;AAC9C,YAAI,CAAC,YAAa,QAAO,CAAC;AAG1B,YAAI,YAAY,eAAe,CAAC,YAAY,UAAU;AACpD,iBAAO,CAAC,UAAU;AAAA,QACpB;AAEA,YAAI,CAAC,YAAY,SAAU,QAAO,CAAC;AAEnC,cAAM,WAA0B,CAAC;AACjC,mBAAW,CAAC,SAAS,KAAK,KAAK,OAAO,QAAQ,YAAY,QAAQ,GAAG;AACnE,cAAI,OAAO,aAAa;AACtB,qBAAS,KAAK,OAAsB;AAAA,UACtC;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,UAA0B;AACpC,aAAK,OAAO,IAAI,YAAoC,QAAe;AAAA,MACrE;AAAA;AAAA;AAAA;AAAA,MAKA,cAA+B;AAC7B,eAAQ,KAAK,OAAO,IAAI,UAAkC,KAAa;AAAA,MACzE;AAAA;AAAA;AAAA;AAAA,MAKA,iBAAuB;AACrB,aAAK,OAAO,OAAO,UAAkC;AAAA,MACvD;AAAA;AAAA;AAAA;AAAA,MAKA,cAAc,OAAyB;AACrC,aAAK,OAAO,IAAI,cAAsC,KAAY;AAAA,MACpE;AAAA;AAAA;AAAA;AAAA,MAKA,gBAAmC;AACjC,eAAQ,KAAK,OAAO,IAAI,YAAoC,KAAa;AAAA,MAC3E;AAAA;AAAA;AAAA;AAAA,MAKA,mBAAyB;AACvB,aAAK,OAAO,OAAO,YAAoC;AAAA,MACzD;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,uBAAuD,KAAoC;AAE/F,cAAM,YAAY,cAAc;AAChC,cAAM,SAAS,QAAQ,kBAAkB,WAAW;AACpD,YAAI,UAAU,MAAgC,MAAM,QAAW;AAC7D,iBAAO,UAAU,MAAgC;AAAA,QACnD;AAGA,cAAM,gBAAgB,MAAM,kBAAkB;AAC9C,YAAI,iBAAiB,cAAc,GAAG,MAAM,QAAW;AACrD,iBAAO,cAAc,GAAG;AAAA,QAC1B;AAGA,cAAM,YAAY,KAAK,OAAO,IAAI,GAAG;AACrC,YAAI,cAAc,QAAW;AAC3B,iBAAO;AAAA,QACT;AAGA,eAAO,eAAe,GAAG;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,UAA0C,KAA2B;AACnE,eAAO,KAAK,OAAO,IAAI,GAAG;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA,MAKA,UAA0C,KAAQ,OAAgC;AAChF,aAAK,OAAO,IAAI,KAAK,KAAK;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,4BAAqD;AACzD,cAAM,YAAY,cAAc;AAChC,cAAM,gBAAgB,MAAM,kBAAkB;AAC9C,cAAM,aAAa,KAAK,OAAO;AAG/B,eAAO;AAAA,UACL,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAI,UAAU,UAAU,EAAE,eAAe,UAAU,OAAO;AAAA,UAC1D,GAAI,UAAU,gBAAgB,EAAE,cAAc,UAAU,aAAa;AAAA,UACrE,GAAI,UAAU,sBAAsB,EAAE,oBAAoB,UAAU,mBAAmB;AAAA,UACvF,GAAI,UAAU,kBAAkB,EAAE,gBAAgB,UAAU,eAAe;AAAA,UAC3E,GAAI,UAAU,sBAAsB,UAAa;AAAA,YAC/C,mBAAmB,UAAU;AAAA,UAC/B;AAAA,UACA,GAAI,UAAU,qBAAqB,UAAa;AAAA,YAC9C,kBAAkB,UAAU;AAAA,UAC9B;AAAA,UACA,GAAI,UAAU,kBAAkB,EAAE,gBAAgB,UAAU,eAAe;AAAA,QAC7E;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,eAA+B;AAC7B,eAAO,KAAK,OAAO;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAKA,cAAoB;AAClB,aAAK,OAAO,MAAM;AAElB,eAAO,QAAQ,cAAc,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACvD,cAAI,UAAU,QAAW;AACvB,iBAAK,OAAO,IAAI,KAA6B,KAAY;AAAA,UAC3D;AAAA,QACF,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,oBAAoC;AAClC,eAAO,KAAK;AAAA,MACd;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,WAA0B;AAC9B,cAAM,KAAK,kBAAkB;AAC7B,aAAK,eAAe;AACpB,aAAK,iBAAiB;AACtB,aAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAGO,IAAM,iBAAiB,IAAI,eAAe;AAAA;AAAA;;;ACnajD,OAAO,WAAW;AAAlB,IAKa;AALb;AAAA;AAAA;AAAA;AAKO,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA,MAIpB,OAAO,CAAC,YAAoB,SAAsB;AAChD,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,IAAI,MAAM,KAAK,WAAW,OAAO,EAAE,GAAG,GAAG,IAAI;AAAA,QACvD;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,CAAC,YAA0B;AAC/B,gBAAQ,IAAI,MAAM,KAAK,UAAK,OAAO,EAAE,CAAC;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,SAAS,CAAC,YAA0B;AAClC,gBAAQ,IAAI,MAAM,MAAM,UAAK,OAAO,EAAE,CAAC;AAAA,MACzC;AAAA;AAAA;AAAA;AAAA,MAKA,SAAS,CAAC,YAA0B;AAClC,gBAAQ,KAAK,MAAM,OAAO,UAAK,OAAO,EAAE,CAAC;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,CAAC,YAA0B;AAChC,gBAAQ,MAAM,MAAM,IAAI,UAAK,OAAO,EAAE,CAAC;AAAA,MACzC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,CAAC,YAA0B;AAC9B,gBAAQ,IAAI,OAAO;AAAA,MACrB;AAAA,IACF;AAAA;AAAA;;;ACjDA,SAAS,oBAA4E;AACrF,SAAS,aAAa;AAiBtB,eAAe,oBAAqC;AAClD,QAAM,EAAE,UAAU,SAAS,IAAI;AAE/B,WAAS,OAAO,UAAU,QAAQ,UAAU,QAAQ;AAClD,QAAI;AACF,YAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,cAAM,aAAa,aAAa;AAChC,mBAAW,KAAK,SAAS,MAAM;AAC/B,mBAAW,KAAK,aAAa,MAAM;AACjC,qBAAW,MAAM,MAAM,QAAQ,CAAC;AAAA,QAClC,CAAC;AACD,mBAAW,OAAO,MAAM,WAAW;AAAA,MACrC,CAAC;AACD,aAAO;AAAA,IACT,QAAQ;AAEN;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI,WAAW,qCAAqC,QAAQ,IAAI,QAAQ,EAAE;AAClF;AA+HA,eAAsB,yBACpB,eAC8B;AAC9B,QAAM,OAAO,MAAM,kBAAkB;AACrC,QAAM,UAAU,aAAa;AAE7B,SAAO,IAAI,QAA6B,CAAC,SAAS,WAAW;AAC3D,QAAI,SAAwB;AAC5B,QAAI,YAA6D;AAEjE,UAAM,UAAU,MAAM;AACpB,UAAI,WAAW;AACb,mBAAW,aAAa,SAAS;AAAA,MACnC;AACA,UAAI,QAAQ;AAEV,YAAI,OAAQ,OAAe,wBAAwB,YAAY;AAC7D,UAAC,OAAe,oBAAoB;AAAA,QACtC;AACA,eAAO,MAAM,MAAM;AACjB,iBAAO,MAAM,qBAAqB;AAAA,QACpC,CAAC;AACD,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,KAAsB,QAAwB;AACnE,YAAM,YAAY,MAAM,IAAI,OAAO,IAAI,IAAI;AAE3C,aAAO,MAAM,4BAA4B,IAAI,GAAG,EAAE;AAGlD,UAAI,UAAU,aAAa,aAAa,eAAe;AACrD,cAAM,EAAE,MAAM,OAAO,OAAO,kBAAkB,IAAI,UAAU;AAG5D,YAAI,OAAO;AACT,gBAAM,WAAW,qBAAqB;AACtC,iBAAO,MAAM,gBAAgB,QAAQ,EAAE;AAEvC,cAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,cAAI,IAAI,WAAW,OAAO,QAAQ,CAAC,CAAC;AAEpC,kBAAQ;AACR,iBAAO,IAAI,WAAW,gBAAgB,QAAQ,EAAE,CAAC;AACjD;AAAA,QACF;AAGA,YAAI,CAAC,QAAQ,CAAC,OAAO;AACnB,gBAAM,WAAW;AACjB,iBAAO,MAAM,QAAQ;AAErB,cAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,cAAI,IAAI,WAAW,QAAQ,CAAC;AAE5B,kBAAQ;AACR,iBAAO,IAAI,WAAW,QAAQ,CAAC;AAC/B;AAAA,QACF;AAGA,YAAI,UAAU,eAAe;AAC3B,gBAAM,WAAW;AACjB,iBAAO,MAAM,QAAQ;AAErB,cAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,cAAI,IAAI,WAAW,QAAQ,CAAC;AAE5B,kBAAQ;AACR,iBAAO,IAAI,WAAW,QAAQ,CAAC;AAC/B;AAAA,QACF;AAGA,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,YAAI,IAAI,YAAY;AAGpB,mBAAW,WAAW,MAAM;AAC1B,kBAAQ;AACR,kBAAQ;AAAA,YACN,MAAM,OAAO,IAAI;AAAA,YACjB,OAAO,OAAO,KAAK;AAAA,YACnB;AAAA,UACF,CAAC;AAAA,QACH,GAAG,GAAG;AACN;AAAA,MACF;AAGA,UAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;AACnD,UAAI,IAAI,WAAW;AAAA,IACrB;AAGA,aAAS,aAAa,aAAa;AAGnC,WAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,aAAO,MAAM,uBAAuB,MAAM,OAAO,EAAE;AACnD,cAAQ;AACR,aAAO,IAAI,WAAW,uBAAuB,MAAM,OAAO,EAAE,CAAC;AAAA,IAC/D,CAAC;AAGD,WAAO,OAAO,MAAM,aAAa,MAAM;AACrC,aAAO;AAAA,QACL,uDAAuD,IAAI,GAAG,aAAa,aAAa;AAAA,MAC1F;AAAA,IACF,CAAC;AAGD,gBAAY,WAAW,WAAW,MAAM;AACtC,aAAO,MAAM,wBAAwB;AACrC,cAAQ;AACR,aAAO,IAAI,WAAW,gEAAgE,CAAC;AAAA,IACzF,GAAG,OAAO;AAAA,EACZ,CAAC;AACH;AAKA,eAAsB,iBAAkC;AACtD,QAAM,OAAO,MAAM,kBAAkB;AACrC,SAAO,oBAAoB,IAAI,GAAG,aAAa,aAAa;AAC9D;AArSA,IA4CM,cA2DA;AAvGN;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAwCA,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2DrB,IAAM,aAAa,CAAC,UAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAsDL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC7JtC,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAQ1B,eAAsB,YAAY,KAA4B;AAC5D,QAAM,WAAW,QAAQ;AACzB,MAAI;AAGJ,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,gBAAU,SAAS,GAAG;AACtB;AAAA,IACF,KAAK;AACH,gBAAU,aAAa,GAAG;AAC1B;AAAA,IACF;AACE,gBAAU,aAAa,GAAG;AAC1B;AAAA,EACJ;AAEA,MAAI;AACF,WAAO,MAAM,iCAAiC,OAAO,EAAE;AACvD,UAAM,UAAU,OAAO;AACvB,WAAO,MAAM,6BAA6B;AAAA,EAC5C,SAAS,OAAO;AACd,WAAO,MAAM,2BAA2B,KAAK,EAAE;AAC/C,UAAM,IAAI,MAAM;AAAA,EAAyE,GAAG,EAAE;AAAA,EAChG;AACF;AAlCA,IAIM;AAJN;AAAA;AAAA;AAAA;AAEA;AAEA,IAAM,YAAY,UAAU,IAAI;AAAA;AAAA;;;ACJhC,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,iBAAAC,gBAAe,uBAAuB;AAC/C,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,cAAc;AAevB,SAAS,eAAuB;AAC9B,MAAI;AAEF,UAAM,kBAAkBA,MAAKC,YAAW,oBAAoB;AAC5D,UAAM,cAAc,KAAK,MAAMJ,cAAa,iBAAiB,OAAO,CAAC;AACrE,UAAMK,WAAU,YAAY;AAC5B,UAAM,WAAW,QAAQ;AACzB,UAAM,OAAO,QAAQ;AACrB,WAAO,gBAAgBA,QAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,EACrD,QAAQ;AACN,WAAO,MAAM,qCAAqC;AAClD,WAAO;AAAA,EACT;AACF;AAhCA,IAaMC,aACAF,YAkCO,aA2OA;AA3Rb;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AAGA,IAAME,cAAaL,eAAc,YAAY,GAAG;AAChD,IAAMG,aAAYF,SAAQI,WAAU;AAkC7B,IAAM,cAAN,MAAkB;AAAA,MACf;AAAA,MAER,cAAc;AAEZ,aAAK,aAAa,QAAQ,IAAI,gBAAgB;AAAA,MAChD;AAAA;AAAA;AAAA;AAAA,MAKQ,gBAAwB;AAC9B,eAAOP,aAAY,EAAE,EAAE,SAAS,KAAK;AAAA,MACvC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,aAAa,OAAe,aAAsC;AAC9E,cAAM,SAAS,IAAI,gBAAgB;AAAA,UACjC,WAAW,aAAa;AAAA,UACxB,cAAc;AAAA,UACd;AAAA,QACF,CAAC;AAED,eAAO,GAAG,KAAK,UAAU,GAAG,cAAc,KAAK,QAAQ,IAAI,OAAO,SAAS,CAAC;AAAA,MAC9E;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,qBAAqB,MAAc,aAA6C;AAC5F,YAAI;AACF,iBAAO,MAAM,yCAAyC;AAEtD,gBAAM,WAAW,MAAM;AAAA,YACrB,GAAG,KAAK,UAAU,GAAG,cAAc,KAAK,KAAK;AAAA,YAC7C;AAAA,cACE,QAAQ;AAAA,cACR,MAAM;AAAA,gBACJ;AAAA,gBACA,cAAc;AAAA,gBACd,WAAW,aAAa;AAAA,gBACxB,YAAY;AAAA,cACd;AAAA,cACA,SAAS;AAAA,gBACP,gBAAgB;AAAA,gBAChB,cAAc,aAAa;AAAA,cAC7B;AAAA,YACF;AAAA,UACF;AAEA,iBAAO,MAAM,2BAA2B;AACxC,iBAAO;AAAA,QACT,SAAS,OAAY;AACnB,iBAAO,MAAM,0BAA0B,MAAM,OAAO,EAAE;AAEtD,cAAI,MAAM,UAAU;AAClB,kBAAM,IAAI;AAAA,cACR,0BAA0B,MAAM,SAAS,cAAc,eAAe;AAAA,cACtE;AAAA,gBACE,YAAY,MAAM,SAAS;AAAA,gBAC3B,MAAM,MAAM,SAAS;AAAA,cACvB;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,IAAI,aAAa,8CAA8C;AAAA,YACnE,eAAe,MAAM;AAAA,UACvB,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,QAA2B;AAC/B,eAAO,MAAM,2BAA2B;AAGxC,cAAM,QAAQ,KAAK,cAAc;AACjC,cAAM,cAAc,MAAM,eAAe;AAGzC,uBAAe,cAAc;AAAA,UAC3B;AAAA,UACA,WAAW,KAAK,IAAI;AAAA,QACtB,CAAC;AAED,eAAO,MAAM,gBAAgB,KAAK,EAAE;AACpC,eAAO,MAAM,iBAAiB,WAAW,EAAE;AAG3C,cAAM,UAAU,MAAM,KAAK,aAAa,OAAO,WAAW;AAC1D,eAAO,MAAM,sBAAsB,OAAO,EAAE;AAG5C,cAAM,gBAAgB,yBAAyB,KAAK;AAGpD,YAAI;AACF,gBAAM,YAAY,OAAO;AAAA,QAC3B,QAAQ;AAEN,iBAAO,QAAQ,sCAAsC;AACrD,iBAAO,KAAK,uCAAuC;AACnD,iBAAO,IAAI,OAAO;AAAA,QACpB;AAGA,YAAI;AACJ,YAAI;AACF,2BAAiB,MAAM;AAAA,QACzB,SAAS,OAAY;AACnB,yBAAe,iBAAiB;AAChC,gBAAM;AAAA,QACR;AAGA,uBAAe,iBAAiB;AAGhC,cAAM,gBAAgB,MAAM,KAAK,qBAAqB,eAAe,MAAM,WAAW;AAGtF,cAAM,YAAY,cAAc,aAC5B,KAAK,IAAI,IAAI,cAAc,aAAa,MACxC;AAGJ,cAAM,cAAkC;AAAA,UACtC,aAAa,cAAc;AAAA,UAC3B,cAAc,cAAc;AAAA,UAC5B;AAAA,QACF;AACA,cAAM,eAAe,sBAAsB,YAAY,WAAW;AAGlE,YAAI,cAAc,MAAM;AACtB,yBAAe,YAAY,cAAc,IAAI;AAAA,QAC/C;AAEA,eAAO,MAAM,kBAAkB;AAE/B,eAAO,cAAc,QAAQ,EAAE,IAAI,WAAW,OAAO,WAAW,MAAM,eAAe;AAAA,MACvF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,SAAwB;AAC5B,eAAO,MAAM,aAAa;AAE1B,cAAM,eAAe,kBAAkB;AACvC,uBAAe,eAAe;AAC9B,uBAAe,iBAAiB;AAEhC,eAAO,MAAM,iBAAiB;AAAA,MAChC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAAoC;AACxC,eAAO,eAAe,gBAAgB;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAyC;AAC7C,cAAM,cAAc,MAAM,eAAe,sBAAsB,UAAU;AACzE,eAAO,aAAa,eAAe;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA,MAKA,cAA+B;AAC7B,eAAO,eAAe,YAAY;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAA8B;AAClC,eAAO,MAAM,yBAAyB;AAEtC,cAAM,cAAc,MAAM,eAAe,sBAAsB,UAAU;AACzE,YAAI,CAAC,aAAa,cAAc;AAC9B,gBAAM,IAAI,oBAAoB,4BAA4B;AAAA,QAC5D;AAEA,YAAI;AACF,gBAAM,WAAW,MAAM;AAAA,YACrB,GAAG,KAAK,UAAU,GAAG,cAAc,KAAK,KAAK;AAAA,YAC7C;AAAA,cACE,QAAQ;AAAA,cACR,MAAM;AAAA,gBACJ,eAAe,YAAY;AAAA,gBAC3B,WAAW,aAAa;AAAA,gBACxB,YAAY;AAAA,cACd;AAAA,cACA,SAAS;AAAA,gBACP,gBAAgB;AAAA,gBAChB,cAAc,aAAa;AAAA,cAC7B;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,YAAY,SAAS,aAAa,KAAK,IAAI,IAAI,SAAS,aAAa,MAAO;AAGlF,gBAAM,iBAAqC;AAAA,YACzC,aAAa,SAAS;AAAA,YACtB,cAAc,SAAS,iBAAiB,YAAY;AAAA,YACpD;AAAA,UACF;AACA,gBAAM,eAAe,sBAAsB,YAAY,cAAc;AAErE,iBAAO,MAAM,0BAA0B;AAAA,QACzC,SAAS,OAAY;AACnB,iBAAO,MAAM,yBAAyB,MAAM,OAAO,EAAE;AAGrD,gBAAM,KAAK,OAAO;AAClB,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGO,IAAM,cAAc,IAAI,YAAY;AAAA;AAAA;;;AC3R3C,SAAS,UAAAQ,eAAiC;AAC1C,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,WAAAC,UAAS,QAAAC,aAAY;AA0B9B,SAAS,gBAAwB;AAC/B,MAAI;AAEF,UAAM,kBAAkBA,MAAKC,YAAW,oBAAoB;AAC5D,UAAM,cAAc,KAAK,MAAML,cAAa,iBAAiB,OAAO,CAAC;AACrE,WAAO,YAAY;AAAA,EACrB,QAAQ;AACN,WAAO,MAAM,qCAAqC;AAClD,WAAO;AAAA,EACT;AACF;AAKA,SAAS,kBAA0B;AACjC,QAAM,WAAW,QAAQ;AACzB,QAAM,OAAO,QAAQ;AACrB,SAAO,GAAG,QAAQ,IAAI,IAAI;AAC5B;AAjDA,IAwBMM,aACAD,YA6BO,YA0WA;AAhab;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AACA;AAgBA,IAAMC,cAAaL,eAAc,YAAY,GAAG;AAChD,IAAMI,aAAYF,SAAQG,WAAU;AA6B7B,IAAM,aAAN,MAAiB;AAAA,MACd;AAAA,MACA;AAAA,MAER,cAAc;AAEZ,aAAK,UAAU,QAAQ,IAAI,gBAAgB;AAG3C,aAAK,SAASP,QAAO,OAAO;AAAA,UAC1B,SAAS,KAAK;AAAA;AAAA,UAGd,WAAW,OAAO,EAAE,SAAS,QAAQ,MAAM;AACzC,mBAAO,MAAM,gBAAgB,QAAQ,UAAU,KAAK,IAAI,OAAO,EAAE;AAGjE,kBAAM,aAAa,cAAc;AACjC,kBAAM,WAAW,gBAAgB;AACjC,kBAAM,YAAY,gBAAgB,UAAU,KAAK,QAAQ;AAGzD,kBAAM,QAAQ,MAAM,YAAY,eAAe;AAG/C,kBAAM,aAAqC;AAAA,cACzC,cAAc;AAAA,YAChB;AAGA,gBAAI,QAAQ,SAAS;AACnB,kBAAI,OAAO,QAAQ,YAAY,YAAY,CAAC,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAC1E,uBAAO,QAAQ,QAAQ,OAAO,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACxD,sBAAI,OAAO,UAAU,UAAU;AAC7B,+BAAW,GAAG,IAAI;AAAA,kBACpB;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF;AAEA,gBAAI,OAAO;AACT,yBAAW,gBAAgB,UAAU,KAAK;AAAA,YAC5C;AAGA,gBAAI,QAAQ,UAAU,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,QAAQ,MAAM,GAAG;AACvE,yBAAW,cAAc,IAAI;AAAA,YAC/B;AAEA,oBAAQ,UAAU;AAAA,UACpB;AAAA;AAAA,UAGA,YAAY,CAAC,EAAE,SAAS,MAAM;AAC5B,mBAAO,MAAM,iBAAiB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,UACxE;AAAA;AAAA,UAGA,iBAAiB,OAAO,EAAE,SAAS,SAAS,MAAM;AAChD,kBAAM,SAAS,SAAS;AAExB,mBAAO,MAAM,cAAc,MAAM,IAAI,SAAS,UAAU,MAAM,OAAO,EAAE;AAGvE,gBAAI,WAAW,YAAY,cAAc;AACvC,qBAAO,MAAM,mCAAmC;AAEhD,kBAAI;AAEF,sBAAM,YAAY,aAAa;AAG/B,uBAAO,MAAM,mCAAmC;AAChD,sBAAM,IAAI,MAAM,sBAAsB;AAAA,cACxC,SAAS,OAAY;AACnB,oBAAI,MAAM,YAAY,wBAAwB;AAC5C,wBAAM;AAAA,gBACR;AAEA,sBAAM,IAAI;AAAA,kBACR;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,eAAe;AACnB,gBAAI;AAEJ,gBAAI;AACF,oBAAM,YAAY,SAAS;AAC3B,kBAAI,aAAa,UAAU,SAAS;AAClC,+BAAe,UAAU;AACzB,+BAAe,UAAU;AAAA,cAC3B;AAAA,YACF,QAAQ;AAEN,6BAAe,SAAS,cAAc;AAAA,YACxC;AAEA,kBAAM,IAAI,SAAS,cAAc,QAAQ,YAAY;AAAA,UACvD;AAAA;AAAA,UAGA,OAAO;AAAA,UACP,YAAY;AAAA,UACZ,kBAAkB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA;AAAA,UAGzD,SAAS;AAAA;AAAA,QACX,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,YAAe,KAAa,UAAwB,CAAC,GAAe;AAChF,YAAI;AACF,iBAAQ,MAAM,KAAK,OAAO,KAAK,OAAO;AAAA,QACxC,SAAS,OAAY;AAEnB,cAAI,MAAM,YAAY,wBAAwB;AAC5C,mBAAO,MAAM,uCAAuC;AACpD,mBAAQ,MAAM,KAAK,OAAO,KAAK,OAAO;AAAA,UACxC;AAGA,cAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,gBAAgB;AAChE,kBAAM,IAAI,aAAa,qCAAqC;AAAA,cAC1D,eAAe,MAAM;AAAA,cACrB,SAAS,KAAK;AAAA,YAChB,CAAC;AAAA,UACH;AAEA,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,SAA2D;AAC3E,cAAM,kBAAkB;AAExB,cAAM,iBAAiB;AAAA,UACrB,GAAG;AAAA,UACH,OAAO,QAAQ,MAAM,IAAI,CAAC,UAA+C;AAAA,YACvE,GAAG;AAAA,YACH,MACE,KAAK,QAAQ,KAAK,KAAK,SAAS,kBAC5B,KAAK,KAAK,UAAU,GAAG,eAAe,IACtC,KAAK;AAAA,UACb,EAAE;AAAA,QACJ;AAEA,eAAO,MAAM,YAAY,eAAe,MAAM,MAAM,QAAQ;AAE5D,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAAiC,cAAc,MAAM,QAAQ;AAAA,YACvF,QAAQ;AAAA,YACR,MAAM;AAAA,UACR,CAAC;AAED,iBAAO,MAAM,wBAAwB,SAAS,cAAc,MAAM,QAAQ;AAC1E,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,wBAAwB;AACrC,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,cAAc,SAA+D;AACjF,eAAO,MAAM,kEAAkE;AAC/E,eAAO,MAAM,YAAY,QAAQ,QAAQ,MAAM,UAAU;AAEzD,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAAmC,cAAc,QAAQ,QAAQ;AAAA,YAC3F,QAAQ;AAAA,YACR,MAAM;AAAA,UACR,CAAC;AAED,iBAAO,MAAM,wBAAwB,SAAS,gBAAgB,MAAM,UAAU;AAC9E,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,0BAA0B;AACvC,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,SAA2D;AAC3E,eAAO,MAAM,YAAY,QAAQ,MAAM,MAAM,QAAQ;AACrD,eAAO,MAAM,iBAAiB,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC,EAAE;AAEhE,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAAiC,cAAc,MAAM,QAAQ;AAAA,YACvF,QAAQ;AAAA,YACR,MAAM;AAAA,UACR,CAAC;AACD,iBAAO,MAAM,aAAa,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC,EAAE;AAE7D,iBAAO,MAAM,wBAAwB,SAAS,OAAO,QAAQ;AAC7D,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,wBAAwB;AACrC,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,UAAU,SAA0B,CAAC,GAA+B;AACxE,cAAM,EAAE,QAAQ,IAAI,SAAS,GAAG,MAAM,OAAO,IAAI;AAEjD,eAAO,MAAM,wBAAwB,KAAK,YAAY,MAAM,EAAE;AAE9D,YAAI;AAEF,gBAAM,cAAc,IAAIG,iBAAgB;AAAA,YACtC,OAAO,MAAM,SAAS;AAAA,YACtB,QAAQ,OAAO,SAAS;AAAA,UAC1B,CAAC;AAED,cAAI,QAAQ;AACV,wBAAY,OAAO,UAAU,MAAM;AAAA,UACrC;AAEA,cAAI,QAAQ,KAAK,SAAS,GAAG;AAC3B,iBAAK,QAAQ,CAAC,QAAQ,YAAY,OAAO,UAAU,GAAG,CAAC;AAAA,UACzD;AAEA,gBAAM,MAAM,GAAG,cAAc,MAAM,IAAI,IAAI,YAAY,SAAS,CAAC;AAEjE,gBAAM,WAAW,MAAM,KAAK,YAA+B,KAAK;AAAA,YAC9D,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO;AAAA,YACL,wBAAwB,SAAS,MAAM,MAAM,kBAAkB,SAAS,KAAK;AAAA,UAC/E;AACA,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,sBAAsB;AACnC,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,sBAAsB,QAAoD;AAC9E,eAAO,MAAM,mCAAmC,MAAM,EAAE;AAExD,YAAI;AACF,gBAAM,MAAM,cAAc,cAAc,KAAK,QAAQ,YAAY,MAAM;AAEvE,gBAAM,WAAW,MAAM,KAAK,YAAuC,KAAK;AAAA,YACtE,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO,MAAM,wBAAwB,SAAS,MAAM,MAAM,gBAAgB;AAC1E,iBAAO;AAAA,QACT,SAAS,QAAQ;AACf,iBAAO,MAAM,8BAA8B;AAC3C,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,wBAAgE;AACpE,eAAO,MAAM,qCAAqC,cAAc,aAAa,MAAM,EAAE;AAErF,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAGzB,cAAc,aAAa,QAAQ;AAAA,YACpC,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO,MAAM,8BAA8B,KAAK,UAAU,QAAQ,CAAC,EAAE;AAGrE,gBAAM,mBAAmB,SAAS;AAElC,iBAAO;AAAA,YACL,sBAAsB,iBAAiB,IAAI,aAAa,iBAAiB,MAAM;AAAA,UACjF;AACA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,iBAAO,MAAM,wCAAwC,KAAK,EAAE;AAC5D,iBAAO,MAAM,kBAAkB,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC,EAAE;AAC/D,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAA8C;AAClD,eAAO,MAAM,0BAA0B;AAEvC,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,YAAkC,cAAc,SAAS;AAAA,YACnF,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO,MAAM,mBAAmB,SAAS,cAAc,EAAE;AACzD,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO,MAAM,yBAAyB;AAGtC,gBAAM,EAAE,SAAAK,SAAQ,IAAI,MAAM;AAC1B,iBAAO;AAAA,YACL,gBAAgBA;AAAA,YAChB,iBAAiB;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAmC;AACvC,YAAI;AACF,gBAAM,KAAK,aAAa;AACxB,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,WAAW,KAAmB;AAC5B,aAAK,UAAU;AAEf,aAAK,SAASR,QAAO,OAAO;AAAA,UAC1B,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,aAAqB;AACnB,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAGO,IAAM,aAAa,IAAI,WAAW;AAAA;AAAA;;;AChazC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,gBAAAS,qBAAoB;AAC7B,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,OAAOC,YAAW;AAClB,OAAO,WAAW;AAWX,SAAS,oBAA4B;AAC1C,MAAI;AAEF,UAAM,kBAAkBD,MAAKE,YAAW,oBAAoB;AAC5D,UAAM,cAAc,KAAK,MAAML,cAAa,iBAAiB,OAAO,CAAC;AACrE,WAAO,YAAY;AAAA,EACrB,QAAQ;AACN,WAAO,MAAM,qCAAqC;AAClD,WAAO;AAAA,EACT;AACF;AAcO,SAAS,gBAAgB,IAAY,IAAoB;AAC9D,QAAM,SAAS,GAAG,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AACvD,QAAM,SAAS,GAAG,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAEvD,WAAS,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM,GAAG,KAAK;AAC/D,UAAM,QAAQ,OAAO,CAAC,KAAK;AAC3B,UAAM,QAAQ,OAAO,CAAC,KAAK;AAE3B,QAAI,QAAQ,MAAO,QAAO;AAC1B,QAAI,QAAQ,MAAO,QAAO;AAAA,EAC5B;AAEA,SAAO;AACT;AAKA,eAAsB,gBACpB,UAGI,CAAC,GACiF;AACtF,QAAM,EAAE,SAAS,OAAO,QAAQ,MAAM,IAAI;AAE1C,MAAI;AAEF,QAAI,CAAC,OAAO;AACV,YAAM,mBAAmB,eAAe,UAAU,kBAAkB;AACpE,UAAI,CAAC,kBAAkB;AACrB,eAAO,MAAM,kCAAkC;AAC/C,eAAO;AAAA,UACL,iBAAiB;AAAA,UACjB,eAAe;AAAA,UACf,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM,6BAA6B;AAG1C,UAAM,WAAW,MAAM,WAAW,aAAa;AAC/C,UAAM,gBAAgB,SAAS;AAC/B,UAAM,iBAAiB;AAEvB,WAAO,MAAM,oBAAoB,cAAc,qBAAqB,aAAa,EAAE;AAEnF,UAAM,kBAAkB,gBAAgB,eAAe,cAAc,IAAI;AAGzE,QAAI,CAAC,UAAU,iBAAiB;AAC9B,gCAA0B,gBAAgB,eAAe,SAAS,eAAe;AAAA,IACnF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,OAAY;AACnB,WAAO,MAAM,yBAAyB,MAAM,OAAO,EAAE;AAErD,WAAO;AAAA,MACL,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,gBAAgB;AAAA,IAClB;AAAA,EACF;AACF;AAKA,SAAS,0BACP,gBACA,eACA,WAAoB,OACd;AACN,QAAM,UAAU,WACZI,OAAM,IAAI,KAAK,iBAAiB,IAChCA,OAAM,OAAO,KAAK,kBAAkB;AACxC,QAAM,UACJ,GAAG,OAAO;AAAA;AAAA,mBACUA,OAAM,IAAI,cAAc,CAAC;AAAA,mBACzBA,OAAM,MAAM,aAAa,CAAC;AAAA;AAAA,eAC9BA,OAAM,KAAK,qCAAqC,CAAC;AAEnE,UAAQ,IAAI,EAAE;AACd,UAAQ;AAAA,IACN,MAAM,SAAS;AAAA,MACb,SAAS;AAAA,MACT,QAAQ,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,EAAE;AAAA,MAC/C,aAAa;AAAA,MACb,aAAa,WAAW,QAAQ;AAAA,IAClC,CAAC;AAAA,EACH;AACA,UAAQ,IAAI,EAAE;AAEd,MAAI,UAAU;AACZ,WAAO,QAAQ,+DAA+D;AAC9E,YAAQ,IAAI,EAAE;AAAA,EAChB;AACF;AAKO,SAAS,cAAc,gBAAyB,MAAc;AACnE,QAAM,SAAS,gBAAgB,MAAM;AACrC,SAAO,GAAG,MAAM,GAAG,OAAO;AAC5B;AAvJA,IASME,aACAD,YAoBO;AA9Bb;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AAEA,IAAMC,cAAaL,eAAc,YAAY,GAAG;AAChD,IAAMI,aAAYH,SAAQI,WAAU;AAoB7B,IAAM,UAAU,kBAAkB;AAAA;AAAA;;;AC9BzC;AAGA;","names":["fileURLToPath","path","config","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"]}
|