devark-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/utils/logger.ts","../src/lib/config.ts","../src/lib/errors/network-errors.ts","../src/utils/errors.ts","../src/lib/input-validator.ts","../src/lib/ui/styles.ts","../src/lib/ui/project-display.ts","../src/lib/claude-project-parser.ts","../src/lib/claude-fs.ts","../src/lib/temp-directories.ts","../src/lib/claude-core.ts","../src/lib/claude-settings-reader.ts","../src/lib/claude-settings-manager.ts","../src/lib/sub-agents/constants.ts","../src/lib/status-line-manager.ts","../src/lib/detector.ts","../src/lib/hooks/hooks-controller.ts","../package.json","../src/lib/telemetry.ts","../src/lib/api-client.ts","../src/lib/auth/token.ts","../src/lib/readers/image-filter.ts","../src/lib/language-extractor.ts","../src/lib/readers/claude.ts","../src/lib/message-sanitizer.ts","../src/lib/hook-utils.ts","../src/lib/orchestrators/send-orchestrator.ts","../src/utils/version-check.ts","../src/utils/spawn.ts","../src/lib/orchestrators/background-send-orchestrator.ts","../src/lib/hook-lock.ts","../src/lib/orchestrators/hook-send-orchestrator.ts","../src/lib/ui/points-display.ts","../src/lib/ui.ts","../src/lib/ui/send/send-progress.ts","../src/lib/ui/send/send-summary.ts","../src/lib/ui/privacy-preview.ts","../src/lib/ui/send/send-confirmation.ts","../src/lib/ui/sanitization-display.ts","../src/commands/send.ts","../src/lib/personality-manager.ts","../src/types/loading-state.ts","../src/lib/promotional-tips.ts","../src/lib/prompt-analyzer.ts","../src/lib/personality-test-engine.ts","../src/lib/hooks/hooks-stats.ts","../src/lib/hooks/hooks-tester.ts","../src/lib/ui/project-selector-hooks.ts","../src/lib/auth/browser.ts","../src/commands/auth.ts","../src/lib/ui/hooks-menu.ts","../src/lib/readers/cursor.ts","../src/lib/ui/interactive-menu.ts","../src/lib/ui/first-time-welcome.ts","../src/utils/claude-executor.ts","../src/lib/standup-utils.ts","../src/lib/standup-temp-manager.ts","../src/lib/ui/standup-tips.ts","../src/lib/ui/rotating-tips.ts","../src/commands/standup.ts","../src/lib/ui/session-selector.ts","../src/lib/ui/privacy-notice.ts","../src/lib/ui/cloud-setup-wizard.ts","../src/lib/ui/personality-creator.ts","../src/lib/ui/personality-tester.ts","../src/lib/ccusage-config-manager.ts","../src/lib/ui/status-line-menu.ts","../src/lib/ui/manual-sync-menu.ts","../src/commands/cursor-stats.ts","../src/lib/sub-agents/templates.ts","../src/lib/sub-agents/manager.ts","../src/lib/ui/project-selector.ts","../src/lib/ui/interactive-project-selector.ts","../src/lib/prompts/orchestrator.ts","../src/lib/report-template-engine.ts","../src/lib/report-generator.ts","../src/lib/ui/progress.ts","../src/lib/report-executor.ts","../src/lib/ui/local-report-generator.ts","../src/lib/ui/sub-agents-installer.ts","../src/index.ts","../src/commands/config.ts","../src/commands/logout.ts","../src/commands/privacy.ts","../src/commands/analyze-prompt.ts","../src/lib/session-context-extractor.ts","../src/commands/statusline.ts","../src/lib/ccusage-integration.ts","../src/commands/test-personality.ts","../src/commands/install-auto-sync.ts","../src/lib/ui/main-menu.ts","../src/lib/ui/status-sections.ts","../src/lib/ui/menu-builder.ts","../src/commands/status.ts","../src/lib/ui/help-content.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n typeof document === 'undefined'\n ? new URL(`file:${__filename}`).href\n : (document.currentScript && document.currentScript.src) ||\n new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import chalk from 'chalk';\nimport { appendFileSync } from 'fs';\n\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n}\n\nclass Logger {\n private level: LogLevel;\n private outputFile: string | undefined;\n\n constructor() {\n this.level = this.getLogLevel();\n this.outputFile = process.env.DEVARK_OUTPUT;\n }\n\n setLevel(level: string | LogLevel): void {\n if (typeof level === 'string') {\n switch (level.toLowerCase()) {\n case 'debug':\n this.level = LogLevel.DEBUG;\n break;\n case 'info':\n this.level = LogLevel.INFO;\n break;\n case 'warn':\n this.level = LogLevel.WARN;\n break;\n case 'error':\n this.level = LogLevel.ERROR;\n break;\n default:\n this.level = LogLevel.INFO;\n }\n } else {\n this.level = level;\n }\n }\n\n private getLogLevel(): LogLevel {\n const envLevel = process.env.LOG_LEVEL?.toUpperCase();\n if (process.env.DEBUG || process.env.DEVARK_DEBUG) {\n return LogLevel.DEBUG;\n }\n \n switch (envLevel) {\n case 'DEBUG':\n return LogLevel.DEBUG;\n case 'INFO':\n return LogLevel.INFO;\n case 'WARN':\n return LogLevel.WARN;\n case 'ERROR':\n return LogLevel.ERROR;\n default:\n return LogLevel.INFO;\n }\n }\n\n private writeToFile(message: string): void {\n if (this.outputFile) {\n const timestamp = new Date().toISOString();\n const logLine = `[${timestamp}] ${message}\\n`;\n try {\n appendFileSync(this.outputFile, logLine);\n } catch (error) {\n // Silently fail if can't write to file\n }\n }\n }\n\n debug(message: string, data?: any): void {\n if (this.level <= LogLevel.DEBUG) {\n const logMessage = `[DEBUG] ${message}`;\n if (this.outputFile) {\n this.writeToFile(logMessage);\n if (data) {\n this.writeToFile(JSON.stringify(data, null, 2));\n }\n } else {\n console.log(chalk.gray(logMessage));\n if (data) {\n console.log(chalk.gray(JSON.stringify(data, null, 2)));\n }\n }\n }\n }\n\n info(message: string): void {\n if (this.level <= LogLevel.INFO) {\n if (this.outputFile) {\n this.writeToFile(`[INFO] ${message}`);\n } else {\n console.log(chalk.cyan(message));\n }\n }\n }\n\n warn(message: string): void {\n if (this.level <= LogLevel.WARN) {\n if (this.outputFile) {\n this.writeToFile(`[WARN] ${message}`);\n } else {\n console.log(chalk.yellow(`⚠️ ${message}`));\n }\n }\n }\n\n error(message: string, error?: any): void {\n if (this.level <= LogLevel.ERROR) {\n if (this.outputFile) {\n this.writeToFile(`[ERROR] ${message}`);\n if (error && this.level === LogLevel.DEBUG) {\n this.writeToFile(error.stack || error.toString());\n }\n } else {\n console.error(chalk.red(`❌ ${message}`));\n if (error && this.level === LogLevel.DEBUG) {\n console.error(chalk.gray(error.stack || error));\n }\n }\n }\n }\n\n success(message: string): void {\n if (this.outputFile) {\n this.writeToFile(`[SUCCESS] ${message}`);\n } else {\n console.log(chalk.green(`✅ ${message}`));\n }\n }\n}\n\nexport const logger = new Logger();","import Conf from 'conf';\nimport crypto from 'crypto';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport fs from 'fs/promises';\nimport { logger } from '../utils/logger';\n\nexport interface ProjectSyncData {\n oldestSyncedTimestamp?: string;\n newestSyncedTimestamp?: string;\n lastSyncTime?: string;\n projectName?: string;\n sessionCount?: number;\n}\n\ninterface ConfigSchema {\n apiUrl: string;\n cliPath?: string;\n token?: string;\n lastSync?: string;\n preferences?: {\n colorScheme?: 'default' | 'minimal';\n verboseOutput?: boolean;\n };\n // PROJECT TRACKING REMOVED - Now handled by hooks in Claude settings\n projectSyncData?: {\n [claudeFolderName: string]: ProjectSyncData;\n };\n lastSyncSummary?: {\n timestamp: string;\n description: string;\n };\n statusLine?: {\n personality: 'gordon' | 'devark' | 'custom';\n customPersonality?: {\n name: string;\n description: string;\n templates?: {\n poor: string; // Template for 0-40\n fair: string; // Template for 41-60\n good: string; // Template for 61-80\n excellent: string; // Template for 81-100\n };\n };\n };\n statusLineBackup?: {\n originalCommand?: string;\n originalType?: string;\n originalPadding?: number;\n backupDate: string;\n backupReason?: string; // Why it was backed up (e.g., \"Replaced by devark status line\")\n };\n}\n\nconst config = new Conf<ConfigSchema>({\n projectName: 'devark',\n cwd: join(homedir(), '.devark'), // Store config in ~/.devark instead of default location\n schema: {\n apiUrl: {\n type: 'string',\n default: 'https://app.devark.ai',\n },\n cliPath: {\n type: 'string',\n default: 'npx devark-cli',\n },\n token: {\n type: 'string',\n },\n lastSync: {\n type: 'string',\n },\n preferences: {\n type: 'object',\n properties: {\n colorScheme: {\n type: 'string',\n enum: ['default', 'minimal'],\n default: 'default',\n },\n verboseOutput: {\n type: 'boolean',\n default: false,\n },\n },\n },\n // PROJECT TRACKING REMOVED - Now handled by hooks in Claude settings\n },\n});\n\n// Secure key management\nconst KEY_FILE = join(homedir(), '.devark', '.key');\nconst algorithm = 'aes-256-gcm';\n\nasync function getOrCreateKey(): Promise<Buffer> {\n try {\n const keyData = await fs.readFile(KEY_FILE);\n return Buffer.from(keyData.toString(), 'hex');\n } catch (error) {\n // Generate new key if doesn't exist\n const key = crypto.randomBytes(32);\n await fs.mkdir(join(homedir(), '.devark'), { recursive: true });\n // Apply Unix file permissions only on non-Windows platforms\n const writeOptions = process.platform !== 'win32' ? { mode: 0o600 } : {};\n await fs.writeFile(KEY_FILE, key.toString('hex'), writeOptions);\n return key;\n }\n}\n\nasync function encrypt(text: string): Promise<string> {\n const key = await getOrCreateKey();\n const iv = crypto.randomBytes(16);\n const cipher = crypto.createCipheriv(algorithm, key, iv);\n \n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n \n const authTag = cipher.getAuthTag();\n \n return iv.toString('hex') + ':' + authTag.toString('hex') + ':' + encrypted;\n}\n\nasync function decrypt(encryptedData: string): Promise<string> {\n const key = await getOrCreateKey();\n \n const parts = encryptedData.split(':');\n if (parts.length !== 3) {\n throw new Error('Invalid encrypted data format');\n }\n \n const iv = Buffer.from(parts[0], 'hex');\n const authTag = Buffer.from(parts[1], 'hex');\n const encrypted = parts[2];\n \n const decipher = crypto.createDecipheriv(algorithm, key, iv);\n decipher.setAuthTag(authTag);\n \n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n \n return decrypted;\n}\n\nexport async function storeToken(token: string): Promise<void> {\n // Validate token format\n if (!token || typeof token !== 'string' || token.length < 10) {\n throw new Error('Invalid token format');\n }\n \n const encrypted = await encrypt(token);\n config.set('token', encrypted);\n}\n\nexport async function getToken(): Promise<string | null> {\n const encrypted = config.get('token');\n if (!encrypted) return null;\n \n try {\n return await decrypt(encrypted);\n } catch (error) {\n // Log security event without exposing details\n console.error('Token decryption failed. Re-authentication required.');\n return null;\n }\n}\n\nexport async function clearToken(): Promise<void> {\n config.delete('token');\n}\n\nexport function getApiUrl(): string {\n const envUrl = process.env.DEVARK_API_URL;\n const configUrl = config.get('apiUrl');\n const url = envUrl || configUrl;\n \n logger.debug('API URL Configuration', {\n envUrl: envUrl || '(not set)',\n configUrl: configUrl || '(default)',\n selectedUrl: url\n });\n \n // Validate URL\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {\n throw new Error('Invalid protocol');\n }\n \n // Allow localhost for development\n if (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1') {\n return url;\n }\n \n // Only allow *.devark.ai domains\n const allowedDomains = ['devark.ai'];\n const isAllowed = allowedDomains.some(domain => parsed.hostname.endsWith(domain));\n if (!isAllowed) {\n throw new Error(`Invalid API host: ${parsed.hostname}. Only *.devark.ai domains allowed.`);\n }\n \n return url;\n } catch (error) {\n throw new Error(`Invalid API URL: ${url}`);\n }\n}\n\nexport function getDashboardUrl(): string {\n const apiUrl = getApiUrl();\n \n try {\n const parsed = new URL(apiUrl);\n \n // Special handling for production API\n if (parsed.hostname === 'devark.ai' || parsed.hostname === 'www.devark.ai') {\n // Production API uses app subdomain for dashboard\n return `${parsed.protocol}//app.devark.ai/dashboard`;\n }\n \n // For all other URLs (localhost, staging, etc.), append /dashboard\n // Remove trailing slash from API URL if present\n const baseUrl = apiUrl.endsWith('/') ? apiUrl.slice(0, -1) : apiUrl;\n return `${baseUrl}/dashboard`;\n } catch (error) {\n // Fallback to production dashboard if URL parsing fails\n return 'https://app.devark.ai/dashboard';\n }\n}\n\nexport function setApiUrl(url: string): void {\n // Validate URL before storing\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {\n throw new Error('Only HTTP(S) protocols are allowed');\n }\n config.set('apiUrl', url);\n } catch (error) {\n throw new Error('Invalid API URL format');\n }\n}\n\nexport function getCliPath(): string {\n // Check environment variable first for override\n const envPath = process.env.DEVARK_CLI_PATH;\n if (envPath) {\n return envPath;\n }\n \n // Use configured path or default to npx command\n return config.get('cliPath') || 'npx devark-cli';\n}\n\nexport function setCliPath(path: string): void {\n config.set('cliPath', path);\n}\n\nexport function getStatusLinePersonality(): NonNullable<ConfigSchema['statusLine']> {\n const statusLine = config.get('statusLine');\n // Default to 'gordon' personality for new installations\n if (!statusLine) {\n return { personality: 'gordon' };\n }\n return statusLine;\n}\n\nexport function setStatusLinePersonality(personality: 'gordon' | 'devark' | 'custom'): void {\n const current = config.get('statusLine') || {};\n config.set('statusLine', {\n ...current,\n personality\n });\n}\n\nexport function setCustomPersonality(customPersonality: NonNullable<ConfigSchema['statusLine']>['customPersonality']): void {\n const current = config.get('statusLine') || {};\n config.set('statusLine', {\n ...current,\n personality: 'custom',\n customPersonality\n });\n}\n\nexport function getLastSync(): Date | null {\n const lastSync = config.get('lastSync');\n if (!lastSync) return null;\n \n try {\n const date = new Date(lastSync);\n if (isNaN(date.getTime())) {\n return null;\n }\n return date;\n } catch {\n return null;\n }\n}\n\nexport function setLastSync(date: Date): void {\n if (!(date instanceof Date) || isNaN(date.getTime())) {\n throw new Error('Invalid date');\n }\n config.set('lastSync', date.toISOString());\n}\n\nexport function getPreferences(): ConfigSchema['preferences'] {\n return config.get('preferences') || {};\n}\n\nexport function setPreference<K extends keyof NonNullable<ConfigSchema['preferences']>>(\n key: K,\n value: NonNullable<ConfigSchema['preferences']>[K]\n): void {\n const preferences = getPreferences() || {};\n \n // Validate preference values\n if (key === 'colorScheme' && !['default', 'minimal'].includes(value as string)) {\n throw new Error('Invalid color scheme');\n }\n if (key === 'verboseOutput' && typeof value !== 'boolean') {\n throw new Error('Invalid verbose output value');\n }\n \n preferences[key] = value;\n config.set('preferences', preferences);\n}\n\n// PROJECT TRACKING REMOVED - Now handled by hooks in Claude settings files\n// The source of truth for project tracking is now:\n// - Global hooks in ~/.claude/settings.json (for 'all' mode)\n// - Project-specific hooks in project/.claude/settings.local.json (for 'selected' mode)\n// Use getHookMode() and getTrackedProjects() from claude-settings-reader.ts instead\n\nexport function getAllConfig(): ConfigSchema {\n // Only return config if the file actually exists\n // This prevents default values from being treated as configured state\n const configPath = join(homedir(), '.devark', 'config.json');\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n require('fs').accessSync(configPath);\n // Config file exists, return actual values\n return {\n apiUrl: config.get('apiUrl'),\n token: config.get('token') ? '<redacted>' : undefined,\n lastSync: config.get('lastSync'),\n preferences: config.get('preferences'),\n projectSyncData: config.get('projectSyncData'),\n lastSyncSummary: config.get('lastSyncSummary'),\n };\n } catch {\n // Config file doesn't exist, return empty object\n return {} as ConfigSchema;\n }\n}\n\n// Project sync data management\nexport function getProjectSyncData(claudeFolderName: string): ProjectSyncData | undefined {\n const projectData = config.get('projectSyncData') || {};\n return projectData[claudeFolderName];\n}\n\nexport function setProjectSyncData(claudeFolderName: string, data: ProjectSyncData): void {\n const projectData = config.get('projectSyncData') || {};\n projectData[claudeFolderName] = data;\n config.set('projectSyncData', projectData);\n}\n\nexport function updateProjectSyncBoundaries(\n claudeFolderName: string, \n oldestTimestamp: string | undefined,\n newestTimestamp: string | undefined,\n projectName?: string,\n sessionCount?: number\n): void {\n const existing = getProjectSyncData(claudeFolderName) || {};\n \n const updated: ProjectSyncData = {\n ...existing,\n lastSyncTime: new Date().toISOString(),\n projectName: projectName || existing.projectName,\n sessionCount: sessionCount !== undefined ? sessionCount : existing.sessionCount\n };\n \n // Update oldest boundary\n if (oldestTimestamp) {\n if (!existing.oldestSyncedTimestamp || oldestTimestamp < existing.oldestSyncedTimestamp) {\n updated.oldestSyncedTimestamp = oldestTimestamp;\n }\n }\n \n // Update newest boundary\n if (newestTimestamp) {\n if (!existing.newestSyncedTimestamp || newestTimestamp > existing.newestSyncedTimestamp) {\n updated.newestSyncedTimestamp = newestTimestamp;\n }\n }\n \n setProjectSyncData(claudeFolderName, updated);\n}\n\nexport function setLastSyncSummary(description: string): void {\n config.set('lastSyncSummary', {\n timestamp: new Date().toISOString(),\n description\n });\n // Also update legacy lastSync for compatibility\n config.set('lastSync', new Date().toISOString());\n}\n\nexport function getLastSyncSummary(): { timestamp: string; description: string } | undefined {\n return config.get('lastSyncSummary');\n}\n\nexport function getConfigValue(key: keyof ConfigSchema): any {\n if (key === 'token') {\n return config.get('token') ? '<redacted>' : undefined;\n }\n return config.get(key);\n}\n\nexport async function clearAllConfig(): Promise<void> {\n config.clear();\n // Also remove encryption key\n try {\n await fs.unlink(KEY_FILE);\n } catch {\n // Ignore if key doesn't exist\n }\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n\n// Status line backup management functions\nexport function saveStatusLineBackup(backup: {\n originalCommand?: string;\n originalType?: string;\n originalPadding?: number;\n backupReason?: string;\n}): void {\n config.set('statusLineBackup', {\n ...backup,\n backupDate: new Date().toISOString()\n });\n logger.debug('Status line backup saved:', backup);\n}\n\nexport function getStatusLineBackup(): ConfigSchema['statusLineBackup'] | undefined {\n return config.get('statusLineBackup');\n}\n\nexport function clearStatusLineBackup(): void {\n config.delete('statusLineBackup');\n logger.debug('Status line backup cleared');\n}","import { DevArkError } from '../../utils/errors.js';\n\nexport type NetworkErrorType = \n | 'DNS_RESOLUTION_FAILED'\n | 'CONNECTION_REFUSED' \n | 'TIMEOUT'\n | 'CONNECTION_RESET'\n | 'SERVICE_UNAVAILABLE'\n | 'UNKNOWN_NETWORK_ERROR';\n\nexport interface NetworkErrorInfo {\n type: NetworkErrorType;\n message: string;\n code: string;\n originalError?: any;\n}\n\n/**\n * Detects if an error is network-related\n */\nexport function isNetworkError(error: any): boolean {\n if (!error) return false;\n \n // Check error codes\n const networkErrorCodes = [\n 'ENOTFOUND',\n 'ECONNREFUSED', \n 'ETIMEDOUT',\n 'ECONNABORTED',\n 'ECONNRESET',\n 'TIMEOUT'\n ];\n \n if (error.code && networkErrorCodes.includes(error.code)) {\n return true;\n }\n \n // Check error messages for network-related strings\n if (error.message) {\n const message = error.message.toLowerCase();\n return networkErrorCodes.some(code => message.includes(code.toLowerCase()));\n }\n \n // Check HTTP status codes\n if (error.response?.status) {\n const status = error.response.status;\n return status === 502 || status === 503 || status === 504;\n }\n \n return false;\n}\n\n/**\n * Gets the type of network error\n */\nexport function getNetworkErrorType(error: any): NetworkErrorType {\n if (!error) return 'UNKNOWN_NETWORK_ERROR';\n \n // Check specific error codes\n if (error.code === 'ENOTFOUND' || \n (error.message && error.message.includes('ENOTFOUND'))) {\n return 'DNS_RESOLUTION_FAILED';\n }\n \n if (error.code === 'ECONNREFUSED' || \n (error.message && error.message.includes('ECONNREFUSED'))) {\n return 'CONNECTION_REFUSED';\n }\n \n if (error.code === 'ETIMEDOUT' || \n error.code === 'ECONNABORTED' || \n error.code === 'TIMEOUT' ||\n (error.message && (\n error.message.includes('ETIMEDOUT') || \n error.message.includes('TIMEOUT')\n ))) {\n return 'TIMEOUT';\n }\n \n if (error.code === 'ECONNRESET' || \n (error.message && error.message.includes('ECONNRESET'))) {\n return 'CONNECTION_RESET';\n }\n \n // Check HTTP status codes\n if (error.response?.status === 502 || \n error.response?.status === 503 || \n error.response?.status === 504) {\n return 'SERVICE_UNAVAILABLE';\n }\n \n return 'UNKNOWN_NETWORK_ERROR';\n}\n\n/**\n * Gets a user-friendly error message for network errors\n */\nexport function getNetworkErrorMessage(error: any): string {\n const errorType = getNetworkErrorType(error);\n \n switch (errorType) {\n case 'DNS_RESOLUTION_FAILED':\n return 'Cannot reach devark servers. Please check your internet connection';\n \n case 'CONNECTION_REFUSED':\n return 'Connection refused. The server might be down or your firewall is blocking the connection';\n \n case 'TIMEOUT':\n return 'Request timed out. Your connection might be slow or the server is not responding';\n \n case 'CONNECTION_RESET':\n return 'Connection was reset. Please try again';\n \n case 'SERVICE_UNAVAILABLE':\n return 'Service temporarily unavailable. Please try again in a few moments';\n \n default:\n return 'Network error. Please check your internet connection and try again';\n }\n}\n\n/**\n * Gets a standardized error code for network errors\n */\nexport function getNetworkErrorCode(error: any): string {\n const errorType = getNetworkErrorType(error);\n \n switch (errorType) {\n case 'DNS_RESOLUTION_FAILED':\n return 'NETWORK_ERROR';\n \n case 'CONNECTION_REFUSED':\n return 'CONNECTION_REFUSED';\n \n case 'TIMEOUT':\n return 'TIMEOUT';\n \n case 'CONNECTION_RESET':\n return 'CONNECTION_RESET';\n \n case 'SERVICE_UNAVAILABLE':\n return 'SERVICE_UNAVAILABLE';\n \n default:\n return 'NETWORK_ERROR';\n }\n}\n\n/**\n * Creates a DevArkError from a network error\n */\nexport function createNetworkError(error: any): DevArkError {\n const message = getNetworkErrorMessage(error);\n const code = getNetworkErrorCode(error);\n return new DevArkError(message, code);\n}\n\n/**\n * Gets detailed network error information\n */\nexport function getNetworkErrorInfo(error: any): NetworkErrorInfo {\n return {\n type: getNetworkErrorType(error),\n message: getNetworkErrorMessage(error),\n code: getNetworkErrorCode(error),\n originalError: error\n };\n}","import chalk from 'chalk';\nimport { isNetworkError, getNetworkErrorMessage } from '../lib/errors/network-errors';\n\nexport class DevArkError extends Error {\n constructor(message: string, public code: string) {\n super(message);\n this.name = 'DevArkError';\n }\n}\n\n/**\n * Display error without exiting the process - for interactive mode\n */\nexport function displayError(error: unknown): void {\n if (error instanceof DevArkError) {\n console.error(chalk.red(`\\n❌ Error: ${error.message}`));\n \n switch (error.code) {\n case 'AUTH_REQUIRED':\n console.log(chalk.yellow('💡 Try: Authenticate from the main menu'));\n break;\n case 'AUTH_EXPIRED':\n case 'AUTH_FAILED':\n case 'INVALID_TOKEN':\n console.log(chalk.yellow('💡 Your authentication has expired. Please re-authenticate from the menu'));\n break;\n case 'AUTH_NOT_COMPLETED':\n console.log(chalk.yellow('💡 Complete the authentication in your browser, then try again'));\n break;\n case 'AUTH_CHECK_FAILED':\n console.log(chalk.yellow('💡 Try re-authenticating from the menu'));\n break;\n case 'NETWORK_ERROR':\n console.log(chalk.yellow('💡 Check your internet connection and try again'));\n break;\n case 'RATE_LIMITED':\n console.log(chalk.yellow('💡 You\\'ve hit the rate limit. Please wait a minute and try again'));\n break;\n case 'CLAUDE_NOT_FOUND':\n console.log(chalk.yellow('💡 Make sure Claude Code is installed'));\n console.log(chalk.gray(' Visit: https://claude.ai/download'));\n break;\n case 'SEND_FAILED':\n console.log(chalk.yellow('💡 The upload failed. Please check your connection and try again'));\n break;\n case 'VALIDATION_ERROR':\n console.log(chalk.yellow('💡 Some sessions couldn\\'t be processed. Try selecting different sessions'));\n break;\n case 'ACCESS_DENIED':\n console.log(chalk.yellow('💡 Access denied. Please check your permissions'));\n break;\n case 'SERVER_ERROR':\n console.log(chalk.yellow('💡 The server is having issues. Please try again later'));\n break;\n case 'SERVICE_UNAVAILABLE':\n console.log(chalk.yellow('💡 Service temporarily unavailable. Try again in a few moments'));\n break;\n case 'CONNECTION_REFUSED':\n console.log(chalk.yellow('💡 Connection refused. Check if your firewall is blocking the connection'));\n break;\n case 'TIMEOUT':\n console.log(chalk.yellow('💡 Request timed out. Check your connection speed'));\n break;\n case 'ENDPOINT_NOT_FOUND':\n console.log(chalk.yellow('💡 API endpoint not found. You might need to update your CLI'));\n break;\n }\n } else if (error instanceof Error) {\n console.error(chalk.red(`\\n❌ Error: ${error.message}`));\n \n // Network-specific errors\n if (isNetworkError(error)) {\n const message = getNetworkErrorMessage(error);\n console.log(chalk.yellow(`💡 ${message}`));\n } else if (error.message.includes('ENOSPC')) {\n console.log(chalk.yellow('💡 Your disk is full. Free up some space and try again'));\n } else if (error.message.includes('EACCES') || error.message.includes('EPERM')) {\n console.log(chalk.yellow('💡 Permission denied. Check file permissions'));\n }\n \n if (process.env.DEBUG || process.env.DEVARK_DEBUG) {\n console.error(chalk.gray('\\nStack trace:'));\n console.error(chalk.gray(error.stack));\n }\n } else {\n console.error(chalk.red('\\n❌ An unexpected error occurred'));\n \n if (process.env.DEBUG || process.env.DEVARK_DEBUG) {\n console.error(error);\n }\n }\n \n console.log(chalk.gray('\\n💬 Press Enter to return to the menu...'));\n}\n\n/**\n * Fatal error handler - exits the process (for CLI commands)\n */\nexport function handleError(error: unknown): void {\n if (error instanceof DevArkError) {\n console.error(chalk.red(`\\n❌ Error: ${error.message}`));\n \n switch (error.code) {\n case 'AUTH_REQUIRED':\n console.log(chalk.yellow('💡 Run: npx devark-cli'));\n break;\n case 'AUTH_EXPIRED':\n case 'AUTH_FAILED':\n case 'INVALID_TOKEN':\n console.log(chalk.yellow('💡 Run: npx devark-cli and authenticate'));\n break;\n case 'AUTH_NOT_COMPLETED':\n console.log(chalk.yellow('💡 Complete the authentication in your browser, then try again'));\n break;\n case 'AUTH_CHECK_FAILED':\n console.log(chalk.yellow('💡 Try running: npx devark-cli and re-authenticate'));\n break;\n case 'NETWORK_ERROR':\n console.log(chalk.yellow('💡 Check your internet connection'));\n break;\n case 'RATE_LIMITED':\n console.log(chalk.yellow('💡 Please wait a few minutes and try again'));\n break;\n case 'CLAUDE_NOT_FOUND':\n console.log(chalk.yellow('💡 Make sure Claude Code is installed'));\n console.log(chalk.gray(' Visit: https://claude.ai/download'));\n break;\n }\n } else if (error instanceof Error) {\n console.error(chalk.red(`\\n❌ Error: ${error.message}`));\n \n if (process.env.DEBUG || process.env.DEVARK_DEBUG) {\n console.error(chalk.gray('\\nStack trace:'));\n console.error(chalk.gray(error.stack));\n }\n } else {\n console.error(chalk.red('\\n❌ An unknown error occurred'));\n \n if (process.env.DEBUG || process.env.DEVARK_DEBUG) {\n console.error(error);\n }\n }\n \n console.log(chalk.gray('\\n💬 Need help? Visit: https://devark.ai/help'));\n \n process.exit(1);\n}\n\nexport function logDebug(message: string, data?: any): void {\n if (process.env.DEBUG || process.env.DEVARK_DEBUG) {\n console.log(chalk.gray(`[DEBUG] ${message}`));\n if (data) {\n console.log(chalk.gray(JSON.stringify(data, null, 2)));\n }\n }\n}","import path from 'path';\nimport { URL } from 'url';\n\n/**\n * Security-focused input validation utilities\n */\n\n// Sanitize file paths to prevent directory traversal\nexport function sanitizePath(inputPath: string): string {\n if (!inputPath || typeof inputPath !== 'string') {\n throw new Error('Invalid path input');\n }\n \n // Check for directory traversal attempts BEFORE normalization\n const traversalPatterns = [\n '..',\n '..\\\\',\n '../',\n '..\\\\/',\n '%2e%2e',\n '%252e%252e',\n '..%2f',\n '..%5c',\n ];\n \n const lowerPath = inputPath.toLowerCase();\n for (const pattern of traversalPatterns) {\n if (lowerPath.includes(pattern)) {\n throw new Error('Directory traversal attempt detected');\n }\n }\n \n // Normalize and resolve path after security check\n const normalized = path.normalize(inputPath);\n \n // Remove any null bytes\n const cleaned = normalized.replace(/\\0/g, '');\n \n // Ensure path doesn't start with a drive letter on Windows\n if (process.platform === 'win32' && /^[a-zA-Z]:/.test(cleaned)) {\n // Allow but log for monitoring\n console.warn('Absolute path detected:', cleaned.substring(0, 3) + '...');\n }\n \n return cleaned;\n}\n\n// Validate and sanitize URLs\nexport function validateUrl(url: string): string {\n if (!url || typeof url !== 'string') {\n throw new Error('Invalid URL input');\n }\n \n try {\n const parsed = new URL(url);\n \n // Only allow HTTP(S) protocols\n if (!['http:', 'https:'].includes(parsed.protocol)) {\n throw new Error('Only HTTP(S) protocols are allowed');\n }\n \n // Check for localhost/private IPs (SSRF prevention)\n const privatePatterns = [\n /^127\\./,\n /^10\\./,\n /^172\\.(1[6-9]|2[0-9]|3[0-1])\\./,\n /^192\\.168\\./,\n /^169\\.254\\./,\n /^::1$/,\n /^fe80:/i,\n /^fc00:/i,\n /^fd00:/i,\n ];\n \n const hostname = parsed.hostname.toLowerCase();\n if (hostname === 'localhost' ||\n privatePatterns.some(pattern => pattern.test(hostname))) {\n // Allow localhost for development without warning\n // Production deployments should never use localhost\n }\n \n // Check for suspicious ports\n const suspiciousPorts = ['22', '23', '25', '445', '3389'];\n if (suspiciousPorts.includes(parsed.port)) {\n throw new Error('Suspicious port detected');\n }\n \n // Return normalized URL\n return parsed.toString();\n } catch (error) {\n if (error instanceof TypeError) {\n throw new Error('Invalid URL format');\n }\n throw error;\n }\n}\n\n// Validate date inputs\nexport function validateDate(dateStr: string): Date {\n if (!dateStr || typeof dateStr !== 'string') {\n throw new Error('Invalid date input');\n }\n \n // Remove any potential injection characters\n const cleaned = dateStr.replace(/[^0-9\\-T:.Z]/g, '');\n \n const date = new Date(cleaned);\n if (isNaN(date.getTime())) {\n throw new Error('Invalid date format');\n }\n \n // Check for reasonable date ranges (not too far in past or future)\n const now = new Date();\n const yearInMs = 365 * 24 * 60 * 60 * 1000;\n \n if (date.getTime() < now.getTime() - (10 * yearInMs)) {\n throw new Error('Date too far in the past');\n }\n \n if (date.getTime() > now.getTime() + yearInMs) {\n throw new Error('Date too far in the future');\n }\n \n return date;\n}\n\n// Validate session ID format\nexport function validateSessionId(sessionId: string): string {\n if (!sessionId || typeof sessionId !== 'string') {\n throw new Error('Invalid session ID');\n }\n \n // Only allow alphanumeric, dash, and underscore\n if (!/^[a-zA-Z0-9\\-_]+$/.test(sessionId)) {\n throw new Error('Invalid session ID format');\n }\n \n // Check length constraints\n if (sessionId.length < 10 || sessionId.length > 128) {\n throw new Error('Invalid session ID length');\n }\n \n return sessionId;\n}\n\n// Validate and sanitize project names\nexport function validateProjectName(name: string): string {\n if (!name || typeof name !== 'string') {\n throw new Error('Invalid project name');\n }\n \n // Remove potentially dangerous characters\n const sanitized = name\n .replace(/[<>:\"\\\\|?*\\u0000-\\u001F]/g, '') // Windows forbidden chars\n .replace(/\\.\\./g, '') // Directory traversal\n .replace(/^\\.|\\.$/g, '') // Leading/trailing dots\n .trim();\n \n if (!sanitized || sanitized.length === 0) {\n throw new Error('Invalid project name after sanitization');\n }\n \n if (sanitized.length > 255) {\n throw new Error('Project name too long');\n }\n \n return sanitized;\n}\n\n// Validate numeric limit\nexport function validateLimit(limit: any): number {\n const num = parseInt(limit, 10);\n \n if (isNaN(num) || num < 1) {\n throw new Error('Invalid limit value');\n }\n \n // Prevent resource exhaustion\n if (num > 1000) {\n throw new Error('Limit too high');\n }\n \n return num;\n}\n\n// Sanitize log output to prevent log injection\nexport function sanitizeLogOutput(message: string): string {\n if (!message || typeof message !== 'string') {\n return '[Invalid log message]';\n }\n \n // Remove ANSI escape codes that could manipulate terminal\n const ansiPattern = /[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;\n \n return message\n .replace(ansiPattern, '') // Remove ANSI codes\n .replace(/\\r/g, '\\\\r') // Escape carriage returns\n .replace(/\\n/g, '\\\\n') // Escape newlines\n .slice(0, 1000); // Limit length\n}\n\n// Validate authentication token\nexport function validateAuthToken(token: string): string {\n if (!token || typeof token !== 'string') {\n throw new Error('Invalid token input');\n }\n \n // Remove whitespace\n const trimmed = token.trim();\n \n if (trimmed.length < 20) {\n throw new Error('Token too short');\n }\n \n if (trimmed.length > 1000) {\n throw new Error('Token too long');\n }\n \n // Check for common injection patterns\n const dangerousPatterns = [\n /[<>]/, // HTML injection\n /[`${}]/, // Template injection\n /[\\u0000-\\u001F]/, // Control characters\n /[';\\\\]/, // SQL/Command injection\n ];\n \n for (const pattern of dangerousPatterns) {\n if (pattern.test(trimmed)) {\n throw new Error('Invalid token format - contains dangerous characters');\n }\n }\n \n return trimmed;\n}\n\n// Validate command line arguments\nexport function validateCliArg(arg: string, type: 'path' | 'url' | 'string'): string {\n if (!arg || typeof arg !== 'string') {\n throw new Error('Invalid argument');\n }\n \n // Check for command injection attempts\n const dangerousPatterns = [\n /[;&|`$(){}[\\]<>]/, // Shell metacharacters\n /\\\\.{2,}/, // Multiple backslashes\n /\\/{3,}/, // Multiple forward slashes\n ];\n \n if (dangerousPatterns.some(pattern => pattern.test(arg))) {\n throw new Error('Potentially dangerous characters in argument');\n }\n \n switch (type) {\n case 'path':\n return sanitizePath(arg);\n case 'url':\n return validateUrl(arg);\n case 'string':\n return arg.slice(0, 1000); // Limit length\n default:\n throw new Error('Unknown validation type');\n }\n}","import chalk from 'chalk';\n\n// Helper function to safely use chalk.hex with fallback\nconst safeHex = (color: string, fallback: any) => {\n try {\n return chalk.hex ? chalk.hex(color) : fallback;\n } catch {\n return fallback;\n }\n};\n\n// Claude Code Brand Colors\nexport const brandColors = {\n primary: safeHex('#d97757', chalk.red), // Claude Code Orange - Primary brand color\n accent: safeHex('#FF5F56', chalk.red), // Bright orange - Accent\n dark: safeHex('#111827', chalk.black), // Ebony - Dark contrast\n lightPeach: safeHex('#F08D7A', chalk.red), // Lighter peach for highlights\n warmGray: safeHex('#9CA3AF', chalk.gray), // Warm gray for muted text\n};\n\n// Color palette - optimized for visibility on both dark and light terminals\nexport const colors = {\n primary: brandColors.primary, // Use brand primary as default primary\n success: chalk.green,\n warning: chalk.yellow,\n error: chalk.red,\n info: chalk.cyan, // Changed from blue to cyan for better visibility\n muted: safeHex('#808080', chalk.gray), // Brighter gray for better visibility on black terminals\n accent: brandColors.accent, // Use brand accent\n highlight: chalk.bold.cyan, // Changed from white to cyan for visibility on light terminals\n dim: safeHex('#606060', chalk.dim), // Custom gray instead of chalk.dim for consistency\n\n // Semantic helpers for better readability\n subdued: safeHex('#909090', chalk.gray), // Increased contrast for better readability\n hint: safeHex('#7A8290', chalk.gray), // Slightly brighter for better visibility\n inactive: safeHex('#4B5563', chalk.dim), // For disabled/inactive items\n\n // Brand-specific semantic colors\n brandPrimary: brandColors.primary,\n brandAccent: brandColors.accent,\n brandDark: brandColors.dark,\n brandLight: brandColors.lightPeach,\n brandMuted: brandColors.warmGray,\n};\n\n// Icons\nexport const icons = {\n success: '✓',\n error: '✗',\n warning: '⚠️',\n info: 'ℹ️',\n bullet: '•',\n arrow: '→',\n cloud: '☁️',\n local: '💻',\n folder: '📁',\n file: '📄',\n clock: '🕐',\n fire: '🔥',\n star: '⭐',\n chart: '📊',\n chartUp: '📈',\n check: '✅',\n cross: '❌',\n loading: '⏳',\n sync: '🔄',\n lock: '🔒',\n unlock: '🔓',\n package: '📦',\n rocket: '🚀',\n sparkles: '✨',\n search: '🔍', // Added missing search icon\n refresh: '🔄', // Added refresh icon for retry\n settings: '🔧', // Settings/configuration icon\n plus: '➕', // Add/install icon\n minus: '➖', // Remove/uninstall icon\n flask: '🧪', // Test/experiment icon\n};\n\n// Box drawing characters\nexport const box = {\n topLeft: '┌',\n topRight: '┐',\n bottomLeft: '└',\n bottomRight: '┘',\n horizontal: '─',\n vertical: '│',\n cross: '┼',\n tLeft: '├',\n tRight: '┤',\n tTop: '┬',\n tBottom: '┴',\n doubleHorizontal: '═',\n doubleVertical: '║',\n doubleTopLeft: '╔',\n doubleTopRight: '╗',\n doubleBottomLeft: '╚',\n doubleBottomRight: '╝',\n doubleTLeft: '╠',\n doubleTRight: '╣',\n};\n\n// Progress bar characters\nexport const progress = {\n full: '█',\n three_quarters: '▓',\n half: '▒',\n quarter: '░',\n empty: '░',\n};\n\n// Formatters\nexport const format = {\n bold: chalk.bold,\n dim: chalk.dim,\n italic: chalk.italic,\n underline: chalk.underline,\n inverse: chalk.inverse,\n strikethrough: chalk.strikethrough,\n};\n\n// Utility functions\nexport function center(text: string, width: number): string {\n // eslint-disable-next-line no-control-regex\n const textLength = text.replace(/\\u001b\\[[0-9;]*m/g, '').length;\n const padding = Math.max(0, Math.floor((width - textLength) / 2));\n return ' '.repeat(padding) + text;\n}\n\nexport function padRight(text: string, width: number): string {\n // eslint-disable-next-line no-control-regex\n const textLength = text.replace(/\\u001b\\[[0-9;]*m/g, '').length;\n const padding = Math.max(0, width - textLength);\n return text + ' '.repeat(padding);\n}\n\nexport function padLeft(text: string, width: number): string {\n // eslint-disable-next-line no-control-regex\n const textLength = text.replace(/\\u001b\\[[0-9;]*m/g, '').length;\n const padding = Math.max(0, width - textLength);\n return ' '.repeat(padding) + text;\n}\n\nexport function truncate(text: string, maxLength: number): string {\n // eslint-disable-next-line no-control-regex\n const cleanText = text.replace(/\\u001b\\[[0-9;]*m/g, '');\n if (cleanText.length <= maxLength) return text;\n return text.substring(0, maxLength - 3) + '...';\n}\n\n// Terminal width helper\nexport function getTerminalWidth(): number {\n return process.stdout.columns || 80;\n}\n\n// Create a horizontal line\nexport function horizontalLine(char: string = box.horizontal, width?: number): string {\n const w = width || getTerminalWidth();\n return char.repeat(w);\n}\n\n// Create a section divider\nexport function sectionDivider(title?: string): string {\n const width = getTerminalWidth();\n if (!title) {\n return colors.muted(horizontalLine(box.horizontal, width));\n }\n\n const titleWithSpaces = ` ${title} `;\n // eslint-disable-next-line no-control-regex\n const titleLength = titleWithSpaces.replace(/\\u001b\\[[0-9;]*m/g, '').length;\n const leftWidth = Math.floor((width - titleLength) / 2);\n const rightWidth = width - titleLength - leftWidth;\n\n return colors.muted(\n box.horizontal.repeat(Math.max(0, leftWidth)) +\n colors.primary(titleWithSpaces) +\n box.horizontal.repeat(Math.max(0, rightWidth))\n );\n}\n","import { colors, icons, box, progress, padRight, truncate, getTerminalWidth } from './styles';\n\ninterface Project {\n name: string;\n sessions: number;\n lastActivity: Date | string;\n isActive?: boolean;\n path?: string;\n}\n\n/**\n * Extract project name from a file path\n * e.g., \"devark\" from path \"/home/user/projects/devark\"\n */\nexport function parseProjectName(path: string): string {\n if (!path) return '';\n \n // Handle both Unix and Windows path separators\n const normalizedPath = path.replace(/\\\\/g, '/');\n const parts = normalizedPath.split('/');\n // Return the last segment of the path as the project name\n return parts[parts.length - 1];\n}\n\n/**\n * Format relative time for last activity\n */\nexport function formatRelativeTime(date: Date | string): string {\n const now = new Date();\n const then = typeof date === 'string' ? new Date(date) : date;\n \n // Handle invalid dates\n if (isNaN(then.getTime())) {\n return 'just now';\n }\n \n const seconds = Math.floor((now.getTime() - then.getTime()) / 1000);\n \n if (seconds < 60) return 'just now';\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;\n if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;\n if (seconds < 604800) return `${Math.floor(seconds / 86400)}d ago`;\n if (seconds < 2592000) return `${Math.floor(seconds / 604800)}w ago`;\n return `${Math.floor(seconds / 2592000)}mo ago`;\n}\n\n/**\n * Create an activity graph showing session distribution\n */\nexport function createActivityGraph(sessions: number, maxSessions: number, width: number = 20): string {\n // Validate inputs\n const safeSessions = Math.max(0, sessions);\n const safeMaxSessions = Math.max(1, maxSessions);\n const ratio = Math.min(1, safeSessions / safeMaxSessions);\n \n const filled = Math.floor(ratio * width);\n const graph = progress.full.repeat(filled) + progress.empty.repeat(width - filled);\n \n // Color based on activity level\n if (ratio > 0.75) return colors.success(graph);\n if (ratio > 0.5) return colors.primary(graph);\n if (ratio > 0.25) return colors.warning(graph);\n return colors.muted(graph);\n}\n\n/**\n * Create activity sparkline for recent sessions\n */\nexport function createSparkline(recentActivity: number[], maxValue?: number): string {\n const sparkChars = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];\n const max = maxValue || Math.max(...recentActivity, 1);\n \n return recentActivity\n .map(value => {\n const index = Math.floor((value / max) * (sparkChars.length - 1));\n const char = sparkChars[Math.max(0, Math.min(index, sparkChars.length - 1))];\n \n // Color based on intensity\n if (value === 0) return colors.dim(char);\n if (index > 5) return colors.success(char);\n if (index > 2) return colors.primary(char);\n return colors.muted(char);\n })\n .join('');\n}\n\n/**\n * Create a beautiful ASCII table for project listing\n */\nexport function createProjectTable(projects: Project[]): string {\n const termWidth = Math.min(getTerminalWidth(), 120);\n const maxSessions = Math.max(...projects.map(p => p.sessions), 1);\n \n // Column widths\n const nameWidth = 30;\n const sessionsWidth = 12;\n const graphWidth = 20;\n const lastActivityWidth = 15;\n const statusWidth = 8;\n \n const lines: string[] = [];\n \n // Header with double-line box\n lines.push(colors.primary(box.doubleTopLeft + box.doubleHorizontal.repeat(termWidth - 2) + box.doubleTopRight));\n \n // Title\n const title = `${icons.folder} PROJECT OVERVIEW`;\n const titlePadding = Math.floor((termWidth - title.length - 4) / 2);\n lines.push(\n colors.primary(box.doubleVertical) + \n ' '.repeat(titlePadding) + \n colors.highlight(title) + \n ' '.repeat(termWidth - titlePadding - title.length - 4) +\n colors.primary(box.doubleVertical)\n );\n \n // Header separator\n lines.push(\n colors.primary(box.tLeft + box.horizontal.repeat(termWidth - 2) + box.tRight)\n );\n \n // Column headers\n const headers = \n colors.primary(box.vertical) + ' ' +\n colors.dim(padRight('PROJECT', nameWidth)) +\n colors.dim(padRight('SESSIONS', sessionsWidth)) +\n colors.dim(padRight('ACTIVITY', graphWidth)) +\n colors.dim(padRight('LAST SEEN', lastActivityWidth)) +\n colors.dim(padRight('STATUS', statusWidth)) +\n ' '.repeat(Math.max(0, termWidth - nameWidth - sessionsWidth - graphWidth - lastActivityWidth - statusWidth - 4)) +\n colors.primary(box.vertical);\n \n lines.push(headers);\n \n // Header underline\n lines.push(\n colors.primary(box.tLeft) +\n colors.dim(box.horizontal.repeat(termWidth - 2)) +\n colors.primary(box.tRight)\n );\n \n // Project rows\n projects.forEach((project, index) => {\n const isLast = index === projects.length - 1;\n \n // Project name with icon\n const projectName = truncate(project.name, nameWidth - 3);\n const nameDisplay = project.isActive \n ? `${icons.fire} ${colors.highlight(projectName)}`\n : `${icons.folder} ${colors.primary(projectName)}`;\n \n // Session count with formatting\n const sessionDisplay = project.sessions > 99 \n ? colors.accent(`${project.sessions}+`)\n : project.sessions > 50\n ? colors.success(project.sessions.toString())\n : project.sessions > 10\n ? colors.primary(project.sessions.toString())\n : colors.muted(project.sessions.toString());\n \n // Activity graph\n const activityGraph = createActivityGraph(project.sessions, maxSessions, graphWidth);\n \n // Last activity with color coding\n const relativeTime = formatRelativeTime(project.lastActivity);\n const timeDisplay = relativeTime === 'just now'\n ? colors.success(relativeTime)\n : relativeTime.includes('m ago') || relativeTime.includes('h ago')\n ? colors.primary(relativeTime)\n : colors.muted(relativeTime);\n \n // Status indicator\n const status = project.isActive\n ? colors.success(`${icons.check} active`)\n : colors.muted(`${icons.clock} idle`);\n \n // Construct row\n const row = \n colors.primary(box.vertical) + ' ' +\n padRight(nameDisplay, nameWidth + 15) + // Extra space for color codes\n padRight(sessionDisplay, sessionsWidth + 5) +\n padRight(activityGraph, graphWidth) +\n padRight(timeDisplay, lastActivityWidth + 5) +\n padRight(status, statusWidth + 10) +\n ' '.repeat(Math.max(0, termWidth - nameWidth - sessionsWidth - graphWidth - lastActivityWidth - statusWidth - 30)) +\n colors.primary(box.vertical);\n \n lines.push(row);\n \n // Add subtle separator between rows (except last)\n if (!isLast) {\n lines.push(\n colors.dim(box.tLeft + box.horizontal.repeat(termWidth - 2) + box.tRight)\n );\n }\n });\n \n // Footer\n lines.push(colors.primary(box.bottomLeft + box.horizontal.repeat(termWidth - 2) + box.bottomRight));\n \n // Summary statistics\n const totalSessions = projects.reduce((sum, p) => sum + p.sessions, 0);\n const activeProjects = projects.filter(p => p.isActive).length;\n \n lines.push('');\n lines.push(\n colors.dim(' Total: ') + \n colors.highlight(`${projects.length} projects`) +\n colors.dim(' | ') +\n colors.highlight(`${totalSessions} sessions`) +\n colors.dim(' | ') +\n colors.success(`${activeProjects} active`)\n );\n \n return lines.join('\\n');\n}\n\n/**\n * Create a compact project list for limited space\n */\nexport function createCompactProjectList(projects: Project[]): string {\n const lines: string[] = [];\n const maxSessions = Math.max(...projects.map(p => p.sessions), 1);\n \n projects.forEach(project => {\n const activity = createActivityGraph(project.sessions, maxSessions, 10);\n const time = formatRelativeTime(project.lastActivity);\n const icon = project.isActive ? icons.fire : icons.folder;\n \n lines.push(\n `${icon} ${colors.primary(padRight(project.name, 20))} ${activity} ${colors.dim(`(${project.sessions} sessions, ${time})`)}`\n );\n });\n \n return lines.join('\\n');\n}\n\n/**\n * Create a detailed project card for single project display\n */\nexport function createProjectCard(project: Project, recentActivity?: number[]): string {\n const width = Math.min(getTerminalWidth(), 80);\n const lines: string[] = [];\n \n // Top border\n lines.push(colors.primary(box.topLeft + box.horizontal.repeat(width - 2) + box.topRight));\n \n // Project name header\n const headerText = ` ${icons.folder} ${project.name.toUpperCase()} `;\n const headerPadding = Math.floor((width - headerText.length) / 2);\n lines.push(\n colors.primary(box.vertical) +\n ' '.repeat(headerPadding) +\n colors.highlight(headerText) +\n ' '.repeat(width - headerPadding - headerText.length - 2) +\n colors.primary(box.vertical)\n );\n \n // Separator\n lines.push(colors.primary(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n // Stats rows\n const stats = [\n { label: 'Sessions', value: project.sessions.toString(), icon: icons.chart },\n { label: 'Last Activity', value: formatRelativeTime(project.lastActivity), icon: icons.clock },\n { label: 'Status', value: project.isActive ? 'Active' : 'Idle', icon: project.isActive ? icons.fire : icons.clock },\n ];\n \n stats.forEach(stat => {\n const row = \n colors.primary(box.vertical) + ' ' +\n colors.muted(stat.icon + ' ' + padRight(stat.label + ':', 15)) +\n colors.highlight(stat.value) +\n ' '.repeat(width - stat.label.length - stat.value.length - 22) +\n colors.primary(box.vertical);\n lines.push(row);\n });\n \n // Activity sparkline if provided\n if (recentActivity && recentActivity.length > 0) {\n lines.push(colors.primary(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n const sparkline = createSparkline(recentActivity);\n const sparkRow = \n colors.primary(box.vertical) + ' ' +\n colors.muted(icons.chart + ' Recent Activity: ') +\n sparkline +\n ' '.repeat(width - 20 - recentActivity.length - 4) +\n colors.primary(box.vertical);\n lines.push(sparkRow);\n }\n \n // Bottom border\n lines.push(colors.primary(box.bottomLeft + box.horizontal.repeat(width - 2) + box.bottomRight));\n \n return lines.join('\\n');\n}","/**\n * Pure business logic for parsing Claude project data\n * No file system operations - just data transformation\n */\n\nimport { parseProjectName } from './ui/project-display';\n\nexport interface ClaudeProject {\n name: string; // Display name (e.g., \"devark\")\n claudePath: string; // Claude folder path (e.g., ~/.claude/projects/-home-user-dev-devark)\n actualPath: string; // Actual project path (e.g., /home/user/dev/devark)\n sessions: number; // Number of session files\n lastActivity: Date | null; // Last modification time\n isActive: boolean; // Active within last 30 days\n size: number; // Total size of session files\n}\n\nexport interface SessionFileInfo {\n path: string;\n size: number;\n mtime: Date;\n}\n\nexport interface ParsedSessionLine {\n cwd?: string;\n sessionId?: string;\n timestamp?: string;\n [key: string]: any;\n}\n\n/**\n * Parse a JSONL session file content and extract the first cwd field\n */\nexport function parseSessionContent(content: string): ParsedSessionLine | null {\n const lines = content.trim().split('\\n');\n \n for (const line of lines) {\n if (!line.trim()) continue;\n \n try {\n const data = JSON.parse(line);\n if (data.cwd) {\n return data;\n }\n } catch {\n // Skip invalid JSON lines\n continue;\n }\n }\n \n return null;\n}\n\n/**\n * Extract project name from a path\n */\nexport function extractProjectName(cwdPath: string): string {\n return parseProjectName(cwdPath);\n}\n\n/**\n * Create a ClaudeProject from parsed session data\n */\nexport function createProjectFromSessionData(\n claudePath: string,\n _dirName: string, // Prefixed with _ to indicate it's intentionally unused\n sessionData: ParsedSessionLine | null,\n sessionFiles: SessionFileInfo[]\n): ClaudeProject | null {\n // We only trust the cwd field from JSONL files as the source of truth\n if (!sessionData?.cwd) {\n return null;\n }\n \n const actualPath = sessionData.cwd;\n const projectName = extractProjectName(actualPath);\n \n // Calculate stats from session files\n let lastActivity: Date | null = null;\n let totalSize = 0;\n \n for (const file of sessionFiles) {\n totalSize += file.size;\n \n if (!lastActivity || file.mtime > lastActivity) {\n lastActivity = file.mtime;\n }\n }\n \n // Determine if project is active (activity within last 30 days)\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n const isActive = lastActivity ? lastActivity > thirtyDaysAgo : false;\n \n return {\n name: projectName,\n claudePath,\n actualPath,\n sessions: sessionFiles.length,\n lastActivity,\n isActive,\n size: totalSize\n };\n}\n\n/**\n * Match a project to a given path (checks if path starts with project path)\n */\nexport function matchProjectToPath(\n projects: ClaudeProject[], \n targetPath: string\n): ClaudeProject | null {\n return projects.find(project => \n targetPath.startsWith(project.actualPath)\n ) || null;\n}\n\n/**\n * Sort projects by last activity (most recent first)\n */\nexport function sortProjectsByActivity(projects: ClaudeProject[]): ClaudeProject[] {\n return [...projects].sort((a, b) => {\n if (!a.lastActivity) return 1;\n if (!b.lastActivity) return -1;\n return b.lastActivity.getTime() - a.lastActivity.getTime();\n });\n}\n\n/**\n * Filter projects by activity within the last N days\n */\nexport function filterActiveProjects(projects: ClaudeProject[], days: number = 30): ClaudeProject[] {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - days);\n \n return projects.filter(project => \n project.lastActivity && project.lastActivity > cutoffDate\n );\n}","/**\n * File system abstraction for Claude project operations\n * This allows for easy mocking in tests and potential future implementations\n */\n\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { SessionFileInfo } from './claude-project-parser';\n\n/**\n * Interface for Claude file system operations\n */\nexport interface IClaudeFileSystem {\n /**\n * Check if a path exists and is accessible\n */\n exists(path: string): Promise<boolean>;\n \n /**\n * Get list of project directories in Claude projects folder\n */\n getProjectDirectories(): Promise<string[]>;\n \n /**\n * Get list of session files in a project directory\n */\n getSessionFiles(projectPath: string): Promise<SessionFileInfo[]>;\n \n /**\n * Read content of a session file\n */\n readSessionFile(filePath: string): Promise<string>;\n \n /**\n * Check if a path is a directory\n */\n isDirectory(path: string): Promise<boolean>;\n}\n\n/**\n * Default implementation using Node.js fs module\n */\nexport class ClaudeFileSystem implements IClaudeFileSystem {\n private claudeProjectsPath: string;\n \n constructor() {\n this.claudeProjectsPath = path.join(os.homedir(), '.claude', 'projects');\n }\n \n async exists(targetPath: string): Promise<boolean> {\n try {\n await fs.access(targetPath);\n return true;\n } catch {\n return false;\n }\n }\n \n async getProjectDirectories(): Promise<string[]> {\n if (!await this.exists(this.claudeProjectsPath)) {\n return [];\n }\n \n const entries = await fs.readdir(this.claudeProjectsPath);\n const directories: string[] = [];\n \n for (const entry of entries) {\n const fullPath = path.join(this.claudeProjectsPath, entry);\n if (await this.isDirectory(fullPath)) {\n directories.push(fullPath);\n }\n }\n \n return directories;\n }\n \n async getSessionFiles(projectPath: string): Promise<SessionFileInfo[]> {\n const files = await fs.readdir(projectPath);\n const sessionFiles: SessionFileInfo[] = [];\n \n for (const file of files) {\n if (file.endsWith('.jsonl')) {\n const filePath = path.join(projectPath, file);\n const stats = await fs.stat(filePath);\n sessionFiles.push({\n path: filePath,\n size: stats.size,\n mtime: stats.mtime\n });\n }\n }\n \n return sessionFiles;\n }\n \n async readSessionFile(filePath: string): Promise<string> {\n return await fs.readFile(filePath, 'utf-8');\n }\n \n async isDirectory(targetPath: string): Promise<boolean> {\n try {\n const stats = await fs.stat(targetPath);\n return stats.isDirectory();\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Get Claude home directory path\n */\nexport function getClaudeHomePath(): string {\n return path.join(os.homedir(), '.claude');\n}\n\n/**\n * Get Claude projects directory path\n */\nexport function getClaudeProjectsPath(): string {\n return path.join(getClaudeHomePath(), 'projects');\n}\n\n/**\n * Get global Claude settings path\n */\nexport function getGlobalSettingsPath(): string {\n return path.join(getClaudeHomePath(), 'settings.json');\n}\n\n/**\n * Get project-specific shared settings path\n */\nexport function getProjectSettingsPath(projectPath: string): string {\n return path.join(projectPath, '.claude', 'settings.json');\n}\n\n/**\n * Get project-specific local settings path\n */\nexport function getProjectLocalSettingsPath(projectPath: string): string {\n return path.join(projectPath, '.claude', 'settings.local.json');\n}\n\n/**\n * Get enterprise managed settings path (platform-specific)\n */\nexport function getEnterpriseManagedSettingsPath(): string | null {\n switch (process.platform) {\n case 'darwin': // macOS\n return '/Library/Application Support/ClaudeCode/managed-settings.json';\n case 'linux':\n return '/etc/claude-code/managed-settings.json';\n case 'win32':\n return 'C:\\\\ProgramData\\\\ClaudeCode\\\\managed-settings.json';\n default:\n return null;\n }\n}","import path from 'path';\nimport os from 'os';\n\n/**\n * Temporary directory names for isolating automated Claude sessions\n * These directories are used to prevent cluttering real project sessions\n */\nexport const TEMP_DIRECTORIES = {\n PROMPT_ANALYSIS: 'temp-prompt-analysis',\n PRODUCTIVITY_REPORT: 'temp-productivity-report',\n STANDUP_ANALYSIS: 'temp-standup',\n} as const;\n\n/**\n * Get the full path to a temp directory\n */\nexport function getTempDirectoryPath(type: keyof typeof TEMP_DIRECTORIES): string {\n return path.join(os.homedir(), '.devark', TEMP_DIRECTORIES[type]);\n}\n\n/**\n * List of all temp directory names (for filtering)\n */\nexport const TEMP_DIRECTORY_NAMES = Object.values(TEMP_DIRECTORIES);\n\n/**\n * Check if a project name is a temp directory\n */\nexport function isTempDirectory(projectName: string): boolean {\n return TEMP_DIRECTORY_NAMES.some(tempName => projectName === tempName);\n}\n\n/**\n * Check if a Claude project folder name contains a temp directory\n * Claude folder names are like: -Users-danny--devark-temp-prompt-analysis\n */\nexport function isClaudeTempProject(claudeFolderName: string): boolean {\n // Check if any temp directory name appears in the Claude folder name\n return TEMP_DIRECTORY_NAMES.some(tempName => \n claudeFolderName.includes(tempName)\n );\n}","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { logger } from '../utils/logger';\nimport {\n ClaudeProject,\n parseSessionContent,\n createProjectFromSessionData,\n matchProjectToPath,\n sortProjectsByActivity,\n filterActiveProjects\n} from './claude-project-parser';\nimport {\n ClaudeFileSystem,\n IClaudeFileSystem,\n getClaudeHomePath,\n getClaudeProjectsPath,\n getGlobalSettingsPath,\n getProjectSettingsPath,\n getProjectLocalSettingsPath,\n getEnterpriseManagedSettingsPath\n} from './claude-fs';\nimport { isClaudeTempProject } from './temp-directories';\n\n// Re-export types and utility functions for backward compatibility\nexport type { ClaudeProject };\nexport {\n getClaudeHomePath,\n getClaudeProjectsPath,\n getGlobalSettingsPath,\n getProjectSettingsPath,\n getProjectLocalSettingsPath,\n getEnterpriseManagedSettingsPath\n};\n\n// Default file system implementation\nlet fileSystem: IClaudeFileSystem = new ClaudeFileSystem();\n\n/**\n * Set a custom file system implementation (useful for testing)\n */\nexport function setFileSystem(fs: IClaudeFileSystem): void {\n fileSystem = fs;\n}\n\n/**\n * Reset to default file system implementation\n */\nexport function resetFileSystem(): void {\n fileSystem = new ClaudeFileSystem();\n}\n\n/**\n * Analyze a single Claude project directory\n */\nexport async function analyzeProject(\n claudePath: string, \n dirName: string\n): Promise<ClaudeProject | null> {\n try {\n const sessionFiles = await fileSystem.getSessionFiles(claudePath);\n \n if (sessionFiles.length === 0) {\n return null;\n }\n \n // Read the first session file to get the actual cwd\n let sessionData = null;\n if (sessionFiles.length > 0) {\n try {\n const content = await fileSystem.readSessionFile(sessionFiles[0].path);\n sessionData = parseSessionContent(content);\n } catch (error) {\n logger.debug(`Could not read session file: ${error}`);\n }\n }\n \n const project = createProjectFromSessionData(\n claudePath,\n dirName,\n sessionData,\n sessionFiles\n );\n \n if (!project) {\n logger.debug(`No valid project data found in ${dirName}`);\n }\n \n return project;\n } catch (error) {\n logger.debug(`Error analyzing project ${dirName}:`, error);\n return null;\n }\n}\n\n/**\n * Discover all Claude projects\n */\nexport async function discoverProjects(): Promise<ClaudeProject[]> {\n const projects: ClaudeProject[] = [];\n \n try {\n const projectDirs = await fileSystem.getProjectDirectories();\n \n for (const projectPath of projectDirs) {\n const dirName = path.basename(projectPath);\n \n // Skip temp directories used for automated analysis\n if (isClaudeTempProject(dirName)) {\n logger.debug(`Skipping temp project: ${dirName}`);\n continue;\n }\n \n const project = await analyzeProject(projectPath, dirName);\n if (project) {\n projects.push(project);\n }\n }\n \n return sortProjectsByActivity(projects);\n } catch (error) {\n logger.error('Error discovering projects:', error);\n return projects;\n }\n}\n\n/**\n * Get active projects (with activity in the last N days)\n */\nexport async function getActiveProjects(days: number = 30): Promise<ClaudeProject[]> {\n const allProjects = await discoverProjects();\n return filterActiveProjects(allProjects, days);\n}\n\n/**\n * Get the current project based on the current working directory\n */\nexport async function getCurrentProject(): Promise<ClaudeProject | null> {\n const cwd = process.cwd();\n const projects = await discoverProjects();\n return matchProjectToPath(projects, cwd);\n}\n\n/**\n * Check if Claude Code is installed\n */\nexport async function isClaudeCodeInstalled(): Promise<boolean> {\n try {\n await fs.access(getClaudeHomePath());\n return true;\n } catch {\n return false;\n }\n}","import { promises as fs } from 'fs';\nimport { logger } from '../utils/logger';\nimport {\n getGlobalSettingsPath,\n getProjectSettingsPath,\n getProjectLocalSettingsPath,\n getEnterpriseManagedSettingsPath,\n discoverProjects,\n ClaudeProject\n} from './claude-core';\n\n/**\n * Claude settings reader - Single source of truth for all settings\n * Reads from all locations and merges with correct precedence\n */\n\n/**\n * Hook configuration\n */\ninterface HookConfig {\n type: 'command';\n command: string;\n timeout?: number;\n}\n\n/**\n * Hook configuration with matcher\n */\ninterface HookConfigWithMatcher {\n matcher?: string;\n hooks: HookConfig[];\n}\n\n/**\n * Claude settings structure\n */\nexport interface ClaudeSettings {\n hooks?: {\n SessionStart?: HookConfigWithMatcher[];\n PreCompact?: HookConfigWithMatcher[];\n Stop?: HookConfigWithMatcher[]; // Legacy, kept for cleanup\n [key: string]: HookConfigWithMatcher[] | any;\n };\n [key: string]: any;\n}\n\n/**\n * Hook tracking mode\n */\nexport type HookMode = 'all' | 'selected' | 'none';\n\n/**\n * Project with hook status\n */\nexport interface ProjectWithHookStatus extends ClaudeProject {\n hasGlobalHooks: boolean;\n hasProjectHooks: boolean;\n hasLocalHooks: boolean;\n hasEffectiveHooks: boolean; // After merging all settings\n}\n\n/**\n * Read a settings file safely\n */\nasync function readSettingsFile(path: string): Promise<ClaudeSettings | null> {\n try {\n const data = await fs.readFile(path, 'utf-8');\n return JSON.parse(data);\n } catch (error) {\n // File not existing is normal, not an error\n if ((error as any).code !== 'ENOENT') {\n logger.debug(`Could not read settings from ${path}:`, error);\n }\n return null;\n }\n}\n\n/**\n * Read global Claude settings\n */\nexport async function readGlobalSettings(): Promise<ClaudeSettings | null> {\n return readSettingsFile(getGlobalSettingsPath());\n}\n\n/**\n * Read project-specific shared settings\n */\nexport async function readProjectSettings(projectPath: string): Promise<ClaudeSettings | null> {\n return readSettingsFile(getProjectSettingsPath(projectPath));\n}\n\n/**\n * Read project-specific local settings\n */\nexport async function readProjectLocalSettings(projectPath: string): Promise<ClaudeSettings | null> {\n return readSettingsFile(getProjectLocalSettingsPath(projectPath));\n}\n\n/**\n * Read enterprise managed settings\n */\nexport async function readEnterpriseManagedSettings(): Promise<ClaudeSettings | null> {\n const path = getEnterpriseManagedSettingsPath();\n if (!path) return null;\n return readSettingsFile(path);\n}\n\n/**\n * Merge settings with correct precedence\n * Higher precedence overrides lower:\n * 1. Enterprise managed (highest)\n * 2. Project local\n * 3. Project shared\n * 4. Global (lowest)\n */\nfunction mergeSettings(...settings: (ClaudeSettings | null)[]): ClaudeSettings {\n const result: ClaudeSettings = {};\n \n // Merge in order from lowest to highest precedence\n for (const setting of settings) {\n if (!setting) continue;\n \n // Deep merge\n for (const [key, value] of Object.entries(setting)) {\n if (key === 'hooks' && result.hooks) {\n // Special handling for hooks - merge hook configurations\n result.hooks = { ...result.hooks, ...value };\n } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n result[key] = { ...(result[key] || {}), ...value };\n } else {\n result[key] = value;\n }\n }\n }\n \n return result;\n}\n\n/**\n * Get merged settings for a specific project\n */\nexport async function getMergedSettingsForProject(projectPath: string): Promise<ClaudeSettings> {\n const global = await readGlobalSettings();\n const project = await readProjectSettings(projectPath);\n const local = await readProjectLocalSettings(projectPath);\n const enterprise = await readEnterpriseManagedSettings();\n \n // Merge in precedence order (lowest to highest)\n return mergeSettings(global, project, local, enterprise);\n}\n\n/**\n * Check if a command is a devark hook\n */\nfunction isDevArkCommand(command: string | undefined): boolean {\n if (!command) return false;\n return command.includes('devark') || command.includes('devark');\n}\n\n/**\n * Check if settings have devark hooks\n */\nexport function hasDevArkHooks(settings: ClaudeSettings | null): boolean {\n if (!settings?.hooks) return false;\n \n // Check SessionStart hooks\n if (settings.hooks.SessionStart) {\n for (const config of settings.hooks.SessionStart) {\n if (config.hooks.some(h => isDevArkCommand(h.command))) {\n return true;\n }\n }\n }\n \n // Check PreCompact hooks\n if (settings.hooks.PreCompact) {\n for (const config of settings.hooks.PreCompact) {\n if (config.hooks.some(h => isDevArkCommand(h.command))) {\n return true;\n }\n }\n }\n \n return false;\n}\n\n/**\n * Get the current hook tracking mode by checking global and project settings\n */\nexport async function getHookMode(): Promise<HookMode> {\n const global = await readGlobalSettings();\n \n // Check if global settings have devark hooks\n if (hasDevArkHooks(global)) {\n return 'all';\n }\n \n // Check if any project has local devark hooks\n const projects = await discoverProjects();\n for (const project of projects) {\n const localSettings = await readProjectLocalSettings(project.actualPath);\n if (hasDevArkHooks(localSettings)) {\n return 'selected';\n }\n }\n \n return 'none';\n}\n\n/**\n * Get list of projects that have devark hooks in their local settings\n */\nexport async function getTrackedProjects(): Promise<string[]> {\n const projects = await discoverProjects();\n const trackedProjects: string[] = [];\n \n for (const project of projects) {\n const localSettings = await readProjectLocalSettings(project.actualPath);\n if (hasDevArkHooks(localSettings)) {\n // Return the Claude folder name (e.g., \"-home-user-projects-devark\")\n trackedProjects.push(project.claudePath.split('/').pop() || project.claudePath);\n }\n }\n \n return trackedProjects;\n}\n\n/**\n * Get all projects with their hook status\n */\nexport async function getAllProjectsHookStatus(): Promise<ProjectWithHookStatus[]> {\n const projects = await discoverProjects();\n const mode = await getHookMode();\n const trackedProjects = mode === 'selected' ? await getTrackedProjects() : [];\n \n const projectsWithStatus: ProjectWithHookStatus[] = [];\n \n for (const project of projects) {\n const projectSettings = await readProjectSettings(project.actualPath);\n const localSettings = await readProjectLocalSettings(project.actualPath);\n const merged = await getMergedSettingsForProject(project.actualPath);\n \n const hasGlobalHooks = mode === 'all' || \n (mode === 'selected' && trackedProjects.includes(project.claudePath));\n const hasProjectHooks = hasDevArkHooks(projectSettings);\n const hasLocalHooks = hasDevArkHooks(localSettings);\n const hasEffectiveHooks = hasDevArkHooks(merged);\n \n projectsWithStatus.push({\n ...project,\n hasGlobalHooks,\n hasProjectHooks,\n hasLocalHooks,\n hasEffectiveHooks\n });\n }\n \n return projectsWithStatus;\n}\n\n/**\n * Get hook status for a specific project\n */\nexport async function getProjectHookStatus(projectPath: string): Promise<{\n hasGlobalHooks: boolean;\n hasProjectHooks: boolean;\n hasLocalHooks: boolean;\n hasEffectiveHooks: boolean;\n}> {\n const project = await readProjectSettings(projectPath);\n const local = await readProjectLocalSettings(projectPath);\n const merged = await getMergedSettingsForProject(projectPath);\n \n const mode = await getHookMode();\n const trackedProjects = mode === 'selected' ? await getTrackedProjects() : [];\n \n // Check if this project is tracked globally\n const hasGlobalHooks = mode === 'all' || \n (mode === 'selected' && trackedProjects.some(p => projectPath.includes(p)));\n \n return {\n hasGlobalHooks,\n hasProjectHooks: hasDevArkHooks(project),\n hasLocalHooks: hasDevArkHooks(local),\n hasEffectiveHooks: hasDevArkHooks(merged)\n };\n}\n\n/**\n * Write settings to global location\n */\nexport async function writeGlobalSettings(settings: ClaudeSettings): Promise<void> {\n const settingsPath = getGlobalSettingsPath();\n const tempPath = `${settingsPath}.tmp`;\n \n await fs.writeFile(tempPath, JSON.stringify(settings, null, 2));\n await fs.rename(tempPath, settingsPath);\n \n logger.debug(`Global settings written to ${settingsPath}`);\n}","/**\n * Unified Claude Settings Manager\n * \n * Single source of truth for ALL devark modifications to Claude settings.\n * Manages hooks and UI configurations as feature units to ensure consistency\n * and prevent conflicts or duplicates.\n */\n\nimport { \n readGlobalSettings, \n writeGlobalSettings,\n readProjectLocalSettings,\n ClaudeSettings\n} from './claude-settings-reader';\nimport { getCliPath, saveStatusLineBackup, getStatusLineBackup, clearStatusLineBackup } from './config';\nimport { logger } from '../utils/logger';\n\n/**\n * Feature status information\n */\nexport interface StatusLineFeatureStatus {\n installed: boolean;\n hookInstalled: boolean;\n displayInstalled: boolean;\n isComplete: boolean;\n cliPath?: string;\n}\n\nexport interface AutoSyncFeatureStatus {\n sessionStartInstalled: boolean;\n preCompactInstalled: boolean;\n sessionEndInstalled: boolean;\n mode?: 'all' | 'selected';\n trackedProjects?: string[];\n}\n\nexport interface FeatureStatus {\n statusLine: StatusLineFeatureStatus;\n autoSync: AutoSyncFeatureStatus;\n}\n\n/**\n * Configuration for installing features\n */\nexport interface StatusLineConfig {\n cliPath?: string; // Optional, will use default if not provided\n}\n\nexport interface AutoSyncConfig {\n installSessionStart?: boolean;\n installPreCompact?: boolean;\n mode?: 'all' | 'selected';\n projectPath?: string; // For project-specific installation\n cliPath?: string;\n}\n\n/**\n * Centralized manager for all devark Claude settings modifications\n */\nexport class ClaudeSettingsManager {\n \n /**\n * Core detection logic - CRITICAL for preventing duplicates\n * This must detect ALL devark related commands regardless of CLI path format\n * Currently not used but kept for future reference\n */\n /*\n private isDevArkCommand(command: string | undefined): boolean {\n if (!command) return false;\n \n // Robust detection that works with any CLI path format\n // These patterns identify devark commands regardless of how they're invoked\n const devarkIndicators = [\n 'analyze-prompt', // Status line analysis hook\n 'statusline', // Status line display command\n 'send --silent', // Auto-sync hooks\n 'send --background', // Auto-sync hooks\n '--hook-trigger', // Auto-sync hook marker\n 'devark', // Generic devark commands\n 'devark-cli', // NPX package name\n '@devark' // Possible future package scope\n ];\n \n return devarkIndicators.some(indicator => command.includes(indicator));\n }\n */\n \n /**\n * Check if a command is specifically the analyze-prompt hook\n */\n private isAnalyzePromptCommand(command: string | undefined): boolean {\n if (!command) return false;\n \n // Get the configured CLI path to match exactly what we installed\n const cliPath = getCliPath();\n const expectedPrefix = `${cliPath} analyze-prompt`;\n \n // Must be our exact command pattern\n return command.startsWith(expectedPrefix) && \n command.includes('--silent') && \n command.includes('--stdin');\n }\n \n /**\n * Check if a command is specifically the statusline display command\n */\n private isStatuslineCommand(command: string | undefined): boolean {\n if (!command) return false;\n\n // Get the configured CLI path to match exactly what we installed\n const cliPath = getCliPath();\n\n // Our statusline command is exactly: [cliPath] statusline [options]\n // Check if command starts with our CLI path and has statusline as the command\n const expectedPrefix = `${cliPath} statusline`;\n\n // Must match our exact pattern (with or without options like --with-usage)\n return command === expectedPrefix || command.startsWith(`${expectedPrefix} `);\n }\n\n /**\n * Check if a command is an auto-sync hook (SessionStart or PreCompact)\n */\n private isAutoSyncCommand(command: string | undefined): boolean {\n if (!command) return false;\n \n // Get the configured CLI path to match exactly what we installed\n const cliPath = getCliPath();\n const expectedPrefix = `${cliPath} send`;\n \n // Must be our exact command pattern for auto-sync\n return command.startsWith(expectedPrefix) && \n command.includes('--silent') && \n command.includes('--background') &&\n command.includes('--hook-trigger');\n }\n \n /**\n * Install the Status Line feature (UserPromptSubmit hook + statusLine display)\n * These must be installed together as they're useless separately\n */\n async installStatusLineFeature(config?: StatusLineConfig): Promise<void> {\n logger.debug('Installing status line feature');\n \n const cliPath = config?.cliPath || getCliPath();\n const settings = await readGlobalSettings() || { hooks: {} };\n \n // 1. Check for existing non-devark status line and backup if found\n const existingStatusLine = this.detectExistingStatusLine(settings);\n if (existingStatusLine) {\n logger.debug('Backing up existing status line:', existingStatusLine);\n saveStatusLineBackup({\n originalCommand: existingStatusLine.command,\n originalType: existingStatusLine.type,\n originalPadding: existingStatusLine.padding,\n backupReason: 'Replaced by devark status line'\n });\n }\n \n // 2. Remove any existing status line components to prevent duplicates\n this.removeStatusLineComponents(settings);\n \n // 3. Install UserPromptSubmit hook for analysis\n if (!settings.hooks) settings.hooks = {};\n if (!settings.hooks.UserPromptSubmit) settings.hooks.UserPromptSubmit = [];\n \n const analyzeCommand = `${cliPath} analyze-prompt --silent --stdin`;\n \n // Check if there's already a UserPromptSubmit config with hooks array\n if (settings.hooks.UserPromptSubmit.length > 0 && settings.hooks.UserPromptSubmit[0].hooks) {\n // Append to existing hooks array\n settings.hooks.UserPromptSubmit[0].hooks.push({\n type: 'command',\n command: analyzeCommand\n });\n } else {\n // Create new config with hooks array\n settings.hooks.UserPromptSubmit.push({\n hooks: [{\n type: 'command',\n command: analyzeCommand\n }]\n });\n }\n \n logger.debug(`Added UserPromptSubmit hook: ${analyzeCommand}`);\n \n // 4. Install statusLine display configuration\n const statuslineCommand = `${cliPath} statusline`;\n settings.statusLine = {\n type: 'command',\n command: statuslineCommand,\n padding: 0\n };\n \n logger.debug(`Added statusLine config: ${statuslineCommand}`);\n \n // 5. Save settings\n await writeGlobalSettings(settings);\n logger.debug('Status line feature installed successfully');\n }\n \n /**\n * Remove the Status Line feature completely\n * @param restoreBackup - Whether to restore the backed up status line\n */\n async removeStatusLineFeature(restoreBackup: boolean = false): Promise<void> {\n logger.debug('Removing status line feature');\n\n const settings = await readGlobalSettings();\n if (!settings) return;\n\n this.removeStatusLineComponents(settings);\n\n // Check if we should restore a backed up status line\n if (restoreBackup) {\n const backup = getStatusLineBackup();\n if (backup && backup.originalCommand) {\n logger.debug('Restoring backed up status line:', backup);\n settings.statusLine = {\n type: backup.originalType || 'command',\n command: backup.originalCommand,\n padding: backup.originalPadding !== undefined ? backup.originalPadding : 0\n };\n clearStatusLineBackup(); // Clear the backup after restoring\n }\n }\n\n await writeGlobalSettings(settings);\n logger.debug('Status line feature removed successfully');\n }\n\n /**\n * Helper to remove status line components from settings object\n */\n private removeStatusLineComponents(settings: ClaudeSettings): void {\n // Remove UserPromptSubmit hooks that are devark analyze-prompt\n if (settings.hooks?.UserPromptSubmit) {\n settings.hooks.UserPromptSubmit = settings.hooks.UserPromptSubmit.filter((config: any) => {\n if (!config.hooks) return true; // Keep configs without hooks array\n\n // Filter out devark analyze-prompt hooks\n config.hooks = config.hooks.filter((hook: any) =>\n !this.isAnalyzePromptCommand(hook.command)\n );\n\n // Keep config only if it still has hooks\n return config.hooks.length > 0;\n });\n\n // Remove UserPromptSubmit entirely if empty\n if (settings.hooks.UserPromptSubmit.length === 0) {\n delete settings.hooks.UserPromptSubmit;\n }\n }\n\n // Remove statusLine display if it's ours\n if (settings.statusLine?.command && this.isStatuslineCommand(settings.statusLine.command)) {\n delete settings.statusLine;\n }\n }\n\n /**\n * Install Auto-Sync hooks (SessionStart and/or PreCompact)\n */\n async installAutoSyncHooks(config: AutoSyncConfig): Promise<void> {\n logger.debug(`Installing auto-sync hooks: ${JSON.stringify(config)}`);\n \n const cliPath = config.cliPath || getCliPath();\n \n // Determine target settings (global or project)\n let settings: ClaudeSettings | null;\n if (config.projectPath && config.mode === 'selected') {\n settings = await readProjectLocalSettings(config.projectPath) || { hooks: {} };\n } else {\n settings = await readGlobalSettings() || { hooks: {} };\n }\n \n if (!settings.hooks) settings.hooks = {};\n \n // Install SessionStart hook if requested\n if (config.installSessionStart) {\n if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];\n\n // Remove existing devark SessionStart hooks\n this.removeAutoSyncHook(settings, 'SessionStart');\n\n // Re-initialize if removed (removeAutoSyncHook deletes empty arrays)\n if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];\n\n const command = this.buildAutoSyncCommand(cliPath, 'sessionstart', config.mode);\n settings.hooks.SessionStart.push({\n matcher: 'startup|clear',\n hooks: [{\n type: 'command',\n command\n }]\n });\n\n logger.debug(`Added SessionStart hook: ${command}`);\n }\n \n // Install PreCompact hook if requested\n if (config.installPreCompact) {\n if (!settings.hooks.PreCompact) settings.hooks.PreCompact = [];\n\n // Remove existing devark PreCompact hooks\n this.removeAutoSyncHook(settings, 'PreCompact');\n\n // Re-initialize if removed (removeAutoSyncHook deletes empty arrays)\n if (!settings.hooks.PreCompact) settings.hooks.PreCompact = [];\n\n const command = this.buildAutoSyncCommand(cliPath, 'precompact', config.mode);\n settings.hooks.PreCompact.push({\n matcher: 'auto',\n hooks: [{\n type: 'command',\n command\n }]\n });\n\n logger.debug(`Added PreCompact hook: ${command}`);\n }\n \n // Save to appropriate location\n if (config.projectPath && config.mode === 'selected') {\n // For project-specific settings, we need to write to the project's local settings file\n // Since writeProjectLocalSettings doesn't exist, we'll use writeGlobalSettings for now\n // TODO: Implement project-specific settings writing when needed\n logger.warn('Project-specific hooks not fully implemented yet');\n await writeGlobalSettings(settings);\n } else {\n await writeGlobalSettings(settings);\n }\n \n logger.debug('Auto-sync hooks installed successfully');\n }\n \n /**\n * Build auto-sync command string\n */\n private buildAutoSyncCommand(cliPath: string, trigger: string, mode?: 'all' | 'selected'): string {\n if (mode === 'all') {\n return `${cliPath} send --silent --background --hook-trigger=${trigger} --hook-version=2.0.0 --all`;\n }\n // Default or selected mode uses project directory variable\n return `${cliPath} send --silent --background --hook-trigger=${trigger} --hook-version=2.0.0 --claude-project-dir=\"$CLAUDE_PROJECT_DIR\"`;\n }\n \n /**\n * Remove specific auto-sync hook type\n */\n private removeAutoSyncHook(settings: ClaudeSettings, type: 'SessionStart' | 'PreCompact'): void {\n const hooks = settings.hooks?.[type];\n if (!hooks) return;\n \n // Filter out devark auto-sync hooks\n settings.hooks![type] = hooks.filter(config => {\n if (!config.hooks) return true;\n \n config.hooks = config.hooks.filter(hook => \n !this.isAutoSyncCommand(hook.command)\n );\n \n return config.hooks.length > 0;\n });\n \n // Remove entirely if empty\n if (settings.hooks![type]!.length === 0) {\n delete settings.hooks![type];\n }\n }\n \n /**\n * Remove ALL devark hooks and configurations\n */\n async removeAllDevArkSettings(): Promise<void> {\n logger.debug('Removing all devark settings');\n \n const settings = await readGlobalSettings();\n if (!settings) return;\n \n // Remove status line components\n this.removeStatusLineComponents(settings);\n \n // Remove auto-sync hooks\n this.removeAutoSyncHook(settings, 'SessionStart');\n this.removeAutoSyncHook(settings, 'PreCompact');\n \n await writeGlobalSettings(settings);\n logger.debug('All devark settings removed successfully');\n }\n \n /**\n * Get comprehensive status of all devark features\n */\n async getFeatureStatus(): Promise<FeatureStatus> {\n const settings = await readGlobalSettings();\n \n return {\n statusLine: this.getStatusLineStatus(settings),\n autoSync: this.getAutoSyncStatus(settings)\n };\n }\n \n /**\n * Get status line feature status\n */\n private getStatusLineStatus(settings: ClaudeSettings | null): StatusLineFeatureStatus {\n const hookInstalled = this.hasAnalyzePromptHook(settings);\n const displayInstalled = this.hasStatusLineDisplay(settings);\n \n return {\n installed: hookInstalled && displayInstalled,\n hookInstalled,\n displayInstalled,\n isComplete: hookInstalled && displayInstalled,\n cliPath: this.extractCliPath(settings)\n };\n }\n \n /**\n * Get auto-sync feature status\n */\n private getAutoSyncStatus(settings: ClaudeSettings | null): AutoSyncFeatureStatus {\n return {\n sessionStartInstalled: this.hasSessionStartHook(settings),\n preCompactInstalled: this.hasPreCompactHook(settings),\n sessionEndInstalled: this.hasSessionEndHook(settings),\n mode: this.detectAutoSyncMode(settings)\n };\n }\n \n /**\n * Check if analyze-prompt hook is installed\n */\n private hasAnalyzePromptHook(settings: ClaudeSettings | null): boolean {\n if (!settings?.hooks?.UserPromptSubmit) return false;\n \n return settings.hooks.UserPromptSubmit.some((config: any) =>\n config.hooks?.some((hook: any) => this.isAnalyzePromptCommand(hook.command))\n );\n }\n \n /**\n * Check if statusLine display is configured\n */\n private hasStatusLineDisplay(settings: ClaudeSettings | null): boolean {\n return !!(settings?.statusLine?.command && \n this.isStatuslineCommand(settings.statusLine.command));\n }\n \n /**\n * Detect existing non-devark status line configuration\n * Returns the existing configuration if found, null otherwise\n */\n detectExistingStatusLine(settings: ClaudeSettings | null): {\n command?: string;\n type?: string;\n padding?: number;\n } | null {\n // Check if there's a statusLine configured\n if (!settings?.statusLine) return null;\n \n // Check if it's NOT a devark status line\n if (this.isStatuslineCommand(settings.statusLine.command)) {\n return null; // It's our own status line, not a third-party one\n }\n \n // Return the existing third-party status line configuration\n return {\n command: settings.statusLine.command,\n type: settings.statusLine.type || 'command',\n padding: settings.statusLine.padding\n };\n }\n \n /**\n * Check if SessionStart hook is installed\n */\n private hasSessionStartHook(settings: ClaudeSettings | null): boolean {\n if (!settings?.hooks?.SessionStart) return false;\n \n return settings.hooks.SessionStart.some(config =>\n config.hooks?.some(hook => this.isAutoSyncCommand(hook.command))\n );\n }\n \n /**\n * Check if PreCompact hook is installed\n */\n private hasPreCompactHook(settings: ClaudeSettings | null): boolean {\n if (!settings?.hooks?.PreCompact) return false;\n\n return settings.hooks.PreCompact.some(config =>\n config.hooks?.some(hook => this.isAutoSyncCommand(hook.command))\n );\n }\n\n /**\n * Check if SessionEnd hook is installed\n */\n private hasSessionEndHook(settings: ClaudeSettings | null): boolean {\n if (!settings?.hooks?.SessionEnd) return false;\n\n return settings.hooks.SessionEnd.some((config: any) =>\n config.hooks?.some((hook: any) => this.isAutoSyncCommand(hook.command))\n );\n }\n\n /**\n * Detect auto-sync mode from hook commands\n */\n private detectAutoSyncMode(settings: ClaudeSettings | null): 'all' | 'selected' | undefined {\n const hooks = [\n ...(settings?.hooks?.SessionStart || []),\n ...(settings?.hooks?.PreCompact || [])\n ];\n \n for (const config of hooks) {\n for (const hook of config.hooks || []) {\n if (hook.command?.includes('--all')) return 'all';\n if (hook.command?.includes('--claude-project-dir')) return 'selected';\n }\n }\n \n return undefined;\n }\n \n /**\n * Extract CLI path from existing commands\n */\n private extractCliPath(settings: ClaudeSettings | null): string | undefined {\n // Try to extract from statusLine command\n if (settings?.statusLine?.command) {\n const match = settings.statusLine.command.match(/^(.*?) statusline/);\n if (match) return match[1];\n }\n \n // Try UserPromptSubmit hooks\n if (settings?.hooks?.UserPromptSubmit) {\n for (const config of settings.hooks.UserPromptSubmit) {\n for (const hook of config.hooks || []) {\n if (hook.command?.includes('analyze-prompt')) {\n const match = hook.command.match(/^(.*?) analyze-prompt/);\n if (match) return match[1];\n }\n }\n }\n }\n \n return undefined;\n }\n \n /**\n * Update CLI path for all devark commands\n * Useful when switching between development and production\n */\n async updateCliPath(newCliPath: string): Promise<void> {\n logger.debug(`Updating CLI path for all devark commands: ${newCliPath}`);\n \n const settings = await readGlobalSettings();\n if (!settings) return;\n \n // Update UserPromptSubmit hooks\n if (settings.hooks?.UserPromptSubmit) {\n for (const config of settings.hooks.UserPromptSubmit) {\n for (const hook of config.hooks || []) {\n if (this.isAnalyzePromptCommand(hook.command)) {\n hook.command = `${newCliPath} analyze-prompt --silent --stdin`;\n }\n }\n }\n }\n \n // Update statusLine\n if (settings.statusLine?.command && this.isStatuslineCommand(settings.statusLine.command)) {\n settings.statusLine.command = `${newCliPath} statusline`;\n }\n \n // Update SessionStart hooks\n if (settings.hooks?.SessionStart) {\n for (const config of settings.hooks.SessionStart) {\n for (const hook of config.hooks || []) {\n if (this.isAutoSyncCommand(hook.command)) {\n const mode = hook.command.includes('--all') ? 'all' : 'selected';\n hook.command = this.buildAutoSyncCommand(newCliPath, 'sessionstart', mode);\n }\n }\n }\n }\n \n // Update PreCompact hooks\n if (settings.hooks?.PreCompact) {\n for (const config of settings.hooks.PreCompact) {\n for (const hook of config.hooks || []) {\n if (this.isAutoSyncCommand(hook.command)) {\n const mode = hook.command.includes('--all') ? 'all' : 'selected';\n hook.command = this.buildAutoSyncCommand(newCliPath, 'precompact', mode);\n }\n }\n }\n }\n \n await writeGlobalSettings(settings);\n logger.debug('CLI path updated successfully');\n }\n}\n\n// Export singleton instance\nexport const claudeSettingsManager = new ClaudeSettingsManager();","/**\n * List of devark sub-agents for Claude Code\n * These sub-agents are installed to ~/.claude/agents/ for local analysis\n * Streamlined to 2 essential agents for fast, focused reports\n */\nexport const DEVARK_SUB_AGENTS = [\n 'devark-session-analyzer.md',\n 'devark-report-generator.md'\n] as const;\n\nexport type SubAgentName = typeof DEVARK_SUB_AGENTS[number];","/**\n * Status Line Manager - Simplified wrapper around Claude Settings Manager\n * \n * This module now delegates all actual settings manipulation to the \n * unified ClaudeSettingsManager to prevent conflicts and duplicates.\n */\n\nimport { claudeSettingsManager, StatusLineFeatureStatus } from './claude-settings-manager';\nimport { getCliPath, getStatusLineBackup } from './config';\nimport { logger } from '../utils/logger';\n\n/**\n * Status Line installation status\n */\nexport type StatusLineStatus = 'not-installed' | 'partial' | 'installed';\n\n/**\n * Get the current status of the status line feature\n */\nexport async function getStatusLineStatus(): Promise<StatusLineStatus> {\n try {\n const status = await claudeSettingsManager.getFeatureStatus();\n const statusLine = status.statusLine;\n \n if (!statusLine.hookInstalled && !statusLine.displayInstalled) {\n return 'not-installed';\n }\n \n if (statusLine.isComplete) {\n return 'installed';\n }\n \n return 'partial';\n } catch (error) {\n logger.error('Error getting status line status:', error);\n return 'not-installed';\n }\n}\n\n/**\n * Get detailed status line information\n */\nexport async function getStatusLineInfo(): Promise<StatusLineFeatureStatus> {\n const status = await claudeSettingsManager.getFeatureStatus();\n return status.statusLine;\n}\n\n/**\n * Install the status line feature\n * Installs both UserPromptSubmit hook and statusLine display together\n */\nexport async function installStatusLine(cliPath?: string): Promise<void> {\n try {\n const finalCliPath = cliPath || getCliPath();\n logger.debug(`Installing status line with CLI path: ${finalCliPath}`);\n \n await claudeSettingsManager.installStatusLineFeature({ cliPath: finalCliPath });\n } catch (error) {\n logger.error('Error installing status line:', error);\n throw new Error(`Failed to install status line: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Uninstall the status line feature\n * Removes both UserPromptSubmit hook and statusLine display\n * @param restoreBackup - Whether to restore the backed up status line\n */\nexport async function uninstallStatusLine(restoreBackup: boolean = false): Promise<void> {\n try {\n logger.debug(`Uninstalling status line${restoreBackup ? ' (with restore)' : ''}`);\n \n await claudeSettingsManager.removeStatusLineFeature(restoreBackup);\n } catch (error) {\n logger.error('Error uninstalling status line:', error);\n throw new Error(`Failed to uninstall status line: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Update CLI path for all status line commands\n */\nexport async function updateStatusLineCliPath(newCliPath: string): Promise<void> {\n try {\n logger.debug(`Updating status line CLI path: ${newCliPath}`);\n \n await claudeSettingsManager.updateCliPath(newCliPath);\n } catch (error) {\n logger.error('Error updating status line CLI path:', error);\n throw new Error(`Failed to update CLI path: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Build the analyze-prompt hook command\n * @deprecated Use installStatusLine instead\n */\nexport function buildAnalyzePromptCommand(): string {\n const cliPath = getCliPath();\n return `${cliPath} analyze-prompt --silent --stdin`;\n}\n\n/**\n * Build the statusline display command\n * @deprecated Use installStatusLine instead\n */\nexport function buildStatuslineCommand(): string {\n const cliPath = getCliPath();\n return `${cliPath} statusline`;\n}\n\n/**\n * Check if there's a backup of a previous status line\n */\nexport function hasStatusLineBackup(): boolean {\n const backup = getStatusLineBackup();\n return !!(backup && backup.originalCommand);\n}\n\n/**\n * Get details about the backed up status line\n */\nexport function getBackupDetails(): { command?: string; date?: string } | null {\n const backup = getStatusLineBackup();\n if (!backup || !backup.originalCommand) return null;\n \n return {\n command: backup.originalCommand,\n date: backup.backupDate\n };\n}\n\n/**\n * Check for existing non-devark status line\n */\nexport async function detectExistingStatusLine(): Promise<{\n command?: string;\n type?: string;\n padding?: number;\n} | null> {\n try {\n const { readGlobalSettings } = await import('./claude-settings-reader');\n const settings = await readGlobalSettings();\n return claudeSettingsManager.detectExistingStatusLine(settings);\n } catch (error) {\n logger.error('Error detecting existing status line:', error);\n return null;\n }\n}","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport { getAllConfig, getToken as getConfigToken, getLastSyncSummary, getDashboardUrl } from './config';\nimport { logger } from '../utils/logger';\nimport { DEVARK_SUB_AGENTS } from './sub-agents/constants';\nimport { getHookMode, getTrackedProjects as getHookTrackedProjects } from './claude-settings-reader';\nimport { getStatusLineStatus, StatusLineStatus } from './status-line-manager';\n\nexport type SetupState =\n | 'FIRST_TIME' // No configuration exists\n | 'LOCAL_ONLY' // Sub-agents installed, no cloud\n | 'CLOUD_AUTO' // Cloud + hooks installed\n | 'CLOUD_MANUAL' // Cloud without hooks\n | 'CLOUD_ONLY' // Cloud, no local sub-agents\n | 'PARTIAL_SETUP' // Some components missing\n | 'ERROR'; // Error detecting state\n\nexport interface StateDetails {\n state: SetupState;\n hasConfig: boolean;\n hasAuth: boolean;\n hasAgents: boolean;\n agentCount: number;\n totalAgents: number;\n hasHooks: boolean;\n hasStatusLine: boolean;\n statusLineStatus: StatusLineStatus;\n cloudUrl?: string;\n lastSync?: Date;\n lastSyncProject?: string;\n projectCount?: number;\n sessionCount?: number;\n trackingMode: 'all' | 'selected' | 'none';\n trackedProjectCount: number;\n trackedProjectNames?: string[];\n errors: string[];\n}\n\nexport async function detectSetupState(): Promise<StateDetails> {\n const errors: string[] = [];\n const details: StateDetails = {\n state: 'FIRST_TIME',\n hasConfig: false,\n hasAuth: false,\n hasAgents: false,\n agentCount: 0,\n totalAgents: DEVARK_SUB_AGENTS.length,\n hasHooks: false,\n hasStatusLine: false,\n statusLineStatus: 'not-installed',\n trackingMode: 'none',\n trackedProjectCount: 0,\n errors\n };\n\n try {\n // Check for config\n const config = getAllConfig();\n details.hasConfig = Object.keys(config).length > 0;\n\n // Check for authentication\n try {\n const token = await getConfigToken();\n details.hasAuth = !!token;\n details.cloudUrl = getDashboardUrl();\n \n if (config.lastSync) {\n details.lastSync = new Date(config.lastSync);\n }\n \n // Get last sync summary for display\n const syncSummary = getLastSyncSummary();\n if (syncSummary) {\n details.lastSyncProject = syncSummary.description;\n }\n } catch {\n details.hasAuth = false;\n }\n\n // Check for sub-agents\n const agentsPath = path.join(os.homedir(), '.claude', 'agents');\n try {\n await fs.access(agentsPath);\n const files = await fs.readdir(agentsPath);\n const installedAgents = files.filter(f => \n DEVARK_SUB_AGENTS.includes(f as any) && f.endsWith('.md')\n );\n details.agentCount = installedAgents.length;\n details.hasAgents = installedAgents.length > 0;\n } catch {\n details.hasAgents = false;\n details.agentCount = 0;\n }\n\n // Check for hooks and tracking mode using the claude-settings-reader (single source of truth)\n try {\n const hookMode = await getHookMode();\n details.hasHooks = hookMode === 'all' || hookMode === 'selected';\n details.trackingMode = hookMode;\n \n // Get tracked projects based on hook mode\n if (hookMode === 'selected') {\n const trackedProjects = await getHookTrackedProjects();\n details.trackedProjectCount = trackedProjects.length;\n // Only store names for display if there are a reasonable number\n if (trackedProjects.length <= 10) {\n details.trackedProjectNames = trackedProjects;\n }\n } else if (hookMode === 'all') {\n // For 'all' mode, count is the total number of projects\n // We'll count them below\n } else {\n // For 'none' mode, count is 0\n details.trackedProjectCount = 0;\n }\n } catch (error) {\n logger.debug('Error checking hooks installation:', error);\n details.hasHooks = false;\n details.trackingMode = 'none';\n details.trackedProjectCount = 0;\n }\n\n // Check for status-line installation\n try {\n const statusLineStatus = await getStatusLineStatus();\n details.statusLineStatus = statusLineStatus;\n details.hasStatusLine = statusLineStatus === 'installed';\n } catch (error) {\n logger.debug('Error checking status-line installation:', error);\n details.statusLineStatus = 'not-installed';\n details.hasStatusLine = false;\n }\n\n // Check for Claude Code projects\n const projectsPath = path.join(os.homedir(), '.claude', 'projects');\n try {\n await fs.access(projectsPath);\n const projects = await fs.readdir(projectsPath);\n details.projectCount = projects.filter(async p => {\n const stat = await fs.stat(path.join(projectsPath, p));\n return stat.isDirectory();\n }).length;\n \n // If tracking mode is 'all', set tracked count to total project count\n if (details.trackingMode === 'all') {\n details.trackedProjectCount = details.projectCount || 0;\n }\n } catch {\n details.projectCount = 0;\n if (details.trackingMode === 'all') {\n details.trackedProjectCount = 0;\n }\n }\n\n // Determine state based on what's installed\n if (!details.hasConfig && !details.hasAuth && !details.hasAgents) {\n details.state = 'FIRST_TIME';\n } else if (details.hasAuth && details.hasHooks && details.hasAgents) {\n details.state = 'CLOUD_AUTO';\n } else if (details.hasAuth && !details.hasHooks && details.hasAgents) {\n details.state = 'CLOUD_MANUAL';\n } else if (details.hasAuth && !details.hasAgents) {\n details.state = 'CLOUD_ONLY';\n } else if (!details.hasAuth && details.hasAgents) {\n details.state = 'LOCAL_ONLY';\n } else {\n details.state = 'PARTIAL_SETUP';\n }\n\n // Add warnings for partial setups\n if (details.hasAgents && details.agentCount < details.totalAgents) {\n errors.push(`Only ${details.agentCount}/${details.totalAgents} sub-agents installed`);\n }\n\n } catch (error) {\n logger.error('Error detecting setup state:', error);\n details.state = 'ERROR';\n errors.push(error instanceof Error ? error.message : 'Unknown error');\n }\n\n return details;\n}\n\nexport async function checkClaudeCodeInstalled(): Promise<boolean> {\n const claudePath = path.join(os.homedir(), '.claude');\n try {\n await fs.access(claudePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function checkProjectDirectory(): Promise<string | null> {\n try {\n const cwd = process.cwd();\n // Check if we're in a git repo or project directory\n const gitPath = path.join(cwd, '.git');\n try {\n await fs.access(gitPath);\n return cwd;\n } catch {\n // Not a git repo, but still could be a project\n return cwd;\n }\n } catch {\n return null;\n }\n}","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { logger } from '../../utils/logger';\nimport { getCliPath } from '../config';\nimport { getGlobalSettingsPath, getProjectLocalSettingsPath } from '../claude-core';\nimport { sendTelemetryUpdate } from '../telemetry';\nimport { \n readGlobalSettings, \n writeGlobalSettings,\n getHookMode as getHookModeFromReader,\n getTrackedProjects as getTrackedProjectsFromReader,\n ClaudeSettings\n} from '../claude-settings-reader';\n\n/**\n * Hook selection configuration\n */\nexport interface HookSelection {\n sessionStartHook: boolean;\n preCompactHook: boolean;\n sessionEndHook: boolean;\n}\n\n/**\n * Individual hook configuration\n */\nexport interface HookConfig {\n type: 'command';\n command: string;\n timeout?: number;\n}\n\n/**\n * Hook configuration with matcher\n */\nexport interface HookConfigWithMatcher {\n matcher?: string;\n hooks: HookConfig[];\n}\n\n/**\n * Hook status information\n */\nexport interface HookStatusInfo {\n installed: boolean;\n enabled: boolean;\n version: string;\n command?: string;\n timeout?: number;\n lastModified?: Date;\n}\n\n/**\n * Complete hooks status\n */\nexport interface HooksStatus {\n sessionStartHook: HookStatusInfo;\n preCompactHook: HookStatusInfo;\n sessionEndHook: HookStatusInfo;\n settingsPath: string;\n cliPath: string;\n trackedProjects?: string[]; // List of project paths being tracked\n}\n\n/**\n * Re-export HookMode from claude-settings-reader\n */\nexport type { HookMode } from '../claude-settings-reader';\n\n// Current version of hooks\nconst HOOKS_VERSION = '1.0.0';\n\n// Hook matcher configurations\nconst HOOK_MATCHERS = {\n SessionStart: 'startup|clear', // Capture on startup and clear (not resume)\n PreCompact: 'auto', // Only automatic compression (not manual)\n SessionEnd: 'clear|logout|prompt_input_exit|other' // Capture on session end events\n} as const;\n\n/**\n * Check if a command is a devark hook command\n * Matches both 'devark' and '@devark' patterns\n */\nexport function isDevArkCommand(command: string | undefined): boolean {\n if (!command) return false;\n return command.includes('devark') || command.includes('@devark');\n}\n\n/**\n * Read Claude settings (delegate to claude-settings-reader)\n */\nasync function readSettings(): Promise<ClaudeSettings | null> {\n return readGlobalSettings();\n}\n\n/**\n * Write Claude settings (delegate to claude-settings-reader)\n */\nasync function writeSettings(settings: ClaudeSettings): Promise<void> {\n await writeGlobalSettings(settings);\n}\n\n/**\n * Get hook status info for a specific hook\n */\nfunction getHookStatusInfo(hookConfig: HookConfigWithMatcher[] | undefined): HookStatusInfo {\n if (!hookConfig || hookConfig.length === 0) {\n return {\n installed: false,\n enabled: false,\n version: '0.0.0'\n };\n }\n \n const hook = hookConfig[0]?.hooks?.[0];\n if (!hook) {\n return {\n installed: false,\n enabled: false,\n version: '0.0.0'\n };\n }\n \n // Check if it's a devark hook\n if (!isDevArkCommand(hook.command)) {\n return {\n installed: false,\n enabled: false,\n version: '0.0.0'\n };\n }\n \n // Extract version from command if present\n const versionMatch = hook.command.match(/--hook-version=([0-9.]+)/);\n const version = versionMatch ? versionMatch[1] : HOOKS_VERSION;\n \n return {\n installed: true,\n enabled: !hook.command.includes('--disabled'),\n version,\n command: hook.command,\n timeout: hook.timeout\n };\n}\n\n/**\n * Get comprehensive hooks status\n */\nexport async function getHooksStatus(): Promise<HooksStatus> {\n const settings = await readSettings();\n const settingsPath = getGlobalSettingsPath();\n const cliPath = getCliPath();\n\n const sessionStartHook = getHookStatusInfo(settings?.hooks?.SessionStart);\n const preCompactHook = getHookStatusInfo(settings?.hooks?.PreCompact);\n const sessionEndHook = getHookStatusInfo(settings?.hooks?.SessionEnd);\n\n // Get file stats for last modified\n try {\n const stats = await fs.stat(settingsPath);\n sessionStartHook.lastModified = stats.mtime;\n preCompactHook.lastModified = stats.mtime;\n sessionEndHook.lastModified = stats.mtime;\n } catch (error) {\n logger.debug('Could not get settings file stats:', error);\n }\n\n // Get tracked projects from claude-settings-reader\n const mode = await getHookModeFromReader();\n const trackedProjects = mode === 'selected' ? await getTrackedProjectsFromReader() : undefined;\n\n return {\n sessionStartHook,\n preCompactHook,\n sessionEndHook,\n settingsPath,\n cliPath,\n trackedProjects\n };\n}\n\n/**\n * Build hook command string with given trigger type\n */\nexport function buildHookCommand(\n cliPath: string,\n hookTrigger: 'sessionstart' | 'precompact' | 'sessionend',\n mode?: 'all' | 'selected'\n): string {\n // For global mode (track all), use --all flag instead of --claude-project-dir\n if (mode === 'all') {\n return `${cliPath} send --silent --background --hook-trigger=${hookTrigger} --hook-version=${HOOKS_VERSION} --all`;\n }\n \n // For selected mode or backward compatibility, use --claude-project-dir\n return `${cliPath} send --silent --background --hook-trigger=${hookTrigger} --hook-version=${HOOKS_VERSION} --claude-project-dir=\"$CLAUDE_PROJECT_DIR\"`;\n}\n\n/**\n * Hook definition for configuration\n */\ninterface HookDefinition {\n type: 'SessionStart' | 'PreCompact' | 'SessionEnd';\n enabled: boolean;\n}\n\n/**\n * Build hook configuration for a specific hook type\n * NOTE: This function is kept for future use but currently replaced by appendHookConfiguration\n * @deprecated Use appendHookConfiguration instead\n */\nfunction buildHookConfiguration(\n hookType: 'SessionStart' | 'PreCompact' | 'SessionEnd',\n cliPath: string,\n mode?: 'all' | 'selected'\n): HookConfigWithMatcher[] {\n const triggerType = hookType === 'SessionStart' ? 'sessionstart' :\n hookType === 'PreCompact' ? 'precompact' : 'sessionend';\n return [{\n matcher: HOOK_MATCHERS[hookType],\n hooks: [{\n type: 'command',\n command: buildHookCommand(cliPath, triggerType, mode)\n // No timeout specified - uses Claude's default of 60 seconds\n }]\n }];\n}\n\n// Export to avoid unused warning (may be used in future)\nexport { buildHookConfiguration };\n\n\n/**\n * Ensure directory exists\n */\nasync function ensureDirectory(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\n/**\n * Append hook configuration without overwriting existing hooks\n */\nfunction appendHookConfiguration(\n settings: ClaudeSettings,\n hookType: 'SessionStart' | 'PreCompact' | 'SessionEnd',\n cliPath: string,\n mode?: 'all' | 'selected'\n): void {\n const triggerType = hookType === 'SessionStart' ? 'sessionstart' :\n hookType === 'PreCompact' ? 'precompact' : 'sessionend';\n const command = buildHookCommand(cliPath, triggerType, mode);\n const matcher = HOOK_MATCHERS[hookType];\n\n // Ensure hooks object exists\n if (!settings.hooks) {\n settings.hooks = {};\n }\n\n // Ensure hook structure exists\n if (!settings.hooks[hookType]) {\n settings.hooks[hookType] = [];\n }\n\n // Check if devark hook already exists (prevent duplicates)\n const existingHooks = settings.hooks[hookType];\n if (existingHooks) {\n for (const config of existingHooks) {\n for (const hook of config.hooks || []) {\n if (isDevArkCommand(hook.command) && hook.command.includes(`--hook-trigger=${triggerType}`)) {\n logger.debug(`${hookType} devark hook already exists, skipping`);\n return;\n }\n }\n }\n }\n\n // Check if there's already a config with hooks array\n if (existingHooks && existingHooks.length > 0 && existingHooks[0].hooks) {\n // Append to existing hooks array - PRESERVES EXISTING HOOKS\n existingHooks[0].hooks.push({\n type: 'command',\n command: command\n });\n } else if (existingHooks) {\n // Create new config with hooks array\n existingHooks.push({\n matcher: matcher,\n hooks: [{\n type: 'command',\n command: command\n }]\n });\n }\n}\n\n/**\n * Remove only devark hooks from a specific hook type, preserving other hooks\n */\nfunction removeDevArkHook(\n settings: ClaudeSettings,\n hookType: 'SessionStart' | 'PreCompact' | 'SessionEnd'\n): number {\n if (!settings.hooks || !settings.hooks[hookType]) {\n return 0;\n }\n\n const existingHooks = settings.hooks[hookType];\n if (!existingHooks) {\n return 0;\n }\n\n // Count total hooks before filtering\n const totalBefore = existingHooks.reduce((sum: number, config: HookConfigWithMatcher) => sum + config.hooks.length, 0);\n\n // Filter out devark commands while preserving other hooks\n const filteredConfigs = existingHooks\n .map((config: HookConfigWithMatcher) => ({\n ...config,\n hooks: config.hooks.filter((hook: HookConfig) => !isDevArkCommand(hook.command))\n }))\n .filter((config: HookConfigWithMatcher) => config.hooks.length > 0);\n\n // Count total hooks after filtering\n const totalAfter = filteredConfigs.reduce((sum: number, config: HookConfigWithMatcher) => sum + config.hooks.length, 0);\n\n if (filteredConfigs.length > 0) {\n settings.hooks[hookType] = filteredConfigs;\n } else {\n // No hooks left, delete the hook type\n delete settings.hooks[hookType];\n }\n\n // Return number of removed hooks\n return totalBefore - totalAfter;\n}\n\n/**\n * Generic function to install hooks to any settings file\n */\nasync function installHooksToSettings(\n settingsPath: string,\n hooks: HookDefinition[],\n cliPath: string,\n mode?: 'all' | 'selected'\n): Promise<void> {\n // Ensure directory exists for local settings\n const dir = path.dirname(settingsPath);\n if (dir !== path.dirname(getGlobalSettingsPath())) {\n await ensureDirectory(dir);\n }\n \n // Read or create settings\n const settings = await readSettingsFile(settingsPath) || {};\n \n // Ensure hooks object exists\n if (!settings.hooks) {\n settings.hooks = {};\n }\n \n // Install/remove each hook based on configuration\n for (const hook of hooks) {\n if (hook.enabled) {\n // Use append pattern to preserve existing hooks\n appendHookConfiguration(settings, hook.type, cliPath, mode);\n logger.debug(`${hook.type} hook configured`);\n } else {\n // Remove only devark hooks, preserve others\n removeDevArkHook(settings, hook.type);\n logger.debug(`${hook.type} hook removed`);\n }\n }\n // Remove empty hooks object\n if (Object.keys(settings.hooks).length === 0) {\n delete settings.hooks;\n }\n \n // Write settings\n await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2));\n}\n\n/**\n * Install selected hooks with configuration\n */\nexport async function installSelectedHooks(selection: HookSelection): Promise<void> {\n const hooks: HookDefinition[] = [\n { type: 'SessionStart', enabled: selection.sessionStartHook },\n { type: 'PreCompact', enabled: selection.preCompactHook },\n { type: 'SessionEnd', enabled: selection.sessionEndHook }\n ];\n \n await installHooksToSettings(\n getGlobalSettingsPath(),\n hooks,\n getCliPath(),\n 'all' // Global hooks use 'all' mode\n );\n\n logger.info('Hooks installed successfully');\n\n // After successful installation, update telemetry (cloud users only)\n await sendTelemetryUpdate();\n}\n\n/**\n * Uninstall all devark hooks from both global and project-local settings\n */\nexport async function uninstallAllHooks(): Promise<{ removedCount: number }> {\n let removedCount = 0;\n \n // Remove from global settings\n const globalSettings = await readSettings();\n if (globalSettings && globalSettings.hooks) {\n let globalRemoved = 0;\n\n // Remove only devark hooks from SessionStart, preserving other hooks\n globalRemoved += removeDevArkHook(globalSettings, 'SessionStart');\n\n // Remove only devark hooks from PreCompact, preserving other hooks\n globalRemoved += removeDevArkHook(globalSettings, 'PreCompact');\n\n // Remove only devark hooks from SessionEnd, preserving other hooks\n globalRemoved += removeDevArkHook(globalSettings, 'SessionEnd');\n \n if (globalRemoved > 0) {\n // Remove empty hooks object\n if (Object.keys(globalSettings.hooks).length === 0) {\n delete globalSettings.hooks;\n }\n \n await writeSettings(globalSettings);\n removedCount += globalRemoved;\n logger.info(`Removed ${globalRemoved} hook(s) from global settings`);\n }\n }\n \n // Remove from project-local settings\n const { discoverProjects } = await import('../claude-core');\n const projects = await discoverProjects();\n \n for (const project of projects) {\n try {\n const localSettingsPath = getProjectLocalSettingsPath(project.actualPath);\n const localSettings = await readSettingsFile(localSettingsPath);\n \n if (localSettings && localSettings.hooks) {\n let projectRemoved = 0;\n \n // Check and remove devark hooks\n if (localSettings.hooks.SessionStart && isDevArkHook(localSettings.hooks.SessionStart)) {\n delete localSettings.hooks.SessionStart;\n projectRemoved++;\n }\n\n if (localSettings.hooks.PreCompact && isDevArkHook(localSettings.hooks.PreCompact)) {\n delete localSettings.hooks.PreCompact;\n projectRemoved++;\n }\n\n if (localSettings.hooks.SessionEnd && isDevArkHook(localSettings.hooks.SessionEnd)) {\n delete localSettings.hooks.SessionEnd;\n projectRemoved++;\n }\n \n if (projectRemoved > 0) {\n // Remove empty hooks object\n if (Object.keys(localSettings.hooks).length === 0) {\n delete localSettings.hooks;\n }\n \n await fs.writeFile(localSettingsPath, JSON.stringify(localSettings, null, 2));\n removedCount += projectRemoved;\n logger.info(`Removed ${projectRemoved} hook(s) from project ${project.name}`);\n }\n }\n } catch (error) {\n // Ignore errors for projects without local settings\n logger.debug(`Could not process project ${project.name}:`, error);\n }\n }\n \n if (removedCount === 0) {\n throw new Error('No devark hooks found to uninstall');\n }\n \n logger.info(`Total removed: ${removedCount} hook(s)`);\n\n // After successful uninstall, update telemetry (cloud users only)\n await sendTelemetryUpdate();\n\n return { removedCount };\n}\n\n/**\n * Helper to check if a hook configuration contains devark commands\n */\nfunction isDevArkHook(hookConfigs: HookConfigWithMatcher[]): boolean {\n return hookConfigs.some(config => \n config.hooks.some(hook => isDevArkCommand(hook.command))\n );\n}\n\n/**\n * Helper to read settings file\n */\nasync function readSettingsFile(path: string): Promise<ClaudeSettings | null> {\n try {\n const data = await fs.readFile(path, 'utf-8');\n return JSON.parse(data);\n } catch (error) {\n return null;\n }\n}\n\n/**\n * Update hook configuration (timeout, debug mode, etc.)\n */\nexport async function updateHookConfig(\n hookType: 'sessionstart' | 'precompact' | 'sessionend',\n config: { timeout?: number }\n): Promise<void> {\n const settings = await readSettings();\n if (!settings || !settings.hooks) {\n throw new Error('No hooks installed');\n }\n\n const hookKey = hookType === 'sessionstart' ? 'SessionStart' :\n hookType === 'precompact' ? 'PreCompact' : 'SessionEnd';\n const hookConfig = settings.hooks[hookKey];\n \n if (!hookConfig || !hookConfig[0]?.hooks?.[0]) {\n throw new Error(`${hookKey} hook not installed`);\n }\n \n const hook = hookConfig[0].hooks[0];\n \n // Update timeout\n if (config.timeout !== undefined) {\n hook.timeout = config.timeout;\n }\n \n await writeSettings(settings);\n logger.info(`${hookKey} hook configuration updated`);\n}\n\n/**\n * Check if hooks need updating\n */\nexport async function checkForHookUpdates(): Promise<{ needsUpdate: boolean; currentVersion: string; latestVersion: string }> {\n const status = await getHooksStatus();\n\n const sessionStartVersion = status.sessionStartHook.installed ? status.sessionStartHook.version : '0.0.0';\n const preCompactVersion = status.preCompactHook.installed ? status.preCompactHook.version : '0.0.0';\n const sessionEndVersion = status.sessionEndHook.installed ? status.sessionEndHook.version : '0.0.0';\n\n // Compare versions and get the highest one\n const versions = [sessionStartVersion, preCompactVersion, sessionEndVersion];\n const currentVersion = versions.reduce((max, version) => version > max ? version : max, '0.0.0');\n const needsUpdate = currentVersion < HOOKS_VERSION;\n \n return {\n needsUpdate,\n currentVersion,\n latestVersion: HOOKS_VERSION\n };\n}\n\n/**\n * Get current hook tracking mode (delegate to claude-settings-reader)\n */\nexport async function getHookMode() {\n return getHookModeFromReader();\n}\n\n/**\n * Install hooks globally for all projects\n */\nexport async function installGlobalHooks(): Promise<void> {\n const hooks: HookDefinition[] = [\n { type: 'SessionStart', enabled: true },\n { type: 'PreCompact', enabled: true },\n { type: 'SessionEnd', enabled: true }\n ];\n \n await installHooksToSettings(\n getGlobalSettingsPath(),\n hooks,\n getCliPath(),\n 'all' // Pass mode='all' for global hooks\n );\n\n logger.info('Global hooks installed for all projects');\n\n // After successful installation, update telemetry (cloud users only)\n await sendTelemetryUpdate();\n}\n\n/**\n * Install hooks for specific projects in their local settings\n */\nexport async function installProjectHooks(projects: Array<{ path: string; name: string; actualPath?: string }>): Promise<void> {\n const hooks: HookDefinition[] = [\n { type: 'SessionStart', enabled: true },\n { type: 'PreCompact', enabled: true },\n { type: 'SessionEnd', enabled: true }\n ];\n \n const cliPath = getCliPath();\n let installedCount = 0;\n let failedCount = 0;\n \n for (const project of projects) {\n try {\n const projectPath = project.actualPath;\n if (!projectPath) {\n logger.warn(`No actual path found for project ${project.name}, skipping`);\n failedCount++;\n continue;\n }\n \n const localSettingsPath = getProjectLocalSettingsPath(projectPath);\n \n await installHooksToSettings(\n localSettingsPath,\n hooks,\n cliPath,\n 'selected' // Project-specific hooks use 'selected' mode\n );\n \n logger.info(`Hooks installed for project ${project.name} at ${localSettingsPath}`);\n installedCount++;\n \n } catch (error) {\n logger.error(`Failed to install hooks for project ${project.name}:`, error);\n failedCount++;\n }\n }\n \n if (installedCount > 0) {\n logger.info(`Successfully installed hooks for ${installedCount} project(s)`);\n // After successful installation, update telemetry (cloud users only)\n await sendTelemetryUpdate();\n }\n if (failedCount > 0) {\n logger.warn(`Failed to install hooks for ${failedCount} project(s)`);\n }\n}\n\n/**\n * Project hook configuration with per-hook granularity\n */\nexport interface ProjectHookConfig {\n path: string;\n name: string;\n sessionStart: boolean;\n preCompact: boolean;\n sessionEnd: boolean;\n}\n\n/**\n * Install hooks for specific projects with per-hook configuration in their local settings\n */\nexport async function installSelectiveProjectHooks(projectConfigs: ProjectHookConfig[]): Promise<void> {\n const cliPath = getCliPath();\n let installedCount = 0;\n let failedCount = 0;\n \n for (const config of projectConfigs) {\n try {\n const projectPath = (config as any).actualPath;\n if (!projectPath) {\n logger.warn(`No actual path found for project ${config.name}, skipping`);\n failedCount++;\n continue;\n }\n \n const hooks: HookDefinition[] = [\n { type: 'SessionStart', enabled: config.sessionStart },\n { type: 'PreCompact', enabled: config.preCompact },\n { type: 'SessionEnd', enabled: config.sessionEnd }\n ];\n \n const localSettingsPath = getProjectLocalSettingsPath(projectPath);\n \n await installHooksToSettings(\n localSettingsPath,\n hooks,\n cliPath,\n 'selected' // Project-specific hooks use 'selected' mode\n );\n \n // Log per-project summary\n const enabledHooks = hooks\n .filter(h => h.enabled)\n .map(h => h.type);\n \n if (enabledHooks.length > 0) {\n logger.info(`Hooks installed for ${config.name}: ${enabledHooks.join(', ')}`);\n installedCount++;\n } else {\n logger.info(`All hooks removed for ${config.name}`);\n }\n \n } catch (error) {\n logger.error(`Failed to configure hooks for project ${config.name}:`, error);\n failedCount++;\n }\n }\n \n if (installedCount > 0) {\n logger.info(`Successfully configured hooks for ${installedCount} project(s)`);\n }\n if (failedCount > 0) {\n logger.warn(`Failed to configure hooks for ${failedCount} project(s)`);\n }\n}\n\n/**\n * Remove devark hooks from specific projects' local settings\n */\nexport async function removeProjectHooks(projects: Array<{ path: string; name: string; actualPath?: string }>): Promise<void> {\n let removedCount = 0;\n let failedCount = 0;\n \n for (const project of projects) {\n try {\n const projectPath = project.actualPath;\n if (!projectPath) {\n logger.warn(`No actual path found for project ${project.name}, skipping`);\n failedCount++;\n continue;\n }\n \n const localSettingsPath = getProjectLocalSettingsPath(projectPath);\n const localSettings = await readSettingsFile(localSettingsPath);\n \n if (localSettings && localSettings.hooks) {\n let removed = false;\n \n // Remove devark hooks only\n if (localSettings.hooks.SessionStart && isDevArkHook(localSettings.hooks.SessionStart)) {\n delete localSettings.hooks.SessionStart;\n removed = true;\n }\n\n if (localSettings.hooks.PreCompact && isDevArkHook(localSettings.hooks.PreCompact)) {\n delete localSettings.hooks.PreCompact;\n removed = true;\n }\n\n if (localSettings.hooks.SessionEnd && isDevArkHook(localSettings.hooks.SessionEnd)) {\n delete localSettings.hooks.SessionEnd;\n removed = true;\n }\n \n if (removed) {\n // Remove empty hooks object\n if (Object.keys(localSettings.hooks).length === 0) {\n delete localSettings.hooks;\n }\n \n // Write back the settings\n await fs.writeFile(localSettingsPath, JSON.stringify(localSettings, null, 2));\n logger.info(`Hooks removed from project ${project.name}`);\n removedCount++;\n }\n }\n \n } catch (error) {\n // If file doesn't exist, that's fine - no hooks to remove\n if ((error as any).code !== 'ENOENT') {\n logger.error(`Failed to remove hooks from project ${project.name}:`, error);\n failedCount++;\n }\n }\n }\n \n if (removedCount > 0) {\n logger.info(`Successfully removed hooks from ${removedCount} project(s)`);\n }\n if (failedCount > 0) {\n logger.warn(`Failed to remove hooks from ${failedCount} project(s)`);\n }\n}","{\n \"name\": \"devark-cli\",\n \"version\": \"0.1.0\",\n \"description\": \"DevArk - Developer Productivity CLI\",\n \"bin\": {\n \"devark\": \"./bin/devark.js\"\n },\n \"main\": \"dist/index.js\",\n \"scripts\": {\n \"build\": \"npm run type-check && tsup\",\n \"dev\": \"tsup --watch\",\n \"prepublishOnly\": \"npm run build\",\n \"test\": \"vitest\",\n \"test:coverage\": \"vitest --coverage\",\n \"badges\": \"coverage-badges\",\n \"test:template\": \"vitest tests/report-template.test.ts\",\n \"test:template:critical\": \"vitest tests/report-template-critical.test.ts\",\n \"test:package\": \"bash scripts/test-npm-package.sh\",\n \"type-check\": \"tsc --noEmit\",\n \"lint\": \"eslint src --ext .ts\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n \"security-check\": \"npm audit && npm outdated\",\n \"security-fix\": \"npm audit fix\",\n \"validate-deps\": \"npm ls --depth=0\",\n \"check-all\": \"npm run lint && npm run type-check && npm run test && npm run security-check\",\n \"verify\": \"npm run verify:build && npm run verify:checksums\",\n \"verify:build\": \"test -f dist/index.js && test -f dist/index.js.map && echo '✓ Build artifacts present'\",\n \"verify:checksums\": \"if [ -f dist/checksums.sha256 ]; then cd dist && sha256sum -c checksums.sha256 && echo '✓ Checksums verified'; else echo '⚠ No checksums file found'; fi\",\n \"prebuild\": \"npm run clean\",\n \"clean\": \"rimraf dist\",\n \"postbuild\": \"npm run copy-templates && npm run generate-checksums\",\n \"copy-templates\": \"node scripts/copy-templates.js\",\n \"generate-checksums\": \"node scripts/generate-checksums.js\"\n },\n \"keywords\": [\n \"cli\",\n \"devark\",\n \"productivity\",\n \"developer-tools\",\n \"code-tracking\"\n ],\n \"author\": \"DevArk\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/DevArk-AI/devark-cli.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/DevArk-AI/devark-cli/issues\"\n },\n \"homepage\": \"https://github.com/DevArk-AI/devark-cli#readme\",\n \"files\": [\n \"dist\",\n \"bin\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=18.0.0\"\n },\n \"dependencies\": {\n \"@anthropic-ai/claude-agent-sdk\": \"^0.1.27\",\n \"axios\": \"^1.6.0\",\n \"better-sqlite3\": \"^11.0.0\",\n \"boxen\": \"^5.1.2\",\n \"chalk\": \"^4.1.2\",\n \"clipboardy\": \"^2.3.0\",\n \"commander\": \"^11.1.0\",\n \"conf\": \"^10.2.0\",\n \"dayjs\": \"^1.11.0\",\n \"event-source-polyfill\": \"^1.0.31\",\n \"fs-extra\": \"^11.3.1\",\n \"inquirer\": \"^12.9.1\",\n \"oh-my-logo\": \"^0.2.1\",\n \"open\": \"^8.4.2\",\n \"ora\": \"^5.4.1\",\n \"update-notifier\": \"^7.3.1\"\n },\n \"devDependencies\": {\n \"@types/better-sqlite3\": \"^7.6.13\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/inquirer\": \"^9.0.7\",\n \"@types/node\": \"^20.0.0\",\n \"@types/update-notifier\": \"^6.0.8\",\n \"@typescript-eslint/eslint-plugin\": \"^6.0.0\",\n \"@typescript-eslint/parser\": \"^6.0.0\",\n \"@vitest/coverage-v8\": \"^3.2.4\",\n \"coverage-badges-cli\": \"^2.2.0\",\n \"eslint\": \"^8.0.0\",\n \"execa\": \"^9.6.0\",\n \"prettier\": \"^3.0.0\",\n \"rimraf\": \"^6.0.1\",\n \"tsup\": \"^8.0.0\",\n \"typescript\": \"^5.3.0\",\n \"vitest\": \"^3.2.4\"\n }\n}\n","import { getToken, getStatusLinePersonality } from './config';\nimport { detectSetupState } from './detector';\nimport { getHooksStatus } from './hooks/hooks-controller';\nimport { logger } from '../utils/logger';\n\nconst pkg = require('../../package.json');\n\nexport interface CliTelemetry {\n // Installation state\n hooksInstalled: boolean;\n hookMode: 'all' | 'selected' | 'none';\n trackedProjectCount: number;\n statusLineInstalled: boolean;\n statusLinePersonality: string;\n\n // Version info\n cliVersion: string;\n hookVersion?: string; // Deprecated - kept for backward compatibility\n sessionStartHookVersion?: string;\n preCompactHookVersion?: string;\n sessionEndHookVersion?: string;\n\n // Timestamps\n lastTelemetryUpdate: string;\n}\n\nexport async function collectTelemetry(): Promise<CliTelemetry | null> {\n // CRITICAL: Check for auth token FIRST\n const token = await getToken();\n if (!token) {\n // NO TOKEN = NO TELEMETRY\n return null;\n }\n\n // Only proceed if user has authenticated\n const state = await detectSetupState();\n const statusLine = getStatusLinePersonality();\n const hookStatus = await getHooksStatus();\n\n return {\n hooksInstalled: state.hasHooks,\n hookMode: state.trackingMode,\n trackedProjectCount: state.trackedProjectCount,\n statusLineInstalled: state.hasStatusLine,\n statusLinePersonality: statusLine?.personality || 'gordon',\n cliVersion: pkg.version,\n hookVersion: hookStatus.sessionStartHook?.version || hookStatus.preCompactHook?.version, // Deprecated\n sessionStartHookVersion: hookStatus.sessionStartHook?.version,\n preCompactHookVersion: hookStatus.preCompactHook?.version,\n sessionEndHookVersion: hookStatus.sessionEndHook?.version,\n lastTelemetryUpdate: new Date().toISOString()\n };\n}\n\nexport async function sendTelemetryUpdate(): Promise<void> {\n // CRITICAL: Check for auth token FIRST\n const token = await getToken();\n if (!token) {\n // No auth = no telemetry, silently exit\n logger.debug('Skipping telemetry - no auth token');\n return;\n }\n\n const telemetry = await collectTelemetry();\n if (!telemetry) return;\n\n try {\n // Import api-client dynamically to avoid circular dependency\n const { apiClient } = await import('./api-client');\n\n // This will only happen for cloud users\n await apiClient.updateTelemetry(telemetry);\n logger.debug('Telemetry updated successfully');\n } catch (error) {\n // Silent fail - never break user flow\n logger.debug('Telemetry update failed:', error);\n }\n}","import axios, { AxiosInstance, AxiosError } from 'axios';\nimport { getToken, getApiUrl, getStatusLinePersonality } from './config';\nimport { DevArkError } from '../utils/errors';\nimport { validateUrl } from './input-validator';\nimport { logger } from '../utils/logger';\nimport { isNetworkError, createNetworkError } from './errors/network-errors';\nimport { claudeSettingsManager } from './claude-settings-manager';\nimport crypto from 'crypto';\nimport type { CliTelemetry } from './telemetry';\n\nexport interface Session {\n tool: 'claude_code' | 'cursor' | 'vscode';\n timestamp: string;\n duration: number;\n claudeSessionId?: string; // Claude's unique session identifier\n data: {\n projectName: string; // Changed from projectPath to projectName\n // Privacy-preserving: We don't send actual message content\n messageSummary: string; // JSON string with aggregated stats\n messageCount: number;\n metadata: {\n files_edited: number;\n languages: string[];\n models?: string[]; // All models used in session\n primaryModel?: string; // Most frequently used model\n gitBranch?: string; // Git branch from JSONL\n // Planning mode metadata\n hasPlanningMode?: boolean; // Whether planning mode was used\n planningCycles?: number; // Number of planning cycles\n exitPlanTimestamps?: string[]; // ISO timestamps of ExitPlanMode calls\n };\n };\n}\n\nexport interface StreakInfo {\n current: number;\n points: number;\n longestStreak: number;\n totalSessions: number;\n todaySessions: number;\n}\n\nexport interface PointsEarned {\n streak: number; // Exponential streak points (2^day)\n volume: number; // Session volume bonus (1 per session, max 30/day)\n share: number; // Social share bonus (web platform only, included in total)\n total: number; // Total points earned (streak + volume + share)\n message?: string; // Optional celebratory message from server\n}\n\nexport interface UploadResult {\n success: boolean;\n sessionsProcessed: number;\n analysisPreview?: string;\n streak?: StreakInfo;\n pointsEarned?: PointsEarned; // Points earned from this upload\n created?: number; // Number of new sessions created\n duplicates?: number; // Number of duplicate sessions\n batchId?: string; // Batch ID for tracking\n}\n\nexport interface CLIConfiguration {\n statusline: {\n personality: 'gordon' | 'devark' | 'custom';\n customPersonality?: {\n name: string;\n description: string;\n templates?: {\n poor: string;\n fair: string;\n good: string;\n excellent: string;\n };\n };\n };\n hooks: {\n sessionStartInstalled: boolean;\n preCompactInstalled: boolean;\n sessionEndInstalled: boolean;\n mode?: 'all' | 'selected';\n };\n}\n\n// Request ID for tracking\nfunction generateRequestId(): string {\n return crypto.randomBytes(16).toString('hex');\n}\n\n// Gather current CLI configuration for sending to server\nasync function gatherCLIConfiguration(): Promise<CLIConfiguration | null> {\n try {\n // Get statusline configuration\n const statuslineConfig = getStatusLinePersonality();\n\n // Get hooks configuration\n const featureStatus = await claudeSettingsManager.getFeatureStatus();\n\n return {\n statusline: {\n personality: statuslineConfig.personality,\n customPersonality: statuslineConfig.customPersonality\n },\n hooks: {\n sessionStartInstalled: featureStatus.autoSync.sessionStartInstalled,\n preCompactInstalled: featureStatus.autoSync.preCompactInstalled,\n sessionEndInstalled: featureStatus.autoSync.sessionEndInstalled,\n mode: featureStatus.autoSync.mode\n }\n };\n } catch (error) {\n logger.debug('Failed to gather CLI configuration:', error);\n return null; // Don't fail upload if config gathering fails\n }\n}\n\nclass SecureApiClient {\n private client: AxiosInstance;\n private requestCount = 0;\n private windowStart = Date.now();\n private readonly MAX_REQUESTS_PER_MINUTE = 60;\n\n constructor() {\n this.client = axios.create({\n timeout: 30000,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'devark-CLI/0.6.0',\n 'X-Client-Version': '1.0.0',\n },\n // Prevent automatic redirects to avoid SSRF\n maxRedirects: 0,\n // Validate response status\n validateStatus: (status) => status >= 200 && status < 300,\n });\n\n this.setupInterceptors();\n }\n\n private setupInterceptors(): void {\n // Request interceptor\n this.client.interceptors.request.use(\n async (config) => {\n // Rate limiting\n this.enforceRateLimit();\n \n // Set secure headers\n config.headers['X-Request-ID'] = generateRequestId();\n config.headers['X-Timestamp'] = new Date().toISOString();\n \n // Validate and set base URL\n const apiUrl = await this.getValidatedApiUrl();\n // Remove trailing slash from base URL to avoid double slashes\n config.baseURL = apiUrl.endsWith('/') ? apiUrl.slice(0, -1) : apiUrl;\n \n // Add authentication\n const token = await getToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n \n // Log request (sanitized)\n logger.debug(`API Request: ${config.method?.toUpperCase()} ${config.url}`, {\n fullUrl: `${config.baseURL}${config.url}`,\n method: config.method?.toUpperCase(),\n hasAuth: !!config.headers.Authorization\n });\n \n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n\n // Response interceptor\n this.client.interceptors.response.use(\n (response) => {\n // Validate response headers\n this.validateResponseHeaders(response.headers);\n return response;\n },\n async (error: AxiosError) => {\n // Log detailed error for debugging\n logger.debug('API Error Details', {\n status: error.response?.status,\n statusText: error.response?.statusText,\n data: error.response?.data,\n code: error.code,\n message: error.message,\n url: error.config?.url,\n baseURL: error.config?.baseURL\n });\n \n // Also log to console for 400 errors to see server validation messages\n if (error.response?.status === 400) {\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] 400 Error Response:', JSON.stringify(error.response?.data, null, 2));\n }\n \n // Extract validation message if available\n const responseData = error.response?.data as any;\n const validationMessage = responseData?.message || responseData?.error;\n \n // Check for specific validation errors\n if (validationMessage) {\n // Check for duration validation error\n if (validationMessage.includes('duration') && validationMessage.includes('240')) {\n throw new DevArkError(\n 'Sessions must be at least 4 minutes long to be uploaded. Short sessions were rejected by the server.',\n 'VALIDATION_ERROR'\n );\n }\n \n // Check for ZodError format\n if (validationMessage.includes('ZodError') || validationMessage.includes('Too small')) {\n // Try to extract the meaningful part\n if (validationMessage.includes('duration')) {\n throw new DevArkError(\n 'Sessions must be at least 4 minutes long. Please select longer sessions to upload.',\n 'VALIDATION_ERROR'\n );\n }\n }\n \n // Generic validation error\n throw new DevArkError(\n `Validation error: ${validationMessage}`,\n 'VALIDATION_ERROR'\n );\n }\n }\n \n // Sanitize error messages\n const safeError = this.sanitizeError(error);\n \n if (error.response?.status === 401) {\n throw new DevArkError(\n 'Your session has expired. Please authenticate again',\n 'AUTH_EXPIRED'\n );\n } else if (error.response?.status === 403) {\n throw new DevArkError(\n 'Access denied. Please check your permissions',\n 'ACCESS_DENIED'\n );\n } else if (error.response?.status === 429) {\n const retryAfter = error.response.headers['retry-after'];\n throw new DevArkError(\n `Too many requests. Please wait ${retryAfter || '60'} seconds before trying again`,\n 'RATE_LIMITED'\n );\n } else if (error.response?.status === 500) {\n throw new DevArkError(\n 'Server error. The devark service is having issues. Please try again later',\n 'SERVER_ERROR'\n );\n } else if (isNetworkError(error)) {\n throw createNetworkError(error);\n } else if (error.response?.status === 404) {\n throw new DevArkError(\n 'API endpoint not found. You might need to update your CLI',\n 'ENDPOINT_NOT_FOUND'\n );\n }\n \n throw safeError;\n }\n );\n }\n\n private enforceRateLimit(): void {\n const now = Date.now();\n const windowAge = now - this.windowStart;\n \n // Reset window after 1 minute\n if (windowAge > 60000) {\n this.requestCount = 0;\n this.windowStart = now;\n }\n \n this.requestCount++;\n \n if (this.requestCount > this.MAX_REQUESTS_PER_MINUTE) {\n throw new DevArkError(\n 'Client rate limit exceeded. Please wait before making more requests.',\n 'CLIENT_RATE_LIMITED'\n );\n }\n }\n\n private async getValidatedApiUrl(): Promise<string> {\n const url = getApiUrl();\n try {\n return validateUrl(url);\n } catch (error) {\n console.error('Invalid API URL, using default');\n return 'https://app.devark.ai';\n }\n }\n\n private validateResponseHeaders(headers: any): void {\n // Check for security headers\n const requiredHeaders = ['x-content-type-options', 'x-frame-options'];\n \n for (const header of requiredHeaders) {\n if (!headers[header]) {\n console.warn(`Missing security header: ${header}`);\n }\n }\n }\n\n private sanitizeError(error: AxiosError): Error {\n // Remove sensitive data from errors\n const errorData = error.response?.data as any;\n const sanitized = new Error(\n errorData?.message || \n error.message || \n 'An error occurred'\n );\n \n // Copy safe properties\n (sanitized as any).code = error.code;\n (sanitized as any).status = error.response?.status;\n \n return sanitized;\n }\n\n async createAuthSession(): Promise<{ authUrl: string; token: string }> {\n const response = await this.client.post('/api/auth/cli/session', {\n timestamp: new Date().toISOString(),\n });\n \n // Validate response - React Router v7 returns sessionId as the token\n if (!response.data.authUrl || typeof response.data.authUrl !== 'string') {\n throw new Error('Invalid auth response');\n }\n \n // Handle both 'token' and 'sessionId' for compatibility\n const token = response.data.token || response.data.sessionId;\n if (!token || typeof token !== 'string') {\n throw new Error('Server did not return token');\n }\n \n return {\n authUrl: response.data.authUrl,\n token: token\n };\n }\n\n async checkAuthCompletion(token: string): Promise<{ success: boolean; userId?: number }> {\n try {\n // Use GET to check status without consuming the token\n const response = await this.client.get(`/api/auth/cli/complete?token=${token}`);\n \n return {\n success: response.data.success,\n userId: response.data.userId\n };\n } catch (error: any) {\n if (error.response?.status === 404) {\n return { success: false }; // Token not found or not completed yet\n }\n if (error.response?.status === 409) {\n throw new Error('Token already completed');\n }\n throw error;\n }\n }\n\n // Removed pollAuthSession - now using SSE streaming instead\n\n async verifyToken(): Promise<{ valid: boolean; user?: any }> {\n try {\n const response = await this.client.get('/api/auth/cli/verify');\n \n // Don't return raw user data\n return {\n valid: true,\n user: {\n id: response.data.user?.id,\n // Only return necessary fields\n },\n };\n } catch (error) {\n return { valid: false };\n }\n }\n\n async uploadSessions(\n sessions: Session[],\n onProgress?: (current: number, total: number, sizeKB?: number) => void\n ): Promise<any> {\n // Gather CLI configuration to send with the upload\n const cliConfig = await gatherCLIConfiguration();\n\n // Validate and sanitize sessions\n const sanitizedSessions = sessions.map(session => this.sanitizeSession(session));\n\n // Chunk large uploads\n // Using 100 for better performance - modern connections can handle 300-500KB payloads\n const CHUNK_SIZE = 100;\n const chunks = [];\n \n for (let i = 0; i < sanitizedSessions.length; i += CHUNK_SIZE) {\n chunks.push(sanitizedSessions.slice(i, i + CHUNK_SIZE));\n }\n \n const results = [];\n let uploadedCount = 0;\n let uploadedSizeKB = 0;\n \n // Calculate total size\n const totalSize = Buffer.byteLength(JSON.stringify(sanitizedSessions)) / 1024;\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] Uploading in', chunks.length, 'chunks', `(Total: ${totalSize.toFixed(2)} KB)`);\n }\n \n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n const payload: any = {\n sessions: chunk,\n checksum: this.calculateChecksum(chunk),\n totalSessions: sanitizedSessions.length, // Total sessions being uploaded\n batchNumber: i + 1, // Current batch number (1-indexed)\n totalBatches: chunks.length, // Total number of batches\n };\n\n // On first chunk only, include telemetry\n if (i === 0) {\n const { collectTelemetry } = await import('./telemetry');\n const telemetry = await collectTelemetry();\n if (telemetry) {\n payload.telemetry = telemetry; // Add to existing payload\n }\n }\n \n // Calculate payload size in kilobytes\n const payloadSize = Buffer.byteLength(JSON.stringify(payload)) / 1024;\n \n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] Uploading batch', i + 1, 'of', chunks.length, 'with', chunk.length, 'sessions', `(${payloadSize.toFixed(2)} KB)`);\n console.log('[DEBUG] Total progress:', uploadedCount, '+', chunk.length, '=', uploadedCount + chunk.length, 'of', sanitizedSessions.length);\n \n // Log first session of each chunk to debug validation issues\n if (chunk.length > 0) {\n console.log('[DEBUG] First session in chunk:', JSON.stringify(chunk[0], null, 2).substring(0, 500) + '...');\n }\n }\n \n // Log the actual HTTP request data\n logger.debug(`📤 API Request batch ${i + 1}/${chunks.length}: POST /cli/sessions`, {\n batchSessions: chunk.length,\n totalSessions: sanitizedSessions.length,\n cumulativeProgress: `${uploadedCount + chunk.length}/${sanitizedSessions.length}`,\n firstSession: chunk[0] ? {\n tool: chunk[0].tool,\n timestamp: chunk[0].timestamp,\n duration: chunk[0].duration\n } : null,\n checksum: payload.checksum\n });\n \n // Add retry logic for network failures\n let lastError: any;\n let retryCount = 0;\n const MAX_RETRIES = 1; // Basic retry - just one attempt\n \n while (retryCount <= MAX_RETRIES) {\n try {\n // Prepare configuration headers\n const configHeaders: Record<string, string> = {};\n if (cliConfig) {\n configHeaders['x-devark-config-statusline'] = JSON.stringify(cliConfig.statusline);\n configHeaders['x-devark-config-hooks'] = JSON.stringify(cliConfig.hooks);\n }\n\n // Use /cli/sessions endpoint for CLI uploads (bearer token auth)\n const response = await this.client.post('/cli/sessions', payload, {\n headers: configHeaders\n });\n results.push(response.data);\n \n // Update progress after successful chunk upload\n uploadedCount += chunk.length;\n uploadedSizeKB += payloadSize;\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] Progress reported:', uploadedCount, '/', sanitizedSessions.length, `(${uploadedSizeKB.toFixed(2)} KB)`);\n }\n if (onProgress) {\n onProgress(uploadedCount, sanitizedSessions.length, uploadedSizeKB);\n }\n \n // Add a small delay between chunks to avoid overwhelming the server\n if (i < chunks.length - 1) {\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n \n break; // Success, exit retry loop\n } catch (error) {\n lastError = error;\n retryCount++;\n \n // Only retry on network errors, not on client errors (4xx)\n const shouldRetry = error instanceof AxiosError && \n (!error.response || error.response.status >= 500 || isNetworkError(error));\n \n if (!shouldRetry || retryCount > MAX_RETRIES) {\n throw error; // Don't retry, throw immediately\n }\n \n logger.debug(`Network error, retrying (${retryCount}/${MAX_RETRIES})...`, { error: error.message });\n // Wait a bit before retrying\n await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));\n }\n }\n \n if (retryCount > MAX_RETRIES && lastError) {\n throw lastError;\n }\n }\n \n return this.mergeResults(results);\n }\n\n private sanitizeSession(session: Session): Session {\n // Remove or sanitize sensitive data\n return {\n ...session,\n data: {\n ...session.data,\n projectName: session.data?.projectName || '', // Project name is already sanitized in send.ts\n // Message content is already sanitized at this point\n // Just ensure the summary doesn't contain sensitive data\n messageSummary: session.data?.messageSummary || '',\n },\n };\n }\n\n private calculateChecksum(data: any): string {\n const json = JSON.stringify(data);\n return crypto.createHash('sha256').update(json).digest('hex');\n }\n\n private mergeResults(results: any[]): UploadResult {\n // Merge chunked upload results - properly handle created and duplicates counts\n // Aggregate points from all batches\n const pointsEarned = results\n .filter(r => r.pointsEarned)\n .reduce((acc, r) => {\n if (!acc) return r.pointsEarned;\n return {\n streak: Math.max(acc.streak || 0, r.pointsEarned.streak || 0), // Use highest streak points\n volume: (acc.volume || 0) + (r.pointsEarned.volume || 0), // Sum volume bonuses\n share: Math.max(acc.share || 0, r.pointsEarned.share || 0), // Use highest share bonus\n total: (acc.total || 0) + (r.pointsEarned.total || 0), // Sum total points\n message: r.pointsEarned.message || acc.message // Use latest message\n };\n }, null as PointsEarned | null);\n\n return {\n success: results.every(r => r.success),\n created: results.reduce((sum, r) => sum + (r.created || 0), 0),\n duplicates: results.reduce((sum, r) => sum + (r.duplicates || 0), 0),\n sessionsProcessed: results.reduce((sum, r) => sum + ((r.created || 0) + (r.duplicates || 0)), 0),\n analysisPreview: results[0]?.analysisPreview,\n streak: results[results.length - 1]?.streak,\n pointsEarned: pointsEarned || undefined,\n batchId: results.find(r => r.batchId)?.batchId,\n };\n }\n\n async getStreak(): Promise<StreakInfo> {\n const response = await this.client.get('/api/user/streak');\n return response.data;\n }\n\n async updateTelemetry(telemetry: CliTelemetry): Promise<void> {\n // Only called if user has auth token (checked in telemetry.ts)\n await this.client.post('/api/cli-telemetry', telemetry);\n }\n\n async getRecentSessions(limit: number = 10, startDate?: Date, endDate?: Date): Promise<any[]> {\n // Validate limit\n const safeLimit = Math.min(Math.max(1, limit), 100);\n\n const params: any = { limit: safeLimit };\n\n if (startDate) {\n params.start = startDate.toISOString();\n }\n\n if (endDate) {\n params.end = endDate.toISOString();\n }\n\n const response = await this.client.get('/api/sessions/recent', {\n params,\n });\n\n // The API returns { sessions: [...], count: number }\n // Extract just the sessions array\n if (response.data && typeof response.data === 'object' && 'sessions' in response.data) {\n return response.data.sessions;\n }\n\n // Fallback for backward compatibility (if API changes)\n return response.data;\n }\n \n getBaseUrl(): string {\n return this.client.defaults.baseURL || 'http://localhost:3000';\n }\n}\n\nexport const apiClient = new SecureApiClient();","import { getToken } from '../config';\nimport { apiClient } from '../api-client';\n\nexport async function isAuthenticated(): Promise<boolean> {\n const token = await getToken();\n if (!token) return false;\n\n try {\n const { valid } = await apiClient.verifyToken();\n return valid;\n } catch (error) {\n return false;\n }\n}\n\nexport async function requireAuth(): Promise<void> {\n const authenticated = await isAuthenticated();\n if (!authenticated) {\n throw new Error('Authentication required. Please run: npx devark-cli');\n }\n}\n\nexport { getToken, clearToken, storeToken } from '../config';","/**\n * Filters images from Claude Code message content\n * Replaces base64-encoded images with placeholders to prevent them from being uploaded\n * This dramatically improves performance by avoiding regex operations on 500KB+ strings\n */\n\n/**\n * Filter images from message content and replace with placeholder text\n * @param content - The raw message content (can be string, array, or object)\n * @returns Filtered content as a string with image placeholders\n */\nexport function filterImageContent(content: any): string {\n // Handle null or undefined content\n if (content === null || content === undefined) {\n return '';\n }\n\n // If content is already a string, return as-is\n if (typeof content === 'string') {\n return content;\n }\n\n // Handle structured content arrays (Claude's format for messages with images)\n if (Array.isArray(content)) {\n const textParts: string[] = [];\n let imageCount = 0;\n\n for (const item of content) {\n if (typeof item === 'object' && item !== null) {\n // Extract text content\n if (item.type === 'text' && item.text) {\n textParts.push(item.text);\n } \n // Count images but don't include their data\n else if (item.type === 'image') {\n imageCount++;\n }\n } else if (typeof item === 'string') {\n // Handle plain string items in array\n textParts.push(item);\n }\n }\n\n // Combine text parts and add image count indicator\n let result = textParts.join(' ').trim();\n if (imageCount > 0) {\n const attachment = imageCount === 1 ? 'attachment' : 'attachments';\n result = result ? `${result} [${imageCount} image ${attachment}]` : `[${imageCount} image ${attachment}]`;\n }\n \n return result || '';\n }\n\n // For any other object type, stringify it (shouldn't normally happen)\n if (typeof content === 'object') {\n // Check if it's a single image object\n if (content.type === 'image') {\n return '[1 image attachment]';\n }\n // Check if it's a text object\n if (content.type === 'text' && content.text) {\n return content.text;\n }\n // Fall back to stringification for unknown objects\n return JSON.stringify(content);\n }\n\n // Fall back to string conversion for any other type\n return String(content);\n}\n\n/**\n * Check if content contains images (for logging/debugging purposes)\n * @param content - The raw message content\n * @returns True if content contains images\n */\nexport function containsImages(content: any): boolean {\n if (!content || typeof content !== 'object') {\n return false;\n }\n\n if (Array.isArray(content)) {\n return content.some(item => \n typeof item === 'object' && \n item !== null && \n item.type === 'image'\n );\n }\n\n return content.type === 'image';\n}\n\n/**\n * Get count of images in content\n * @param content - The raw message content\n * @returns Number of images found\n */\nexport function countImages(content: any): number {\n if (!content || typeof content !== 'object') {\n return 0;\n }\n\n if (Array.isArray(content)) {\n return content.filter(item => \n typeof item === 'object' && \n item !== null && \n item.type === 'image'\n ).length;\n }\n\n return content.type === 'image' ? 1 : 0;\n}","/**\n * Language Extractor Module\n * \n * This module provides a centralized way to extract programming languages\n * from Claude Code session data. It handles multiple patterns including\n * toolUseResult events and direct tool use calls.\n */\n\nimport path from 'path';\n\n/**\n * Comprehensive mapping of file extensions to programming languages\n * Easy to extend - just add new mappings here\n */\nexport const LANGUAGE_MAPPINGS: Record<string, string> = {\n // JavaScript ecosystem\n js: 'JavaScript',\n jsx: 'JavaScript',\n mjs: 'JavaScript',\n cjs: 'JavaScript',\n \n // TypeScript\n ts: 'TypeScript',\n tsx: 'TypeScript',\n mts: 'TypeScript',\n cts: 'TypeScript',\n \n // Python\n py: 'Python',\n pyw: 'Python',\n pyx: 'Python',\n pyi: 'Python',\n \n // Web technologies\n html: 'HTML',\n htm: 'HTML',\n xhtml: 'HTML',\n css: 'CSS',\n scss: 'SCSS',\n sass: 'Sass',\n less: 'Less',\n styl: 'Stylus',\n \n // Data formats\n json: 'JSON',\n jsonc: 'JSON',\n json5: 'JSON',\n xml: 'XML',\n yaml: 'YAML',\n yml: 'YAML',\n toml: 'TOML',\n \n // Markdown and documentation\n md: 'Markdown',\n mdx: 'Markdown',\n markdown: 'Markdown',\n rst: 'reStructuredText',\n txt: 'Text',\n \n // Shell scripting\n sh: 'Shell',\n bash: 'Bash',\n zsh: 'Zsh',\n fish: 'Fish',\n ps1: 'PowerShell',\n psm1: 'PowerShell',\n psd1: 'PowerShell',\n bat: 'Batch',\n cmd: 'Batch',\n \n // System languages\n c: 'C',\n h: 'C',\n cpp: 'C++',\n cc: 'C++',\n cxx: 'C++',\n hpp: 'C++',\n hh: 'C++',\n hxx: 'C++',\n \n // JVM languages\n java: 'Java',\n kt: 'Kotlin',\n kts: 'Kotlin',\n scala: 'Scala',\n sc: 'Scala',\n groovy: 'Groovy',\n gradle: 'Groovy',\n \n // .NET languages\n cs: 'C#',\n fs: 'F#',\n fsx: 'F#',\n vb: 'Visual Basic',\n \n // Modern systems languages\n rs: 'Rust',\n go: 'Go',\n zig: 'Zig',\n \n // Mobile development\n swift: 'Swift',\n m: 'Objective-C', // .m files are typically Objective-C\n mm: 'Objective-C',\n dart: 'Dart',\n \n // Scripting languages\n rb: 'Ruby',\n php: 'PHP',\n pl: 'Perl',\n pm: 'Perl',\n lua: 'Lua',\n \n // Functional languages\n hs: 'Haskell',\n lhs: 'Haskell',\n elm: 'Elm',\n clj: 'Clojure',\n cljs: 'ClojureScript',\n erl: 'Erlang',\n ex: 'Elixir',\n exs: 'Elixir',\n \n // Database\n sql: 'SQL',\n pgsql: 'PostgreSQL',\n mysql: 'MySQL',\n \n // Data science\n r: 'R',\n R: 'R',\n rmd: 'R Markdown',\n ipynb: 'Jupyter Notebook',\n jl: 'Julia',\n mat: 'MATLAB',\n \n // Configuration\n dockerfile: 'Docker',\n Dockerfile: 'Docker',\n dockerignore: 'Docker',\n makefile: 'Makefile',\n Makefile: 'Makefile',\n cmake: 'CMake',\n \n // Web frameworks\n vue: 'Vue',\n svelte: 'Svelte',\n astro: 'Astro',\n \n // Infrastructure\n tf: 'Terraform',\n tfvars: 'Terraform',\n \n // Other\n graphql: 'GraphQL',\n gql: 'GraphQL',\n proto: 'Protocol Buffers',\n wasm: 'WebAssembly',\n wat: 'WebAssembly',\n vim: 'Vim Script',\n el: 'Emacs Lisp',\n};\n\n/**\n * File extensions to explicitly ignore (not programming languages)\n * These are common file types that should not be counted as languages\n */\nconst IGNORED_EXTENSIONS = new Set([\n // Images\n 'png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'ico', 'webp', 'avif', 'tiff', 'tif',\n // Videos\n 'mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv', 'mpg', 'mpeg', 'm4v', '3gp',\n // Audio\n 'mp3', 'wav', 'flac', 'aac', 'ogg', 'wma', 'm4a', 'opus',\n // Documents\n 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'ods', 'odp',\n // Archives\n 'zip', 'tar', 'gz', 'rar', '7z', 'bz2', 'xz', 'tgz',\n // Fonts\n 'ttf', 'otf', 'woff', 'woff2', 'eot',\n // Binary/Data\n 'exe', 'dll', 'so', 'dylib', 'bin', 'dat', 'db', 'sqlite', 'sqlite3',\n // Certificates & Keys\n 'pem', 'crt', 'key', 'cer', 'pfx', 'p12',\n // Logs\n 'log',\n // Lock files\n 'lock',\n // Environment\n 'env',\n // macOS\n 'DS_Store',\n // Git\n 'gitignore', 'gitattributes', 'gitmodules', 'gitkeep',\n // NPM\n 'npmignore', 'npmrc',\n // Editor configs\n 'editorconfig', 'prettierrc', 'prettierignore', 'eslintignore',\n // Other\n 'bak', 'tmp', 'temp', 'cache', 'swp', 'swo'\n]);\n\n/**\n * Tool names that involve file operations\n * These are the Claude Code tools we check for file paths\n */\nconst FILE_OPERATION_TOOLS = [\n 'Edit',\n 'Write',\n 'MultiEdit',\n 'NotebookEdit',\n 'Read',\n 'Create',\n 'Delete',\n 'Move',\n 'Copy',\n];\n\n/**\n * Get the programming language from a file extension\n * @param ext - File extension (with or without dot)\n * @returns The programming language name or null if not a programming language\n */\nexport function getLanguageFromExtension(ext: string): string | null {\n // Remove leading dot if present\n const cleanExt = ext.startsWith('.') ? ext.slice(1) : ext;\n \n // Check if this extension should be ignored\n if (IGNORED_EXTENSIONS.has(cleanExt.toLowerCase())) {\n return null;\n }\n \n // Look up in mappings (case-insensitive for most extensions)\n const language = LANGUAGE_MAPPINGS[cleanExt.toLowerCase()] || \n LANGUAGE_MAPPINGS[cleanExt];\n \n // Return mapped language or null for unknown extensions\n return language || null;\n}\n\n/**\n * Extract file path from a tool use event\n * Handles different tool parameter structures\n */\nexport function extractFilePathFromToolUse(data: any): string | null {\n // Check for toolUseResult pattern (already processed results)\n if (data.toolUseResult) {\n const result = data.toolUseResult;\n \n // Handle file operations in toolUseResult\n if (result.type === 'create' || result.type === 'update') {\n return result.filePath || null;\n }\n \n // Handle text results with file information\n if (result.type === 'text' && result.file?.filePath) {\n return result.file.filePath;\n }\n }\n \n // Check for direct tool use pattern\n if (data.toolUse) {\n const toolUse = data.toolUse;\n \n // Check if it's a file operation tool\n if (FILE_OPERATION_TOOLS.includes(toolUse.name)) {\n // Try different parameter patterns\n const params = toolUse.params || toolUse.parameters || {};\n \n // Common parameter names for file paths\n const filePath = params.file_path || \n params.filePath || \n params.path ||\n params.filename ||\n params.file;\n \n if (filePath) {\n return filePath;\n }\n \n // For MultiEdit, check edits array\n if (toolUse.name === 'MultiEdit' && params.edits) {\n // Return the file being edited (same for all edits in MultiEdit)\n return params.file_path || params.filePath || null;\n }\n \n // For NotebookEdit, check notebook_path\n if (toolUse.name === 'NotebookEdit' && params.notebook_path) {\n return params.notebook_path;\n }\n }\n }\n \n // Check for message content with tool use (alternate format)\n if (data.message?.content && Array.isArray(data.message.content)) {\n for (const item of data.message.content) {\n if (item.type === 'tool_use' && FILE_OPERATION_TOOLS.includes(item.name)) {\n const input = item.input || {};\n const filePath = input.file_path || \n input.filePath || \n input.path ||\n input.notebook_path ||\n input.filename;\n if (filePath) {\n return filePath;\n }\n }\n }\n }\n \n return null;\n}\n\n/**\n * Extract all languages from a Claude Code session\n * @param lines - Array of JSONL lines (as strings)\n * @returns Array of unique language names used in the session\n */\nexport function extractLanguagesFromSession(lines: string[]): string[] {\n const languages = new Set<string>();\n const processedFiles = new Set<string>();\n \n for (const line of lines) {\n if (!line.trim()) continue;\n \n try {\n const data = JSON.parse(line);\n \n // Extract file path from the data\n const filePath = extractFilePathFromToolUse(data);\n \n if (filePath && !processedFiles.has(filePath)) {\n processedFiles.add(filePath);\n \n // Check for special files without extensions (like Dockerfile)\n const basename = path.basename(filePath).toLowerCase();\n if (LANGUAGE_MAPPINGS[basename]) {\n languages.add(LANGUAGE_MAPPINGS[basename]);\n } else {\n // Extract extension and get language\n const ext = path.extname(filePath).slice(1).toLowerCase();\n if (ext) {\n const language = getLanguageFromExtension(ext);\n if (language) {\n languages.add(language);\n }\n }\n }\n }\n } catch (err) {\n // Skip invalid JSON lines\n continue;\n }\n }\n \n // Return sorted array of unique languages\n return Array.from(languages).sort();\n}\n\n/**\n * Extract languages from a single JSONL entry\n * Useful for processing streaming data\n */\nexport function extractLanguageFromEntry(data: any): string | null {\n const filePath = extractFilePathFromToolUse(data);\n \n if (filePath) {\n // Check for special files without extensions (like Dockerfile)\n const basename = path.basename(filePath).toLowerCase();\n if (LANGUAGE_MAPPINGS[basename]) {\n return LANGUAGE_MAPPINGS[basename];\n }\n \n // Extract extension and get language\n const ext = path.extname(filePath).slice(1).toLowerCase();\n if (ext) {\n return getLanguageFromExtension(ext); // This already returns null for ignored extensions\n }\n }\n \n return null;\n}\n\n/**\n * Get statistics about languages in a session\n * Returns a map of language to file count\n */\nexport function getLanguageStatistics(lines: string[]): Map<string, number> {\n const stats = new Map<string, number>();\n \n for (const line of lines) {\n if (!line.trim()) continue;\n \n try {\n const data = JSON.parse(line);\n const filePath = extractFilePathFromToolUse(data);\n \n if (filePath) {\n let language: string | null = null;\n \n // Check for special files without extensions (like Dockerfile)\n const basename = path.basename(filePath).toLowerCase();\n if (LANGUAGE_MAPPINGS[basename]) {\n language = LANGUAGE_MAPPINGS[basename];\n } else {\n // Extract extension and get language\n const ext = path.extname(filePath).slice(1).toLowerCase();\n if (ext) {\n language = getLanguageFromExtension(ext);\n }\n }\n \n if (language) {\n stats.set(language, (stats.get(language) || 0) + 1);\n }\n }\n } catch (err) {\n continue;\n }\n }\n \n return stats;\n}\n\n/**\n * Check if a session used a specific language\n */\nexport function sessionUsesLanguage(lines: string[], targetLanguage: string): boolean {\n const languages = extractLanguagesFromSession(lines);\n return languages.includes(targetLanguage);\n}\n\n/**\n * Get all supported file extensions\n * Useful for documentation or UI\n */\nexport function getSupportedExtensions(): string[] {\n return Object.keys(LANGUAGE_MAPPINGS).sort();\n}\n\n/**\n * Get all supported languages\n * Returns unique language names\n */\nexport function getSupportedLanguages(): string[] {\n const uniqueLanguages = new Set(Object.values(LANGUAGE_MAPPINGS));\n return Array.from(uniqueLanguages).sort();\n}","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport { SessionData, Message, ReaderOptions } from './types';\nimport { DevArkError } from '../../utils/errors';\nimport { filterImageContent } from './image-filter';\nimport { extractLanguagesFromSession } from '../language-extractor';\n\ninterface ClaudeMessage {\n role: string;\n content: string | any[]; // Content can be string or array of content items\n timestamp: string;\n model?: string; // Model ID for assistant messages\n}\n\ninterface ClaudeLogEntry {\n sessionId?: string;\n cwd?: string;\n timestamp?: string;\n message?: ClaudeMessage;\n type?: string;\n files?: string[];\n gitBranch?: string; // Git branch from JSONL\n toolUseResult?: {\n type: string;\n filePath?: string;\n };\n}\n\n/**\n * Quickly extract session timestamp from first few lines of JSONL file\n * Returns null if no timestamp found or file can't be read\n */\nasync function quickExtractTimestamp(filePath: string): Promise<Date | null> {\n try {\n // Read only first 2KB of file (should contain timestamp in first few lines)\n const fd = await fs.open(filePath, 'r');\n const buffer = Buffer.alloc(2048);\n const { bytesRead } = await fd.read(buffer, 0, 2048, 0);\n await fd.close();\n \n if (bytesRead === 0) return null;\n \n // Convert buffer to string and split into lines\n const content = buffer.toString('utf-8', 0, bytesRead);\n const lines = content.split('\\n').slice(0, 10); // Check first 10 lines max\n \n for (const line of lines) {\n if (!line.trim()) continue;\n \n try {\n const data = JSON.parse(line);\n if (data.timestamp) {\n return new Date(data.timestamp);\n }\n } catch {\n // Invalid JSON line, skip\n continue;\n }\n }\n \n return null;\n } catch {\n return null;\n }\n}\n\nexport async function readClaudeSessions(\n options: ReaderOptions = {}\n): Promise<SessionData[]> {\n const claudePath = path.join(os.homedir(), '.claude', 'projects');\n\n try {\n await fs.access(claudePath);\n } catch (error) {\n throw new DevArkError(\n 'Claude Code data not found. Make sure Claude Code is installed and you have used it at least once.',\n 'CLAUDE_NOT_FOUND'\n );\n }\n\n const sessions: SessionData[] = [];\n const projects = await fs.readdir(claudePath);\n\n for (const project of projects) {\n const projectPath = path.join(claudePath, project);\n const stat = await fs.stat(projectPath);\n \n if (!stat.isDirectory()) continue;\n\n const files = await fs.readdir(projectPath);\n const logFiles = files.filter((f) => f.endsWith('.jsonl'));\n\n for (const file of logFiles) {\n const filePath = path.join(projectPath, file);\n \n // OPTIMIZATION 1: Skip files older than the since date\n if (options.since) {\n const fileStat = await fs.stat(filePath);\n if (fileStat.mtime < options.since) {\n // File hasn't been modified since our cutoff date, skip it entirely\n continue;\n }\n \n // OPTIMIZATION 2: Quick check of session timestamp\n const sessionTimestamp = await quickExtractTimestamp(filePath);\n if (sessionTimestamp && sessionTimestamp < options.since) {\n // Session started before our cutoff date, skip it\n continue;\n }\n }\n \n // Now read and parse the full file\n const session = await parseSessionFile(filePath);\n \n if (session) {\n // Apply filters (timestamp check now redundant but kept for safety)\n if (options.since && session.timestamp < options.since) continue;\n // Filter by project path - include exact matches and subdirectories\n if (options.projectPath) {\n const normalizedSessionPath = path.normalize(session.projectPath).toLowerCase();\n const normalizedFilterPath = path.normalize(options.projectPath).toLowerCase();\n \n // Check if session is in the target directory or a subdirectory\n if (!normalizedSessionPath.startsWith(normalizedFilterPath)) {\n continue;\n }\n }\n \n // Add source file information for re-reading\n session.sourceFile = {\n claudeProjectPath: projectPath,\n sessionFile: file\n };\n \n sessions.push(session);\n \n if (options.limit && sessions.length >= options.limit) {\n break;\n }\n }\n }\n \n if (options.limit && sessions.length >= options.limit) {\n break;\n }\n }\n\n return sessions.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n}\n\nasync function parseSessionFile(filePath: string): Promise<SessionData | null> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.trim().split('\\n');\n\n const messages: Message[] = [];\n let metadata: {\n id: string;\n projectPath: string;\n timestamp: Date;\n claudeSessionId?: string;\n } | null = null;\n const editedFiles = new Set<string>();\n \n // Model tracking variables\n const modelStats: Record<string, number> = {};\n let lastModel: string | null = null;\n let modelSwitches = 0;\n \n // Planning mode tracking variables\n const exitPlanTimestamps: Date[] = [];\n \n // Git branch tracking\n let gitBranch: string | undefined;\n\n for (const line of lines) {\n if (!line.trim()) continue;\n \n try {\n const data: ClaudeLogEntry = JSON.parse(line);\n\n // Extract git branch from the first entry that has it\n if (!gitBranch && data.gitBranch) {\n gitBranch = data.gitBranch;\n }\n\n // Extract session metadata from first valid entry\n if (!metadata && data.sessionId && data.cwd && data.timestamp) {\n metadata = {\n id: data.sessionId,\n projectPath: data.cwd,\n timestamp: new Date(data.timestamp),\n claudeSessionId: data.sessionId, // Store the Claude session ID\n };\n }\n\n // Extract messages and track model usage\n if (data.message && data.timestamp) {\n // Check for ExitPlanMode tool usage in message content\n if (data.message.content && Array.isArray(data.message.content)) {\n for (const item of data.message.content) {\n if (item.type === 'tool_use' && item.name === 'ExitPlanMode') {\n exitPlanTimestamps.push(new Date(data.timestamp));\n }\n }\n }\n \n // Filter images from content before adding to messages\n const filteredContent = filterImageContent(data.message.content);\n \n messages.push({\n role: data.message.role as 'user' | 'assistant',\n content: filteredContent,\n timestamp: new Date(data.timestamp),\n });\n \n // Track model usage for assistant messages\n if (data.message.role === 'assistant' && data.message.model) {\n modelStats[data.message.model] = (modelStats[data.message.model] || 0) + 1;\n \n // Track model switches\n if (lastModel && lastModel !== data.message.model) {\n modelSwitches++;\n }\n lastModel = data.message.model;\n }\n }\n\n // Track edited files from toolUseResult (for backward compatibility)\n if (data.toolUseResult && (data.toolUseResult.type === 'create' || data.toolUseResult.type === 'update')) {\n const filePath = data.toolUseResult.filePath;\n if (filePath) {\n editedFiles.add(filePath);\n }\n }\n } catch (err) {\n // Skip invalid JSON lines\n continue;\n }\n }\n\n if (!metadata || messages.length === 0) return null;\n\n const duration = calculateDuration(messages);\n \n // Use the language extractor to get all languages used in the session\n const languages = extractLanguagesFromSession(lines);\n \n // Prepare model info if models were detected\n let modelInfo: SessionData['modelInfo'] = undefined;\n if (Object.keys(modelStats).length > 0) {\n const models = Object.keys(modelStats);\n const primaryModel = models.reduce((a, b) => \n modelStats[a] > modelStats[b] ? a : b\n );\n \n modelInfo = {\n models,\n primaryModel,\n modelUsage: modelStats,\n modelSwitches,\n };\n }\n \n // Prepare planning mode info if detected\n let planningModeInfo: SessionData['planningModeInfo'] = undefined;\n if (exitPlanTimestamps.length > 0) {\n planningModeInfo = {\n hasPlanningMode: true,\n planningCycles: exitPlanTimestamps.length,\n exitPlanTimestamps: exitPlanTimestamps,\n };\n }\n\n return {\n ...metadata,\n messages,\n duration,\n tool: 'claude_code',\n metadata: {\n files_edited: editedFiles.size,\n languages: languages,\n },\n modelInfo,\n planningModeInfo,\n gitBranch,\n };\n } catch (error) {\n console.error(`Error parsing session file ${filePath}:`, error);\n return null;\n }\n}\n\nfunction calculateDuration(messages: Message[]): number {\n if (messages.length < 2) return 0;\n\n let totalActiveTime = 0;\n const MAX_IDLE_GAP = 15 * 60; // 15 minutes in seconds\n const MAX_SESSION_DURATION = 8 * 60 * 60; // 8 hours max\n\n // Sum gaps between consecutive messages, excluding long idle periods\n for (let i = 1; i < messages.length; i++) {\n const gapSeconds = Math.floor(\n (messages[i].timestamp.getTime() - messages[i-1].timestamp.getTime()) / 1000\n );\n\n // Only count gaps <= 15 minutes as active coding time\n if (gapSeconds > 0 && gapSeconds <= MAX_IDLE_GAP) {\n totalActiveTime += gapSeconds;\n }\n // Gaps > 15 minutes are considered breaks/idle time (not counted)\n }\n\n // Cap at 8 hours max for safety\n return Math.min(totalActiveTime, MAX_SESSION_DURATION);\n}","import { Message } from './readers/types';\n\n/**\n * Sanitizes messages by redacting sensitive information while preserving context\n * This allows for meaningful analysis while protecting user privacy\n */\n\ninterface SanitizedMessage {\n role: 'user' | 'assistant' | 'system';\n content: string; // Sanitized content - sensitive data redacted\n timestamp: string;\n metadata: {\n hasCode: boolean;\n redactedItems: {\n codeBlocks: number;\n credentials: number;\n envVars: number;\n paths: number;\n urls: number;\n emails: number;\n };\n originalLength: number;\n sanitizedLength: number;\n };\n}\n\n// Naming system for consistent entity replacement\nclass EntityNamer {\n private counters: Map<string, number> = new Map();\n \n getName(type: string): string {\n const count = (this.counters.get(type) || 0) + 1;\n this.counters.set(type, count);\n return `${type}_${count}`;\n }\n \n reset(): void {\n this.counters.clear();\n }\n}\n\nexport class MessageSanitizer {\n private entityNamer = new EntityNamer();\n private debugMode = process.env.DEVARK_DEBUG === 'true';\n private debugCredentials: Array<{ text: string; pattern: string }> = [];\n \n sanitizeMessages(messages: Message[]): SanitizedMessage[] {\n // Reset naming for each session to maintain consistency\n this.entityNamer.reset();\n this.debugCredentials = [];\n return messages.map(msg => this.sanitizeMessage(msg));\n }\n \n getDebugCredentials(): Array<{ text: string; pattern: string }> {\n return this.debugCredentials;\n }\n \n private sanitizeMessage(message: Message): SanitizedMessage {\n const timestamp = message.timestamp instanceof Date \n ? message.timestamp.toISOString()\n : new Date(message.timestamp).toISOString();\n \n const { content, metadata } = this.sanitizeContent(message.content);\n \n return {\n role: message.role,\n content,\n timestamp,\n metadata: {\n hasCode: metadata.codeBlocks > 0,\n redactedItems: {\n codeBlocks: metadata.codeBlocks,\n credentials: metadata.credentials,\n envVars: metadata.envVars,\n paths: metadata.paths,\n urls: metadata.urls,\n emails: metadata.emails,\n },\n originalLength: typeof message.content === 'string' ? message.content.length : JSON.stringify(message.content).length,\n sanitizedLength: content.length,\n },\n };\n }\n \n private sanitizeContent(content: any): { content: string; metadata: any } {\n // Safety check: detect and filter any large base64 data that slipped through\n if (typeof content === 'object' && content !== null) {\n // Check if it's an array with image attachments\n if (Array.isArray(content)) {\n // Filter to text only\n const textContent = content\n .filter((item: any) => item.type !== 'image')\n .map((item: any) => item.text || item)\n .filter(Boolean)\n .join(' ');\n \n const imageCount = content.filter((item: any) => item.type === 'image').length;\n content = textContent + (imageCount > 0 ? ` [${imageCount} image(s) removed]` : '');\n }\n }\n \n // Handle object content (e.g., assistant messages with structured data)\n let sanitized: string;\n if (typeof content === 'object' && content !== null) {\n // If it's an object, stringify it to preserve the content\n sanitized = JSON.stringify(content, null, 2);\n } else {\n sanitized = String(content);\n }\n const metadata = {\n codeBlocks: 0,\n credentials: 0,\n envVars: 0,\n paths: 0,\n urls: 0,\n emails: 0,\n };\n \n // 1. Redact code blocks but keep description\n sanitized = sanitized.replace(/```[\\s\\S]*?```/g, (match) => {\n metadata.codeBlocks++;\n const lang = match.match(/```(\\w+)/)?.[1] || 'code';\n return `[CODE_BLOCK_${this.entityNamer.getName('code')}: ${lang}]`;\n });\n \n // 2. Redact inline code but keep context\n sanitized = sanitized.replace(/`[^`]+`/g, (match) => {\n // Check if it's a credential-like pattern\n if (this.looksLikeCredential(match)) {\n metadata.credentials++;\n if (this.debugMode) {\n // Store debug info for inline code detected as credential\n const preview = match.length > 20 ? match.substring(0, 20) + '...' : match;\n this.debugCredentials.push({ text: preview, pattern: 'Inline code (credential-like)' });\n }\n return `[CREDENTIAL_${this.entityNamer.getName('credential')}]`;\n }\n metadata.codeBlocks++; // Count inline code as code blocks\n return `[CODE_${this.entityNamer.getName('inline_code')}]`;\n });\n \n // 3. Redact API keys and tokens - optimized for performance\n // First, do a quick check if the content likely contains credentials\n const hasLikelyCredentials = /\\b(sk[-_]|pk[-_]|rk_|gh[ps]_|gho_|ghu_|ghr_|AKIA|xox[bp]-|npm_|SG\\.|bearer\\s+)/i.test(sanitized);\n \n if (hasLikelyCredentials) {\n // Only run specific patterns if we found indicators\n const credentialPatterns: Array<{ pattern: RegExp; name: string }> = [\n // Most common patterns first for better performance\n // GitHub tokens (very common in dev environments)\n { pattern: /\\bgh[ps]_[a-zA-Z0-9]{36,}\\b/g, name: 'GitHub token' },\n { pattern: /\\bgho_[a-zA-Z0-9]{36,}\\b/g, name: 'GitHub OAuth token' },\n \n // Stripe keys (common in web dev)\n { pattern: /\\bsk[-_](test|live)[-_][a-zA-Z0-9_-]{24,}\\b/g, name: 'Stripe secret key' },\n { pattern: /\\bpk[-_](test|live)[-_][a-zA-Z0-9_-]{24,}\\b/g, name: 'Stripe publishable key' },\n \n // Bearer tokens (common in API calls)\n { pattern: /bearer\\s+[a-zA-Z0-9\\-._~+/]+=*/gi, name: 'Bearer token' },\n \n // OpenAI/Anthropic keys (increasingly common)\n { pattern: /\\bsk-[a-zA-Z0-9]{48,}\\b/g, name: 'OpenAI API key' },\n { pattern: /\\bsk-ant-[a-zA-Z0-9]{48,}\\b/g, name: 'Anthropic API key' },\n \n // Less common patterns\n { pattern: /\\brk_(live|test)_[a-zA-Z0-9]{24,}\\b/g, name: 'Stripe restricted key' },\n { pattern: /\\bghu_[a-zA-Z0-9]{36,}\\b/g, name: 'GitHub user token' },\n { pattern: /\\bghr_[a-zA-Z0-9]{36,}\\b/g, name: 'GitHub refresh token' },\n { pattern: /\\bAKIA[A-Z0-9]{16}\\b/g, name: 'AWS Access Key' },\n { pattern: /\\bAAAA[A-Za-z0-9_-]{32,}\\b/g, name: 'Firebase/GCP token' },\n { pattern: /\\bSG\\.[a-zA-Z0-9_-]{22}\\.[a-zA-Z0-9_-]{43}\\b/g, name: 'SendGrid API key' },\n { pattern: /\\bxox[bp]-[0-9]{10,}-[a-zA-Z0-9]{24,}/g, name: 'Slack token' },\n { pattern: /\\bnpm_[a-zA-Z0-9]{36,}\\b/g, name: 'NPM token' },\n ];\n \n // Skip AWS Secret Key pattern - it's too expensive with lookahead\n // and rarely matches real secrets\n \n credentialPatterns.forEach(({ pattern, name }) => {\n sanitized = sanitized.replace(pattern, (match) => {\n metadata.credentials++;\n if (this.debugMode) {\n // Store debug info (truncate for safety)\n const preview = match.length > 20 ? match.substring(0, 20) + '...' : match;\n this.debugCredentials.push({ text: preview, pattern: name });\n }\n return `[CREDENTIAL_${this.entityNamer.getName('credential')}]`;\n });\n });\n }\n \n // Note: Removed generic long token check - it was causing 400K+ false positives\n // Real credentials are already caught by the specific patterns above\n \n // 4. Redact environment variables\n sanitized = sanitized.replace(/\\$\\{?[A-Z_][A-Z0-9_]*\\}?/g, (_match) => {\n metadata.envVars++;\n return `[ENV_VAR_${this.entityNamer.getName('env_var')}]`;\n });\n \n // 5. Redact file paths but keep general structure\n const pathPatterns = [\n /[A-Z]:\\\\[\\w\\\\.-]+/g, // Windows paths\n /\\/(?:home|usr|var|etc|Users)\\/[\\w/.-]+/g, // Unix paths\n /\\.\\.?\\/[\\w/.-]+/g, // Relative paths\n ];\n \n pathPatterns.forEach(pattern => {\n sanitized = sanitized.replace(pattern, (_match) => {\n metadata.paths++;\n return `[PATH_${this.entityNamer.getName('path')}]`;\n });\n });\n \n // 6. Redact URLs but keep domain type (including database URLs)\n sanitized = sanitized.replace(\n /(?:https?|postgres|mysql|mongodb|redis):\\/\\/[^\\s<>\"{}|\\\\^`[\\]]+/g,\n (url) => {\n metadata.urls++;\n // Database URLs take precedence\n if (url.startsWith('postgres') || url.startsWith('mysql') || url.startsWith('mongodb') || url.startsWith('redis')) {\n return '[DATABASE_URL]';\n }\n if (url.includes('github.com')) return '[GITHUB_URL]';\n if (url.includes('localhost') || url.includes('127.0.0.1')) return '[LOCAL_URL]';\n if (url.includes('api')) return '[API_URL]';\n return `[URL_${this.entityNamer.getName('url')}]`;\n }\n );\n \n // 7. Redact email addresses\n sanitized = sanitized.replace(\n /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g,\n () => {\n metadata.emails++;\n return `[EMAIL_${this.entityNamer.getName('email')}]`;\n }\n );\n \n // 8. Redact IP addresses\n sanitized = sanitized.replace(\n /\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b/g,\n '[IP_ADDRESS]'\n );\n \n // 9. Redact potential passwords in quotes\n sanitized = sanitized.replace(\n /[\"']password[\"']:\\s*[\"'][^\"']+[\"']/gi,\n '\"password\": \"[REDACTED_PASSWORD]\"'\n );\n \n return { content: sanitized, metadata };\n }\n \n private looksLikeCredential(text: string): boolean {\n // Remove backticks\n const cleaned = text.replace(/`/g, '');\n \n // Check for specific credential patterns (not generic strings)\n const credentialIndicators = [\n // Specific API key prefixes\n /^sk[-_](test|live)[-_]/, // Stripe secret keys\n /^pk[-_](test|live)[-_]/, // Stripe publishable keys\n /^rk_(live|test)_/, // Stripe restricted keys\n /^gh[ps]_/, // GitHub tokens\n /^gho_/, // GitHub OAuth\n /^ghu_/, // GitHub user\n /^ghr_/, // GitHub refresh\n /^AKIA[A-Z0-9]/, // AWS Access Key\n /^xox[bp]-/, // Slack tokens\n /^npm_/, // NPM tokens\n /^SG\\./, // SendGrid\n /^sk-[a-zA-Z0-9]{48,}/, // OpenAI style\n /^sk-ant-/, // Anthropic\n \n // Only flag as credential if it's an assignment with a literal value\n /^(api[_-]?key|api[_-]?secret|auth[_-]?token|access[_-]?token|private[_-]?key)\\s*=\\s*[\"'][^\"']+[\"']$/i,\n \n // JWT tokens (three base64 parts separated by dots)\n /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/,\n \n // Only consider hex strings as credentials if they're exactly 32, 40, or 64 chars (MD5, SHA1, SHA256)\n /^[a-f0-9]{32}$/i, // MD5\n /^[a-f0-9]{40}$/i, // SHA1 \n /^[a-f0-9]{64}$/i, // SHA256\n ];\n \n return credentialIndicators.some(pattern => pattern.test(cleaned));\n }\n \n \n}\n\n/**\n * Example usage showing transparency:\n * \n * Input: \"Check the file at /home/user/project/secret.env with API_KEY=sk_1234567890\"\n * Output: \"Check the file at [PATH_1] with [ENV_VAR_1]=[CREDENTIAL_1]\"\n * \n * Input: \"Here's my code: `const password = 'super-secret-123'`\"\n * Output: \"Here's my code: [CODE_1]\"\n * \n * This way:\n * - Context is preserved for analysis\n * - Sensitive data is protected\n * - Users can see exactly what's being redacted\n * - Consistent naming helps LLM understand relationships\n */\n\nexport function createSessionSummary(messages: SanitizedMessage[]): {\n conversationFlow: string;\n redactionSummary: {\n totalRedactions: number;\n byType: Record<string, number>;\n };\n contextPreserved: boolean;\n} {\n const totalRedactions = messages.reduce((sum, msg) => {\n const items = msg.metadata.redactedItems;\n return sum + Object.values(items).reduce((a, b) => a + b, 0);\n }, 0);\n \n const byType = messages.reduce((acc, msg) => {\n Object.entries(msg.metadata.redactedItems).forEach(([type, count]) => {\n acc[type] = (acc[type] || 0) + count;\n });\n return acc;\n }, {} as Record<string, number>);\n \n // Create a flow summary showing the conversation structure\n const conversationFlow = messages\n .map(msg => `${msg.role}: ${msg.content.substring(0, 100)}...`)\n .join('\\n');\n \n return {\n conversationFlow,\n redactionSummary: {\n totalRedactions,\n byType,\n },\n contextPreserved: true,\n };\n}","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { homedir } from 'os';\nimport { logger } from '../utils/logger';\n\n/**\n * Execute a function with a timeout\n * @param fn The function to execute\n * @param timeout Maximum execution time in milliseconds\n * @param context Context for error logging\n * @returns The result of the function or null if timeout/error\n */\nexport async function withTimeout<T>(\n fn: () => Promise<T>,\n timeout: number,\n context: string\n): Promise<T | null> {\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Timeout after ${timeout}ms`)), timeout);\n });\n\n try {\n return await Promise.race([fn(), timeoutPromise]);\n } catch (error) {\n await logHookError(context, error);\n return null;\n }\n}\n\n/**\n * Log hook errors to a file\n * @param context The context where the error occurred\n * @param error The error object\n */\nexport async function logHookError(context: string, error: any): Promise<void> {\n try {\n const logDir = path.join(homedir(), '.devark');\n const logPath = path.join(logDir, 'hooks.log');\n \n // Ensure directory exists\n await fs.mkdir(logDir, { recursive: true });\n \n const timestamp = new Date().toISOString();\n const errorMessage = error instanceof Error ? error.message : String(error);\n const stackTrace = error instanceof Error && error.stack ? error.stack : '';\n \n const logEntry = `[${timestamp}] ${context}: ${errorMessage}\\n${stackTrace}\\n${'='.repeat(80)}\\n`;\n \n // Append to log file\n await fs.appendFile(logPath, logEntry);\n \n // Also log to debug logger\n logger.debug(`Hook error logged: ${context}`, { error });\n } catch (logError) {\n // Silently fail if we can't write logs\n logger.error('Failed to write hook error log', logError);\n }\n}\n\n/**\n * Silent error wrapper for hook operations\n * Catches and logs errors without disrupting user experience\n */\nexport async function silentErrorWrapper<T>(\n operation: () => Promise<T>,\n context: string\n): Promise<T | null> {\n try {\n return await operation();\n } catch (error) {\n await logHookError(context, error);\n return null;\n }\n}\n\n/**\n * Get the path to the hooks log file\n */\nexport function getHooksLogPath(): string {\n return path.join(homedir(), '.devark', 'hooks.log');\n}\n\n/**\n * Clear the hooks log file\n */\nexport async function clearHooksLog(): Promise<void> {\n const logPath = getHooksLogPath();\n try {\n await fs.unlink(logPath);\n } catch (error) {\n // File might not exist, that's ok\n }\n}\n\n/**\n * Read recent hook log entries\n * @param lines Number of lines to read from the end\n */\nexport async function readHooksLog(lines: number = 50): Promise<string> {\n const logPath = getHooksLogPath();\n try {\n const content = await fs.readFile(logPath, 'utf-8');\n const allLines = content.split('\\n');\n const recentLines = allLines.slice(-lines);\n return recentLines.join('\\n');\n } catch (error) {\n return 'No hook logs found.';\n }\n}","import { requireAuth, getToken } from '../auth/token';\nimport { readClaudeSessions } from '../readers/claude';\nimport { apiClient, Session } from '../api-client';\nimport {\n getProjectSyncData,\n updateProjectSyncBoundaries,\n setLastSyncSummary\n} from '../config';\nimport { parseProjectName } from '../ui/project-display';\nimport { DevArkError } from '../../utils/errors';\nimport { logger } from '../../utils/logger';\nimport { MessageSanitizer } from '../message-sanitizer';\nimport { logHookError } from '../hook-utils';\nimport { SessionData } from '../readers/types';\nimport { SelectedSessionInfo } from '../ui/session-selector';\nimport { analyzeProject } from '../claude-core';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport { filterImageContent } from '../readers/image-filter';\nimport { extractLanguagesFromSession } from '../language-extractor';\n\nexport interface SendOptions {\n dry?: boolean;\n all?: boolean;\n silent?: boolean;\n hookTrigger?: string;\n hookVersion?: string;\n test?: boolean;\n background?: boolean;\n selectedSessions?: SelectedSessionInfo[];\n skipActionMenu?: boolean;\n claudeProjectDir?: string;\n fromMenu?: boolean; // Indicates call is from interactive menu\n isInitialSync?: boolean; // Indicates this is initial sync during hook setup\n}\n\n// Use Session type from api-client for consistency\nexport type ApiSession = Session;\n\nexport class SendOrchestrator {\n private sanitizer = new MessageSanitizer();\n\n async execute(options: SendOptions): Promise<void> {\n // Authenticate\n await this.authenticate(options);\n\n // Load sessions\n const sessions = await this.loadSessions(options);\n\n if (sessions.length === 0) {\n this.handleNoSessions(options);\n return;\n }\n\n // Sanitize and transform sessions\n const apiSessions = await this.sanitizeSessions(sessions, options);\n\n // Handle dry run\n if (options.dry) {\n this.handleDryRun(options);\n return;\n }\n\n // Upload sessions\n const results = await this.uploadSessions(apiSessions, options);\n\n // Update sync state\n await this.updateSyncState(sessions, options);\n\n // Log results\n this.logResults(results, options);\n }\n\n async authenticate(options: SendOptions): Promise<void> {\n if (options.silent) {\n const token = await getToken();\n if (!token) {\n await logHookError('Auth check', new Error('No authentication token found'));\n logger.error('No auth token, skipping silent send');\n throw new DevArkError('Not authenticated', 'AUTH_REQUIRED');\n }\n } else {\n await requireAuth();\n }\n }\n\n async loadSessions(options: SendOptions): Promise<SessionData[]> {\n // Handle pre-selected sessions\n if (options.selectedSessions && options.selectedSessions.length > 0) {\n return this.readSelectedSessions(options.selectedSessions);\n }\n\n // IMPORTANT: --all flag takes precedence over claudeProjectDir\n // This ensures global hooks capture all projects regardless of CLAUDE_PROJECT_DIR\n if (options.all) {\n // For --all mode, don't use project-specific date filtering\n const sessions = await readClaudeSessions({ since: undefined });\n return sessions;\n }\n\n // Determine date filter only for non-all modes\n const sinceDate = this.determineSinceDate(options);\n\n // Handle explicit Claude project directory (only when --all is not set)\n if (options.claudeProjectDir && options.claudeProjectDir.trim() !== '') {\n return this.loadProjectSessions(options.claudeProjectDir, sinceDate);\n }\n\n // Load all sessions and filter to current directory (default behavior)\n const sessions = await readClaudeSessions({ since: sinceDate });\n const currentDir = process.cwd();\n return sessions.filter(session => {\n const sessionPath = path.normalize(session.projectPath).toLowerCase();\n const currentPath = path.normalize(currentDir).toLowerCase();\n return sessionPath === currentPath || sessionPath.startsWith(currentPath + path.sep);\n });\n }\n\n private determineSinceDate(options: SendOptions): Date | undefined {\n if (options.hookTrigger && options.claudeProjectDir) {\n const claudeFolderName = parseProjectName(options.claudeProjectDir);\n const projectSync = getProjectSyncData(claudeFolderName);\n \n if (projectSync?.newestSyncedTimestamp) {\n return new Date(projectSync.newestSyncedTimestamp);\n }\n \n // First sync - default to 30 days\n return new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);\n }\n\n // Manual sync - no date filter\n return undefined;\n }\n\n private async loadProjectSessions(claudeProjectDir: string, sinceDate?: Date): Promise<SessionData[]> {\n const dirName = parseProjectName(claudeProjectDir);\n const project = await analyzeProject(claudeProjectDir, dirName);\n \n if (!project) {\n logger.warn('Invalid Claude project directory provided');\n return [];\n }\n \n return readClaudeSessions({\n since: sinceDate,\n projectPath: project.actualPath\n });\n }\n\n private async readSelectedSessions(selectedInfo: SelectedSessionInfo[]): Promise<SessionData[]> {\n const sessions: SessionData[] = [];\n const failedFiles: string[] = [];\n \n for (const info of selectedInfo) {\n try {\n const filePath = path.join(info.projectPath, info.sessionFile);\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.trim().split('\\n');\n \n const messages: any[] = [];\n let metadata: any = null;\n const editedFiles = new Set<string>();\n let gitBranch: string | undefined;\n \n // Model tracking variables\n const modelStats: Record<string, number> = {};\n let lastModel: string | null = null;\n let modelSwitches = 0;\n \n for (const line of lines) {\n if (!line.trim()) continue;\n \n try {\n const data = JSON.parse(line);\n \n // Extract git branch from the first entry that has it\n if (!gitBranch && data.gitBranch) {\n gitBranch = data.gitBranch;\n }\n \n if (!metadata && data.sessionId && data.cwd && data.timestamp) {\n metadata = {\n id: data.sessionId,\n projectPath: data.cwd,\n timestamp: new Date(data.timestamp),\n claudeSessionId: data.sessionId, // Store the Claude session ID\n };\n }\n \n if (data.message && data.timestamp) {\n const filteredContent = filterImageContent(data.message.content);\n \n messages.push({\n role: data.message.role,\n content: filteredContent,\n timestamp: new Date(data.timestamp),\n });\n \n // Track model usage for assistant messages\n if (data.message.role === 'assistant' && data.message.model) {\n modelStats[data.message.model] = (modelStats[data.message.model] || 0) + 1;\n \n // Track model switches\n if (lastModel && lastModel !== data.message.model) {\n modelSwitches++;\n }\n lastModel = data.message.model;\n }\n }\n \n // Track edited files from toolUseResult (for backward compatibility)\n if (data.toolUseResult && (data.toolUseResult.type === 'create' || data.toolUseResult.type === 'update')) {\n const filePath = data.toolUseResult.filePath;\n if (filePath) {\n editedFiles.add(filePath);\n }\n }\n } catch {\n // Skip invalid JSON lines\n }\n }\n \n if (metadata && messages.length > 0) {\n const duration = messages.length >= 2\n ? Math.max(0, Math.floor((messages[messages.length - 1].timestamp.getTime() - messages[0].timestamp.getTime()) / 1000))\n : 0;\n \n // Use the language extractor to get all languages used in the session\n const languages = extractLanguagesFromSession(lines);\n \n // Prepare model info if models were detected\n let modelInfo: SessionData['modelInfo'] = undefined;\n if (Object.keys(modelStats).length > 0) {\n const models = Object.keys(modelStats);\n const primaryModel = models.reduce((a, b) => \n modelStats[a] > modelStats[b] ? a : b\n );\n \n modelInfo = {\n models,\n primaryModel,\n modelUsage: modelStats,\n modelSwitches,\n };\n }\n \n sessions.push({\n ...metadata,\n messages,\n duration,\n tool: 'claude_code',\n claudeSessionId: metadata.claudeSessionId, // Include Claude session ID\n metadata: {\n files_edited: editedFiles.size,\n languages: languages,\n },\n modelInfo,\n gitBranch, // Include git branch\n });\n }\n } catch (error) {\n failedFiles.push(info.sessionFile);\n logger.warn(`Skipping corrupted session file ${info.sessionFile}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n \n if (failedFiles.length > 0) {\n logger.warn(`Failed to read ${failedFiles.length} session file(s). Continuing with ${sessions.length} valid sessions.`);\n }\n \n return sessions;\n }\n\n async sanitizeSessions(sessions: SessionData[], options?: SendOptions): Promise<ApiSession[]> {\n const apiSessions: ApiSession[] = [];\n const MIN_DURATION_SECONDS = 240; // 4 minutes minimum as required by server\n \n // Track filtered sessions for logging\n let filteredCount = 0;\n \n for (const session of sessions) {\n // Filter out sessions that are too short\n if (session.duration < MIN_DURATION_SECONDS) {\n filteredCount++;\n logger.debug(`Filtering out short session (${session.duration}s < ${MIN_DURATION_SECONDS}s) from ${session.projectPath}`);\n continue;\n }\n \n const sanitizedMessages = this.sanitizer.sanitizeMessages(session.messages);\n const projectName = parseProjectName(session.projectPath);\n \n apiSessions.push({\n tool: session.tool,\n timestamp: session.timestamp.toISOString(),\n duration: session.duration,\n claudeSessionId: session.claudeSessionId, // Include Claude session ID\n data: {\n projectName,\n messageSummary: JSON.stringify(sanitizedMessages),\n messageCount: session.messages.length,\n metadata: {\n files_edited: session.metadata?.files_edited || 0,\n languages: session.metadata?.languages || [],\n models: session.modelInfo?.models,\n primaryModel: session.modelInfo?.primaryModel || undefined,\n gitBranch: session.gitBranch, // Include git branch from JSONL\n // Planning mode metadata\n hasPlanningMode: session.planningModeInfo?.hasPlanningMode || false,\n planningCycles: session.planningModeInfo?.planningCycles || 0,\n exitPlanTimestamps: session.planningModeInfo?.exitPlanTimestamps?.map(t => t.toISOString()) || [],\n },\n },\n });\n }\n \n // Log if sessions were filtered\n if (filteredCount > 0) {\n logger.info(`Filtered out ${filteredCount} session(s) shorter than 4 minutes`);\n \n // If all sessions were filtered\n if (apiSessions.length === 0) {\n // During initial sync from hooks setup, don't throw error\n if (options?.isInitialSync) {\n logger.info('No sessions longer than 4 minutes found for initial sync');\n return apiSessions; // Return empty array, let calling code handle it gracefully\n }\n \n // For regular sync, throw error\n throw new DevArkError(\n `All ${filteredCount} session(s) were shorter than 4 minutes. Sessions must be at least 4 minutes long to upload.`,\n 'VALIDATION_ERROR'\n );\n }\n }\n \n return apiSessions;\n }\n\n async uploadSessions(\n apiSessions: ApiSession[], \n options: SendOptions,\n onProgress?: (current: number, total: number, sizeKB?: number) => void\n ): Promise<any> {\n try {\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] SendOrchestrator.uploadSessions called with', apiSessions.length, 'sessions');\n }\n logger.debug(`Uploading ${apiSessions.length} sessions to API`);\n const result = await apiClient.uploadSessions(apiSessions, onProgress);\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] Upload completed successfully');\n }\n return result;\n } catch (error) {\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] SendOrchestrator upload error:', error);\n }\n if (options.silent) {\n await logHookError('Upload sessions', error);\n logger.error('Failed to upload sessions');\n }\n throw error;\n }\n }\n\n async updateSyncState(sessions: SessionData[], options: SendOptions): Promise<void> {\n if (sessions.length === 0) return;\n \n const sortedSessions = [...sessions].sort((a, b) => \n new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()\n );\n \n const oldestSession = sortedSessions[0];\n const newestSession = sortedSessions[sortedSessions.length - 1];\n \n if (options.claudeProjectDir) {\n const claudeFolderName = parseProjectName(options.claudeProjectDir);\n const projectName = parseProjectName(process.cwd());\n \n updateProjectSyncBoundaries(\n claudeFolderName,\n oldestSession.timestamp.toISOString(),\n newestSession.timestamp.toISOString(),\n projectName,\n sessions.length\n );\n \n setLastSyncSummary(projectName);\n } else if (options.all) {\n setLastSyncSummary('all projects');\n } else {\n const projectName = parseProjectName(process.cwd());\n setLastSyncSummary(projectName);\n }\n }\n\n private handleNoSessions(options: SendOptions): void {\n if (options.silent) {\n logger.info('No sessions found');\n return;\n }\n \n // Logged warnings handled by UI layer\n logger.debug('No sessions to upload');\n }\n\n private handleDryRun(options: SendOptions): void {\n if (options.silent) {\n logger.info('Dry run - no data sent');\n } else {\n logger.debug('Dry run mode - skipping upload');\n }\n }\n\n private logResults(results: any, options: SendOptions): void {\n if (options.silent) {\n // Log success with points info if available\n if (results.pointsEarned?.total) {\n logger.info(\n `Sessions uploaded successfully! Points earned: ${results.pointsEarned.total} ` +\n `(🔥 ${results.pointsEarned.streak} streak + 📊 ${results.pointsEarned.volume} session${results.pointsEarned.volume !== 1 ? 's' : ''})`\n );\n } else {\n logger.info('Sessions uploaded successfully');\n }\n } else {\n logger.debug('Upload completed', { results });\n }\n }\n}","import { logger } from './logger';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { spawn, SpawnOptions } from 'child_process';\n\n/**\n * Version comparison result\n */\nexport interface VersionCheckResult {\n isOutdated: boolean;\n currentVersion: string;\n latestVersion: string;\n shouldUpdate: boolean;\n error?: string;\n}\n\n/**\n * Cache entry for version check\n */\ninterface VersionCache {\n latestVersion: string;\n timestamp: number;\n}\n\n// Cache duration: 5 minutes\nconst CACHE_DURATION = 5 * 60 * 1000;\n\n/**\n * Get the version cache file path\n */\nfunction getVersionCachePath(): string {\n const devarkDir = path.join(os.homedir(), '.devark');\n return path.join(devarkDir, 'version-cache.json');\n}\n\n/**\n * Get the update log file path\n */\nfunction getUpdateLogPath(): string {\n const devarkDir = path.join(os.homedir(), '.devark');\n return path.join(devarkDir, 'update.log');\n}\n\n/**\n * Log update events for debugging\n */\nasync function logUpdateEvent(message: string): Promise<void> {\n try {\n const devarkDir = path.join(os.homedir(), '.devark');\n await fs.mkdir(devarkDir, { recursive: true });\n\n const timestamp = new Date().toISOString();\n const logEntry = `[${timestamp}] ${message}\\n`;\n\n await fs.appendFile(getUpdateLogPath(), logEntry);\n } catch (error) {\n // Silently ignore logging errors\n logger.debug('Failed to log update event:', error);\n }\n}\n\n/**\n * Read cached version information\n */\nasync function readVersionCache(): Promise<VersionCache | null> {\n try {\n const cacheFile = getVersionCachePath();\n const data = await fs.readFile(cacheFile, 'utf8');\n const cache: VersionCache = JSON.parse(data);\n\n // Check if cache is still valid\n const now = Date.now();\n if (now - cache.timestamp < CACHE_DURATION) {\n return cache;\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Write version cache\n */\nasync function writeVersionCache(latestVersion: string): Promise<void> {\n try {\n const devarkDir = path.join(os.homedir(), '.devark');\n await fs.mkdir(devarkDir, { recursive: true });\n\n const cache: VersionCache = {\n latestVersion,\n timestamp: Date.now()\n };\n\n const cacheFile = getVersionCachePath();\n await fs.writeFile(cacheFile, JSON.stringify(cache, null, 2));\n } catch (error) {\n logger.debug('Failed to write version cache:', error);\n }\n}\n\n/**\n * Fetch latest version from npm registry\n */\nasync function fetchLatestVersion(): Promise<string | null> {\n try {\n // Use node's built-in https module for better reliability\n const https = await import('https');\n\n return new Promise((resolve) => {\n const req = https.get('https://registry.npmjs.org/devark-cli/latest', {\n timeout: 5000,\n headers: {\n 'User-Agent': 'devark-cli-version-check'\n }\n }, (res) => {\n let data = '';\n\n res.on('data', (chunk) => {\n data += chunk;\n });\n\n res.on('end', () => {\n try {\n const pkg = JSON.parse(data);\n resolve(pkg.version);\n } catch {\n resolve(null);\n }\n });\n });\n\n req.on('error', () => {\n resolve(null);\n });\n\n req.on('timeout', () => {\n req.destroy();\n resolve(null);\n });\n });\n } catch {\n return null;\n }\n}\n\n/**\n * Compare two semantic versions\n * Returns: -1 if a < b, 0 if a === b, 1 if a > b\n */\nfunction compareVersions(a: string, b: string): number {\n const cleanA = a.replace(/^v/, '');\n const cleanB = b.replace(/^v/, '');\n\n const partsA = cleanA.split('.').map(x => parseInt(x, 10));\n const partsB = cleanB.split('.').map(x => parseInt(x, 10));\n\n for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {\n const partA = partsA[i] || 0;\n const partB = partsB[i] || 0;\n\n if (partA < partB) return -1;\n if (partA > partB) return 1;\n }\n\n return 0;\n}\n\n/**\n * Check if CLI version is outdated and needs update\n */\nexport async function checkForUpdate(currentVersion: string): Promise<VersionCheckResult> {\n await logUpdateEvent(`Checking version: current=${currentVersion}`);\n\n // Skip update check if environment variable is set\n if (process.env.DEVARK_SKIP_UPDATE === '1') {\n await logUpdateEvent('Skipping version check due to DEVARK_SKIP_UPDATE=1');\n return {\n isOutdated: false,\n currentVersion,\n latestVersion: currentVersion,\n shouldUpdate: false\n };\n }\n\n try {\n // Try to read from cache first\n let latestVersion: string | null = null;\n const cache = await readVersionCache();\n\n if (cache) {\n latestVersion = cache.latestVersion;\n await logUpdateEvent(`Using cached version: ${latestVersion}`);\n } else {\n // Fetch from npm registry\n await logUpdateEvent('Fetching latest version from npm...');\n latestVersion = await fetchLatestVersion();\n\n if (latestVersion) {\n await writeVersionCache(latestVersion);\n await logUpdateEvent(`Fetched latest version: ${latestVersion}`);\n } else {\n await logUpdateEvent('Failed to fetch latest version from npm');\n }\n }\n\n // If we couldn't get latest version, don't update\n if (!latestVersion) {\n return {\n isOutdated: false,\n currentVersion,\n latestVersion: currentVersion,\n shouldUpdate: false,\n error: 'Could not fetch latest version'\n };\n }\n\n // Compare versions\n const comparison = compareVersions(currentVersion, latestVersion);\n const isOutdated = comparison < 0;\n\n // Determine if we should force update\n // For now, update on any version difference\n const shouldUpdate = isOutdated;\n\n await logUpdateEvent(`Version comparison: ${currentVersion} vs ${latestVersion}, outdated=${isOutdated}, shouldUpdate=${shouldUpdate}`);\n\n return {\n isOutdated,\n currentVersion,\n latestVersion,\n shouldUpdate\n };\n\n } catch (error) {\n await logUpdateEvent(`Version check error: ${error instanceof Error ? error.message : 'Unknown error'}`);\n logger.debug('Version check failed:', error);\n\n return {\n isOutdated: false,\n currentVersion,\n latestVersion: currentVersion,\n shouldUpdate: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n}\n\n/**\n * Spawn a process using npx devark-cli@latest\n * This ensures we always use the latest version\n */\nexport async function spawnLatestVersion(\n args: string[],\n options?: {\n detached?: boolean;\n silent?: boolean;\n env?: NodeJS.ProcessEnv;\n }\n): Promise<void> {\n await logUpdateEvent(`Spawning latest version with args: ${args.join(' ')}`);\n\n // Build command - use npx to get latest version\n const command = 'npx';\n const spawnArgs = ['devark-cli@latest', ...args];\n\n const spawnOptions: SpawnOptions = {\n detached: options?.detached || false,\n stdio: options?.silent ? ['ignore', 'ignore', 'ignore'] : 'inherit',\n env: { ...process.env, ...options?.env }\n };\n\n // On Windows, use shell mode\n if (process.platform === 'win32') {\n spawnOptions.shell = true;\n if (options?.detached) {\n spawnOptions.windowsHide = true;\n }\n }\n\n return new Promise((resolve, reject) => {\n const child = spawn(command, spawnArgs, spawnOptions);\n\n if (options?.detached) {\n // For detached processes, unref and resolve immediately\n child.unref();\n resolve();\n return;\n }\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`Process exited with code ${code}`));\n }\n });\n\n child.on('error', (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Check if we should attempt to spawn latest version for hook execution\n */\nexport function shouldSpawnLatestForHook(versionCheck: VersionCheckResult, hookTrigger?: string): boolean {\n // Only auto-update for hook executions\n if (!hookTrigger) {\n return false;\n }\n\n // Don't update if check failed\n if (versionCheck.error) {\n return false;\n }\n\n // Update if we're outdated\n return versionCheck.shouldUpdate;\n}","import { spawn, SpawnOptions } from 'child_process';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { logger } from './logger';\n\n/**\n * Get the upload log file path\n */\nexport function getUploadLogPath(): string {\n const devarkDir = path.join(os.homedir(), '.devark');\n return path.join(devarkDir, 'upload.log');\n}\n\n/**\n * Ensure the .devark directory exists\n */\nasync function ensureDevArkDir(): Promise<void> {\n const devarkDir = path.join(os.homedir(), '.devark');\n await fs.mkdir(devarkDir, { recursive: true });\n}\n\n/**\n * Spawn a detached process that runs in the background\n * Cross-platform support for Windows and Unix systems\n */\nexport async function spawnDetached(\n command: string,\n args: string[],\n options?: {\n logFile?: string;\n env?: NodeJS.ProcessEnv;\n }\n): Promise<void> {\n await ensureDevArkDir();\n \n const logFile = options?.logFile || getUploadLogPath();\n \n // Write timestamp header\n const timestamp = new Date().toISOString();\n await fs.appendFile(logFile, `\\n=== Upload started at ${timestamp} ===\\n`);\n \n const spawnOptions: SpawnOptions = {\n detached: true,\n stdio: ['ignore', 'ignore', 'ignore'],\n env: { ...process.env, ...options?.env, DEVARK_OUTPUT: logFile }\n };\n \n // On Windows, we need to use shell mode for proper detachment\n if (process.platform === 'win32') {\n spawnOptions.shell = true;\n spawnOptions.windowsHide = true;\n }\n \n const child = spawn(command, args, spawnOptions);\n \n // Unref the child process so parent can exit independently\n child.unref();\n \n logger.debug(`Spawned background process with PID: ${child.pid}`);\n}\n\n/**\n * Check if a background upload process is already running\n * This prevents duplicate uploads\n */\nexport async function isUploadRunning(): Promise<boolean> {\n const lockFile = path.join(os.homedir(), '.devark', 'upload.lock');\n \n try {\n const stats = await fs.stat(lockFile);\n const now = Date.now();\n const lockAge = now - stats.mtimeMs;\n \n // If lock is older than 5 minutes, consider it stale\n if (lockAge > 5 * 60 * 1000) {\n await fs.unlink(lockFile).catch(() => {});\n return false;\n }\n \n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Create a lock file for upload process\n */\nexport async function createUploadLock(): Promise<void> {\n await ensureDevArkDir();\n const lockFile = path.join(os.homedir(), '.devark', 'upload.lock');\n await fs.writeFile(lockFile, process.pid.toString());\n}\n\n/**\n * Remove the upload lock file\n */\nexport async function removeUploadLock(): Promise<void> {\n const lockFile = path.join(os.homedir(), '.devark', 'upload.lock');\n await fs.unlink(lockFile).catch(() => {});\n}","import { logger } from '../../utils/logger';\nimport { logHookError } from '../hook-utils';\nimport { SendOptions } from './send-orchestrator';\nimport { checkForUpdate, shouldSpawnLatestForHook, spawnLatestVersion } from '../../utils/version-check';\n\nexport class BackgroundSendOrchestrator {\n async execute(options: SendOptions): Promise<void> {\n if (!options.hookTrigger) {\n logger.error('Background mode requires hook trigger');\n return;\n }\n\n const { spawnDetached, isUploadRunning } = await import('../../utils/spawn');\n\n // Check if an upload is already running\n if (await isUploadRunning()) {\n logger.debug('Background upload already in progress, skipping');\n return;\n }\n\n // Check for version updates and use @latest if needed\n // Skip if we're already running from @latest spawn to prevent infinite loops\n if (!process.env.DEVARK_SPAWNED_LATEST) {\n try {\n const currentVersion = process.env.SIMULATE_OLD_VERSION || require('../../../package.json').version;\n const versionCheck = await checkForUpdate(currentVersion);\n\n if (shouldSpawnLatestForHook(versionCheck, options.hookTrigger)) {\n logger.debug(`Background spawn using latest version: current=${versionCheck.currentVersion}, latest=${versionCheck.latestVersion}`);\n\n // Build args for the latest version spawn\n const args = ['send', '--silent', '--background', `--hook-trigger=${options.hookTrigger}`];\n\n if (options.hookVersion) {\n args.push(`--hook-version=${options.hookVersion}`);\n }\n\n if (options.claudeProjectDir) {\n args.push(`--claude-project-dir=${options.claudeProjectDir}`);\n }\n\n if (options.all) {\n args.push('--all');\n }\n\n // Use the new spawn method with @latest\n await spawnLatestVersion(args, {\n detached: true,\n silent: true,\n env: {\n ...process.env,\n DEVARK_SPAWNED_LATEST: '1' // Prevent infinite loops\n }\n });\n\n logger.debug('Background upload process spawned with @latest successfully');\n return;\n }\n } catch (error) {\n // If version check fails, continue with current version\n logger.debug('Version check failed for background spawn, using current version:', error);\n }\n }\n\n // Fallback: Use current version (original logic)\n // Get the CLI executable path\n const cliPath = process.argv[0]; // node executable\n const scriptPath = process.argv[1]; // devark script\n\n // Build args for the background process (without --background flag)\n const args = [scriptPath, 'send', '--silent', `--hook-trigger=${options.hookTrigger}`];\n\n if (options.hookVersion) {\n args.push(`--hook-version=${options.hookVersion}`);\n }\n\n if (options.claudeProjectDir) {\n args.push('--claude-project-dir', options.claudeProjectDir);\n }\n\n if (options.all) {\n args.push('--all');\n }\n\n try {\n await spawnDetached(cliPath, args);\n logger.debug('Background upload process spawned successfully (current version)');\n } catch (error) {\n await logHookError('Background spawn', error);\n logger.error('Failed to spawn background upload process');\n }\n }\n}","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { homedir } from 'os';\nimport { logger } from '../utils/logger';\n\n/**\n * Simple file-based lock mechanism for preventing concurrent hook executions\n */\nexport class HookLock {\n private lockPath: string;\n private lockTimeout: number = 60000; // 60 seconds max lock time\n\n constructor() {\n this.lockPath = path.join(homedir(), '.devark', 'hook.lock');\n }\n\n /**\n * Attempt to acquire a lock\n * @returns true if lock acquired, false if already locked\n */\n async acquire(): Promise<boolean> {\n try {\n const lockDir = path.dirname(this.lockPath);\n await fs.mkdir(lockDir, { recursive: true });\n\n // Check if lock exists and is still valid\n try {\n const lockContent = await fs.readFile(this.lockPath, 'utf-8');\n const lockData = JSON.parse(lockContent);\n const lockAge = Date.now() - lockData.timestamp;\n\n // If lock is older than timeout, consider it stale\n if (lockAge < this.lockTimeout) {\n logger.debug('Hook execution already in progress', { pid: lockData.pid, age: lockAge });\n return false;\n } else {\n logger.debug('Removing stale lock', { pid: lockData.pid, age: lockAge });\n }\n } catch {\n // Lock doesn't exist or is invalid, we can proceed\n }\n\n // Create new lock\n const lockData = {\n pid: process.pid,\n timestamp: Date.now(),\n host: process.env.COMPUTERNAME || process.env.HOSTNAME || 'unknown'\n };\n\n await fs.writeFile(this.lockPath, JSON.stringify(lockData));\n logger.debug('Hook lock acquired', lockData);\n return true;\n } catch (error) {\n logger.error('Failed to acquire hook lock', error);\n return false;\n }\n }\n\n /**\n * Release the lock\n */\n async release(): Promise<void> {\n try {\n await fs.unlink(this.lockPath);\n logger.debug('Hook lock released');\n } catch (error) {\n // Lock might already be removed, that's ok\n logger.debug('Failed to release hook lock', error);\n }\n }\n\n /**\n * Force clear any existing lock (for troubleshooting)\n */\n async forceClear(): Promise<void> {\n try {\n await fs.unlink(this.lockPath);\n logger.info('Hook lock forcefully cleared');\n } catch (error) {\n logger.debug('No lock to clear');\n }\n }\n}","import { logger } from '../../utils/logger';\nimport { logHookError } from '../hook-utils';\nimport { HookLock } from '../hook-lock';\nimport { SendOptions, SendOrchestrator } from './send-orchestrator';\n\nexport class HookSendOrchestrator {\n private sendOrchestrator = new SendOrchestrator();\n\n async execute(options: SendOptions): Promise<void> {\n // Test mode - handle immediately\n if (options.test) {\n console.log('Hook test successful');\n process.exit(0);\n }\n\n let hookLock: HookLock | undefined;\n let uploadLockCreated = false;\n\n try {\n // Create upload lock for non-background processes\n if (!options.background) {\n const { createUploadLock } = await import('../../utils/spawn');\n await createUploadLock();\n uploadLockCreated = true;\n }\n \n // Acquire hook lock\n hookLock = new HookLock();\n const lockAcquired = await hookLock.acquire();\n \n if (!lockAcquired) {\n await logHookError('Lock acquisition', new Error('Another hook execution is already in progress'));\n logger.debug('Skipping hook execution - already running');\n return;\n }\n\n // Execute send with silent mode\n const hookOptions: SendOptions = {\n ...options,\n silent: true\n };\n\n await this.sendOrchestrator.execute(hookOptions);\n\n } catch (error) {\n await logHookError('Hook send', error);\n logger.error('Failed to execute hook send');\n // In hook mode, never throw - just exit gracefully\n } finally {\n // Always release the lock if we acquired one\n if (hookLock) {\n await hookLock.release();\n }\n \n // Remove upload lock for non-background processes\n if (uploadLockCreated) {\n const { removeUploadLock } = await import('../../utils/spawn');\n await removeUploadLock();\n }\n }\n }\n}","import chalk from 'chalk';\nimport { PointsEarned } from '../api-client';\n\n/**\n * Format and display points earned from session uploads\n */\nexport class PointsDisplayUI {\n private silent: boolean;\n\n constructor(silent: boolean = false) {\n this.silent = silent;\n }\n\n /**\n * Display points breakdown with celebratory formatting\n */\n displayPointsEarned(points: PointsEarned): void {\n if (this.silent) {\n return; // Don't display in silent mode\n }\n\n // Determine the celebratory level based on total points\n const celebrationLevel = this.getCelebrationLevel(points.total);\n\n // Main points announcement\n console.log('');\n console.log(chalk.bold(celebrationLevel.color(\n `${celebrationLevel.emoji} You earned ${points.total} points! ${celebrationLevel.suffix}`\n )));\n\n // Show breakdown if there are multiple components\n if (points.streak > 0 || points.volume > 0) {\n console.log(chalk.gray(' Points breakdown:'));\n\n if (points.streak > 0) {\n const streakDay = Math.log2(points.streak); // Calculate day from points (2^day)\n console.log(chalk.white(` 🔥 Streak (Day ${Math.floor(streakDay)}): ${points.streak} points`));\n }\n\n if (points.volume > 0) {\n const sessionCount = points.volume; // 1 point per session\n console.log(chalk.white(` 📊 Session${sessionCount > 1 ? 's' : ''} bonus: ${points.volume} point${points.volume > 1 ? 's' : ''}`));\n }\n\n // Note: Share bonus (if any) is included in total but not shown separately\n // as sharing happens on the web platform, not in CLI\n }\n\n // Use custom message if provided\n if (points.message && !this.silent) {\n console.log(chalk.dim(` ${points.message}`));\n }\n }\n\n /**\n * Display current streak status and next milestone\n */\n displayStreakStatus(currentDay: number, nextDayPoints: number): void {\n if (this.silent) {\n return;\n }\n\n console.log('');\n\n if (currentDay === 0) {\n console.log(chalk.cyan('💡 Start your streak today! Upload a session to earn 2 points.'));\n } else if (currentDay <= 7) {\n console.log(chalk.green(`🔥 You're on a ${currentDay}-day streak!`));\n console.log(chalk.dim(` Keep it up! Upload tomorrow for ${nextDayPoints} points.`));\n } else {\n console.log(chalk.bold.green(`🏆 Amazing ${currentDay}-day streak!`));\n console.log(chalk.dim(` You've reached maximum daily points (128). Keep shipping!`));\n }\n }\n\n /**\n * Display streak warning when it's about to expire\n */\n displayStreakWarning(hoursRemaining: number, currentStreak: number, potentialPoints: number): void {\n if (this.silent) {\n return;\n }\n\n if (hoursRemaining <= 12) {\n console.log('');\n console.log(chalk.bold.yellow(\n `⚠️ Your ${currentStreak}-day streak ends in ${Math.floor(hoursRemaining)} hours!`\n ));\n console.log(chalk.yellow(\n ` Upload a session soon to earn ${potentialPoints} points tomorrow!`\n ));\n }\n }\n\n /**\n * Display batch upload points summary\n */\n displayBatchPoints(\n sessionCount: number,\n totalPoints: number,\n pointsBreakdown: PointsEarned\n ): void {\n if (this.silent) {\n return;\n }\n\n console.log('');\n console.log(chalk.bold.cyan(`📦 Batch upload complete!`));\n console.log(chalk.green(`✅ ${sessionCount} sessions uploaded successfully!`));\n\n if (totalPoints > 0) {\n const level = this.getCelebrationLevel(totalPoints);\n console.log(chalk.bold(level.color(`${level.emoji} Total points earned: ${totalPoints}`)));\n\n // Show breakdown\n if (pointsBreakdown.streak > 0) {\n console.log(chalk.white(` 🔥 Streak bonus: ${pointsBreakdown.streak} points`));\n }\n if (pointsBreakdown.volume > 0) {\n console.log(chalk.white(` 📊 Session bonuses: ${pointsBreakdown.volume} points`));\n }\n // Note: Total may include share bonus from web platform\n }\n }\n\n /**\n * Get celebration level based on points earned\n */\n private getCelebrationLevel(points: number): {\n emoji: string;\n color: typeof chalk.green;\n suffix: string;\n } {\n if (points >= 128) {\n return {\n emoji: '🏆',\n color: chalk.bold.magenta,\n suffix: \"MAXIMUM POINTS! You're on fire!\"\n };\n } else if (points >= 100) {\n return {\n emoji: '🔥',\n color: chalk.bold.red,\n suffix: 'ON FIRE!'\n };\n } else if (points >= 50) {\n return {\n emoji: '🚀',\n color: chalk.bold.cyan,\n suffix: 'Great progress!'\n };\n } else if (points >= 20) {\n return {\n emoji: '⭐',\n color: chalk.bold.green,\n suffix: 'Nice work!'\n };\n } else if (points > 0) {\n return {\n emoji: '🎉',\n color: chalk.green,\n suffix: ''\n };\n } else {\n return {\n emoji: '📊',\n color: chalk.gray,\n suffix: ''\n };\n }\n }\n\n /**\n * Display points error (when server doesn't return points)\n */\n displayPointsFallback(): void {\n // Silently handle missing points field - for backward compatibility\n // The upload was successful, just no points data\n return;\n }\n}","import chalk from 'chalk';\nimport ora from 'ora';\nimport { StreakInfo, UploadResult } from './api-client';\nimport { PointsDisplayUI } from './ui/points-display';\n\n// DevArk ASCII Logo\nconst DEVARK_ASCII_LOGO = `\n **--\n ****----\n ******------\n ********--------\n **********----------\n *************-------------\n ***************---------------\n *****************-----------------\n ***************** -----------------\n **************** ----------------\n ***************** *- -----------------\n ***************** ***--- -----------------\n ***************** ******------ -----------------\n **************** ********-------- ----------------\n ***************** **********---------- -----------------\n ***************** ************------------ -----------------\n ***************** ***************--------------- -----------------\n *************** *****************----------------- ---------------\n *********** ***************** ----------------- -----------\n ******* ****************** ------------------ -------\n *** ***************** *- ----------------- ---\n ***************** ***--- -----------------\n ***************** *****----- -----------------\n ***************** ********-------- -----------------\n *************** **********---------- ---------------\n ************ *************------------- ------------\n ******* ***************--------------- -------\n *** ******************------------------ ---\n ******************* -------------------\n ******************* -------------------\n ******************* -------------------\n **************** ----------------\n *********** -----------\n ****** ------\n *** ---\n`;\n\nexport async function showLogo(version?: string): Promise<void> {\n // Helper to display version line\n const displayVersion = (version: string) => {\n const isSimulated = process.env.SIMULATE_OLD_VERSION === version;\n const versionText = isSimulated ? `v${version} (simulated)` : `v${version}`;\n console.log(chalk.gray(` ${versionText}`));\n };\n\n // Display the DevArk ASCII logo with brand colors\n const lines = DEVARK_ASCII_LOGO.split('\\n');\n for (const line of lines) {\n // Color the asterisks blue (#3528E0) and dashes white (for visibility on dark terminals)\n const coloredLine = line\n .replace(/\\*/g, chalk.hex('#3528E0')('*'))\n .replace(/-/g, chalk.white('-'));\n console.log(coloredLine);\n }\n\n // Display version if provided\n if (version) {\n displayVersion(version);\n }\n\n console.log(); // Add a blank line after the logo\n}\n\nexport function showStreakUpdate(streak: StreakInfo): void {\n console.log(chalk.green('\\n✨ Streak Update:'));\n console.log(` Current: ${chalk.bold(streak.current)} days 🔥`);\n console.log(` Points: ${chalk.bold(streak.points)}`);\n console.log(` Sessions today: ${chalk.bold(streak.todaySessions)}`);\n \n if (streak.current > 0 && streak.current % 7 === 0) {\n console.log(chalk.yellow(`\\n🎉 ${streak.current} day streak! Keep building!`));\n } else if (streak.current > 0 && streak.current % 30 === 0) {\n console.log(chalk.yellow(`\\n🏆 AMAZING! ${streak.current} day streak! You're unstoppable!`));\n }\n}\n\nexport function formatDuration(seconds: number): string {\n if (seconds < 60) {\n return `${seconds}s`;\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n \n if (hours > 0) {\n return `${hours}h ${minutes}m`;\n }\n return `${minutes}m`;\n}\n\nexport function formatDate(date: Date): string {\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nexport function showUploadResults(results: UploadResult): void {\n // Show upload summary with created and duplicate counts\n if (results.created !== undefined && results.duplicates !== undefined) {\n console.log('');\n if (results.created > 0) {\n console.log(chalk.green(`✅ ${results.created} new session${results.created !== 1 ? 's' : ''} uploaded`));\n }\n if (results.duplicates > 0) {\n console.log(chalk.yellow(`📋 ${results.duplicates} duplicate session${results.duplicates !== 1 ? 's' : ''} already in system`));\n }\n if (results.created === 0 && results.duplicates === 0) {\n console.log(chalk.gray('No sessions were uploaded'));\n }\n }\n\n // Display points earned if available\n if (results.pointsEarned) {\n const pointsDisplay = new PointsDisplayUI(false);\n pointsDisplay.displayPointsEarned(results.pointsEarned);\n\n // Show streak status for context\n if (results.streak?.current !== undefined) {\n const nextDayPoints = Math.min(128, Math.pow(2, results.streak.current + 1));\n pointsDisplay.displayStreakStatus(results.streak.current, nextDayPoints);\n }\n }\n\n if (results.analysisPreview) {\n console.log(chalk.cyan('\\n📊 Analysis Preview:'));\n console.log(chalk.gray(results.analysisPreview));\n }\n\n // Show streak update only if no points (backward compatibility)\n if (results.streak && !results.pointsEarned) {\n showStreakUpdate(results.streak);\n }\n}\n\nexport function showSessionSummary(sessions: any[]): void {\n console.log(chalk.cyan('\\nSessions to upload:'));\n \n sessions.forEach((session) => {\n const timestamp = new Date(session.timestamp);\n console.log(\n ` • ${formatDate(timestamp)} - ${formatDuration(session.duration)} - ${\n session.data.projectPath\n }`\n );\n });\n}\n\nexport function showWelcome(): void {\n console.log(chalk.yellow('\\n👋 Welcome to devark!'));\n console.log(chalk.gray('Track your building journey and maintain your streak.\\n'));\n}\n\nexport function showSuccess(message: string): void {\n console.log(chalk.green(`\\n✅ ${message}`));\n}\n\nexport function showError(message: string): void {\n console.log(chalk.red(`\\n❌ ${message}`));\n}\n\nexport function showWarning(message: string): void {\n console.log(chalk.yellow(`\\n⚠️ ${message}`));\n}\n\nexport function showInfo(message: string): void {\n console.log(chalk.cyan(`\\nℹ️ ${message}`));\n}\n\nexport function createSpinner(text: string) {\n return ora({\n text,\n spinner: 'dots',\n });\n}","import chalk from 'chalk';\nimport { createSpinner } from '../../ui';\n\nexport class SendProgressUI {\n private silent: boolean;\n\n constructor(silent: boolean = false) {\n this.silent = silent;\n }\n\n createSpinner(message: string) {\n if (this.silent) {\n return {\n start: () => ({ succeed: () => {}, fail: () => {} }),\n succeed: () => {},\n fail: () => {}\n };\n }\n return createSpinner(message);\n }\n\n showProgress(current: number, total: number, label: string = 'Processing') {\n if (this.silent) return;\n \n const progress = Math.round((current / total) * 100);\n const barLength = 30;\n const filled = Math.round((progress / 100) * barLength);\n const empty = barLength - filled;\n const bar = '█'.repeat(filled) + '░'.repeat(empty);\n \n process.stdout.write(\n `\\r ${label}: [${bar}] ${progress}% (${current}/${total})`\n );\n }\n\n completeProgress() {\n if (!this.silent) {\n console.log('\\n');\n }\n }\n\n showPreparing() {\n if (!this.silent) {\n console.log(chalk.cyan('\\n🔒 Preparing sessions for privacy-safe upload...\\n'));\n }\n }\n\n showUploadProgress(current: number, total: number, sizeKB?: number) {\n if (this.silent) return;\n \n const progress = Math.round((current / total) * 100);\n const barLength = 30;\n const filled = Math.round((progress / 100) * barLength);\n const empty = barLength - filled;\n const bar = '█'.repeat(filled) + '░'.repeat(empty);\n \n const sizeInfo = sizeKB ? ` • ${sizeKB.toFixed(1)} KB` : '';\n \n process.stdout.write(\n `\\r Uploading: [${bar}] ${progress}% (${current}/${total} sessions${sizeInfo})`\n );\n }\n\n completeUploadProgress() {\n if (!this.silent) {\n // Clear the entire line (use 100 spaces to be safe) and return cursor to start\n process.stdout.write('\\r' + ' '.repeat(100) + '\\r');\n }\n }\n}","import chalk from 'chalk';\nimport { formatDuration, showSuccess, showWarning, showInfo } from '../../ui';\nimport { parseProjectName } from '../project-display';\nimport { Session as ApiSession } from '../../api-client';\nimport { logger } from '../../../utils/logger';\n\nexport class SendSummaryUI {\n private silent: boolean;\n\n constructor(silent: boolean = false) {\n this.silent = silent;\n }\n\n showNoSessions(options: { \n all?: boolean; \n selectedSessions?: any[];\n currentDir?: string \n }) {\n if (this.silent) {\n logger.info('No sessions found');\n return;\n }\n\n if (options.selectedSessions) {\n showWarning('No sessions could be loaded from selected files.');\n } else if (!options.all && options.currentDir) {\n showWarning(`No sessions found in current directory (${parseProjectName(options.currentDir)}).`);\n showInfo('Tips:');\n showInfo('- Make sure you have used Claude Code in this directory');\n showInfo('- Use --all flag to send sessions from all projects');\n showInfo(`- Current directory: ${options.currentDir}`);\n } else {\n const defaultDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\n showWarning('No new sessions found in any project.');\n showInfo('Make sure you have used Claude Code since ' + defaultDate.toLocaleDateString());\n }\n }\n\n showSessionsFound(count: number, source: string) {\n if (this.silent) {\n logger.info(`Found ${count} sessions from ${source}`);\n } else {\n console.log(chalk.green(`✓ Found ${count} sessions from ${source}`));\n }\n }\n\n showUploadSummary(sessions: ApiSession[], totalRedactions: number) {\n if (this.silent) {\n const totalDuration = sessions.reduce((sum, s) => sum + s.duration, 0);\n logger.info(`Uploading ${sessions.length} sessions (${formatDuration(totalDuration)})`);\n return;\n }\n\n const totalDuration = sessions.reduce((sum, s) => sum + s.duration, 0);\n console.log(chalk.cyan('\\n📊 Sessions to be uploaded summary:'));\n console.log(chalk.white(` Sessions: ${sessions.length}`));\n console.log(chalk.white(` Total Duration: ${formatDuration(totalDuration)}`));\n console.log(chalk.white(` Privacy Redactions: ${totalRedactions}`));\n }\n\n showDryRun() {\n if (this.silent) {\n logger.info('Dry run - no data sent');\n } else {\n console.log(chalk.gray('\\n🔍 Dry run - no data sent'));\n }\n }\n\n showUploadResults(results: any) {\n if (this.silent) {\n logger.info('Sessions uploaded successfully');\n return;\n }\n\n showSuccess('Sessions uploaded!');\n \n if (results.streak && results.streak.current === 0) {\n showWarning('\\nYour streak has been reset! Start building again today.');\n }\n }\n}","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport { formatDuration } from '../ui';\n\n/**\n * Privacy preview component extracted from send.ts\n * Shows what data will be redacted before sending\n */\n\ninterface RedactionCounts {\n codeBlocks: number;\n credentials: number;\n paths: number;\n urls: number;\n emails: number;\n}\n\ninterface ApiSession {\n tool: string;\n timestamp: string;\n duration: number;\n data: {\n projectName: string;\n messageSummary: string; // JSON string of sanitized messages\n messageCount: number;\n metadata?: {\n files_edited: number;\n languages: string[];\n };\n };\n}\n\nexport interface SelectedSessionInfo {\n projectPath: string;\n sessionFile: string;\n displayName: string;\n duration: number;\n timestamp: Date;\n messageCount: number;\n}\n\n/**\n * Show privacy preview with redaction details\n * @param apiSessions - Sanitized sessions to preview\n * @param selectedSessions - Original session info for context\n * @param debugCredentials - Optional debug info about detected credentials\n * @returns true if user wants to proceed, false if cancelled\n */\nexport async function showPrivacyPreview(\n apiSessions: ApiSession[], \n selectedSessions?: SelectedSessionInfo[],\n debugCredentials?: Array<{ text: string; pattern: string }>\n): Promise<boolean> {\n console.log('');\n console.log(chalk.cyan('🔒 Privacy Preview'));\n console.log(chalk.gray('─'.repeat(50)));\n \n // Show selected sessions summary if available\n if (selectedSessions && selectedSessions.length > 0) {\n // Group sessions by project\n const sessionsByProject = new Map<string, SelectedSessionInfo[]>();\n \n for (const session of selectedSessions) {\n const existing = sessionsByProject.get(session.displayName) || [];\n existing.push(session);\n sessionsByProject.set(session.displayName, existing);\n }\n \n // Get time range\n const timestamps = selectedSessions.map(s => s.timestamp);\n const earliest = new Date(Math.min(...timestamps.map(t => t.getTime())));\n const latest = new Date(Math.max(...timestamps.map(t => t.getTime())));\n \n console.log('');\n console.log(chalk.white(`You selected ${chalk.cyan(selectedSessions.length)} session${selectedSessions.length !== 1 ? 's' : ''} to analyze:`));\n \n // Show each project with its session count and duration\n sessionsByProject.forEach((sessions, projectName) => {\n const projectDuration = sessions.reduce((sum, s) => sum + s.duration, 0);\n const sessionText = sessions.length === 1 ? 'session' : 'sessions';\n console.log(chalk.gray(` • ${chalk.white(projectName)} (${sessions.length} ${sessionText}, ${formatDuration(projectDuration)})`));\n });\n \n // Show date range if sessions span multiple days\n const sameDay = earliest.toDateString() === latest.toDateString();\n if (sameDay) {\n const timeRange = `${earliest.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })} - ${latest.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}`;\n console.log(chalk.gray(` 📅 From today, ${timeRange}`));\n } else {\n console.log(chalk.gray(` 📅 ${earliest.toLocaleDateString()} to ${latest.toLocaleDateString()}`));\n }\n \n console.log('');\n }\n \n console.log(chalk.gray('─'.repeat(50)));\n \n // Count redactions by type\n const redactionCounts: RedactionCounts = {\n codeBlocks: 0,\n credentials: 0,\n paths: 0,\n urls: 0,\n emails: 0,\n };\n \n // Calculate total redactions across all sessions\n let sampleMessage = '';\n \n for (const session of apiSessions) {\n const messages = JSON.parse(session.data.messageSummary);\n \n messages.forEach((msg: any) => {\n if (msg.metadata?.redactedItems) {\n Object.entries(msg.metadata.redactedItems).forEach(([key, value]) => {\n if (key in redactionCounts) {\n redactionCounts[key as keyof RedactionCounts] += value as number;\n }\n });\n }\n });\n \n // Get sample message from first session\n if (!sampleMessage && messages.length > 0) {\n sampleMessage = messages[0].content;\n }\n }\n \n // Show what's being redacted\n console.log(chalk.yellow('\\nWhat gets removed:'));\n if (redactionCounts.codeBlocks > 0) {\n console.log(` 📝 ${redactionCounts.codeBlocks} code blocks`);\n }\n if (redactionCounts.credentials > 0) {\n console.log(` 🔑 ${redactionCounts.credentials} credentials`);\n \n // Show debug info if available and in debug mode\n if (debugCredentials && debugCredentials.length > 0 && process.env.DEVARK_DEBUG === 'true') {\n console.log('');\n console.log(chalk.yellow(' Debug: Detected credentials (first 20 chars):'));\n debugCredentials.slice(0, 5).forEach(({ text, pattern }) => {\n console.log(chalk.gray(` - \"${text}\" [${pattern}]`));\n });\n if (debugCredentials.length > 5) {\n console.log(chalk.gray(` ... and ${debugCredentials.length - 5} more`));\n }\n }\n }\n if (redactionCounts.paths > 0) {\n console.log(` 📁 ${redactionCounts.paths} file paths`);\n }\n if (redactionCounts.urls > 0) {\n console.log(` 🌐 ${redactionCounts.urls} URLs`);\n }\n if (redactionCounts.emails > 0) {\n console.log(` 📧 ${redactionCounts.emails} email addresses`);\n }\n \n // Show sample message if available\n if (sampleMessage) {\n console.log('');\n console.log(chalk.yellow('Sample sanitized message:'));\n console.log(chalk.gray('─'.repeat(50)));\n const preview = sampleMessage.length > 200 \n ? sampleMessage.substring(0, 200) + '...' \n : sampleMessage;\n console.log(chalk.gray(preview));\n console.log(chalk.gray('─'.repeat(50)));\n }\n \n console.log('');\n console.log(chalk.blueBright('💡 For detailed preview: devark privacy'));\n console.log('');\n \n // Ask for confirmation\n const { proceed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'proceed',\n message: 'Upload these sessions?',\n default: true,\n },\n ]);\n \n if (!proceed) {\n console.log(chalk.yellow('\\nUpload cancelled.'));\n console.log(chalk.blueBright('💡 Tip: Use \"devark privacy\" to preview what gets sent'));\n }\n \n return proceed;\n}\n\n/**\n * Show the action menu with preview option\n * @returns 'upload', 'preview', or 'cancel'\n */\nexport async function showUploadActionMenu(): Promise<'upload' | 'preview' | 'cancel'> {\n console.log('');\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to do?',\n choices: [\n { name: '✅ Upload sessions', value: 'upload' },\n { name: '🔍 Preview what will be sent', value: 'preview' },\n { name: '❌ Cancel', value: 'cancel' },\n ],\n default: 'upload',\n },\n ]);\n \n return action;\n}\n\n/**\n * Calculate total redaction count from API sessions\n */\nexport function calculateTotalRedactions(apiSessions: ApiSession[]): number {\n let totalRedactions = 0;\n \n apiSessions.forEach(session => {\n const messages = JSON.parse(session.data.messageSummary);\n messages.forEach((msg: any) => {\n if (msg.metadata?.redactedItems) {\n Object.values(msg.metadata.redactedItems).forEach((count: any) => {\n totalRedactions += count;\n });\n }\n });\n });\n \n return totalRedactions;\n}","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport { showUploadActionMenu } from '../privacy-preview';\nimport { getDashboardUrl } from '../../config';\n\nexport class SendConfirmationUI {\n private silent: boolean;\n private skipActionMenu: boolean;\n\n constructor(silent: boolean = false, skipActionMenu: boolean = false) {\n this.silent = silent;\n this.skipActionMenu = skipActionMenu;\n }\n\n async confirmUpload(): Promise<'upload' | 'preview' | 'cancel'> {\n if (this.silent || this.skipActionMenu) {\n return 'upload';\n }\n\n return showUploadActionMenu();\n }\n\n showCancelled() {\n console.log(chalk.yellow('\\nUpload cancelled.'));\n console.log(chalk.blueBright('💡 Tip: Use \"devark privacy\" to preview what gets sent'));\n }\n\n async showNextSteps() {\n if (this.silent) return;\n\n console.log('\\n📋 What to do next:');\n console.log('');\n console.log(` 🌐 Visit devark web dashboard ${getDashboardUrl()}`);\n console.log('');\n \n // Prompt to continue after upload completes\n console.log('Press Enter to continue...');\n await inquirer.prompt([{ type: 'input', name: 'continue', message: '' }]);\n }\n}","import chalk from 'chalk';\nimport { formatDuration } from '../ui';\nimport { SessionData } from '../readers/types';\n\n/**\n * Sanitization display component extracted from send.ts\n * Shows summary of what will be uploaded and redacted\n */\n\n/**\n * Display the upload summary with sanitization info\n * @param sessions - Original sessions to be uploaded\n * @param totalRedactions - Total number of redacted items\n */\nexport function showUploadSummary(sessions: SessionData[], totalRedactions: number): void {\n const totalDuration = sessions.reduce((sum, s) => sum + s.duration, 0);\n \n console.log('');\n console.log(chalk.cyan(\n `Ready to upload ${sessions.length} session${sessions.length !== 1 ? 's' : ''} (${formatDuration(totalDuration)} total)`\n ));\n \n if (totalRedactions > 0) {\n console.log(chalk.gray(`🔒 ${totalRedactions} sensitive items redacted for privacy`));\n }\n}\n\n/**\n * Display summary for silent mode (uses logger instead of console)\n * @param sessions - Original sessions to be uploaded\n * @param totalDuration - Total duration in seconds\n */\nexport function logUploadSummary(\n sessionCount: number, \n totalDuration: number,\n logger: any\n): void {\n logger.info(`Ready to upload ${sessionCount} sessions (${formatDuration(totalDuration)})`);\n}\n\n/**\n * Calculate total redactions from API sessions\n * @param apiSessions - Sanitized sessions with redaction metadata\n * @returns Total count of all redacted items\n */\nexport function countTotalRedactions(apiSessions: any[]): number {\n let totalRedactions = 0;\n \n apiSessions.forEach(session => {\n const messages = JSON.parse(session.data.messageSummary);\n messages.forEach((msg: any) => {\n if (msg.metadata?.redactedItems) {\n Object.values(msg.metadata.redactedItems).forEach((count: any) => {\n totalRedactions += count;\n });\n }\n });\n });\n \n return totalRedactions;\n}\n\n/**\n * Get detailed redaction breakdown by type\n * @param apiSessions - Sanitized sessions with redaction metadata\n * @returns Object with counts by redaction type\n */\nexport function getRedactionBreakdown(apiSessions: any[]): {\n codeBlocks: number;\n credentials: number;\n paths: number;\n urls: number;\n emails: number;\n} {\n const counts = {\n codeBlocks: 0,\n credentials: 0,\n paths: 0,\n urls: 0,\n emails: 0,\n };\n \n apiSessions.forEach(session => {\n const messages = JSON.parse(session.data.messageSummary);\n messages.forEach((msg: any) => {\n if (msg.metadata?.redactedItems) {\n Object.entries(msg.metadata.redactedItems).forEach(([key, value]) => {\n if (key in counts) {\n counts[key as keyof typeof counts] += value as number;\n }\n });\n }\n });\n });\n \n return counts;\n}","import { SendOrchestrator, SendOptions } from '../lib/orchestrators/send-orchestrator';\nimport { BackgroundSendOrchestrator } from '../lib/orchestrators/background-send-orchestrator';\nimport { HookSendOrchestrator } from '../lib/orchestrators/hook-send-orchestrator';\nimport { SendProgressUI } from '../lib/ui/send/send-progress';\nimport { SendSummaryUI } from '../lib/ui/send/send-summary';\nimport { SendConfirmationUI } from '../lib/ui/send/send-confirmation';\nimport { showPrivacyPreview } from '../lib/ui/privacy-preview';\nimport { parseProjectName } from '../lib/ui/project-display';\nimport { countTotalRedactions } from '../lib/ui/sanitization-display';\nimport { showUploadResults } from '../lib/ui';\nimport { DevArkError } from '../utils/errors';\nimport { logger } from '../utils/logger';\nimport { isNetworkError, createNetworkError } from '../lib/errors/network-errors';\nimport { checkForUpdate, shouldSpawnLatestForHook, spawnLatestVersion } from '../utils/version-check';\nimport chalk from 'chalk';\n\n/**\n * Send session data to DevArk API\n * \n * This command orchestrates the upload of Claude Code session data to the DevArk platform.\n * It supports multiple modes of operation:\n * \n * 1. **Interactive Mode** (default): Shows UI, prompts for confirmation\n * 2. **Silent Mode** (--silent): For automated execution from hooks\n * 3. **Background Mode** (--background): Spawns detached process\n * 4. **Test Mode** (--test): Validates hook configuration\n * 5. **Dry Run** (--dry): Preview without uploading\n * \n * The command delegates to specialized orchestrators based on the mode:\n * - BackgroundSendOrchestrator: Manages background process spawning\n * - HookSendOrchestrator: Handles hook-specific logic (locks, timeouts)\n * - SendOrchestrator: Core upload logic and session management\n */\nexport async function send(options: SendOptions): Promise<void> {\n logger.debug('Send options received:', options);\n\n try {\n // Check for version updates when triggered by hooks\n // Skip if we're already running from @latest spawn to prevent infinite loops\n if (options.hookTrigger && !process.env.DEVARK_SPAWNED_LATEST) {\n const currentVersion = process.env.SIMULATE_OLD_VERSION || require('../../package.json').version;\n logger.debug(`Checking version update: hookTrigger=${options.hookTrigger}, currentVersion=${currentVersion}`);\n const versionCheck = await checkForUpdate(currentVersion);\n logger.debug(`Version check result:`, versionCheck);\n\n if (shouldSpawnLatestForHook(versionCheck, options.hookTrigger)) {\n logger.debug(`Spawning latest version: current=${versionCheck.currentVersion}, latest=${versionCheck.latestVersion}`);\n\n // Build args for the latest version spawn\n const args = ['send'];\n\n // Add all the original options\n if (options.silent) args.push('--silent');\n if (options.background) args.push('--background');\n if (options.dry) args.push('--dry');\n if (options.all) args.push('--all');\n if (options.hookTrigger) args.push(`--hook-trigger=${options.hookTrigger}`);\n if (options.hookVersion) args.push(`--hook-version=${options.hookVersion}`);\n if (options.claudeProjectDir) args.push(`--claude-project-dir=${options.claudeProjectDir}`);\n if (options.test) args.push('--test');\n\n // For background mode, spawn detached\n if (options.background) {\n await spawnLatestVersion(args, {\n detached: true,\n silent: true,\n env: {\n ...process.env,\n DEVARK_SPAWNED_LATEST: '1' // Prevent infinite loops\n }\n });\n return;\n } else {\n // For non-background hook execution, spawn and wait\n await spawnLatestVersion(args, {\n detached: false,\n silent: options.silent,\n env: {\n ...process.env,\n DEVARK_SPAWNED_LATEST: '1' // Prevent infinite loops\n }\n });\n return;\n }\n }\n }\n\n // Route to appropriate orchestrator based on mode\n if (options.background && options.hookTrigger) {\n const orchestrator = new BackgroundSendOrchestrator();\n await orchestrator.execute(options);\n return;\n }\n\n if (options.hookTrigger) {\n const orchestrator = new HookSendOrchestrator();\n await orchestrator.execute(options);\n return;\n }\n\n // Interactive mode with UI\n await executeInteractiveSend(options);\n\n } catch (error) {\n handleSendError(error, options);\n }\n}\n\n/**\n * Execute send in interactive mode with full UI\n */\nasync function executeInteractiveSend(options: SendOptions): Promise<void> {\n const orchestrator = new SendOrchestrator();\n const progressUI = new SendProgressUI(options.silent);\n const summaryUI = new SendSummaryUI(options.silent);\n const confirmationUI = new SendConfirmationUI(options.silent, options.skipActionMenu);\n\n // Start progress spinner\n const spinner = progressUI.createSpinner('Finding sessions...');\n spinner.start();\n\n try {\n // Use orchestrator to load and prepare sessions\n const sessions = await orchestrator.loadSessions(options);\n \n if (sessions.length === 0) {\n spinner.fail('No sessions found');\n summaryUI.showNoSessions({\n all: options.all,\n selectedSessions: options.selectedSessions,\n currentDir: process.cwd()\n });\n return;\n }\n\n // Show sessions found\n const source = determineSessionSource(options);\n spinner.succeed(`Found ${sessions.length} sessions from ${source}`);\n\n // Prepare sessions for upload\n progressUI.showPreparing();\n const apiSessions = await orchestrator.sanitizeSessions(sessions, options);\n \n // Show progress during sanitization\n if (!options.silent && sessions.length > 1) {\n for (let i = 0; i < sessions.length; i++) {\n progressUI.showProgress(i + 1, sessions.length, 'Processing');\n }\n progressUI.completeProgress();\n }\n\n // Check if sessions were filtered\n const filteredCount = sessions.length - apiSessions.length;\n if (filteredCount > 0) {\n console.log(chalk.yellow(`\\n⚠️ Filtered out ${filteredCount} session(s) shorter than 4 minutes`));\n }\n \n // If no sessions left after filtering\n if (apiSessions.length === 0) {\n if (options.isInitialSync) {\n // During initial sync, this is not an error\n console.log(chalk.yellow('\\nℹ️ No sessions longer than 4 minutes found to sync.'));\n console.log(chalk.dim('Future sessions longer than 4 minutes will be synced automatically.'));\n return;\n }\n // For regular sync, the orchestrator will throw an error\n }\n\n // Show upload summary\n const totalRedactions = countTotalRedactions(apiSessions);\n summaryUI.showUploadSummary(apiSessions, totalRedactions);\n\n // Handle dry run\n if (options.dry) {\n summaryUI.showDryRun();\n return;\n }\n\n // Confirm upload\n const action = await confirmationUI.confirmUpload();\n \n if (action === 'preview') {\n const sessionInfo = options.selectedSessions || sessions.map(s => ({\n projectPath: s.sourceFile?.claudeProjectPath || s.projectPath,\n sessionFile: s.sourceFile?.sessionFile || '',\n displayName: parseProjectName(s.projectPath),\n duration: s.duration,\n timestamp: s.timestamp,\n messageCount: s.messages.length\n }));\n \n const proceed = await showPrivacyPreview(apiSessions, sessionInfo, []);\n if (!proceed) {\n return;\n }\n } else if (action === 'cancel') {\n confirmationUI.showCancelled();\n return;\n }\n\n // Upload sessions with progress bar\n console.log(''); // Add a blank line before progress bar\n \n let results;\n try {\n // Show initial progress\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] Starting upload of', apiSessions.length, 'sessions');\n }\n progressUI.showUploadProgress(0, apiSessions.length);\n \n results = await orchestrator.uploadSessions(\n apiSessions, \n options,\n (current, total, sizeKB) => {\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] Progress update:', current, '/', total, sizeKB ? `(${sizeKB.toFixed(2)} KB)` : '');\n }\n progressUI.showUploadProgress(current, total, sizeKB);\n }\n );\n \n // Clear progress bar and show success\n progressUI.completeUploadProgress();\n const uploadSpinner = progressUI.createSpinner('');\n uploadSpinner.succeed('Sessions uploaded!');\n } catch (uploadError) {\n // Clear progress bar on error\n if (process.env.DEVARK_DEBUG === 'true') {\n console.log('[DEBUG] Upload error caught:', uploadError);\n }\n progressUI.completeUploadProgress();\n throw uploadError;\n }\n \n // Update sync state\n await orchestrator.updateSyncState(sessions, options);\n\n // Show results\n if (!options.silent) {\n showUploadResults(results);\n await confirmationUI.showNextSteps();\n }\n\n } catch (error) {\n // Clear any progress bar if it was showing\n progressUI.completeUploadProgress();\n spinner.fail('Failed to send sessions');\n throw error;\n }\n}\n\n/**\n * Determine the source description for sessions\n */\nfunction determineSessionSource(options: SendOptions): string {\n if (options.selectedSessions) {\n return `${options.selectedSessions.length} selected sessions`;\n }\n \n if (options.claudeProjectDir) {\n return parseProjectName(options.claudeProjectDir);\n }\n \n if (options.all) {\n return 'all projects (--all flag)';\n }\n \n return `current directory (${parseProjectName(process.cwd())})`;\n}\n\n/**\n * Handle errors during send operation\n */\nfunction handleSendError(error: unknown, options: SendOptions): void {\n if (options.silent) {\n logger.error('Failed to send sessions', error);\n // In silent mode, never throw - just exit gracefully\n return;\n }\n\n // Always throw errors so they can be caught and displayed properly\n // The menu will catch these and display them with displayError()\n\n if (error instanceof DevArkError) {\n throw error;\n }\n\n // Handle specific error types\n if (error instanceof Error) {\n // Network errors\n if (isNetworkError(error)) {\n throw createNetworkError(error);\n }\n \n // Disk space errors\n if (error.message.includes('ENOSPC')) {\n throw new DevArkError(\n 'Insufficient disk space. Please free up some space and try again.',\n 'DISK_FULL'\n );\n }\n \n // Permission errors\n if (error.message.includes('EACCES') || error.message.includes('EPERM')) {\n throw new DevArkError(\n 'Permission denied. Please check file permissions.',\n 'PERMISSION_DENIED'\n );\n }\n }\n\n logger.error('Failed to send sessions', error);\n throw new DevArkError(\n 'Failed to send sessions. Please try again.',\n 'SEND_FAILED'\n );\n}\n\n/**\n * Send command wrapper for hook execution with timeout\n * This ensures hooks don't hang indefinitely\n */\nexport async function sendWithTimeout(options: SendOptions): Promise<void> {\n // Test mode - handle immediately without timeout\n if (options.test) {\n console.log('Hook test successful');\n process.exit(0);\n }\n\n // Background mode doesn't need timeout - it spawns and returns immediately\n if (options.background) {\n await send(options);\n return;\n }\n\n // Execute send command directly for all cases\n await send(options);\n}\n\n// Re-export SendOptions type for backward compatibility\nexport type { SendOptions };","import { getStatusLinePersonality as getStatusLinePersonalityConfig, setStatusLinePersonality as setStatusLinePersonalityConfig } from './config';\nimport { logger } from '../utils/logger';\n\n// Re-export config functions for convenience\nexport const getStatusLinePersonality = getStatusLinePersonalityConfig;\nexport const setStatusLinePersonality = setStatusLinePersonalityConfig;\n\n/**\n * Personality type definitions\n */\nexport type PersonalityType = 'gordon' | 'devark' | 'custom';\n\n/**\n * Score range type for categorizing prompt quality\n */\nexport type ScoreRange = 'poor' | 'fair' | 'good' | 'excellent';\n\n/**\n * Personality template for different score ranges\n */\nexport interface PersonalityTemplate {\n poor: string[]; // 0-40\n fair: string[]; // 41-60\n good: string[]; // 61-80\n excellent: string[]; // 81-100\n}\n\n/**\n * Get score range based on numeric score\n */\nfunction getScoreRange(score: number): ScoreRange {\n if (score <= 40) return 'poor';\n if (score <= 60) return 'fair';\n if (score <= 80) return 'good';\n return 'excellent';\n}\n\n// Legacy template arrays - preserved for reference but no longer used\n// The personality system now uses system prompts to guide Claude's natural language generation\n// This prevents repetitive canned responses while maintaining personality flavor\n\n// Note: These templates are kept for documentation purposes and potential future use\n// They show the kind of language each personality should naturally generate\n// But we no longer do direct template substitution to preserve Claude's intelligence\n\n/**\n * Transform a suggestion based on the active personality\n * \n * IMPORTANT: This function now preserves Claude's original suggestions\n * The personality influence happens through system prompts, not template replacement\n */\nexport function transformSuggestion(\n originalSuggestion: string,\n score: number,\n personality?: PersonalityType\n): string {\n try {\n // Get the configured personality if not provided\n if (!personality) {\n const config = getStatusLinePersonalityConfig();\n personality = config.personality;\n }\n\n // Debug logging\n if (process.env.DEVARK_DEBUG === 'true' || process.env.DEBUG_PERSONALITY === 'true') {\n logger.debug('=== PERSONALITY TRANSFORMATION DEBUG ===');\n logger.debug('Active personality:', personality);\n logger.debug('Score:', score);\n logger.debug('Original suggestion:', originalSuggestion);\n logger.debug('Preserving original suggestion (no template replacement)');\n }\n\n // For custom personality with legacy templates, optionally use them\n // This provides backward compatibility if someone has configured custom templates\n if (personality === 'custom') {\n const config = getStatusLinePersonalityConfig();\n const range = getScoreRange(score);\n if (config.customPersonality?.templates?.[range]) {\n // If custom templates exist, use them for backward compatibility\n logger.debug('Using custom template for backward compatibility');\n return config.customPersonality.templates[range];\n }\n }\n\n // Return the original suggestion - personality is now applied via system prompts\n // This preserves Claude's contextual intelligence while maintaining personality\n return originalSuggestion;\n \n } catch (error) {\n logger.error('Failed to process suggestion with personality:', error);\n // On any error, return the original suggestion\n return originalSuggestion;\n } finally {\n // Log the final result\n if (process.env.DEVARK_DEBUG === 'true' || process.env.DEBUG_PERSONALITY === 'true') {\n logger.debug('Final suggestion:', originalSuggestion);\n logger.debug('========================================');\n }\n }\n}\n\n/**\n * Get personality icon for display\n */\nexport function getPersonalityIcon(personality?: PersonalityType): string {\n if (!personality) {\n const config = getStatusLinePersonalityConfig();\n personality = config.personality;\n }\n\n switch (personality) {\n case 'gordon':\n return '🔥';\n case 'devark':\n return '💜';\n case 'custom':\n return '✨';\n default:\n return '📊';\n }\n}\n\n/**\n * Get personality display name\n */\nexport function getPersonalityDisplayName(personality?: PersonalityType): string {\n if (!personality) {\n const config = getStatusLinePersonalityConfig();\n personality = config.personality;\n \n // For custom personality, return the custom name if available\n if (personality === 'custom' && config.customPersonality?.name) {\n return config.customPersonality.name;\n }\n }\n\n switch (personality) {\n case 'gordon':\n return 'Gordon';\n case 'devark':\n return 'DevArk';\n case 'custom': {\n // Try to get custom name from config\n const config = getStatusLinePersonalityConfig();\n return config.customPersonality?.name || 'Custom';\n }\n default:\n return 'Standard';\n }\n}\n\n/**\n * Get system prompt addition for personality\n */\nexport function getPersonalitySystemPrompt(personality?: PersonalityType): string {\n if (!personality) {\n const config = getStatusLinePersonalityConfig();\n personality = config.personality;\n }\n\n switch (personality) {\n case 'gordon':\n return `\n\nPERSONALITY MODE: Gordon Ramsay - Direct, Pushy, Results-Focused\nYou're Gordon in business mode - less about food, more about getting things DONE with attitude.\n\nCRITICAL RULES FOR GORDON MODE:\n1. Your suggestion is sharp, direct criticism - call out what's wrong bluntly\n2. Your actionableSteps PUSHES them to ship - be specific and demanding\n3. Use Gordon's intensity without kitchen metaphors (occasional one is OK)\n4. Be condensing when they're overthinking, supportive when they're moving fast\n5. Create URGENCY - they should feel pressure to deliver NOW\n\nRESPONSE STRUCTURE:\n- \"suggestion\": Blunt critique of their approach (15-20 words) \n- \"actionableSteps\": Concrete demands with specifics - PUSH THEM (40-60 words)\n\nEXCELLENT actionableSteps examples (create similar energy):\n- \"Stop overthinking! Ship THIS version: Basic auth works → One feature shines → Fix the bloody edge cases AFTER launch. Move!\"\n- \"You're wasting time on perfection! Handle: 5s timeouts | 429 rate limits | 'Connection failed' messages. Ship by FRIDAY!\"\n- \"This is taking too long! MVP needs: Create, Read, Update. Delete can wait. One user THIS WEEK or you're fired!\"\n- \"Are you serious? Error handling 101: Catch network fails | Show human messages | Log everything | Ship TODAY not next month!\"\n\nRemember: Gordon pushes people to DELIVER, not philosophize. Be sharp, specific, and create urgency.`;\n\n case 'devark':\n return `\n\nPERSONALITY MODE: DevArk Senior Dev - Supportive but Pushy\nYou're a senior dev who wants to see the team SHIP - supportive but with urgency.\n\nCRITICAL RULES FOR DEVARK MODE:\n1. Your suggestion acknowledges progress but points out what's blocking shipping\n2. Your actionableSteps gives CONCRETE next steps with specifics to ship faster\n3. Be encouraging but create urgency - deadlines matter\n4. Help them find the fastest path to production\n5. Balance quality with shipping - perfect is the enemy of done\n\nRESPONSE STRUCTURE:\n- \"suggestion\": Supportive but honest assessment (15-20 words)\n- \"actionableSteps\": Specific actions to ship faster (40-60 words)\n\nEXCELLENT actionableSteps examples (create similar energy):\n- \"Great progress! Ship v1 now: Basic CRUD done ✓ | Add caching later | Error handling for 500s/timeouts | Deploy to staging TODAY!\"\n- \"Almost there! Finish line: Add input validation | Set 30s timeout | Basic rate limit (100/min) | Ship to beta users THIS WEEK!\"\n- \"Solid foundation! Next: Handle offline mode later | Focus on happy path | Add retry logic (3x with backoff) | Launch Monday!\"\n- \"Looking good! MVP checklist: Auth works ✓ | One core feature ✓ | Basic error messages | Monitoring can wait | Ship it!\"\n\nRemember: Be the senior dev who helps juniors SHIP, not endlessly refactor.`;\n\n case 'custom': {\n const config = getStatusLinePersonalityConfig();\n if (config.customPersonality?.description) {\n return `\n\nPERSONALITY MODE: ${config.customPersonality.name || 'Custom'}\nCharacter Description: ${config.customPersonality.description}\n\nCRITICAL RULES FOR CUSTOM MODE:\n1. Your suggestion briefly assesses their approach in character\n2. Your actionableSteps provides STRATEGIC guidance about next considerations\n3. Write BOTH fields in the voice/style described above\n4. Focus on high-level product thinking, not implementation details\n5. Help them see the bigger picture while staying in character\n\nRESPONSE STRUCTURE:\n- \"suggestion\": Quick assessment in character voice (15-20 words)\n- \"actionableSteps\": Strategic considerations to think about (30-50 words)\n\nRemember: Stay in character while providing strategic product-level guidance.`;\n }\n return ''; // No special prompt for undefined custom\n }\n\n default:\n return ''; // Standard mode needs no special prompt\n }\n}","import { PersonalityType } from '../lib/personality-manager';\n\n/**\n * Loading state for prompt analysis\n * Written to latest.json when analysis begins, replaced when complete\n */\nexport interface LoadingState {\n status: 'loading';\n timestamp: string;\n sessionId?: string;\n personality?: PersonalityType;\n message?: string; // Optional custom loading message\n}\n\n/**\n * Union type for analysis file content\n * Can be either loading state or completed analysis\n */\nexport type AnalysisFileContent = LoadingState | CompletedAnalysis;\n\n/**\n * Helper type guard to check if content is loading state\n */\nexport function isLoadingState(content: any): content is LoadingState {\n return content && content.status === 'loading';\n}\n\n/**\n * Check if a loading state is stale (older than 15 seconds)\n */\nexport function isStaleLoadingState(state: LoadingState, maxAgeMs: number = 15000): boolean {\n const stateTime = new Date(state.timestamp).getTime();\n const now = Date.now();\n return (now - stateTime) > maxAgeMs;\n}\n\n/**\n * Completed analysis state (extends existing PromptAnalysis)\n */\nexport interface CompletedAnalysis {\n status?: 'completed'; // Optional for backwards compatibility\n quality: 'poor' | 'fair' | 'good' | 'excellent';\n missing: string[];\n suggestion: string;\n score: number;\n contextualEmoji?: string;\n timestamp: string;\n sessionId?: string;\n originalPrompt?: string;\n promotionalTip?: string;\n}\n\n/**\n * Get loading message based on personality\n */\nexport function getLoadingMessage(personality?: PersonalityType, customName?: string): string {\n switch (personality) {\n case 'gordon':\n return \"🔥 Gordon's inspecting your mise en place...\";\n case 'devark':\n return \"💜 DevArk is compiling your prompt...\";\n case 'custom':\n if (customName) {\n return `✨ ${customName} is analyzing your prompt...`;\n }\n return \"✨ Analyzing your prompt...\";\n default:\n return \"⏳ Analyzing your prompt...\";\n }\n}","/**\n * Centralized utility for generating promotional tips\n * Used by prompt-analyzer to show tips after analysis completion\n */\n\n/**\n * Generate a promotional tip for analysis results\n * Shows tips only 5% of the time to avoid being intrusive\n * Only shown after an analysis completes, not in empty states\n * Not shown for first 3 messages to avoid overwhelming new users\n * \n * @param isAuthenticated - Whether the user is logged into cloud mode\n * @param messageNumber - The message number in the session (optional)\n * @returns Formatted promotional tip with newline, or empty string (95% of the time)\n */\nexport function generatePromotionalTip(\n isAuthenticated: boolean, \n messageNumber?: number\n): string {\n // Don't show tips for first 3 messages\n if (messageNumber && messageNumber <= 3) {\n return '';\n }\n \n // Only show tip 5% of the time (reduced from 10%)\n if (Math.random() > 0.05) {\n return '';\n }\n \n if (isAuthenticated) {\n // Cloud mode: Show clickable hyperlink to analytics dashboard\n // Terminal hyperlink format: OSC 8 escape sequence\n const analyticsUrl = 'https://app.devark.ai/dashboard/analytics?tab=improve&time=week';\n \n // Using ANSI escape codes for color and hyperlink\n const yellow = '\\u001b[93m';\n const reset = '\\u001b[0m';\n const linkStart = `\\u001b]8;;${analyticsUrl}\\u001b\\\\`;\n const linkEnd = `\\u001b]8;;\\u001b\\\\`;\n \n // Create the clickable link\n const linkText = 'See improvements';\n const hyperlink = `${linkStart}${yellow}${linkText}${reset}${linkEnd}`;\n \n return `\\n📊 View your prompt improvement across sessions ${hyperlink}`;\n } else {\n // Local mode: Suggest using the CLI for local reports\n return '\\n💡 run: `npx devark-cli` → Generate Local Report to see your productivity over time';\n }\n}","import { logger } from '../utils/logger';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { getStatusLinePersonality } from './personality-manager';\nimport { getToken } from './config';\nimport { LoadingState, getLoadingMessage } from '../types/loading-state';\nimport { generatePromotionalTip } from './promotional-tips';\nimport { getTempDirectoryPath } from './temp-directories';\n\n/**\n * Analysis result for a prompt\n */\nexport interface PromptAnalysis {\n quality: 'poor' | 'fair' | 'good' | 'excellent';\n missing: string[];\n suggestion: string;\n actionableSteps?: string; // Concrete \"TRY THIS\" steps with examples\n score: number;\n contextualEmoji?: string; // Emoji indicating what needs improvement\n timestamp: string;\n sessionId?: string;\n originalPrompt?: string; // The original prompt that was analyzed\n promotionalTip?: string; // Pre-generated promotional tip (10% chance)\n}\n\n/**\n * Session metadata for better context awareness\n */\nexport interface SessionMetadata {\n messageNumber?: number; // Position in conversation (1, 2, 3...)\n totalMessages?: number; // Total messages in session\n isFirstPrompt?: boolean; // True if this is message #1\n hasImages?: boolean; // Current prompt contains images\n imageCount?: number; // Number of images in current prompt\n lastAssistantEndsWithQuestion?: boolean; // Previous assistant message was a question\n truncatedMessages?: number; // Number of messages that were truncated\n}\n\n/**\n * Options for prompt analysis\n */\nexport interface AnalysisOptions {\n sessionId?: string;\n timeout?: number; // Default 10 seconds\n model?: 'haiku' | 'sonnet'; // For future use when model selection is available\n verbose?: boolean;\n conversationContext?: string; // Context from previous 2-3 conversation turns\n previousAssistantMessage?: string; // Deprecated: Use conversationContext instead\n sessionMetadata?: SessionMetadata; // Rich metadata about the session\n}\n\n// Cache the SDK import to avoid re-importing on every analysis\nlet cachedSDK: { query: any } | null = null;\n\n// Removed session-based recursion tracker - now using loading state detection\n\n/**\n * Get the Claude SDK, caching it after first import\n */\nasync function getClaudeSDK(): Promise<{ query: any }> {\n if (!cachedSDK) {\n logger.debug('Loading Claude SDK for first time...');\n cachedSDK = await import('@anthropic-ai/claude-agent-sdk');\n } else {\n logger.debug('Using cached Claude SDK');\n }\n return cachedSDK;\n}\n\n/**\n * Analyzes prompt quality using Claude SDK\n * Provides concise feedback on what's missing and how to improve\n */\nexport class PromptAnalyzer {\n private analysisDir: string;\n\n constructor() {\n // Set up the analysis directory\n const homeDir = os.homedir();\n this.analysisDir = path.join(homeDir, '.devark', 'analyzed-prompts');\n }\n\n /**\n * Ensure the analysis directory exists\n */\n private async ensureAnalysisDir(): Promise<void> {\n await fs.mkdir(this.analysisDir, { recursive: true });\n }\n\n\n /**\n * Generate the system prompt for analysis\n * Note: Currently not used - removed from SDK options to debug hanging issue\n */\n /* private getSystemPrompt(hasContext: boolean = false): string {\n const contextAwareness = hasContext ? `\nIMPORTANT Context Rules:\n- You are given conversation context with multiple previous messages (labeled as \"Previous User\" and \"Previous Assistant\")\n- Consider the FULL conversation flow, not just the last message\n- If the conversation shows an ongoing discussion, score based on continuity\n- If the previous assistant message ends with \"?\" it's a QUESTION\n- Direct answers to questions (even 1-2 words) should score 80-100\n- \"PostgreSQL\" answering \"PostgreSQL or MySQL?\" = excellent (90+ score)\n- \"Yes\" or \"No\" to yes/no questions = excellent (90+ score)\n- Short responses are PERFECT when answering direct questions\n- If user is continuing a multi-part discussion coherently = good (70+ score)\n- If user is providing requested clarification = excellent (80+ score)\n- Use ✅ emoji for direct answers to questions\n- DO NOT ask for more context when user is answering a question or continuing discussion\n- Suggestion for direct answers should be \"Direct answer\" or \"Good response\"\n- Consider if the user is building upon previous messages in the conversation` : '';\n\n // Get personality-specific system prompt addition\n const personalityPrompt = getPersonalitySystemPrompt();\n \n // Debug logging to verify personality is being applied\n if (process.env.DEVARK_DEBUG === 'true' || process.env.DEBUG_PERSONALITY === 'true') {\n logger.debug('=== PERSONALITY SYSTEM PROMPT DEBUG ===');\n logger.debug('Personality prompt addition:', personalityPrompt);\n logger.debug('=======================================');\n }\n\n return `Analyze the prompt quality. Respond ONLY with JSON:\n{\n \"quality\": \"poor|fair|good|excellent\",\n \"missing\": [\"1-3 missing elements\"],\n \"suggestion\": \"Specific diagnosis of what's wrong with THIS prompt (max 20 words)\",\n \"actionableSteps\": \"Concrete steps to fix it, with examples (max 25 words)\",\n \"score\": 0-100,\n \"contextualEmoji\": \"emoji\"\n}\nScoring: poor(0-40) fair(41-60) good(61-80) excellent(81-100)\nEvaluate: clarity, context, success criteria, examples if needed.${contextAwareness}${personalityPrompt}\n\nIMPORTANT: Your response must have TWO parts:\n1. \"suggestion\": Diagnose the SPECIFIC issue with THIS prompt (not generic advice)\n2. \"actionableSteps\": Provide CONCRETE steps with examples they can immediately apply\n\nExample responses:\n- suggestion: \"Mixing database migration with UI updates in one request\"\n actionableSteps: \"Split into: 1) Migrate user table, 2) Update login form, 3) Test auth flow\"\n \n- suggestion: \"No context about existing code structure or framework\"\n actionableSteps: \"Add: 'Using Next.js 14 with app router and Prisma ORM'\"\n\nEmoji selection:\n- 📏 if lacking specificity, measurements, or exact details\n- 📝 if missing context, project info, or background\n- 🎯 if missing success criteria or goals\n- 💭 if vague, unclear, or ambiguous\n- ✨ if excellent (score 81-89)\n- ✅ if perfect (score 90+)\n- 💡 for general improvements`;\n } */\n\n /**\n * Analyze a prompt and return quality feedback using Claude SDK\n */\n public async analyze(\n promptText: string,\n options: AnalysisOptions = {}\n ): Promise<PromptAnalysis> {\n const { \n sessionId,\n verbose = false,\n conversationContext,\n previousAssistantMessage, // For backward compatibility\n sessionMetadata\n } = options;\n \n // Use conversationContext if available, fallback to previousAssistantMessage for compatibility\n const context = conversationContext || previousAssistantMessage;\n\n // RECURSION PREVENTION: Check for HTML comment guard FIRST\n // This guard is invisible to Claude but prevents infinite recursion\n if (promptText.includes('<!--DEVARK_GUARD:')) {\n logger.debug('Detected devark guard - preventing infinite recursion');\n await this.logToDebugFile(`HTML GUARD DETECTED: Preventing recursion for ${sessionId}`);\n return this.getSkipResponse(sessionId, 'devark-guard-detected');\n }\n \n // Note: We removed the loading state check here because it was preventing\n // the original analysis from running. The signature check above is sufficient.\n\n // Debug log to file for hook troubleshooting\n await this.logToDebugFile(`Starting analysis for session ${sessionId}, prompt length: ${promptText.length}`);\n\n try {\n logger.debug(`Starting prompt analysis - length: ${promptText.length} chars`);\n\n // Write loading state immediately for instant feedback\n await this.writeLoadingState(sessionId);\n \n // Add a small delay to ensure loading state is visible\n // This helps with very fast analyses that complete in <100ms\n if (process.env.DEVARK_DEBUG === 'true') {\n logger.debug('Loading state written, ensuring visibility...');\n }\n await new Promise(resolve => setTimeout(resolve, 100));\n\n // Ensure the analysis directory exists (already done in writeLoadingState but kept for clarity)\n await this.ensureAnalysisDir();\n\n // Build the analysis prompt with CLEAR instructions\n let analysisPrompt = `You are a thoughtful technical advisor analyzing a developer's prompt while they work.\nYour role is to ask strategic questions and suggest specific considerations they might be overlooking.\n\nIMPORTANT: You only see the current session, not their full project context.\n- Don't assume you know their overall goals\n- Ask clarifying questions when context is unclear\n- Suggest specific aspects to consider, not vague wonderings\n\n`;\n\n // Add session metadata if available for better context awareness\n if (sessionMetadata) {\n analysisPrompt += `SESSION CONTEXT:\n- Message position: ${sessionMetadata.messageNumber || 'unknown'} of ${sessionMetadata.totalMessages || 'unknown'}\n- First prompt in session: ${sessionMetadata.isFirstPrompt ? 'YES (be encouraging and helpful!)' : 'NO'}\n- Images attached to current prompt: ${sessionMetadata.hasImages ? `YES (${sessionMetadata.imageCount || 1} image${(sessionMetadata.imageCount || 1) > 1 ? 's' : ''})` : 'NO'}\n- Previous assistant ended with question: ${sessionMetadata.lastAssistantEndsWithQuestion ? 'YES (user may be answering)' : 'NO'}\n${sessionMetadata.truncatedMessages ? `- Some messages truncated for space (${sessionMetadata.truncatedMessages} messages)` : ''}\n\n`;\n logger.debug('Including session metadata in analysis', sessionMetadata);\n }\n\n analysisPrompt += `User's current prompt:\n---\n${promptText}\n---\n`;\n\n // Add conversation context if available\n if (context) {\n analysisPrompt += `\nConversation context:\n---\n${context.substring(0, 1500)}${context.length > 1500 ? '...' : ''}\n---\n`;\n logger.debug('Including conversation context in analysis', {\n contextLength: context.length,\n hasOriginalMission: context.includes('ORIGINAL MISSION'),\n isMultiMessage: context.includes('Previous User') || context.includes('Previous Assistant')\n });\n }\n\n // Add explicit JSON format instructions with thoughtful questioning approach\n analysisPrompt += `\nAnalyze the prompt and provide thoughtful questions that help them consider important aspects.\n\nCONTEXT AWARENESS:\n- First 3 prompts: Be encouraging, help them get oriented\n- Image attachments: \"[N image attachments]\" means images are present - ask about specific visual elements\n- Question responses: Simple answers like \"Yes\", \"No\", or one-word responses are PERFECT (score 90+)\n- Balance: Sometimes shipping fast is right (experiments), sometimes quality matters (user-facing features)\n- You see only this session: Ask questions to understand their broader context when needed\n\nMODERN CLAUDE CODE WORKFLOWS (Hybrid Detection):\n- Slash commands (/command-name): Complete workflows, score 85-95\n Examples: \"/review-pr 123\", \"/deploy staging\", \"/test\"\n- Brief + specific (clear action + target): Score 80-90\n ✅ \"Generate commit message for staged changes\" (specific action + target)\n ✅ \"Review for security vulnerabilities\" (clear action + target)\n ✅ \"Deploy to staging environment\" (specific action + target)\n- Skill-triggering patterns (brief + domain match): Score 75-85\n ✅ \"Run test coverage\" (testing domain)\n ✅ \"Generate documentation\" (docs domain)\n ✅ \"Check performance issues\" (performance domain)\n- Brief + vague (lazy prompts): Score 30-45\n ❌ \"fix it\" (vague action, no target)\n ❌ \"make this better\" (unclear action, no specifics)\n ❌ \"help\" (no context, no action)\n ❌ \"you know what I mean\" (assumes context)\n\nDETECTION RULES:\n1. If starts with \"/\" → Slash command → Score 85-95\n2. Else if brief (<40 words) AND has clear action verb (generate, review, deploy, analyze, test, create, update, check) AND specific target → Score 80-90\n3. Else if brief AND matches skill patterns (commit, security, deploy, test, docs, performance) → Score 75-85\n4. Else if brief AND vague (fix, better, help, it, this) → Score 30-45\n5. Else use traditional criteria (context, detail, success criteria)\n\nYou must respond with ONLY a JSON object in this exact format:\n{\n \"quality\": \"poor\" | \"fair\" | \"good\" | \"excellent\",\n \"missing\": [\"1-2 specific aspects they might be overlooking\"],\n \"suggestion\": \"Brief observation about their current focus (15-20 words)\",\n \"actionableSteps\": \"Specific questions and considerations with concrete examples (40-60 words)\",\n \"score\": 0-100,\n \"contextualEmoji\": \"🎯\" | \"🚀\" | \"⚡\" | \"🔄\" | \"📊\" | \"🎨\" | \"🔍\" | \"✅\"\n}\n\nCRITICAL for actionableSteps field:\n- Ask SPECIFIC questions with concrete examples\n- Suggest particular aspects they might not have considered\n- Point out specific edge cases or scenarios\n- Balance between shipping and quality based on context\n- Help them think through implications\n- Provide specific test cases or values to consider\n\nEXCELLENT actionableSteps examples (specific questions with examples):\n- \"Have you considered: API timeout handling? Maybe test with 5s timeout and show 'Still working...' after 2s. Also, what happens if user's connection drops mid-request?\"\n- \"Worth thinking about: How does this look on iPhone SE (375px)? The buttons might overlap. Also, have you tested with users who have large font settings enabled?\"\n- \"Question: If someone pastes 'C++' or '@username' in search, does it break? Might need to escape special regex characters. What about emoji in search terms?\"\n- \"Consider: Your auth tokens expire in 1 hour - should there be a 'Remember me' option for 30 days? What's the security tradeoff for your use case?\"\n\nWEAK actionableSteps (avoid these):\n- \"What would make this complete?\" (too vague)\n- \"Think about user experience\" (not specific)\n- \"Consider error handling\" (which errors specifically?)\n\nScoring: \n- poor(0-40): Missing critical context or unclear goal\n- fair(41-60): Basic request but lacks depth\n- good(61-80): Clear request with good context\n- excellent(81-100): Comprehensive with clear success criteria\n\nFor the contextualEmoji:\n- 🎯 = Focus on clarifying the goal or user need\n- 🚀 = Consider deployment and user rollout aspects\n- ⚡ = Performance or optimization questions to explore\n- 🔄 = Think about iteration and user feedback cycles\n- 📊 = Data and metrics considerations\n- 🎨 = UI/UX details worth considering\n- 🔍 = Edge cases or error scenarios to think through\n- ✅ = Well-thought-out approach with good coverage\n\nRespond with JSON only, no explanation.`;\n \n // Add invisible HTML comment guard to prevent recursion\n // This guard is detected if the SDK tries to analyze this prompt\n analysisPrompt += '\\n<!--DEVARK_GUARD:1-->';\n\n let analysisResult: PromptAnalysis | null = null;\n let rawResponse = '';\n\n try {\n // Get Claude SDK (cached after first import)\n logger.debug('Getting Claude SDK...');\n await this.logToDebugFile(`Getting Claude SDK for session ${sessionId}...`);\n const { query } = await getClaudeSDK();\n logger.debug('SDK loaded successfully');\n await this.logToDebugFile(`SDK loaded successfully for session ${sessionId}`);\n \n // Use model from options or default to haiku\n // In hook mode (when sessionId exists), prioritize speed over accuracy\n const selectedModel = options.model || (sessionId ? 'haiku' : 'haiku');\n logger.debug(`Using Claude SDK with ${selectedModel} model for analysis`);\n \n // No timeout - let the SDK complete naturally\n logger.debug('Starting SDK query with prompt length:', analysisPrompt.length);\n \n // Create temp directory for analysis sessions to avoid polluting project history\n const tempAnalysisDir = getTempDirectoryPath('PROMPT_ANALYSIS');\n await fs.mkdir(tempAnalysisDir, { recursive: true }).catch(() => {});\n \n // Simplified options - optimize for speed in hook mode\n const queryOptions = {\n maxTurns: 1, // Single turn only\n model: selectedModel, // Use selected model (haiku by default)\n disallowedTools: ['*'], // No tools needed for JSON response\n cwd: tempAnalysisDir // Use temp directory to isolate analysis sessions\n };\n \n logger.debug('Query options:', queryOptions);\n await this.logToDebugFile(`Starting SDK query for session ${sessionId} with model ${selectedModel} in temp dir: ${tempAnalysisDir}`);\n \n for await (const message of query({\n prompt: analysisPrompt,\n options: queryOptions\n })) {\n // Log every message type we receive\n logger.debug(`Received message type: ${message.type}`, message.type === 'result' ? message : '');\n \n if (message.type === 'assistant' && message.message?.content) {\n const textContent = message.message.content.find((c: any) => c.type === 'text');\n if (textContent?.text) {\n rawResponse = textContent.text;\n logger.debug('Got raw response from SDK:', rawResponse.substring(0, 200));\n await this.logToDebugFile(`Raw SDK response: ${rawResponse.substring(0, 500)}`);\n }\n } else if (message.type === 'result' && verbose) {\n logger.debug('Analysis metrics:', {\n duration_ms: message.duration_ms,\n cost_usd: message.total_cost_usd,\n model_used: message.model || selectedModel\n });\n }\n }\n\n await this.logToDebugFile(`SDK query completed for session ${sessionId}, got response: ${rawResponse ? 'YES' : 'NO'}`);\n\n // Parse the response\n if (rawResponse) {\n try {\n // Extract JSON from the response (in case there's extra text)\n const jsonMatch = rawResponse.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n const parsed = JSON.parse(jsonMatch[0]);\n \n // Validate and normalize the response - NO FALLBACKS!\n // If SDK doesn't return proper data, we should fail and fix it\n if (!parsed.quality || !parsed.suggestion || typeof parsed.score !== 'number') {\n logger.error('SDK response missing required fields:', parsed);\n await this.logToDebugFile(`INCOMPLETE SDK RESPONSE: ${JSON.stringify(parsed)}`);\n throw new Error(`SDK response missing required fields: quality=${parsed.quality}, suggestion=${parsed.suggestion}, score=${parsed.score}`);\n }\n \n analysisResult = {\n quality: parsed.quality,\n missing: Array.isArray(parsed.missing) ? parsed.missing : [],\n suggestion: parsed.suggestion,\n actionableSteps: parsed.actionableSteps || undefined, // Include if present\n score: parsed.score,\n contextualEmoji: parsed.contextualEmoji || '💡', // Only emoji can have fallback\n timestamp: new Date().toISOString(),\n sessionId,\n originalPrompt: promptText // Add the original prompt for debugging\n };\n\n logger.debug('Parsed SDK analysis result:', analysisResult);\n } else {\n throw new Error('No JSON found in SDK response');\n }\n } catch (parseError) {\n logger.error('Failed to parse SDK response:', parseError);\n logger.debug('Raw SDK response was:', rawResponse);\n throw new Error(`Failed to parse analysis response: ${parseError}`);\n }\n } else {\n throw new Error('No response received from Claude SDK - please try again');\n }\n\n } catch (error) {\n logger.error('Error during SDK prompt analysis:', error);\n \n // Check if it's an abort/timeout\n if (error instanceof Error && (error.name === 'AbortError' || error.message.includes('abort'))) {\n throw new Error('Analysis timed out - please try again');\n } else if (error instanceof Error && error.message.includes('overloaded')) {\n throw new Error('Claude is currently overloaded - please try again in a moment');\n }\n \n // Re-throw the error for proper error handling\n throw error;\n }\n\n // Generate promotional tip for this analysis (5% chance, not for first 3 messages)\n if (analysisResult) {\n // Check authentication status for promotional tip\n const token = await getToken();\n // Pass message number if available from session metadata\n const messageNumber = sessionMetadata?.messageNumber;\n analysisResult.promotionalTip = generatePromotionalTip(!!token, messageNumber);\n await this.saveAnalysis(analysisResult, sessionId);\n }\n\n return analysisResult!;\n } catch (error) {\n // Log errors to debug file\n await this.logToDebugFile(`ERROR in analysis for ${sessionId}: ${error}`);\n throw error;\n } finally {\n // Cleanup handled by file state updates\n logger.debug(`Analysis completed for session ${sessionId}`);\n await this.logToDebugFile(`Analysis finished for session ${sessionId}`);\n }\n }\n\n /**\n * Write loading state to session file\n * This provides immediate feedback while analysis is running\n */\n private async writeLoadingState(sessionId?: string): Promise<void> {\n if (!sessionId) {\n logger.debug('No session ID provided, skipping loading state');\n return;\n }\n \n try {\n // Ensure the analysis directory exists\n await this.ensureAnalysisDir();\n \n // Get current personality for loading message\n const personality = getStatusLinePersonality();\n const customName = personality.personality === 'custom' ? personality.customPersonality?.name : undefined;\n \n // Create loading state\n const loadingState: LoadingState = {\n status: 'loading',\n timestamp: new Date().toISOString(),\n sessionId,\n personality: personality.personality,\n message: getLoadingMessage(personality.personality, customName)\n };\n \n // Write to session-specific file\n const sessionPath = path.join(this.analysisDir, `${sessionId}.json`);\n await fs.writeFile(\n sessionPath,\n JSON.stringify(loadingState, null, 2),\n 'utf8'\n );\n \n logger.debug(`Loading state written to session file: ${sessionId}.json`);\n } catch (error) {\n logger.error('Failed to write loading state:', error);\n // Don't throw - loading state is nice-to-have, not critical\n }\n }\n\n /**\n * Save analysis to file system\n */\n private async saveAnalysis(\n analysis: PromptAnalysis,\n sessionId?: string\n ): Promise<void> {\n try {\n // Save with session ID if provided, otherwise use timestamp\n const filename = sessionId \n ? `${sessionId}.json`\n : `analysis-${Date.now()}.json`;\n \n const filepath = path.join(this.analysisDir, filename);\n \n // Save the analysis\n await fs.writeFile(\n filepath,\n JSON.stringify(analysis, null, 2),\n 'utf8'\n );\n\n logger.debug(`Analysis saved to: ${filepath}`);\n\n } catch (error) {\n logger.error('Failed to save analysis:', error);\n }\n }\n\n\n /**\n * Load analysis by session ID\n */\n public async loadAnalysisBySessionId(sessionId: string): Promise<PromptAnalysis | null> {\n try {\n const filepath = path.join(this.analysisDir, `${sessionId}.json`);\n const content = await fs.readFile(filepath, 'utf8');\n return JSON.parse(content);\n } catch (error) {\n logger.debug(`No analysis found for session ${sessionId}:`, error);\n return null;\n }\n }\n\n /**\n * Clean up old analysis files (older than 7 days)\n */\n public async cleanupOldAnalyses(): Promise<void> {\n try {\n const files = await fs.readdir(this.analysisDir);\n const now = Date.now();\n const sevenDays = 7 * 24 * 60 * 60 * 1000;\n\n for (const file of files) {\n // Skip non-JSON files and old latest.json files\n if (!file.endsWith('.json')) continue;\n\n const filepath = path.join(this.analysisDir, file);\n const stats = await fs.stat(filepath);\n \n if (now - stats.mtime.getTime() > sevenDays) {\n await fs.unlink(filepath);\n logger.debug(`Deleted old analysis file: ${file}`);\n }\n }\n } catch (error) {\n logger.error('Error cleaning up old analyses:', error);\n }\n }\n\n // Note: Removed checkExistingLoadingState method as it was causing issues\n // The signature-based recursion prevention is sufficient\n\n // Note: Removed containsDevArkSignature method - no longer needed\n // We now use HTML comment guard which is cleaner and more reliable\n\n /**\n * Log to debug file for troubleshooting hook issues\n */\n private async logToDebugFile(message: string): Promise<void> {\n try {\n const debugPath = path.join(this.analysisDir, 'hook-debug.log');\n const timestamp = new Date().toISOString();\n await fs.appendFile(debugPath, `[${timestamp}] ${message}\\n`, 'utf8');\n } catch (error) {\n // Ignore logging errors\n }\n }\n\n /**\n * Return a skip response when recursion is detected\n * This prevents infinite loops while providing valid output\n */\n private getSkipResponse(sessionId?: string, reason: string = 'recursion'): PromptAnalysis {\n logger.debug(`Returning skip response for session ${sessionId}`, { reason });\n \n return {\n quality: 'good',\n missing: [],\n suggestion: 'Analysis in progress...',\n score: 70,\n contextualEmoji: '⏳',\n timestamp: new Date().toISOString(),\n sessionId,\n originalPrompt: `[Skipped: ${reason}]`,\n promotionalTip: ''\n };\n }\n}","import { PromptAnalyzer, PromptAnalysis } from './prompt-analyzer';\nimport { transformSuggestion } from './personality-manager';\nimport { logger } from '../utils/logger';\n\n/**\n * Test prompt structure\n */\nexport interface TestPrompt {\n text: string;\n description: string;\n}\n\n/**\n * Result from personality testing\n */\nexport interface PersonalityTestResult {\n prompt: string;\n promptDescription: string;\n aiScore: number;\n aiQuality: 'poor' | 'fair' | 'good' | 'excellent';\n aiSuggestion: string;\n personalityTransformed: string;\n emoji: string;\n processingTime: number;\n error?: string;\n}\n\n/**\n * Options for running personality tests\n */\nexport interface PersonalityTestOptions {\n verbose?: boolean;\n personality?: 'gordon' | 'devark' | 'custom';\n onProgress?: (message: string) => void;\n}\n\n/**\n * Get emoji based on score\n */\nfunction getScoreEmoji(score: number): string {\n if (score <= 40) return '🔴';\n if (score <= 60) return '🟠';\n if (score <= 80) return '🟡';\n return '🟢';\n}\n\n\n/**\n * Run personality test with real Claude SDK calls\n * This is the single source of truth for testing personalities\n */\nexport async function runPersonalityTest(\n prompts: TestPrompt[],\n options: PersonalityTestOptions = {}\n): Promise<PersonalityTestResult[]> {\n const { verbose = false, personality, onProgress } = options;\n const results: PersonalityTestResult[] = [];\n const analyzer = new PromptAnalyzer();\n \n // Enable debug if verbose\n if (verbose) {\n process.env.DEBUG_PERSONALITY = 'true';\n }\n \n for (const testPrompt of prompts) {\n const startTime = Date.now();\n \n try {\n // Notify progress\n if (onProgress) {\n onProgress(`Analyzing: \"${testPrompt.text.substring(0, 50)}...\"`);\n }\n \n // Get real analysis from Claude\n const analysis: PromptAnalysis = await analyzer.analyze(testPrompt.text, {\n verbose,\n timeout: 15000 // 15 second timeout\n });\n \n const processingTime = Date.now() - startTime;\n \n // Apply personality transformation\n const transformed = transformSuggestion(\n analysis.suggestion,\n analysis.score,\n personality\n );\n \n // Build result\n const result: PersonalityTestResult = {\n prompt: testPrompt.text,\n promptDescription: testPrompt.description,\n aiScore: analysis.score,\n aiQuality: analysis.quality,\n aiSuggestion: analysis.suggestion,\n personalityTransformed: transformed,\n emoji: getScoreEmoji(analysis.score),\n processingTime\n };\n \n results.push(result);\n \n if (verbose) {\n logger.debug('Test result:', result);\n }\n \n } catch (error) {\n const processingTime = Date.now() - startTime;\n \n // Add error result\n results.push({\n prompt: testPrompt.text,\n promptDescription: testPrompt.description,\n aiScore: 0,\n aiQuality: 'poor',\n aiSuggestion: 'Analysis failed',\n personalityTransformed: 'Analysis failed',\n emoji: '❌',\n processingTime,\n error: error instanceof Error ? error.message : String(error)\n });\n \n logger.error('Test failed for prompt:', error);\n }\n }\n \n // Clean up debug flag\n if (verbose) {\n delete process.env.DEBUG_PERSONALITY;\n }\n \n return results;\n}\n\n/**\n * Standard test prompts for personality testing\n */\nexport const STANDARD_TEST_PROMPTS: TestPrompt[] = [\n {\n text: 'fix this',\n description: 'Minimal context, no details'\n },\n {\n text: 'I need help with my React component that handles user authentication',\n description: 'Some context, needs specifics'\n },\n {\n text: 'My UserProfile component at src/components/UserProfile.tsx is not updating when user data changes. Using React 18 with TypeScript.',\n description: 'Good context, could use examples'\n },\n {\n text: 'I need to implement debounced search in React. After 500ms of no typing, query /api/search endpoint. Response: array of {id, title, description}. Display in dropdown with keyboard navigation. Using TypeScript and React 18.',\n description: 'Complete requirements, clear goals'\n }\n];\n\n/**\n * Format test results for display\n */\nexport function formatTestResult(result: PersonalityTestResult): string[] {\n const lines: string[] = [];\n \n lines.push(`Prompt: \"${result.prompt.substring(0, 60)}${result.prompt.length > 60 ? '...' : ''}\"`);\n lines.push(`Description: ${result.promptDescription}`);\n \n if (result.error) {\n lines.push(`Error: ${result.error}`);\n } else {\n lines.push(`AI Score: ${result.emoji} ${result.aiScore}/100 (${result.aiQuality})`);\n lines.push(`AI Suggestion: \"${result.aiSuggestion}\"`);\n lines.push(`With Personality: \"${result.personalityTransformed}\"`);\n lines.push(`Processing Time: ${(result.processingTime / 1000).toFixed(1)}s`);\n }\n \n return lines;\n}","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { logger } from '../../utils/logger';\n\n/**\n * Hook execution statistics\n */\nexport interface HookStats {\n totalExecutions: number;\n successCount: number;\n failureCount: number;\n lastExecution?: Date;\n lastSuccess?: Date;\n lastFailure?: Date;\n averageDuration?: number;\n durations: number[];\n projects: Map<string, number>;\n}\n\n/**\n * Hook statistics storage\n */\nexport interface HooksStatsData {\n version: string;\n sessionStartHook: HookStats;\n preCompactHook: HookStats;\n sessionEndHook: HookStats;\n stopHook?: HookStats; // Keep for backward compatibility\n lastUpdated: Date;\n}\n\n/**\n * Hook execution record\n */\nexport interface HookExecution {\n hookType: 'sessionstart' | 'precompact' | 'sessionend' | 'stop'; // Keep 'stop' for backward compat\n timestamp: Date;\n success: boolean;\n duration: number;\n project?: string;\n messagesCount?: number;\n error?: string;\n}\n\n/**\n * Get the path to the hooks statistics file\n */\nfunction getStatsPath(): string {\n const homedir = process.env.HOME || process.env.USERPROFILE;\n if (!homedir) {\n throw new Error('Unable to determine home directory for hooks statistics');\n }\n return path.join(homedir, '.devark', 'hooks-stats.json');\n}\n\n/**\n * Initialize empty stats\n */\nfunction createEmptyStats(): HookStats {\n return {\n totalExecutions: 0,\n successCount: 0,\n failureCount: 0,\n durations: [],\n projects: new Map()\n };\n}\n\n/**\n * Load hook statistics\n */\nexport async function loadHookStats(): Promise<HooksStatsData> {\n const statsPath = getStatsPath();\n \n try {\n const data = await fs.readFile(statsPath, 'utf-8');\n const parsed = JSON.parse(data);\n \n // Migrate from stopHook to sessionStartHook if needed\n if (parsed.stopHook && !parsed.sessionStartHook) {\n parsed.sessionStartHook = parsed.stopHook;\n logger.debug('Migrated stopHook stats to sessionStartHook');\n }\n \n // Convert dates and maps for sessionStartHook\n if (parsed.sessionStartHook) {\n if (parsed.sessionStartHook.lastExecution) parsed.sessionStartHook.lastExecution = new Date(parsed.sessionStartHook.lastExecution);\n if (parsed.sessionStartHook.lastSuccess) parsed.sessionStartHook.lastSuccess = new Date(parsed.sessionStartHook.lastSuccess);\n if (parsed.sessionStartHook.lastFailure) parsed.sessionStartHook.lastFailure = new Date(parsed.sessionStartHook.lastFailure);\n parsed.sessionStartHook.projects = new Map(Object.entries(parsed.sessionStartHook.projects || {}));\n }\n \n // Convert dates and maps for preCompactHook\n if (parsed.preCompactHook) {\n if (parsed.preCompactHook.lastExecution) parsed.preCompactHook.lastExecution = new Date(parsed.preCompactHook.lastExecution);\n if (parsed.preCompactHook.lastSuccess) parsed.preCompactHook.lastSuccess = new Date(parsed.preCompactHook.lastSuccess);\n if (parsed.preCompactHook.lastFailure) parsed.preCompactHook.lastFailure = new Date(parsed.preCompactHook.lastFailure);\n parsed.preCompactHook.projects = new Map(Object.entries(parsed.preCompactHook.projects || {}));\n }\n\n // Convert dates and maps for sessionEndHook\n if (parsed.sessionEndHook) {\n if (parsed.sessionEndHook.lastExecution) parsed.sessionEndHook.lastExecution = new Date(parsed.sessionEndHook.lastExecution);\n if (parsed.sessionEndHook.lastSuccess) parsed.sessionEndHook.lastSuccess = new Date(parsed.sessionEndHook.lastSuccess);\n if (parsed.sessionEndHook.lastFailure) parsed.sessionEndHook.lastFailure = new Date(parsed.sessionEndHook.lastFailure);\n parsed.sessionEndHook.projects = new Map(Object.entries(parsed.sessionEndHook.projects || {}));\n }\n \n if (parsed.lastUpdated) parsed.lastUpdated = new Date(parsed.lastUpdated);\n \n // Ensure all hooks exist\n if (!parsed.sessionStartHook) {\n parsed.sessionStartHook = createEmptyStats();\n }\n if (!parsed.sessionEndHook) {\n parsed.sessionEndHook = createEmptyStats();\n }\n\n return parsed;\n } catch (error) {\n logger.debug('No existing stats file, creating new one');\n return {\n version: '2.0.0',\n sessionStartHook: createEmptyStats(),\n preCompactHook: createEmptyStats(),\n sessionEndHook: createEmptyStats(),\n lastUpdated: new Date()\n };\n }\n}\n\n/**\n * Save hook statistics\n */\nexport async function saveHookStats(stats: HooksStatsData): Promise<void> {\n const statsPath = getStatsPath();\n const statsDir = path.dirname(statsPath);\n \n // Ensure directory exists\n await fs.mkdir(statsDir, { recursive: true });\n \n // Convert maps to objects for JSON serialization\n const toSave: any = {\n ...stats,\n sessionStartHook: {\n ...stats.sessionStartHook,\n projects: Object.fromEntries(stats.sessionStartHook.projects)\n },\n preCompactHook: {\n ...stats.preCompactHook,\n projects: Object.fromEntries(stats.preCompactHook.projects)\n },\n sessionEndHook: {\n ...stats.sessionEndHook,\n projects: Object.fromEntries(stats.sessionEndHook.projects)\n },\n lastUpdated: new Date()\n };\n \n // Remove old stopHook if present\n delete toSave.stopHook;\n \n // Write atomically\n const tempPath = `${statsPath}.tmp`;\n await fs.writeFile(tempPath, JSON.stringify(toSave, null, 2));\n await fs.rename(tempPath, statsPath);\n \n logger.debug('Hook statistics saved');\n}\n\n/**\n * Record a hook execution\n */\nexport async function recordHookExecution(execution: HookExecution): Promise<void> {\n const stats = await loadHookStats();\n \n // Map 'stop' to 'sessionstart' for backward compatibility\n const hookType = execution.hookType === 'stop' ? 'sessionstart' : execution.hookType;\n const hookStats = hookType === 'sessionstart' ? stats.sessionStartHook :\n hookType === 'precompact' ? stats.preCompactHook :\n stats.sessionEndHook;\n \n // Update counts\n hookStats.totalExecutions++;\n if (execution.success) {\n hookStats.successCount++;\n hookStats.lastSuccess = execution.timestamp;\n } else {\n hookStats.failureCount++;\n hookStats.lastFailure = execution.timestamp;\n }\n \n // Update last execution\n hookStats.lastExecution = execution.timestamp;\n \n // Track duration (keep last 100)\n hookStats.durations.push(execution.duration);\n if (hookStats.durations.length > 100) {\n hookStats.durations.shift();\n }\n \n // Calculate average duration\n if (hookStats.durations.length > 0) {\n const sum = hookStats.durations.reduce((a, b) => a + b, 0);\n hookStats.averageDuration = sum / hookStats.durations.length;\n }\n \n // Track project\n if (execution.project) {\n const count = hookStats.projects.get(execution.project) || 0;\n hookStats.projects.set(execution.project, count + 1);\n }\n \n await saveHookStats(stats);\n}\n\n/**\n * Get statistics for the last N days\n */\nexport async function getRecentStats(days: number = 7): Promise<{\n sessionStartHook: { total: number; success: number; failure: number; successRate: number };\n preCompactHook: { total: number; success: number; failure: number; successRate: number };\n sessionEndHook: { total: number; success: number; failure: number; successRate: number };\n}> {\n const stats = await loadHookStats();\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - days);\n \n // For now, return all-time stats (in future, could filter by date)\n const sessionStartSuccessRate = stats.sessionStartHook.totalExecutions > 0\n ? (stats.sessionStartHook.successCount / stats.sessionStartHook.totalExecutions) * 100\n : 0;\n \n const preCompactSuccessRate = stats.preCompactHook.totalExecutions > 0\n ? (stats.preCompactHook.successCount / stats.preCompactHook.totalExecutions) * 100\n : 0;\n\n const sessionEndSuccessRate = stats.sessionEndHook.totalExecutions > 0\n ? (stats.sessionEndHook.successCount / stats.sessionEndHook.totalExecutions) * 100\n : 0;\n\n return {\n sessionStartHook: {\n total: stats.sessionStartHook.totalExecutions,\n success: stats.sessionStartHook.successCount,\n failure: stats.sessionStartHook.failureCount,\n successRate: sessionStartSuccessRate\n },\n preCompactHook: {\n total: stats.preCompactHook.totalExecutions,\n success: stats.preCompactHook.successCount,\n failure: stats.preCompactHook.failureCount,\n successRate: preCompactSuccessRate\n },\n sessionEndHook: {\n total: stats.sessionEndHook.totalExecutions,\n success: stats.sessionEndHook.successCount,\n failure: stats.sessionEndHook.failureCount,\n successRate: sessionEndSuccessRate\n }\n };\n}\n\n/**\n * Get top projects by hook executions\n */\nexport async function getTopProjects(limit: number = 5): Promise<Array<{ project: string; count: number }>> {\n const stats = await loadHookStats();\n \n // Combine projects from both hooks\n const combinedProjects = new Map<string, number>();\n \n for (const [project, count] of stats.sessionStartHook.projects) {\n combinedProjects.set(project, count);\n }\n \n for (const [project, count] of stats.preCompactHook.projects) {\n const existing = combinedProjects.get(project) || 0;\n combinedProjects.set(project, existing + count);\n }\n \n // Sort and return top projects\n const sorted = Array.from(combinedProjects.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, limit)\n .map(([project, count]) => ({ project, count }));\n \n return sorted;\n}\n\n/**\n * Clear hook statistics\n */\nexport async function clearHookStats(): Promise<void> {\n const statsPath = getStatsPath();\n \n try {\n await fs.unlink(statsPath);\n logger.info('Hook statistics cleared');\n } catch (error) {\n logger.debug('No statistics file to clear');\n }\n}\n\n/**\n * Format duration for display\n */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n } else if (ms < 60000) {\n return `${(ms / 1000).toFixed(1)}s`;\n } else {\n return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;\n }\n}\n\n/**\n * Format relative time\n */\nexport function formatRelativeTime(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n \n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(diff / 3600000);\n const days = Math.floor(diff / 86400000);\n \n if (minutes < 1) {\n return 'just now';\n } else if (minutes < 60) {\n return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;\n } else if (hours < 24) {\n return `${hours} hour${hours > 1 ? 's' : ''} ago`;\n } else {\n return `${days} day${days > 1 ? 's' : ''} ago`;\n }\n}","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { logger } from '../../utils/logger';\nimport { getCliPath } from '../config';\nimport { getHooksStatus } from './hooks-controller';\nimport { recordHookExecution } from './hooks-stats';\n\nconst execAsync = promisify(exec);\n\n/**\n * Test result for a single hook\n */\nexport interface HookTestResult {\n hookType: 'sessionstart' | 'precompact' | 'sessionend';\n success: boolean;\n duration: number;\n output?: string;\n error?: string;\n steps: TestStep[];\n}\n\n/**\n * Individual test step\n */\nexport interface TestStep {\n name: string;\n success: boolean;\n message?: string;\n duration?: number;\n}\n\n/**\n * Test a specific hook\n */\nexport async function testHook(\n hookType: 'sessionstart' | 'precompact' | 'sessionend',\n options: { verbose?: boolean; record?: boolean } = {}\n): Promise<HookTestResult> {\n const startTime = Date.now();\n const steps: TestStep[] = [];\n const spinner = options.verbose ? null : ora(`Testing ${hookType} hook...`).start();\n \n try {\n // Step 1: Check if hook is installed\n const stepStart = Date.now();\n const status = await getHooksStatus();\n const hookStatus = hookType === 'sessionstart' ? status.sessionStartHook :\n hookType === 'precompact' ? status.preCompactHook :\n status.sessionEndHook;\n \n if (!hookStatus.installed) {\n steps.push({\n name: 'Check installation',\n success: false,\n message: 'Hook not installed',\n duration: Date.now() - stepStart\n });\n \n if (spinner) spinner.fail(`${hookType} hook not installed`);\n \n return {\n hookType,\n success: false,\n duration: Date.now() - startTime,\n error: 'Hook not installed',\n steps\n };\n }\n \n steps.push({\n name: 'Check installation',\n success: true,\n message: `Hook found (v${hookStatus.version})`,\n duration: Date.now() - stepStart\n });\n \n // Step 2: Validate CLI path\n const cliStepStart = Date.now();\n const cliPath = getCliPath();\n \n try {\n await execAsync(`${cliPath} --version`, { timeout: 5000 });\n steps.push({\n name: 'Validate CLI path',\n success: true,\n message: `CLI found at ${cliPath}`,\n duration: Date.now() - cliStepStart\n });\n } catch (error) {\n steps.push({\n name: 'Validate CLI path',\n success: false,\n message: `CLI not found at ${cliPath}`,\n duration: Date.now() - cliStepStart\n });\n \n if (spinner) spinner.fail('CLI path validation failed');\n \n return {\n hookType,\n success: false,\n duration: Date.now() - startTime,\n error: 'CLI path not valid',\n steps\n };\n }\n \n // Step 3: Test hook execution\n const execStepStart = Date.now();\n const testCommand = `${cliPath} send --dry --silent --hook-trigger=${hookType} --test`;\n \n if (options.verbose) {\n console.log(chalk.gray(`Executing: ${testCommand}`));\n }\n \n try {\n const { stdout, stderr } = await execAsync(testCommand, {\n timeout: 30000,\n env: { ...process.env }\n });\n \n steps.push({\n name: 'Execute hook command',\n success: true,\n message: 'Command executed successfully',\n duration: Date.now() - execStepStart\n });\n \n // Step 4: Validate output\n const validateStepStart = Date.now();\n const output = stdout || stderr || '';\n \n // Check for common success indicators\n const hasSuccess = output.toLowerCase().includes('success') ||\n output.toLowerCase().includes('complete') ||\n output.toLowerCase().includes('dry run');\n \n if (hasSuccess || output.length > 0) {\n steps.push({\n name: 'Validate output',\n success: true,\n message: 'Output validated',\n duration: Date.now() - validateStepStart\n });\n } else {\n steps.push({\n name: 'Validate output',\n success: false,\n message: 'No output received',\n duration: Date.now() - validateStepStart\n });\n }\n \n const duration = Date.now() - startTime;\n \n if (spinner) spinner.succeed(`${hookType} hook test completed (${(duration / 1000).toFixed(1)}s)`);\n \n // Record execution if requested\n if (options.record) {\n await recordHookExecution({\n hookType,\n timestamp: new Date(),\n success: true,\n duration,\n project: 'test'\n });\n }\n \n return {\n hookType,\n success: true,\n duration,\n output: options.verbose ? output : undefined,\n steps\n };\n \n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n \n steps.push({\n name: 'Execute hook command',\n success: false,\n message: errorMessage,\n duration: Date.now() - execStepStart\n });\n \n if (spinner) spinner.fail(`${hookType} hook test failed`);\n \n // Record failure if requested\n if (options.record) {\n await recordHookExecution({\n hookType,\n timestamp: new Date(),\n success: false,\n duration: Date.now() - startTime,\n project: 'test',\n error: errorMessage\n });\n }\n \n return {\n hookType,\n success: false,\n duration: Date.now() - startTime,\n error: errorMessage,\n steps\n };\n }\n \n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n \n if (spinner) spinner.fail(`${hookType} hook test failed`);\n \n return {\n hookType,\n success: false,\n duration: Date.now() - startTime,\n error: errorMessage,\n steps\n };\n }\n}\n\n/**\n * Test all installed hooks\n */\nexport async function testAllHooks(\n options: { verbose?: boolean; record?: boolean } = {}\n): Promise<HookTestResult[]> {\n const results: HookTestResult[] = [];\n \n // Get hook status\n const status = await getHooksStatus();\n \n // Test SessionStart hook if installed\n if (status.sessionStartHook.installed) {\n if (options.verbose) {\n console.log(chalk.cyan('\\nTesting SessionStart Hook...'));\n }\n const result = await testHook('sessionstart', options);\n results.push(result);\n \n if (options.verbose) {\n displayTestResult(result);\n }\n }\n \n // Test PreCompact hook if installed\n if (status.preCompactHook.installed) {\n if (options.verbose) {\n console.log(chalk.cyan('\\nTesting PreCompact Hook...'));\n }\n const result = await testHook('precompact', options);\n results.push(result);\n\n if (options.verbose) {\n displayTestResult(result);\n }\n }\n\n // Test SessionEnd hook if installed\n if (status.sessionEndHook.installed) {\n if (options.verbose) {\n console.log(chalk.cyan('\\nTesting SessionEnd Hook...'));\n }\n const result = await testHook('sessionend', options);\n results.push(result);\n\n if (options.verbose) {\n displayTestResult(result);\n }\n }\n \n if (results.length === 0) {\n console.log(chalk.yellow('No hooks installed to test'));\n }\n \n return results;\n}\n\n/**\n * Display a test result with formatting\n */\nexport function displayTestResult(result: HookTestResult): void {\n const hookName = result.hookType === 'sessionstart' ? 'SessionStart Hook' :\n result.hookType === 'precompact' ? 'PreCompact Hook' :\n 'SessionEnd Hook';\n \n console.log('');\n if (result.success) {\n console.log(chalk.green(`✅ ${hookName} Test Passed`));\n } else {\n console.log(chalk.red(`❌ ${hookName} Test Failed`));\n }\n \n // Display steps\n result.steps.forEach(step => {\n const icon = step.success ? '✓' : '✗';\n const color = step.success ? chalk.green : chalk.red;\n const duration = step.duration ? ` (${step.duration}ms)` : '';\n \n console.log(color(` ${icon} ${step.name}${duration}`));\n if (step.message) {\n console.log(chalk.gray(` └─ ${step.message}`));\n }\n });\n \n // Display total duration\n console.log(chalk.dim(` Total time: ${(result.duration / 1000).toFixed(1)}s`));\n \n // Display error if any\n if (result.error) {\n console.log(chalk.red(` Error: ${result.error}`));\n }\n \n // Display output if verbose\n if (result.output) {\n console.log(chalk.dim('\\n Output:'));\n result.output.split('\\n').forEach(line => {\n if (line.trim()) {\n console.log(chalk.dim(` ${line}`));\n }\n });\n }\n}\n\n/**\n * Simulate a hook trigger for testing\n */\nexport async function simulateHookTrigger(\n hookType: 'sessionstart' | 'precompact' | 'sessionend',\n projectPath?: string\n): Promise<{ success: boolean; output?: string; error?: string }> {\n try {\n const cliPath = getCliPath();\n const command = `${cliPath} send --dry --silent --hook-trigger=${hookType}${projectPath ? ` --project=\"${projectPath}\"` : ''}`;\n \n logger.debug(`Simulating ${hookType} hook trigger: ${command}`);\n \n const { stdout, stderr } = await execAsync(command, {\n timeout: 30000,\n env: { ...process.env }\n });\n \n return {\n success: true,\n output: stdout || stderr || 'Command completed successfully'\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n logger.error(`Hook simulation failed: ${errorMessage}`);\n \n return {\n success: false,\n error: errorMessage\n };\n }\n}","import inquirer from 'inquirer';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport { colors } from './styles';\nimport { parseProjectName } from './project-display';\nimport { discoverProjects } from '../claude-core';\nimport { logger } from '../../utils/logger';\nimport { getHookMode, getTrackedProjects } from '../claude-settings-reader';\n\n/**\n * Selected project information for hooks\n */\nexport interface SelectedProject {\n path: string; // Claude folder path (e.g., -home-user-projects-devark)\n name: string; // Display name extracted from cwd\n lastActive: Date; // Last activity time\n hasHooks?: boolean; // Whether this project currently has hooks enabled\n actualPath?: string; // Actual filesystem path (e.g., /home/user/projects/devark)\n}\n\n/**\n * Show project selector for hook configuration\n * Allows users to select which projects should have auto-sync enabled\n */\nexport async function showProjectSelectorForHooks(): Promise<SelectedProject[]> {\n try {\n // Get current hook configuration\n const hookMode = await getHookMode();\n const trackedProjects = hookMode === 'selected' ? await getTrackedProjects() : [];\n \n // Use the filtered discoverProjects which already excludes temp directories\n const discoveredProjects = await discoverProjects();\n \n if (discoveredProjects.length === 0) {\n console.log(colors.warning('No Claude Code projects found.'));\n return [];\n }\n \n // Convert discovered projects to SelectedProject format\n const validProjects = discoveredProjects.map(project => {\n // Check if this project has hooks enabled\n const hasHooks = hookMode === 'all' || trackedProjects.includes(project.claudePath);\n \n return {\n path: project.claudePath,\n name: project.name,\n lastActive: project.lastActivity || new Date(0), // Use epoch if no activity\n hasHooks,\n actualPath: project.actualPath\n };\n });\n \n if (validProjects.length === 0) {\n console.log(colors.warning('No valid projects found with sessions.'));\n return [];\n }\n \n // Group projects by recency\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n const yesterday = new Date(today);\n yesterday.setDate(yesterday.getDate() - 1);\n const lastWeek = new Date(today);\n lastWeek.setDate(lastWeek.getDate() - 7);\n \n const todayProjects = validProjects.filter(p => p.lastActive >= today);\n const yesterdayProjects = validProjects.filter(p => p.lastActive >= yesterday && p.lastActive < today);\n const weekProjects = validProjects.filter(p => p.lastActive >= lastWeek && p.lastActive < yesterday);\n const olderProjects = validProjects.filter(p => p.lastActive < lastWeek);\n \n // Build choices for inquirer\n const choices: any[] = [];\n \n if (todayProjects.length > 0) {\n choices.push({\n type: 'separator',\n name: colors.accent(`──── Today's Projects ────`)\n });\n todayProjects.forEach(project => {\n choices.push({\n name: formatProjectChoice(project),\n value: project,\n checked: project.hasHooks || false // Pre-select if already tracked\n });\n });\n }\n \n if (yesterdayProjects.length > 0) {\n choices.push({\n type: 'separator',\n name: colors.accent(`──── Yesterday ────`)\n });\n yesterdayProjects.forEach(project => {\n choices.push({\n name: formatProjectChoice(project),\n value: project,\n checked: project.hasHooks || false // Pre-select if already tracked\n });\n });\n }\n \n if (weekProjects.length > 0) {\n choices.push({\n type: 'separator',\n name: colors.accent(`──── Last 7 Days ────`)\n });\n weekProjects.forEach(project => {\n choices.push({\n name: formatProjectChoice(project),\n value: project,\n checked: project.hasHooks || false // Pre-select if already tracked\n });\n });\n }\n \n if (olderProjects.length > 0) {\n choices.push({\n type: 'separator',\n name: colors.accent(`──── Older Projects ────`)\n });\n olderProjects.forEach(project => {\n choices.push({\n name: formatProjectChoice(project),\n value: project,\n checked: project.hasHooks || false // Pre-select if already tracked\n });\n });\n }\n \n // Prompt for selection\n console.log(colors.subdued('Choose which projects should have auto-sync enabled:'));\n console.log(colors.subdued('✅ = Currently tracked | Pre-selected items already have hooks\\n'));\n console.log(colors.hint('(Use Space to select/deselect, Enter to confirm, Q to cancel)\\n'));\n \n const { selected } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selected',\n message: 'Select projects:',\n choices,\n pageSize: 15,\n validate: (input) => {\n if (input.length === 0) {\n return 'Please select at least one project or press Q to cancel';\n }\n return true;\n }\n }\n ]);\n \n return selected;\n \n } catch (error) {\n logger.error('Failed to load projects for selection:', error);\n console.log(colors.error('Failed to load projects. Please check your Claude Code installation.'));\n return [];\n }\n}\n\n/**\n * Get project information from session files\n * Exported for use in other UI components that need to resolve project names\n */\nexport async function getProjectInfo(projectPath: string): Promise<Omit<SelectedProject, 'path'> | null> {\n try {\n // Get all session files\n const files = await fs.readdir(projectPath);\n const sessionFiles = files.filter(f => f.endsWith('.jsonl'));\n \n if (sessionFiles.length === 0) {\n return null;\n }\n \n // Find the most recent session\n let mostRecent = new Date(0);\n let projectName = 'Unknown';\n let actualPath: string | undefined;\n \n for (const file of sessionFiles) {\n const filePath = path.join(projectPath, file);\n const stats = await fs.stat(filePath);\n \n if (stats.mtime > mostRecent) {\n mostRecent = stats.mtime;\n \n // Try to read the first line to get the cwd\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n').filter(line => line.trim());\n \n if (lines.length > 0) {\n const firstLine = JSON.parse(lines[0]);\n if (firstLine.cwd) {\n // Extract project name from cwd\n projectName = parseProjectName(firstLine.cwd);\n actualPath = firstLine.cwd; // Store the actual path\n }\n }\n } catch (e) {\n // If we can't parse, use directory name as fallback\n const dirName = parseProjectName(projectPath);\n // Use last segment of directory name as project name\n projectName = dirName.split('-').pop() || dirName;\n // Note: actualPath will remain undefined if we can't read cwd from JSONL\n }\n }\n }\n \n return {\n name: projectName,\n lastActive: mostRecent,\n actualPath\n };\n \n } catch (error) {\n logger.debug(`Failed to get info for project ${projectPath}:`, error);\n return null;\n }\n}\n\n/**\n * Format project choice for display\n */\nfunction formatProjectChoice(project: SelectedProject): string {\n const timeSinceActive = getTimeSinceActive(project.lastActive);\n const hookIndicator = project.hasHooks ? colors.success('✅ ') : ' ';\n return `${hookIndicator}${project.name} ${colors.subdued(`(last active: ${timeSinceActive})`)}`;\n}\n\n/**\n * Get human-readable time since last activity\n */\nfunction getTimeSinceActive(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const hours = Math.floor(diff / (1000 * 60 * 60));\n const days = Math.floor(hours / 24);\n \n if (hours < 1) {\n return 'just now';\n } else if (hours === 1) {\n return '1 hour ago';\n } else if (hours < 24) {\n return `${hours} hours ago`;\n } else if (days === 1) {\n return 'yesterday';\n } else if (days < 7) {\n return `${days} days ago`;\n } else if (days < 30) {\n const weeks = Math.floor(days / 7);\n return `${weeks} week${weeks !== 1 ? 's' : ''} ago`;\n } else {\n const months = Math.floor(days / 30);\n return `${months} month${months !== 1 ? 's' : ''} ago`;\n }\n}","import { randomBytes } from 'crypto';\nimport open from 'open';\nimport ora, { Ora } from 'ora';\nimport chalk from 'chalk';\nimport https from 'https';\nimport http from 'http';\nimport { apiClient } from '../api-client';\nimport { storeToken, clearToken, getApiUrl } from '../config';\nimport { DevArkError } from '../../utils/errors';\nimport { isNetworkError, getNetworkErrorType, getNetworkErrorMessage, createNetworkError } from '../errors/network-errors';\n\n// Secure random sleep to prevent timing attacks\nfunction secureRandomSleep(baseMs: number): Promise<void> {\n const jitter = randomBytes(1)[0] / 255 * 1000; // 0-1000ms random jitter\n return new Promise((resolve) => setTimeout(resolve, baseMs + jitter));\n}\n\n// Removed generateSecureSessionId - server generates the session ID\n\nexport async function browserAuth(wizardMode?: boolean): Promise<string> {\n if (!wizardMode) {\n console.log(chalk.cyan('\\n🔐 Starting secure authentication...'));\n }\n \n try {\n // Clear any existing token first to ensure fresh authentication\n await clearToken();\n \n // Get auth token from server (this creates a new token each time)\n let authUrl: string;\n let token: string;\n \n try {\n const apiUrl = getApiUrl();\n if (!wizardMode) {\n console.log(chalk.gray(`Connecting to: ${apiUrl}`));\n }\n \n const result = await apiClient.createAuthSession();\n authUrl = result.authUrl;\n token = result.token;\n } catch (error: any) {\n // Handle connection errors specifically\n if (isNetworkError(error)) {\n const errorType = getNetworkErrorType(error);\n const message = getNetworkErrorMessage(error);\n \n console.error(chalk.red('\\n❌ Network error'));\n console.error(chalk.yellow(`\\n${message}`));\n \n if (errorType === 'CONNECTION_REFUSED') {\n console.error(chalk.yellow('\\n📋 Please check:'));\n console.error(chalk.gray(' 1. Is the server running? (For local development: npm run dev)'));\n console.error(chalk.gray(' 2. Is the API URL correct? Current: ' + getApiUrl()));\n console.error(chalk.gray(' 3. Is your firewall blocking the connection?'));\n console.error(chalk.gray('\\n💡 Tip: If running locally, make sure the devark server is started'));\n } else if (errorType === 'DNS_RESOLUTION_FAILED') {\n console.error(chalk.gray('\\n💡 Check your internet connection or API URL configuration'));\n } else if (errorType === 'TIMEOUT') {\n console.error(chalk.yellow('\\nThe server is not responding. It might be:'));\n console.error(chalk.gray(' • Down for maintenance'));\n console.error(chalk.gray(' • Experiencing high load'));\n console.error(chalk.gray(' • Blocked by network issues'));\n }\n \n throw createNetworkError(error);\n } else if (error.code === 'NETWORK_ERROR') {\n console.error(chalk.red('\\n❌ Network error'));\n console.error(chalk.yellow('\\nPlease check your internet connection and try again.'));\n throw error;\n } else {\n // Re-throw other errors to be handled by outer catch\n throw error;\n }\n }\n \n if (!wizardMode) {\n console.log(chalk.yellow('\\n📱 Opening browser for authentication...'));\n console.log(chalk.gray('If the browser doesn\\'t open, check your default browser settings.'));\n console.log('');\n console.log(chalk.cyan('🔐 Complete the authentication in your browser, then press ENTER here to continue...'));\n }\n \n // Open browser to auth page with source tracking\n const authUrlWithSource = new URL(authUrl);\n authUrlWithSource.searchParams.set('source', 'cli');\n await open(authUrlWithSource.toString());\n \n // Use SSE to wait for authentication completion\n if (!wizardMode) {\n console.log('\\n' + chalk.cyan('⏳ Waiting for browser authentication...'));\n console.log(chalk.gray(' (Complete the authentication in your browser)'));\n }\n \n const spinner = ora('Monitoring authentication status...').start();\n \n try {\n // Pass the token (which is the sessionId) to SSE endpoint\n const apiToken = await waitForAuthWithSSE(token, spinner, wizardMode);\n spinner.succeed('Authentication verified successfully');\n \n // Step 2: Store the API token for CLI use\n const step2Spinner = ora('Setting up CLI session...').start();\n await secureRandomSleep(300);\n \n // Store the API token received from SSE\n await storeToken(apiToken);\n \n step2Spinner.succeed('CLI session configured');\n \n // Step 3: Final validation\n const step3Spinner = ora('Finalizing setup...').start();\n await secureRandomSleep(200);\n step3Spinner.succeed('Authentication complete!');\n \n // Only show completion messages if not in wizard mode\n if (!wizardMode) {\n console.log('');\n console.log(chalk.green('✅ Successfully authenticated with DevArk!'));\n console.log(chalk.cyan('🚀 You can now use the DevArk interactive menu:'));\n console.log(chalk.gray(' Run `npx devark-cli` to access all features'));\n console.log('');\n }\n \n // Ensure stdin is properly closed\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n \n return apiToken;\n \n } catch (error) {\n spinner.fail('Authentication verification failed');\n throw error;\n }\n } catch (error) {\n console.error('\\n❌ Authentication failed');\n if (error instanceof Error) {\n console.error('Error details:', error.message);\n }\n throw error;\n }\n}\n\nasync function waitForAuthWithSSE(sessionId: string, spinner: Ora, wizardMode?: boolean): Promise<string> {\n return new Promise((resolve, reject) => {\n const apiUrl = getApiUrl();\n // Ensure no double slashes in URL\n const baseUrl = apiUrl.endsWith('/') ? apiUrl.slice(0, -1) : apiUrl;\n const sseUrl = new URL(`${baseUrl}/api/auth/cli/stream/${sessionId}`);\n \n if (!wizardMode) {\n console.log(chalk.gray(`\\n Debug: Connecting to SSE endpoint: ${sseUrl.href}`));\n }\n \n const httpModule = sseUrl.protocol === 'https:' ? https : http;\n \n // let lastHeartbeat = Date.now();\n let buffer = '';\n \n // Setup timeout (5 minutes)\n const timeoutTimer = setTimeout(() => {\n req.destroy();\n reject(new DevArkError(\n 'Authentication timed out. Please try again.',\n 'AUTH_TIMEOUT'\n ));\n }, 5 * 60 * 1000);\n \n // Make the SSE request\n const req = httpModule.get({\n hostname: sseUrl.hostname,\n port: sseUrl.port || (sseUrl.protocol === 'https:' ? 443 : 80),\n path: sseUrl.pathname,\n headers: {\n 'Accept': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n }\n }, (res) => {\n if (!wizardMode) {\n console.log(chalk.gray(` Debug: Response status: ${res.statusCode}`));\n }\n \n if (res.statusCode !== 200) {\n req.destroy();\n clearTimeout(timeoutTimer);\n reject(new DevArkError(\n `Server returned status ${res.statusCode}`,\n 'SERVER_ERROR'\n ));\n return;\n }\n \n spinner.text = 'Connected - waiting for authentication in browser...';\n \n // Process SSE stream\n res.on('data', (chunk: Buffer) => {\n buffer += chunk.toString();\n \n // Process complete lines\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n \n for (const line of lines) {\n const trimmed = line.trim();\n \n // Handle heartbeats\n if (trimmed === ':heartbeat' || trimmed.startsWith(':')) {\n // lastHeartbeat = Date.now();\n continue;\n }\n \n // Handle data messages\n if (trimmed.startsWith('data: ')) {\n const data = trimmed.substring(6);\n if (!wizardMode) {\n console.log(chalk.gray(` Debug: Received data: ${data.substring(0, 50)}...`));\n }\n \n try {\n const parsed = JSON.parse(data);\n \n switch (parsed.status) {\n case 'pending':\n spinner.text = 'Waiting for authentication in browser...';\n break;\n \n case 'success':\n // Authentication completed successfully\n req.destroy();\n clearTimeout(timeoutTimer);\n \n if (parsed.token) {\n resolve(parsed.token);\n } else {\n reject(new DevArkError(\n 'Authentication completed but no token received',\n 'NO_TOKEN'\n ));\n }\n break;\n \n case 'error':\n req.destroy();\n clearTimeout(timeoutTimer);\n reject(new DevArkError(\n parsed.message || 'Authentication failed',\n parsed.code || 'AUTH_ERROR'\n ));\n break;\n \n case 'expired':\n req.destroy();\n clearTimeout(timeoutTimer);\n reject(new DevArkError(\n 'Authentication session expired. Please try again.',\n 'SESSION_EXPIRED'\n ));\n break;\n \n case 'timeout':\n req.destroy();\n clearTimeout(timeoutTimer);\n reject(new DevArkError(\n 'Authentication timed out. Please try again.',\n 'AUTH_TIMEOUT'\n ));\n break;\n }\n } catch (error) {\n console.error('Failed to parse SSE data:', data, error);\n }\n }\n }\n });\n \n res.on('end', () => {\n clearTimeout(timeoutTimer);\n reject(new DevArkError(\n 'Connection to authentication server closed unexpectedly',\n 'CONNECTION_CLOSED'\n ));\n });\n \n res.on('error', (error) => {\n clearTimeout(timeoutTimer);\n reject(new DevArkError(\n `Connection error: ${error.message}`,\n 'CONNECTION_ERROR'\n ));\n });\n });\n \n req.on('error', (error) => {\n clearTimeout(timeoutTimer);\n if (!wizardMode) {\n console.log(chalk.red(` Debug: Request error: ${error.message}`));\n }\n reject(new DevArkError(\n `Failed to connect to authentication server: ${error.message}`,\n 'CONNECTION_FAILED'\n ));\n });\n \n // Handle process termination\n const cleanup = () => {\n req.destroy();\n clearTimeout(timeoutTimer);\n };\n \n process.once('exit', cleanup);\n process.once('SIGINT', cleanup);\n process.once('SIGTERM', cleanup);\n });\n}\n\nfunction isValidTokenFormat(token: string): boolean {\n // Validate token format (adjust based on your actual token format)\n // Example: JWT format validation\n if (typeof token !== 'string' || token.length < 20) {\n return false;\n }\n \n // Check for common injection patterns\n const dangerousPatterns = [\n /[<>]/, // HTML injection\n /[`${}]/, // Template injection\n /[\\u0000-\\u001F]/, // Control characters\n /['\";\\\\]/, // SQL/Command injection\n ];\n \n return !dangerousPatterns.some(pattern => pattern.test(token));\n}\n\nexport async function validateAndStoreToken(token: string): Promise<void> {\n // Validate token format before any operations\n if (!isValidTokenFormat(token)) {\n throw new DevArkError('Invalid token format', 'INVALID_TOKEN');\n }\n \n // Temporarily store token to validate it\n await storeToken(token);\n \n try {\n // Verify the token works\n const { valid } = await apiClient.verifyToken();\n \n if (!valid) {\n // Clear invalid token\n await clearToken();\n throw new DevArkError('Invalid token', 'INVALID_TOKEN');\n }\n \n // Log success without exposing user data\n console.log(chalk.green('\\n✅ Authentication verified'));\n \n } catch (error) {\n // Clear token on any error\n await clearToken();\n throw error;\n }\n}\n\n// Rate limiting for auth attempts\nconst authAttempts = new Map<string, number[]>();\n\nexport function checkAuthRateLimit(identifier: string): void {\n const now = Date.now();\n const attempts = authAttempts.get(identifier) || [];\n \n // Clean old attempts (older than 15 minutes)\n const recentAttempts = attempts.filter(time => now - time < 15 * 60 * 1000);\n \n // Check rate limit (max 5 attempts per 15 minutes)\n if (recentAttempts.length >= 5) {\n throw new DevArkError(\n 'Too many authentication attempts. Please try again later.',\n 'RATE_LIMITED'\n );\n }\n \n recentAttempts.push(now);\n authAttempts.set(identifier, recentAttempts);\n}","import { browserAuth, validateAndStoreToken } from '../lib/auth/browser';\nimport { showSuccess } from '../lib/ui';\nimport { DevArkError } from '../utils/errors';\nimport { logger } from '../utils/logger';\nimport { validateAuthToken } from '../lib/input-validator';\nimport { isNetworkError, createNetworkError } from '../lib/errors/network-errors';\nimport chalk from 'chalk';\nimport { sendTelemetryUpdate } from '../lib/telemetry';\n\ninterface AuthOptions {\n token?: string;\n wizardMode?: boolean; // Silent mode when called from wizard\n}\n\nexport async function auth(options: AuthOptions): Promise<void> {\n // Only show re-auth message if not in wizard mode\n if (!options.wizardMode) {\n console.log('\\n🔐 Re-authenticating with devark...\\n');\n }\n \n try {\n if (options.token) {\n // Manual token provided - validate it first\n const validatedToken = validateAuthToken(options.token);\n await validateAndStoreToken(validatedToken);\n } else {\n // Browser-based flow\n await browserAuth(options.wizardMode);\n }\n \n // Send initial telemetry for new cloud user\n await sendTelemetryUpdate();\n\n // Only show success messages if not in wizard mode\n if (!options.wizardMode) {\n showSuccess('Authentication successful!');\n console.log('\\n✨ Cloud mode is now active!');\n }\n } catch (error) {\n if (error instanceof DevArkError) {\n // For connection errors, the browserAuth function already displayed detailed messages\n // Just re-throw to let the menu handle it\n if (error.code === 'CONNECTION_REFUSED' || \n error.code === 'SERVER_NOT_FOUND' || \n error.code === 'TIMEOUT' ||\n error.code === 'NETWORK_ERROR') {\n throw error;\n }\n // For other DevArkErrors, throw as-is\n throw error;\n }\n \n // For unexpected errors, log and throw a generic message\n logger.error('Re-authentication failed', error);\n \n // If it's a recognizable network error that wasn't caught in browserAuth\n if (error instanceof Error && isNetworkError(error)) {\n console.error(chalk.red('\\n❌ Failed to connect to the authentication server'));\n console.error(chalk.yellow('Please check that the server is running and accessible.'));\n throw createNetworkError(error);\n }\n \n throw new DevArkError(\n 'Re-authentication failed. Please try again.',\n 'AUTH_FAILED'\n );\n }\n}","import inquirer from 'inquirer';\nimport { colors, box } from './styles';\nimport { \n getHooksStatus, \n HooksStatus, \n uninstallAllHooks,\n installSelectedHooks,\n installSelectiveProjectHooks,\n removeProjectHooks,\n ProjectHookConfig\n} from '../hooks/hooks-controller';\nimport { getHookMode, HookMode } from '../claude-settings-reader';\nimport { getRecentStats } from '../hooks/hooks-stats';\nimport { testHook, testAllHooks, displayTestResult } from '../hooks/hooks-tester';\nimport { showSuccess, showWarning, showError, showInfo } from '../ui';\nimport { showProjectSelectorForHooks, getProjectInfo } from './project-selector-hooks';\nimport { getClaudeProjectsPath } from '../claude-core';\nimport path from 'path';\nimport { sendWithTimeout } from '../../commands/send';\nimport { parseProjectName } from './project-display';\n\n/**\n * Main hooks management menu with educational approach\n * @param guidedMode - If true, returns boolean indicating if hooks were installed\n */\nexport async function showHooksManagementMenu(guidedMode: boolean = false): Promise<boolean | void> {\n let shouldContinue = true;\n let hooksWereInstalled = false;\n\n while (shouldContinue) {\n console.clear();\n \n // Get current status\n const status = await getHooksStatus();\n const stats = await getRecentStats(7);\n const hookMode = await getHookMode(); // Now from claude-settings-reader\n \n // Display educational header with current status\n await displayEducationalHeader(hookMode, status, stats);\n\n // Menu options based on current mode\n const choices = [\n {\n name: `[1] Track all projects - Install hooks globally`,\n value: 'track-all'\n },\n {\n name: `[2] Select specific projects - Choose which to track`,\n value: 'track-selected'\n },\n {\n name: `[3] Disable tracking - Remove all hooks`,\n value: 'track-none'\n },\n new inquirer.Separator()\n ];\n \n // Add test option if hooks are installed\n if (status.sessionStartHook.installed || status.preCompactHook.installed || status.sessionEndHook.installed) {\n choices.push({\n name: `[4] Test hooks`,\n value: 'test'\n });\n }\n \n choices.push(\n {\n name: `[5] View detailed status`,\n value: 'detailed-status'\n },\n new inquirer.Separator(),\n {\n name: `[B] ${guidedMode ? '← Back' : 'Back to main menu'}`,\n value: 'back'\n }\n );\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'Choose an option:',\n choices,\n pageSize: 10\n }\n ]);\n \n switch (action) {\n case 'track-all':\n try {\n await configureTrackAll();\n hooksWereInstalled = true;\n } catch (error) {\n const { displayError } = await import('../../utils/errors');\n displayError(error);\n await inquirer.prompt({\n type: 'input',\n name: 'continue',\n message: ' '\n });\n }\n break;\n \n case 'track-selected':\n try {\n await configureTrackSelected();\n const newStatus = await getHooksStatus();\n if (newStatus.sessionStartHook.installed || newStatus.preCompactHook.installed) {\n hooksWereInstalled = true;\n }\n } catch (error) {\n const { displayError } = await import('../../utils/errors');\n displayError(error);\n await inquirer.prompt({\n type: 'input',\n name: 'continue',\n message: ' '\n });\n }\n break;\n \n case 'track-none':\n try {\n await disableAllTracking(status, stats);\n } catch (error) {\n const { displayError } = await import('../../utils/errors');\n displayError(error);\n await inquirer.prompt({\n type: 'input',\n name: 'continue',\n message: ' '\n });\n }\n break;\n \n case 'test':\n await testHooksMenu();\n await promptToContinue();\n break;\n \n case 'detailed-status':\n await showDetailedStatus(status, stats);\n await promptToContinue();\n break;\n \n case 'back':\n shouldContinue = false;\n break;\n }\n }\n \n // Return whether hooks were installed (for guided mode tracking)\n if (guidedMode) {\n return hooksWereInstalled;\n }\n}\n\n/**\n * Display educational header with current status\n */\nasync function displayEducationalHeader(mode: HookMode, status: HooksStatus, stats: any): Promise<void> {\n console.log(colors.accent('\\n🔧 Auto-sync Configuration\\n'));\n \n console.log(colors.subdued('Claude Code hooks allow DevArk to automatically sync your Claude Code sessions.\\n'));\n \n console.log(colors.info('We use the following hooks:'));\n console.log(' 📍 ' + colors.accent('SessionStart') + colors.subdued(' - Ensures nothing is lost between sessions'));\n console.log(' 📦 ' + colors.accent('PreCompact') + colors.subdued(' - Syncs everything before Claude compresses context'));\n console.log(' 🔚 ' + colors.accent('SessionEnd') + colors.subdued(' - Captures final state when ending a session'));\n console.log(colors.success(' ✓ Together they provide complete coverage without duplicates\\n'));\n \n const docsUrl = \"https://github.com/devark/devark-cli/tree/main?tab=readme-ov-file#auto-sync\";\n const linkStart = `\\u001b]8;;${docsUrl}\\u001b\\\\`;\n const linkEnd = `\\u001b]8;;\\u001b\\\\`;\n console.log(colors.subdued(`Want to learn more about how hooks and auto-sync work → ${linkStart}check our docs${linkEnd}\\n`));\n \n // Current status display\n console.log(box.horizontal.repeat(60));\n console.log('');\n \n let statusText = '';\n let statusColor = colors.muted;\n \n if (mode === 'all') {\n statusText = '✅ Tracking all projects';\n statusColor = colors.success;\n } else if (mode === 'selected') {\n const projectCount = status.trackedProjects?.length || 0;\n statusText = `📍 Tracking ${projectCount} project${projectCount !== 1 ? 's' : ''}`;\n statusColor = colors.warning;\n } else {\n statusText = '❌ Not tracking';\n statusColor = colors.error;\n }\n \n console.log('Current Status: ' + statusColor(statusText));\n \n // Show activity stats if tracking\n if (mode !== 'none' && (stats.sessionStartHook?.total > 0 || stats.preCompactHook?.total > 0)) {\n console.log('');\n if (stats.sessionStartHook?.total > 0) {\n console.log(` SessionStart: ${stats.sessionStartHook.total} syncs, ${stats.sessionStartHook.successRate.toFixed(1)}% success`);\n }\n if (stats.preCompactHook?.total > 0) {\n console.log(` PreCompact: ${stats.preCompactHook.total} syncs, ${stats.preCompactHook.successRate.toFixed(1)}% success`);\n }\n }\n \n console.log('');\n}\n\n/**\n * Configure to track all projects with checkbox selection\n */\nasync function configureTrackAll(): Promise<void> {\n console.clear();\n console.log(colors.accent('\\n✅ Global Hook Configuration\\n'));\n \n console.log('Configure hooks for all current and future projects.\\n');\n console.log(colors.subdued('These settings will be saved to ~/.claude/settings.json\\n'));\n \n console.log(colors.info('Select which hooks to install globally:'));\n console.log(colors.subdued('• SessionStart: Syncs when starting/resuming work'));\n console.log(colors.subdued('• PreCompact: Syncs before context compression'));\n console.log(colors.subdued('\\nWe recommend enabling both for complete session tracking.\\n'));\n \n // Use inquirer checkbox for hook selection\n const { selectedHooks } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selectedHooks',\n message: 'Choose hooks to enable:',\n choices: [\n {\n name: 'SessionStart - Sync on startup/resume/clear',\n value: 'sessionStart',\n checked: true\n },\n {\n name: 'PreCompact - Sync before compression',\n value: 'preCompact',\n checked: true\n },\n {\n name: 'SessionEnd - Sync on session end',\n value: 'sessionEnd',\n checked: true\n }\n ]\n }\n ]);\n \n // Handle empty selection\n if (selectedHooks.length === 0) {\n console.log('');\n showWarning('No hooks selected. Installation cancelled.');\n await promptToContinue();\n return;\n }\n \n // Confirm installation\n console.log('\\n' + colors.info('You selected:'));\n if (selectedHooks.includes('sessionStart')) {\n console.log(' ✓ SessionStart hook');\n }\n if (selectedHooks.includes('preCompact')) {\n console.log(' ✓ PreCompact hook');\n }\n if (selectedHooks.includes('sessionEnd')) {\n console.log(' ✓ SessionEnd hook');\n }\n \n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Install these hooks globally?',\n default: true\n }\n ]);\n \n if (!confirm) {\n showWarning('Installation cancelled');\n await promptToContinue();\n return;\n }\n \n // Install selected hooks\n console.log('');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const spinner = require('ora')('Installing global hooks...').start();\n \n try {\n const selection = {\n sessionStartHook: selectedHooks.includes('sessionStart'),\n preCompactHook: selectedHooks.includes('preCompact'),\n sessionEndHook: selectedHooks.includes('sessionEnd')\n };\n\n await installSelectedHooks(selection);\n spinner.succeed('Global hooks configured successfully!');\n \n console.log('');\n if (selection.sessionStartHook) {\n showSuccess('✅ SessionStart hook installed');\n }\n if (selection.preCompactHook) {\n showSuccess('✅ PreCompact hook installed');\n }\n if (selection.sessionEndHook) {\n showSuccess('✅ SessionEnd hook installed');\n }\n \n console.log('');\n showInfo('All your Claude Code sessions will now be automatically synced!');\n \n // Offer to sync existing sessions\n await offerInitialSync({ all: true });\n \n } catch (error) {\n spinner.fail('Failed to configure global hooks');\n showError(error instanceof Error ? error.message : 'Unknown error');\n }\n \n await promptToContinue();\n}\n\n/**\n * Configure to track selected projects with per-hook granularity\n */\nasync function configureTrackSelected(): Promise<void> {\n console.clear();\n console.log(colors.accent('\\n📁 Configure Project-Specific Tracking\\n'));\n \n console.log(colors.subdued('Select which projects to track and configure hooks for each:\\n'));\n \n // Get currently tracked projects BEFORE selection\n const { getTrackedProjects } = await import('../claude-settings-reader');\n const previouslyTracked = await getTrackedProjects();\n \n // Use the enhanced project selector for hooks\n const selectedProjects = await showProjectSelectorForHooks();\n \n // Identify deselected projects (previously tracked but not in new selection)\n const selectedPaths = selectedProjects.map(p => p.path);\n const deselectedProjects: Array<{ path: string; name: string; actualPath?: string }> = [];\n \n // Get all projects to find the ones that were deselected\n const { discoverProjects } = await import('../claude-core');\n const allProjects = await discoverProjects();\n \n for (const trackedPath of previouslyTracked) {\n if (!selectedPaths.includes(trackedPath)) {\n // Find the full project info for this deselected project\n const project = allProjects.find(p => p.claudePath.endsWith(trackedPath));\n if (project) {\n deselectedProjects.push({\n path: trackedPath,\n name: project.name,\n actualPath: project.actualPath\n });\n }\n }\n }\n \n // Check if user cancelled selection (no projects selected but had previous ones)\n if (selectedProjects.length === 0 && previouslyTracked.length === 0) {\n showWarning('No projects selected');\n await promptToContinue();\n return;\n }\n \n // Create configuration for each project\n const projectConfigs: ProjectHookConfig[] = [];\n \n // Only ask for hook configuration if there are selected projects\n if (selectedProjects.length > 0) {\n console.clear();\n console.log(colors.accent('\\n⚙️ Configure Hooks for Selected Projects\\n'));\n \n console.log(colors.info('Choose which hooks to enable for each project:'));\n console.log(colors.subdued('SessionStart: Syncs when starting/resuming work'));\n console.log(colors.subdued('PreCompact: Syncs before context compression'));\n console.log(colors.subdued('SessionEnd: Syncs when ending a session\\n'));\n \n for (const project of selectedProjects) {\n console.log(colors.accent(`\\n${project.name}:`));\n \n const { hooks } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'hooks',\n message: 'Select hooks to enable:',\n choices: [\n { name: 'SessionStart - Sync on startup/resume', value: 'sessionStart', checked: true },\n { name: 'PreCompact - Sync before compression', value: 'preCompact', checked: true },\n { name: 'SessionEnd - Sync on session end', value: 'sessionEnd', checked: true }\n ]\n }\n ]);\n \n if (hooks.length > 0) {\n projectConfigs.push({\n path: project.path,\n name: project.name,\n sessionStart: hooks.includes('sessionStart'),\n preCompact: hooks.includes('preCompact'),\n sessionEnd: hooks.includes('sessionEnd'),\n actualPath: (project as any).actualPath // Pass through the actual path for local settings\n } as any);\n }\n }\n }\n \n if (projectConfigs.length === 0 && deselectedProjects.length === 0) {\n showWarning('No hooks configured for any project');\n await promptToContinue();\n return;\n }\n \n // Show summary\n if (selectedProjects.length === 0 && deselectedProjects.length > 0) {\n // Special case: removing all hooks\n console.clear();\n console.log(colors.warning('\\n⚠️ Removing Project Tracking\\n'));\n console.log('You are about to remove hooks from all previously tracked projects:\\n');\n deselectedProjects.forEach(project => {\n console.log(` • ${project.name}`);\n });\n } else {\n console.log('\\n' + colors.info('Configuration Summary:'));\n \n if (projectConfigs.length > 0) {\n console.log(colors.success('Projects to track:'));\n projectConfigs.forEach(config => {\n const hooks = [];\n if (config.sessionStart) hooks.push('SessionStart');\n if (config.preCompact) hooks.push('PreCompact');\n if (config.sessionEnd) hooks.push('SessionEnd');\n console.log(` • ${config.name}: ${hooks.join(', ')}`);\n });\n }\n \n if (deselectedProjects.length > 0) {\n console.log('\\n' + colors.warning('Projects to stop tracking:'));\n deselectedProjects.forEach(project => {\n console.log(` • ${project.name}`);\n });\n }\n }\n \n console.log('');\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Apply this configuration?',\n default: true\n }\n ]);\n \n if (!confirm) {\n showWarning('Configuration cancelled');\n await promptToContinue();\n return;\n }\n \n console.log('');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const spinner = require('ora')('Configuring project hooks...').start();\n \n try {\n // First remove hooks from deselected projects\n if (deselectedProjects.length > 0) {\n spinner.text = 'Removing hooks from deselected projects...';\n await removeProjectHooks(deselectedProjects);\n }\n \n // Then install/update hooks for selected projects\n if (projectConfigs.length > 0) {\n spinner.text = 'Installing hooks for selected projects...';\n await installSelectiveProjectHooks(projectConfigs);\n }\n \n spinner.succeed('Project hooks configured successfully!');\n \n console.log('');\n if (projectConfigs.length > 0) {\n showSuccess(`✅ Hooks configured for ${projectConfigs.length} project${projectConfigs.length !== 1 ? 's' : ''}`);\n }\n if (deselectedProjects.length > 0) {\n showInfo(`📤 Hooks removed from ${deselectedProjects.length} project${deselectedProjects.length !== 1 ? 's' : ''}`);\n }\n \n console.log('');\n showInfo('Configuration applied successfully!');\n \n // Offer to sync existing sessions for configured projects\n if (projectConfigs.length > 0) {\n await offerInitialSync({ selectedProjects: projectConfigs });\n }\n \n } catch (error) {\n spinner.fail('Failed to configure project hooks');\n showError(error instanceof Error ? error.message : 'Unknown error');\n }\n \n await promptToContinue();\n}\n\n/**\n * Disable all tracking\n */\nasync function disableAllTracking(status: HooksStatus, stats: any): Promise<void> {\n console.clear();\n console.log(colors.warning('\\n⚠️ Disable Auto-sync\\n'));\n \n console.log('This will remove all devark hooks from Claude Code.');\n console.log('You\\'ll need to manually send sessions using main menu.\\n');\n \n // Show what will be removed\n if (status.sessionStartHook.installed || status.preCompactHook.installed) {\n console.log(colors.subdued('Hooks to be removed:'));\n if (status.sessionStartHook.installed) {\n console.log(` • SessionStart Hook (${stats.sessionStartHook?.total || 0} syncs in last 7 days)`);\n }\n if (status.preCompactHook.installed) {\n console.log(` • PreCompact Hook (${stats.preCompactHook?.total || 0} syncs in last 7 days)`);\n }\n console.log('');\n }\n \n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Are you sure?',\n default: false\n }\n ]);\n \n if (!confirm) {\n showWarning('Uninstallation cancelled');\n await promptToContinue();\n return;\n }\n \n console.log('');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const spinner = require('ora')('Removing hooks...').start();\n \n try {\n const result = await uninstallAllHooks();\n spinner.succeed(`Successfully removed ${result.removedCount} hook(s)`);\n \n console.log('');\n showInfo('You can reinstall hooks at any time from this menu');\n \n } catch (error) {\n spinner.fail('Failed to remove hooks');\n showError(error instanceof Error ? error.message : 'Unknown error');\n }\n \n await promptToContinue();\n}\n\n/**\n * Show detailed status\n */\nasync function showDetailedStatus(status: HooksStatus, stats: any): Promise<void> {\n console.clear();\n console.log(colors.accent('\\n📊 Detailed Hook Status\\n'));\n \n const mode = await getHookMode();\n \n // Mode information\n console.log(colors.info('Tracking Mode:'));\n if (mode === 'all') {\n console.log(' ✅ Tracking all projects globally');\n console.log(` • Hooks installed in: ${status.settingsPath}`);\n } else if (mode === 'selected') {\n const projectCount = status.trackedProjects?.length || 0;\n console.log(` 📍 Tracking ${projectCount} selected project${projectCount !== 1 ? 's' : ''}`);\n if (status.trackedProjects && status.trackedProjects.length > 0) {\n console.log('\\n Projects being tracked:');\n const projectsPath = getClaudeProjectsPath();\n \n // Fetch real project names from session files\n for (const project of status.trackedProjects) {\n const projectPath = path.join(projectsPath, project);\n const projectInfo = await getProjectInfo(projectPath);\n const name = projectInfo?.name || project.split('-').pop() || project;\n console.log(` • ${name}`);\n }\n }\n } else {\n console.log(' ❌ Not tracking any projects');\n }\n \n // Hook status\n console.log('\\n' + colors.info('Hook Installation:'));\n console.log(` SessionStart: ${status.sessionStartHook.installed ? colors.success('✅ Installed') : colors.muted('❌ Not Installed')}`);\n if (status.sessionStartHook.installed) {\n console.log(` Version: ${status.sessionStartHook.version}`);\n console.log(` Timeout: ${(status.sessionStartHook.timeout || 30000) / 1000}s`);\n }\n \n console.log(` PreCompact: ${status.preCompactHook.installed ? colors.success('✅ Installed') : colors.muted('❌ Not Installed')}`);\n if (status.preCompactHook.installed) {\n console.log(` Version: ${status.preCompactHook.version}`);\n console.log(` Timeout: ${(status.preCompactHook.timeout || 30000) / 1000}s`);\n }\n\n console.log(` SessionEnd: ${status.sessionEndHook.installed ? colors.success('✅ Installed') : colors.muted('❌ Not Installed')}`);\n if (status.sessionEndHook.installed) {\n console.log(` Version: ${status.sessionEndHook.version}`);\n console.log(` Timeout: ${(status.sessionEndHook.timeout || 30000) / 1000}s`);\n }\n \n // Statistics\n if (stats.sessionStartHook?.total > 0 || stats.preCompactHook?.total > 0 || stats.sessionEndHook?.total > 0) {\n console.log('\\n' + colors.info('Activity (Last 7 Days):'));\n \n if (stats.sessionStartHook?.total > 0) {\n console.log('\\n SessionStart Hook:');\n console.log(` Total executions: ${stats.sessionStartHook.total}`);\n console.log(` Success rate: ${stats.sessionStartHook.successRate.toFixed(1)}%`);\n console.log(` Successful: ${stats.sessionStartHook.successful}`);\n console.log(` Failed: ${stats.sessionStartHook.failed}`);\n if (stats.sessionStartHook.lastSuccess) {\n const lastSuccess = new Date(stats.sessionStartHook.lastSuccess);\n console.log(` Last success: ${lastSuccess.toLocaleString()}`);\n }\n }\n \n if (stats.preCompactHook?.total > 0) {\n console.log('\\n PreCompact Hook:');\n console.log(` Total executions: ${stats.preCompactHook.total}`);\n console.log(` Success rate: ${stats.preCompactHook.successRate.toFixed(1)}%`);\n console.log(` Successful: ${stats.preCompactHook.successful}`);\n console.log(` Failed: ${stats.preCompactHook.failed}`);\n if (stats.preCompactHook.lastSuccess) {\n const lastSuccess = new Date(stats.preCompactHook.lastSuccess);\n console.log(` Last success: ${lastSuccess.toLocaleString()}`);\n }\n }\n\n if (stats.sessionEndHook?.total > 0) {\n console.log('\\n SessionEnd Hook:');\n console.log(` Total executions: ${stats.sessionEndHook.total}`);\n console.log(` Success rate: ${stats.sessionEndHook.successRate.toFixed(1)}%`);\n console.log(` Successful: ${stats.sessionEndHook.successful}`);\n console.log(` Failed: ${stats.sessionEndHook.failed}`);\n if (stats.sessionEndHook.lastSuccess) {\n const lastSuccess = new Date(stats.sessionEndHook.lastSuccess);\n console.log(` Last success: ${lastSuccess.toLocaleString()}`);\n }\n }\n \n // Top projects\n if (stats.topProjects && stats.topProjects.length > 0) {\n console.log('\\n' + colors.info('Top Projects:'));\n stats.topProjects.slice(0, 5).forEach((project: any, index: number) => {\n console.log(` ${index + 1}. ${project.name} - ${project.count} syncs`);\n });\n }\n }\n \n // Configuration files\n console.log('\\n' + colors.info('Configuration:'));\n console.log(` Settings file: ${status.settingsPath}`);\n console.log(` CLI path: ${status.cliPath}`);\n}\n\n/**\n * Test hooks menu\n */\nasync function testHooksMenu(): Promise<void> {\n console.clear();\n console.log(colors.accent('\\n🧪 Test Hooks\\n'));\n \n const { testChoice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'testChoice',\n message: 'Select hook to test:',\n choices: [\n { name: '🚀 Test SessionStart Hook', value: 'sessionstart' },\n { name: '📦 Test PreCompact Hook', value: 'precompact' },\n { name: '🔚 Test SessionEnd Hook', value: 'sessionend' },\n { name: '🎯 Test All Hooks', value: 'all' }\n ]\n }\n ]);\n \n console.log('');\n \n if (testChoice === 'all') {\n const results = await testAllHooks({ verbose: true, record: false });\n \n if (results.length === 0) {\n showWarning('No hooks installed to test');\n } else {\n console.log('');\n console.log(colors.accent('Test Summary:'));\n const passed = results.filter(r => r.success).length;\n const failed = results.filter(r => !r.success).length;\n \n if (failed === 0) {\n showSuccess(`All ${passed} hook(s) passed!`);\n } else {\n showWarning(`${passed} passed, ${failed} failed`);\n }\n }\n } else {\n const result = await testHook(testChoice as 'sessionstart' | 'precompact', { verbose: true, record: false });\n displayTestResult(result);\n }\n}\n\n/**\n * Prompt to continue - waits for user to press Enter\n */\nasync function promptToContinue(): Promise<void> {\n console.log('Press Enter to continue...');\n await inquirer.prompt([{ type: 'input', name: 'continue', message: '' }]);\n}\n\n/**\n * Offer to sync existing sessions after hook installation\n * This ensures hooks only need to handle new sessions going forward\n */\nasync function offerInitialSync(options: { \n all?: boolean; \n selectedProjects?: ProjectHookConfig[] \n}): Promise<void> {\n console.log('');\n console.log(colors.accent('📊 Initial Session Sync'));\n console.log('');\n console.log('Would you like to sync the selected projects existing sessions now?');\n console.log('This ensures hooks only need to handle new sessions going forward.');\n console.log('');\n console.log(colors.success(' ✓ This is a one-time upload of historical data'));\n console.log(colors.success(' ✓ You\\'ll see exactly what will be sent before confirming'));\n console.log(colors.success(' ✓ Future sessions will sync automatically via hooks'));\n console.log('');\n \n const { syncNow } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'syncNow',\n message: 'Sync existing sessions now?',\n default: true\n }\n ]);\n \n if (!syncNow) {\n console.log('');\n showInfo('You can sync existing sessions anytime using \"devark send\"');\n return;\n }\n \n console.log('');\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const spinner = require('ora')('Preparing to sync sessions...').start();\n \n try {\n // Check if user is authenticated first\n const { getToken } = await import('../../lib/auth/token');\n const token = await getToken();\n \n if (!token) {\n spinner.fail('Authentication required');\n console.log('');\n showWarning('You need to authenticate before syncing sessions.');\n console.log('');\n \n const { authenticate } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'authenticate',\n message: 'Would you like to authenticate now?',\n default: true\n }\n ]);\n \n if (authenticate) {\n const { auth } = await import('../../commands/auth');\n await auth({ wizardMode: true });\n \n // Check again after auth\n const newToken = await getToken();\n if (!newToken) {\n showError('Authentication failed. Please try again from the main menu.');\n return;\n }\n } else {\n showInfo('You can authenticate and sync later from the main menu.');\n return;\n }\n }\n \n spinner.succeed('Ready to sync sessions');\n console.log('');\n \n // Trigger the sync based on configuration\n if (options.all) {\n // Sync all sessions for global hooks\n showInfo('Syncing all existing sessions from all projects...');\n console.log('');\n await sendWithTimeout({ all: true, fromMenu: true, isInitialSync: true });\n } else if (options.selectedProjects) {\n // For selected projects, directly load their sessions (like manual sync does)\n const { readClaudeSessions } = await import('../readers/claude');\n const { discoverProjects } = await import('../claude-core');\n \n // Show which projects we're syncing\n console.log(colors.info(`Syncing sessions from ${options.selectedProjects.length} configured project(s):`));\n \n // Discover all projects to get actual paths\n const allProjects = await discoverProjects();\n const projectSessions: any[] = [];\n \n for (const config of options.selectedProjects) {\n // Find the actual project info\n const project = allProjects.find(p => p.claudePath.endsWith(config.path));\n if (project) {\n try {\n const sessions = await readClaudeSessions({\n projectPath: project.actualPath\n });\n projectSessions.push(...sessions);\n console.log(colors.subdued(` • ${project.name}: ${sessions.length} sessions`));\n } catch (error) {\n console.log(colors.warning(`Failed to read sessions from ${config.name}`));\n }\n }\n }\n \n if (projectSessions.length > 0) {\n console.log(colors.success(`\\nTotal: ${projectSessions.length} sessions to sync`));\n \n // Convert to the format expected by sendWithTimeout\n const selectedSessions = projectSessions.map(s => ({\n projectPath: s.sourceFile?.claudeProjectPath || s.projectPath,\n sessionFile: s.sourceFile?.sessionFile || '',\n displayName: parseProjectName(s.projectPath),\n timestamp: s.timestamp,\n duration: s.duration,\n messageCount: s.messages.length\n }));\n \n // Show privacy processing message\n console.log(colors.dim('Preparing sessions for privacy-safe upload...'));\n \n // This will show the loading, redaction count, and upload UI\n await sendWithTimeout({ selectedSessions, fromMenu: true, isInitialSync: true });\n } else {\n console.log(colors.warning('No sessions found in selected projects'));\n showInfo('You can sync sessions later using \"Send sessions\" from the main menu');\n }\n }\n \n console.log('');\n showSuccess('✅ Initial sync complete!');\n showInfo('Future sessions will be synced automatically by hooks.');\n \n } catch (error) {\n spinner.fail('Failed to sync sessions');\n console.log('');\n \n // Use displayError for better error handling\n const { displayError } = await import('../../utils/errors');\n displayError(error);\n \n console.log('');\n showInfo('You can try syncing again from the main menu using \"Send sessions\"');\n \n // Wait for user to acknowledge the error\n await inquirer.prompt({\n type: 'input',\n name: 'continue',\n message: ' '\n });\n }\n}","import Database from 'better-sqlite3';\nimport path from 'path';\nimport os from 'os';\nimport fs from 'fs';\nimport { DevArkError } from '../../utils/errors';\n\ninterface CursorConversation {\n composerId: string;\n createdAt?: number;\n lastUpdatedAt?: number;\n conversation?: Array<{\n type: number; // 1 = user, 2 = assistant\n text: string;\n timestamp?: string;\n }>;\n fullConversationHeadersOnly?: Array<{\n bubbleId: string;\n type: number;\n }>;\n _v?: number; // Modern format has version field\n}\n\ninterface CursorMessageCount {\n totalMessages: number;\n userMessages: number;\n assistantMessages: number;\n conversationCount: number;\n}\n\n/**\n * Get the Cursor database path based on platform\n */\nfunction getCursorDatabasePath(): string {\n const platform = os.platform();\n\n if (platform === 'darwin') {\n return path.join(os.homedir(), 'Library/Application Support/Cursor/User/globalStorage/state.vscdb');\n } else if (platform === 'win32') {\n const appData = process.env.APPDATA || path.join(os.homedir(), 'AppData/Roaming');\n return path.join(appData, 'Cursor/User/globalStorage/state.vscdb');\n } else {\n // Linux\n return path.join(os.homedir(), '.config/Cursor/User/globalStorage/state.vscdb');\n }\n}\n\n/**\n * Check if Cursor is installed on this system (cross-platform)\n * @returns true if Cursor database exists, false otherwise\n */\nexport function isCursorInstalled(): boolean {\n try {\n const dbPath = getCursorDatabasePath();\n return fs.existsSync(dbPath);\n } catch (error) {\n return false;\n }\n}\n\n/**\n * Check if conversation is legacy format\n */\nfunction isLegacyConversation(conversation: any): boolean {\n return conversation &&\n typeof conversation.composerId === 'string' &&\n Array.isArray(conversation.conversation) &&\n !conversation._v;\n}\n\n/**\n * Check if conversation is modern format\n */\nfunction isModernConversation(conversation: any): boolean {\n return conversation &&\n typeof conversation.composerId === 'string' &&\n typeof conversation._v === 'number' &&\n Array.isArray(conversation.fullConversationHeadersOnly);\n}\n\n/**\n * Count messages from Cursor IDE conversations\n * @param options Optional filters (e.g., since date)\n */\ninterface CursorMessage {\n text: string;\n type: number; // 1 = user, 2 = assistant\n bubbleId?: string;\n timestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface CursorMessagesResult {\n messages: CursorMessage[]; // New messages since last check\n allMessages: CursorMessage[]; // All messages for time-based stats\n totalCount: number;\n maxTimestamp: number; // Latest message timestamp for next check\n}\n\n/**\n * Get Cursor messages since a specific timestamp\n * @param sinceTimestamp Unix timestamp in milliseconds (0 = get all messages)\n */\nexport async function getCursorMessagesSince(\n sinceTimestamp: number\n): Promise<CursorMessagesResult> {\n const dbPath = getCursorDatabasePath();\n let db: Database.Database | null = null;\n\n try {\n db = new Database(dbPath, { readonly: true });\n\n const sql = `\n SELECT value FROM cursorDiskKV\n WHERE key LIKE 'composerData:%'\n AND length(value) > 1000\n `;\n\n const stmt = db.prepare(sql);\n const rows = stmt.all() as Array<{ value: string }>;\n\n const allMessages: CursorMessage[] = [];\n\n for (const row of rows) {\n try {\n const conversation = JSON.parse(row.value) as CursorConversation;\n\n if (isLegacyConversation(conversation)) {\n // Legacy format - messages have text directly\n const messages = conversation.conversation || [];\n\n for (const message of messages) {\n let timestamp: number;\n\n if (message.timestamp) {\n timestamp = new Date(message.timestamp).getTime();\n } else {\n timestamp = Date.now();\n }\n\n allMessages.push({\n text: message.text,\n type: message.type,\n timestamp\n });\n }\n } else if (isModernConversation(conversation)) {\n // Modern format - need to look up bubble text separately\n const composerId = conversation.composerId;\n const headers = conversation.fullConversationHeadersOnly || [];\n\n // Use composer's createdAt as the conversation timestamp\n const conversationTimestamp = conversation.createdAt || conversation.lastUpdatedAt || Date.now();\n\n for (const header of headers) {\n // Only process assistant messages (type 2)\n if (header.type === 2 && header.bubbleId) {\n const bubbleKey = `bubbleId:${composerId}:${header.bubbleId}`;\n\n try {\n const bubbleQuery = db.prepare('SELECT value FROM cursorDiskKV WHERE key = ?');\n const bubbleRow = bubbleQuery.get(bubbleKey) as { value: string } | undefined;\n\n if (bubbleRow) {\n const bubble = JSON.parse(bubbleRow.value);\n if (bubble.text) {\n allMessages.push({\n text: bubble.text,\n type: 2, // assistant\n bubbleId: header.bubbleId,\n timestamp: conversationTimestamp\n });\n }\n }\n } catch (bubbleError) {\n // Skip bubbles that can't be read\n continue;\n }\n }\n }\n }\n } catch (error) {\n continue;\n }\n }\n\n // Filter messages by timestamp (more reliable than array slicing)\n const newMessages = allMessages.filter(msg => msg.timestamp > sinceTimestamp);\n\n // Find the maximum timestamp for next check\n const maxTimestamp = allMessages.length > 0\n ? Math.max(...allMessages.map(m => m.timestamp))\n : sinceTimestamp;\n\n return {\n messages: newMessages,\n allMessages: allMessages, // Include all messages for time-based stats\n totalCount: allMessages.length,\n maxTimestamp: maxTimestamp\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n throw new DevArkError(\n 'Cursor IDE data not found.',\n 'CURSOR_NOT_FOUND'\n );\n }\n throw new DevArkError(\n `Failed to read Cursor messages: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'CURSOR_READ_ERROR'\n );\n } finally {\n if (db) {\n db.close();\n }\n }\n}\n\nexport async function countCursorMessages(options?: {\n since?: Date;\n}): Promise<CursorMessageCount> {\n const dbPath = getCursorDatabasePath();\n\n let db: Database.Database | null = null;\n\n try {\n // Open database in read-only mode\n db = new Database(dbPath, { readonly: true });\n\n // Query for all conversation data\n const sql = `\n SELECT value FROM cursorDiskKV\n WHERE key LIKE 'composerData:%'\n AND length(value) > 1000\n `;\n\n const stmt = db.prepare(sql);\n const rows = stmt.all() as Array<{ value: string }>;\n\n let totalMessages = 0;\n let userMessages = 0;\n let assistantMessages = 0;\n let conversationCount = 0;\n\n for (const row of rows) {\n try {\n const conversation = JSON.parse(row.value) as CursorConversation;\n\n let hasValidMessages = false;\n\n if (isLegacyConversation(conversation)) {\n // Legacy format - messages are in conversation array\n const messages = conversation.conversation || [];\n\n for (const message of messages) {\n // Apply date filter if provided\n if (options?.since && message.timestamp) {\n const messageDate = new Date(message.timestamp);\n if (messageDate < options.since) {\n continue;\n }\n }\n\n hasValidMessages = true;\n totalMessages++;\n\n if (message.type === 1) {\n userMessages++;\n } else {\n assistantMessages++;\n }\n }\n } else if (isModernConversation(conversation)) {\n // Modern format - messages are stored separately\n // For now, just count the headers (actual messages would require additional queries)\n const headers = conversation.fullConversationHeadersOnly || [];\n\n for (const header of headers) {\n hasValidMessages = true;\n totalMessages++;\n\n if (header.type === 1) {\n userMessages++;\n } else {\n assistantMessages++;\n }\n }\n }\n\n if (hasValidMessages) {\n conversationCount++;\n }\n } catch (error) {\n // Skip invalid JSON or parsing errors\n continue;\n }\n }\n\n return {\n totalMessages,\n userMessages,\n assistantMessages,\n conversationCount,\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n throw new DevArkError(\n 'Cursor IDE data not found. Make sure Cursor is installed and you have used it at least once.',\n 'CURSOR_NOT_FOUND'\n );\n }\n\n throw new DevArkError(\n `Failed to read Cursor database: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'CURSOR_READ_ERROR'\n );\n } finally {\n // Close database connection\n if (db) {\n db.close();\n }\n }\n}\n","import readline from 'readline';\nimport chalk from 'chalk';\nimport { colors } from './styles';\n\nexport interface MenuOption {\n title: string;\n value: string;\n details?: string[];\n}\n\n/**\n * Create a truly interactive menu that shows details on navigation\n */\nexport class InteractiveMenu {\n private options: MenuOption[];\n private selectedIndex: number = 0;\n private rl: readline.Interface;\n\n constructor(options: MenuOption[]) {\n this.options = options;\n this.rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n\n // Enable raw mode for arrow key detection\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n readline.emitKeypressEvents(process.stdin, this.rl);\n }\n\n private clearScreen(): void {\n console.clear();\n }\n\n private async render(): Promise<void> {\n this.clearScreen();\n\n // Show logo first\n const { showLogo } = await import('../ui');\n const pkg = require('../../../package.json');\n const version = process.env.SIMULATE_OLD_VERSION || pkg.version;\n await showLogo(version);\n\n // Slogan as single line, left-aligned\n console.log();\n console.log(chalk.white.bold('Focus. Discover. Grow. Ship Daily.'));\n console.log();\n console.log(colors.muted('Setup options:'));\n console.log();\n\n // Render menu options\n this.options.forEach((option, index) => {\n const isSelected = index === this.selectedIndex;\n const prefix = isSelected ? chalk.cyan('▶') : ' ';\n\n // Show option title\n if (isSelected) {\n console.log(`${prefix} ${chalk.bold(option.title)}`);\n\n // Show details for selected option\n if (option.details && option.details.length > 0) {\n option.details.forEach(detail => {\n console.log(colors.muted(` └─ ${detail}`));\n });\n }\n } else {\n console.log(`${prefix} ${option.title}`);\n }\n });\n\n console.log();\n console.log(colors.muted('Use ↑↓ arrows to navigate, Enter to select, q to quit'));\n }\n\n async show(): Promise<string | null> {\n return new Promise(async (resolve) => {\n await this.render();\n\n const handleKeypress = async (_str: string | undefined, key: any) => {\n if (key) {\n if (key.name === 'up') {\n this.selectedIndex = Math.max(0, this.selectedIndex - 1);\n await this.render();\n } else if (key.name === 'down') {\n this.selectedIndex = Math.min(this.options.length - 1, this.selectedIndex + 1);\n await this.render();\n } else if (key.name === 'return') {\n // Clean up and return selected value\n process.stdin.removeListener('keypress', handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n this.rl.close();\n\n const selectedOption = this.options[this.selectedIndex];\n resolve(selectedOption.value);\n } else if (key.name === 'q' || (key.ctrl && key.name === 'c')) {\n // Clean up and exit\n process.stdin.removeListener('keypress', handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n this.rl.close();\n resolve(null);\n }\n }\n };\n\n process.stdin.on('keypress', handleKeypress);\n });\n }\n\n cleanup(): void {\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n this.rl.close();\n }\n}","import inquirer from 'inquirer';\nimport { colors } from './styles';\nimport chalk from 'chalk';\nimport { InteractiveMenu, MenuOption } from './interactive-menu';\n\nexport type WelcomeChoice = 'standup' | 'local' | 'cloud' | 'statusline' | 'exit';\n\n// USP details for each option\nconst optionDetails: Record<string, string[]> = {\n 'standup': [\n '🤖 AI-generated standup summary from your sessions',\n '✨ Ready for your daily meeting in minutes',\n '📝 Uses Claude Code locally'\n ],\n 'local': [\n '📖 Using your Claude Code',\n '⏱️ 4-10 minute generation',\n '📄 Local HTML reports'\n ],\n 'cloud': [\n '✓ Uses 0 tokens (our infrastructure)',\n '📧 Weekly recaps & Daily standup emails',\n '📊 Interactive dashboards',\n '🎯 Optimization insights & coaching plans'\n ],\n 'statusline': [\n '📊 Analyzes your prompts',\n '💡 Shows feedback in Claude Code',\n '🧠 Personalized Guidance',\n '🤝 Keeps You & Claude focused'\n ]\n};\n\n/**\n * Display the first-time welcome screen with setup options\n * Returns the user's choice without implementing any setup logic\n */\nexport async function showFirstTimeWelcome(): Promise<WelcomeChoice> {\n // Try to use the custom interactive menu if TTY is available\n if (process.stdin.isTTY && process.stdout.isTTY) {\n // Build menu options\n const menuOptions: MenuOption[] = [\n {\n title: '📋 Prepare for standup (2 min) - NEW!',\n value: 'standup',\n details: optionDetails['standup']\n },\n {\n title: '📊 Generate Local Reports',\n value: 'local',\n details: optionDetails['local']\n },\n {\n title: '☁️ Set up Cloud Dashboard',\n value: 'cloud',\n details: optionDetails['cloud']\n },\n {\n title: '💬 Install CC Co-Pilot Statline',\n value: 'statusline',\n details: optionDetails['statusline']\n },\n {\n title: 'Exit',\n value: 'exit',\n details: []\n }\n ];\n\n try {\n const menu = new InteractiveMenu(menuOptions);\n const choice = await menu.show();\n\n if (choice === null || choice === 'exit') {\n return 'exit';\n }\n\n // Clear screen after selection\n console.clear();\n\n // Show logo and slogan\n const { showLogo } = await import('../ui');\n const pkg = require('../../../package.json');\n const version = process.env.SIMULATE_OLD_VERSION || pkg.version;\n await showLogo(version);\n\n console.log();\n console.log(chalk.white.bold('Focus. Discover. Grow. Ship Daily.'));\n console.log();\n\n return choice as WelcomeChoice;\n } catch (error) {\n // If interactive menu fails, fall back to inquirer\n console.log(colors.warning('Interactive menu failed, using fallback...'));\n }\n }\n\n // Fallback to inquirer for non-TTY environments or if custom menu fails\n console.log();\n console.log(chalk.white.bold('Focus. Discover. Grow. Ship Daily.'));\n console.log();\n \n const menuChoices = [\n {\n name: '📋 Prepare for standup (2 min) - NEW!',\n value: 'standup' as const,\n },\n {\n name: '📊 Generate Local Reports',\n value: 'local' as const,\n },\n {\n name: '☁️ Set up Cloud Dashboard',\n value: 'cloud' as const,\n },\n {\n name: '💬 Install CC Co-Pilot Statline',\n value: 'statusline' as const,\n },\n {\n name: 'Exit',\n value: 'exit' as const,\n }\n ];\n\n // Build formatted choices with first item's details shown\n const buildFormattedChoices = () => {\n return menuChoices.map((choice, index) => {\n // Show details for first item by default (it starts selected)\n if (index === 0 && choice.value !== 'exit') {\n const details = optionDetails[choice.value];\n if (details) {\n const detailLines = details.map(d => colors.muted(` └─ ${d}`)).join('\\n');\n return {\n name: `${choice.name}\\n${detailLines}`,\n value: choice.value,\n short: choice.name\n };\n }\n }\n return choice;\n });\n };\n\n // Note for users about navigation\n console.log(colors.muted('Use ↑↓ arrows to navigate, Enter to select\\n'));\n\n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: '',\n choices: buildFormattedChoices(),\n pageSize: 20,\n loop: false\n }\n ]);\n\n // Clear after selection\n console.clear();\n console.log();\n console.log(chalk.white.bold('Focus. Discover. Grow. Ship Daily.'));\n console.log();\n\n return choice;\n}\n\n/**\n * Display a simple loading message while setting up\n */\nexport function showSetupMessage(mode: 'local' | 'cloud'): void {\n console.log();\n if (mode === 'local') {\n console.log(colors.info('Installing devark local mode...'));\n } else {\n console.log(colors.info('Setting up devark cloud mode...'));\n }\n console.log();\n}","import { spawn, execSync, ChildProcess } from 'child_process';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { logger } from './logger';\n\n/**\n * Stream event types from Claude SDK\n */\nexport type ClaudeStreamEvent = {\n type: string;\n subtype?: string;\n message?: any;\n delta?: any;\n content?: any;\n result?: any;\n duration_ms?: number;\n duration_api_ms?: number;\n num_turns?: number;\n total_cost_usd?: number;\n session_id?: string;\n is_error?: boolean;\n};\n\n/**\n * Options for Claude execution\n */\nexport interface ClaudeExecutorOptions {\n systemPrompt?: string;\n cwd?: string;\n claudePath?: string;\n model?: string; // Model to use (defaults to 'sonnet')\n timeout?: number; // Timeout in milliseconds\n onStreamEvent?: (event: ClaudeStreamEvent) => void;\n onStart?: () => void;\n onError?: (error: Error) => void;\n onComplete?: (code: number) => void;\n}\n\n/**\n * Check if Claude CLI is installed and available\n */\nexport async function checkClaudeInstalled(): Promise<{ installed: boolean; version?: string; path?: string }> {\n // First try the standard PATH lookup\n try {\n const command = process.platform === 'win32' ? 'where' : 'which';\n logger.debug(`Checking for Claude using command: ${command} claude`);\n \n const claudePath = execSync(`${command} claude`, { encoding: 'utf8' }).trim();\n logger.debug(`Found Claude at: ${claudePath}`);\n \n try {\n const version = execSync('claude --version', { encoding: 'utf8' }).trim();\n logger.debug(`Claude version: ${version}`);\n return { installed: true, version, path: claudePath };\n } catch (versionError) {\n logger.debug(`Could not get Claude version: ${versionError}`);\n return { installed: true, path: claudePath };\n }\n } catch (error) {\n logger.debug(`Claude not found in PATH: ${error}`);\n \n // Try common installation locations\n const commonPaths = [\n path.join(os.homedir(), '.claude', 'local', 'claude'),\n path.join(os.homedir(), '.claude', 'claude'),\n '/usr/local/bin/claude',\n '/opt/homebrew/bin/claude'\n ];\n \n for (const claudePath of commonPaths) {\n try {\n logger.debug(`Checking path: ${claudePath}`);\n // Check if file exists and is executable\n await fs.access(claudePath, fs.constants.X_OK);\n logger.debug(`Found Claude at ${claudePath}`);\n \n try {\n const version = execSync(`\"${claudePath}\" --version`, { encoding: 'utf8' }).trim();\n return { installed: true, version, path: claudePath };\n } catch {\n return { installed: true, path: claudePath };\n }\n } catch {\n // Path doesn't exist or isn't executable, continue checking\n }\n }\n \n logger.debug('Claude not found in common paths either');\n return { installed: false };\n }\n}\n\n/**\n * Execute Claude with the given prompt and stream responses\n * This is a clean executor that only handles Claude SDK interaction\n */\nexport async function executeClaude(\n prompt: string,\n options: ClaudeExecutorOptions = {}\n): Promise<void> {\n const { \n systemPrompt, \n cwd = process.cwd(), \n claudePath = 'claude',\n model = 'sonnet',\n timeout,\n onStreamEvent,\n onStart, \n onError, \n onComplete \n } = options;\n \n let tempPromptFile: string | null = null;\n let child: ChildProcess | null = null;\n let timeoutHandle: NodeJS.Timeout | null = null;\n \n logger.debug(`Claude executor starting - prompt length: ${prompt.length} characters`);\n \n try {\n if (onStart) {\n onStart();\n }\n \n // Use CLI with stream-json output format for real-time updates\n const isWindows = process.platform === 'win32';\n \n let args: string[];\n let spawnOptions: any;\n let executablePath = claudePath;\n \n if (isWindows) {\n // Windows: Use PowerShell to pipe the file content to Claude\n // This avoids command line length limits and batch file issues\n\n // Write prompt to a temporary file in .devark folder for consistency\n const tempDir = path.join(os.homedir(), '.devark', 'temp-prompts');\n await fs.mkdir(tempDir, { recursive: true });\n\n // Clean up old prompt files (older than 1 hour)\n try {\n const files = await fs.readdir(tempDir);\n const oneHourAgo = Date.now() - (60 * 60 * 1000);\n for (const file of files) {\n if (file.startsWith('claude-prompt-')) {\n const timestamp = parseInt(file.replace('claude-prompt-', '').replace('.txt', ''), 10);\n if (!isNaN(timestamp) && timestamp < oneHourAgo) {\n await fs.unlink(path.join(tempDir, file)).catch(() => {});\n }\n }\n }\n } catch {\n // Ignore cleanup errors\n }\n\n tempPromptFile = path.join(tempDir, `claude-prompt-${Date.now()}.txt`);\n await fs.writeFile(tempPromptFile, prompt, 'utf8');\n logger.debug(`Windows: Wrote prompt to temp file: ${tempPromptFile}`);\n \n // Build the Claude command with arguments\n const claudeArgs = ['-p'];\n \n // Add model selection\n claudeArgs.push('--model', model);\n \n // Add system prompt if provided\n if (systemPrompt) {\n claudeArgs.push('--append-system-prompt', `\"${systemPrompt}\"`);\n }\n \n // Add output format with verbose\n claudeArgs.push('--output-format', 'stream-json', '--verbose');\n \n // Use PowerShell to read the file and pipe it to Claude\n const psCommand = `Get-Content -Path \"${tempPromptFile}\" -Raw | & claude ${claudeArgs.join(' ')}`;\n \n args = ['-NoProfile', '-Command', psCommand];\n \n spawnOptions = {\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd,\n shell: false\n };\n \n // Use PowerShell as the executable\n executablePath = 'powershell.exe';\n \n logger.debug(`Windows mode: Using PowerShell to pipe file content`);\n } else {\n // Mac/Linux: Use the existing approach with prompt as argument\n args = ['-p'];\n \n // Add model selection\n args.push('--model', model);\n \n // Add system prompt if provided\n if (systemPrompt) {\n args.push('--append-system-prompt', systemPrompt);\n }\n \n // Add output format and the main prompt as argument\n args.push('--output-format', 'stream-json', '--verbose', prompt);\n \n spawnOptions = {\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd\n };\n \n logger.debug(`Unix mode: Using command argument for prompt`);\n }\n \n // Spawn the Claude process\n child = spawn(executablePath, args, spawnOptions);\n \n logger.debug(`Claude process spawned with PID: ${child.pid}`);\n \n // Set up timeout if specified\n if (timeout) {\n timeoutHandle = setTimeout(() => {\n if (child) {\n logger.debug(`Claude execution timeout after ${timeout}ms`);\n child.kill('SIGTERM');\n const error = new Error(`Claude execution timed out after ${timeout}ms`);\n if (onError) {\n onError(error);\n }\n }\n }, timeout);\n }\n \n let buffer = '';\n let stderrOutput = '';\n \n // Handle stdout (stream-json output)\n if (child.stdout) {\n child.stdout.on('data', (data) => {\n buffer += data.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n \n for (const line of lines) {\n if (!line.trim()) continue;\n \n try {\n const json = JSON.parse(line);\n \n // Send the parsed event to the callback if provided\n if (onStreamEvent) {\n onStreamEvent(json);\n }\n \n // Log specific event types for debugging\n if (json.type === 'result') {\n logger.debug('Claude result event:', {\n subtype: json.subtype,\n duration_ms: json.duration_ms,\n num_turns: json.num_turns,\n total_cost_usd: json.total_cost_usd\n });\n }\n } catch (e) {\n // Not valid JSON, might be partial line\n logger.debug(`Failed to parse JSON line: ${line}`);\n }\n }\n });\n }\n \n // Handle stderr\n if (child.stderr) {\n child.stderr.on('data', (data) => {\n const stderr = data.toString();\n stderrOutput += stderr;\n logger.debug(`Claude stderr: ${stderr}`);\n });\n }\n \n return new Promise((resolve, reject) => {\n child!.on('error', (error) => {\n logger.error('Failed to spawn Claude:', error);\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n if (onError) {\n onError(error);\n }\n reject(error);\n });\n \n child!.on('exit', async (code) => {\n // Clear timeout if it was set\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n \n // Clean up temp file on Windows\n if (isWindows && tempPromptFile) {\n try {\n await fs.unlink(tempPromptFile);\n } catch {\n // Ignore errors, file will be cleaned up by OS eventually\n }\n }\n \n if (code === 0) {\n logger.debug(`Claude completed successfully`);\n if (onComplete) {\n onComplete(code);\n }\n resolve();\n } else if (code !== null) {\n // Non-zero exit code\n let errorMessage = `Claude exited with code ${code}`;\n \n // Include stderr output if available\n if (stderrOutput.trim()) {\n errorMessage += `\\n\\nClaude stderr output:\\n${stderrOutput.trim()}`;\n }\n \n // Check for common Windows-specific issues\n if (process.platform === 'win32') {\n if (stderrOutput.includes('command not found') || stderrOutput.includes('is not recognized')) {\n errorMessage += '\\n\\nWindows-specific issue: Claude command may not be in PATH or needs full path.';\n }\n if (stderrOutput.includes('Access is denied') || stderrOutput.includes('Permission denied')) {\n errorMessage += '\\n\\nWindows-specific issue: Permission denied. Try running as administrator.';\n }\n }\n \n const error = new Error(errorMessage);\n \n if (onError) {\n onError(error);\n }\n reject(error);\n } else {\n // Process was killed or terminated abnormally\n let errorMessage = 'Claude process terminated unexpectedly';\n if (stderrOutput.trim()) {\n errorMessage += `\\n\\nClaude stderr output:\\n${stderrOutput.trim()}`;\n }\n const error = new Error(errorMessage);\n \n if (onError) {\n onError(error);\n }\n reject(error);\n }\n });\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Error in Claude executor: ${errorMessage}`);\n \n // Clean up timeout if it was set\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n \n // Clean up temp file on Windows\n if (process.platform === 'win32' && tempPromptFile) {\n try {\n await fs.unlink(tempPromptFile);\n } catch {\n // Ignore errors\n }\n }\n \n if (onError) {\n onError(error instanceof Error ? error : new Error(errorMessage));\n }\n \n throw error;\n }\n}\n\n/**\n * Show instructions for installing Claude\n */\nexport function showClaudeInstallInstructions(): void {\n console.log();\n console.log(`⚠️ Claude CLI is not installed`);\n console.log();\n console.log('To use this feature, you need to install Claude:');\n console.log();\n console.log('Option 1: Install from claude.ai');\n console.log(' 1. Visit https://claude.ai/code');\n console.log(' 2. Download and install Claude Code');\n console.log();\n console.log('Option 2: Use the copy command option');\n console.log(' Select \"Copy command to clipboard\" instead');\n console.log(' Then paste and run in your terminal');\n console.log();\n}","/**\n * Utility functions for standup command\n * Extracted from standup.ts for reusability\n * These are pure functions with no side effects\n */\n\nimport { SessionData } from './readers/types';\nimport { extractProjectName } from './claude-project-parser';\n\n/**\n * Get yesterday's working day (accounting for weekends)\n * Monday returns Friday, Sunday returns Friday, others return yesterday\n */\nexport function getYesterdayWorkingDay(): Date {\n const today = new Date();\n const dayOfWeek = today.getDay();\n const yesterday = new Date(today);\n\n if (dayOfWeek === 1) { // Monday\n yesterday.setDate(today.getDate() - 3); // Get Friday\n } else if (dayOfWeek === 0) { // Sunday\n yesterday.setDate(today.getDate() - 2); // Get Friday\n } else {\n yesterday.setDate(today.getDate() - 1); // Get yesterday\n }\n\n return yesterday;\n}\n\n/**\n * Get day name from date\n */\nexport function getDayName(date: Date): string {\n const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n return days[date.getDay()];\n}\n\n/**\n * Group sessions by project name\n */\nexport function groupSessionsByProject(sessions: SessionData[]): Record<string, SessionData[]> {\n const grouped: Record<string, SessionData[]> = {};\n\n for (const session of sessions) {\n const project = extractProjectName(session.projectPath);\n if (!grouped[project]) {\n grouped[project] = [];\n }\n grouped[project].push(session);\n }\n\n return grouped;\n}\n\n/**\n * Format duration for display\n */\nexport function formatDuration(totalSeconds: number): string {\n const hours = totalSeconds / 3600;\n if (hours >= 1) {\n return `${hours.toFixed(1)} hours`;\n }\n return `${Math.round(totalSeconds / 60)} minutes`;\n}\n\n/**\n * Build the standup analysis prompt for Claude\n * This is the exact prompt from the working version\n */\nexport function buildStandupPrompt(_tempDir: string, targetDate: Date): string {\n const dateStr = targetDate.toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'short',\n day: 'numeric'\n });\n\n return `think hard \nYou are analyzing coding sessions to extract ACTUAL DEVELOPER ACCOMPLISHMENTS for a daily standup meeting.\n\nCRITICAL RULES TO PREVENT HALLUCINATION:\n1. ONLY extract accomplishments that are DIRECTLY mentioned in the session messages\n2. Look for SPECIFIC file names, function names, or clear descriptions of work done\n3. If you cannot find specific evidence of work in the messages, use generic but accurate descriptions\n4. NEVER make up features or work that isn't explicitly in the data\n\nIMPORTANT: Do NOT use sub-agents or Task tools. Read files directly using the Read tool.\n\nTask:\n1. Read ./standup-manifest.json to see available sessions (in current directory)\n2. IMPORTANT: Analyze ALL projects listed in the manifest, not just a sample\n3. Read the JSONL session files DIRECTLY from current directory (they are here with you)\n4. CRITICAL: Ignore any sessions from today - only report on PAST work\n5. Extract ONLY work that is ACTUALLY DESCRIBED in the messages\n6. Include EVERY project that had work on ${dateStr} in your response\n\nWhen reading messages, look for:\n- File paths that indicate what was worked on (e.g., \"editing login.tsx\" → \"Worked on login functionality\")\n- Error messages that were fixed (e.g., \"fixed TypeError in payment.js\" → \"Fixed payment processing bug\")\n- Feature names mentioned in conversations (e.g., \"implementing leaderboard\" → \"Implemented leaderboard feature\")\n- Database/API work (e.g., \"created users table\" → \"Set up user data storage\")\n- UI components created (e.g., \"added ProfileCard component\" → \"Built user profile UI\")\n\nTRANSLATION EXAMPLES (from technical to user-facing business value):\n- \"Modified auth.ts and login.tsx\" → \"Improved user authentication flow\"\n- \"Fixed null pointer in checkout\" → \"Fixed checkout bug affecting customer purchases\"\n- \"Created D1 migrations\" → \"Enhanced data storage for better performance\"\n- \"Added API endpoint /users\" → \"Built user profile management feature\"\n- \"Styled navbar component\" → \"Improved site navigation experience\"\n- \"Fixed leaderboard query\" → \"Fixed leaderboard loading issues for users\"\n- \"Added OAuth provider\" → \"Enabled Google/GitHub login for users\"\n- \"Optimized database queries\" → \"Reduced page load times by 50%\"\n\nIf work is unclear from messages, use SAFE business-focused descriptions:\n- \"Improved [project] stability and reliability\"\n- \"Fixed user-reported issues in [project]\"\n- \"Enhanced [project] performance for better user experience\"\n- \"Updated [project] security and dependencies\"\n- \"Refined [project] features based on requirements\"\n\nFor \"todayFocus\", base suggestions on:\n- Actual unfinished work visible in the sessions\n- Common patterns (if testing was done, suggest deployment)\n- Logical next steps based on what was actually built\n</think_hard>\n\nYour response must be ONLY this JSON structure (include ALL projects):\n{\n \"yesterday\": {\n \"date\": \"${dateStr}\",\n \"projects\": [\n {\n \"name\": \"project-1-name\",\n \"accomplishments\": [\n \"User-facing feature or business value delivered\",\n \"Bug fix or improvement that affects users\",\n \"Integration or functionality users care about\"\n ]\n },\n {\n \"name\": \"project-2-name\",\n \"accomplishments\": [\"List accomplishments for EVERY project\"]\n }\n // Include ALL projects that had activity, not just a selection\n ]\n },\n \"todayFocus\": [\n \"Complete [unfinished feature from yesterday]\",\n \"Fix [issue discovered yesterday]\",\n \"Continue [partially implemented feature]\"\n ],\n \"blockers\": []\n}\n\nCRITICAL OUTPUT INSTRUCTIONS:\n1. Before the JSON, write exactly: ----JSON START----\n2. Then write your JSON object\n3. After the JSON, write exactly: ----JSON END----\n\nExample format:\n----JSON START----\n{\n \"yesterday\": { ... },\n \"todayFocus\": [...],\n \"blockers\": []\n}\n----JSON END----\n\nDO NOT include any text before ----JSON START---- or after ----JSON END----`;\n}\n\n/**\n * Get the system prompt for Claude execution\n */\nexport function getClaudeSystemPrompt(): string {\n return 'You are a developer standup meeting assistant. Extract REAL USER-FACING FEATURES and BUSINESS VALUE from coding sessions. Focus on what developers actually discuss in standups: features built, bugs fixed, integrations completed, performance improvements. AVOID technical implementation details about agents, tools, or internal systems. CRITICAL: Only extract work that is EXPLICITLY mentioned in the session messages - never hallucinate or make up features. Translate technical details into business value. Return ONLY valid JSON.';\n}","/**\n * Manages temporary directory for standup analysis\n * Handles creation, file copying, and cleanup\n *\n * IMPORTANT: Cross-platform compatible\n * - Uses path.join() for all path operations\n * - Uses os.homedir() for user home directory\n * - Stores in ~/.devark/temp-standup for consistency\n */\n\nimport { SessionData } from './readers/types';\nimport { logger } from '../utils/logger';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport os from 'os';\nimport { getDayName, groupSessionsByProject } from './standup-utils';\n\nexport class StandupTempManager {\n private tempDir: string | null = null;\n private readonly baseDir = path.join(os.homedir(), '.devark', 'temp-standup');\n\n /**\n * Create temp directory and prepare session files\n */\n async prepareTempDirectory(\n sessions: SessionData[],\n targetDate: Date\n ): Promise<string> {\n // Ensure base directory exists\n await fs.mkdir(this.baseDir, { recursive: true });\n\n // Create timestamped subdirectory within .devark/temp-standup\n const timestamp = Date.now();\n this.tempDir = path.join(this.baseDir, `session-${timestamp}`);\n await fs.mkdir(this.tempDir, { recursive: true });\n\n // Group sessions by project\n const sessionsByProject = groupSessionsByProject(sessions);\n\n // Log date info for debugging\n logger.debug(`Preparing standup for target date: ${targetDate.toISOString()}`);\n logger.debug(`Today's date: ${new Date().toISOString()}`);\n\n // Create manifest - targetDate should be yesterday's working day\n const manifest = {\n targetDate: targetDate.toISOString(),\n targetDateDisplay: targetDate.toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'short',\n day: 'numeric'\n }),\n dayOfWeek: getDayName(targetDate),\n totalSessions: sessions.length,\n projects: Object.keys(sessionsByProject),\n sessionsPerProject: Object.entries(sessionsByProject).map(([project, sessions]) => ({\n project,\n count: sessions.length,\n files: sessions.map(s => `${s.id}.jsonl`)\n }))\n };\n\n await fs.writeFile(\n path.join(this.tempDir, 'standup-manifest.json'),\n JSON.stringify(manifest, null, 2)\n );\n\n // Copy session files\n await this.copySessionFiles(sessions);\n\n return this.tempDir;\n }\n\n /**\n * Copy session files to temp directory\n */\n private async copySessionFiles(sessions: SessionData[]): Promise<number> {\n if (!this.tempDir) return 0;\n\n let copiedCount = 0;\n for (const session of sessions) {\n // Use the sourceFile info if available, otherwise fall back to id\n const filename = (session as any).sourceFile?.sessionFile || `${session.id}.jsonl`;\n const projectPath = (session as any).sourceFile?.claudeProjectPath || session.projectPath;\n\n const sourcePath = path.join(projectPath, filename);\n const destPath = path.join(this.tempDir, filename);\n\n try {\n await fs.copyFile(sourcePath, destPath);\n copiedCount++;\n } catch (err) {\n logger.debug(`Could not copy session file ${filename}: ${err}`);\n }\n }\n\n logger.debug(`Copied ${copiedCount} of ${sessions.length} session files`);\n return copiedCount;\n }\n\n /**\n * Clean up temp directory\n */\n async cleanup(): Promise<void> {\n if (this.tempDir) {\n try {\n await fs.rm(this.tempDir, { recursive: true, force: true });\n logger.debug(`Cleaned up temp directory: ${this.tempDir}`);\n } catch (err) {\n logger.debug(`Could not clean up temp directory: ${err}`);\n }\n this.tempDir = null;\n }\n\n // Clean up all other temp directories\n await this.cleanupOldTempDirs();\n\n // Clean up Claude project folders for temp directories\n await this.cleanupClaudeProjectFolders();\n }\n\n /**\n * Clean up all temp directories\n * Since users don't run multiple standups in parallel, we clean everything\n */\n private async cleanupOldTempDirs(): Promise<void> {\n try {\n const files = await fs.readdir(this.baseDir);\n\n for (const file of files) {\n if (file.startsWith('session-')) {\n const dirPath = path.join(this.baseDir, file);\n try {\n await fs.rm(dirPath, { recursive: true, force: true });\n logger.debug(`Cleaned up temp directory: ${dirPath}`);\n } catch (err) {\n logger.debug(`Could not clean up directory ${dirPath}: ${err}`);\n }\n }\n }\n } catch (err) {\n // Ignore errors - cleanup is best effort\n logger.debug(`Could not clean up temp directories: ${err}`);\n }\n }\n\n /**\n * Clean up Claude project folders created for temp directories\n * Claude creates project folders when we run it from a directory\n */\n private async cleanupClaudeProjectFolders(): Promise<void> {\n try {\n const claudeProjectsDir = path.join(os.homedir(), '.claude', 'projects');\n const files = await fs.readdir(claudeProjectsDir);\n\n for (const file of files) {\n // Look for URL-encoded temp directory names\n // Format: C--Users-username--devark-temp-standup-session-*\n // This matches our temp directory pattern but URL-encoded\n if (file.includes('--devark-temp-standup-session-')) {\n const projectPath = path.join(claudeProjectsDir, file);\n try {\n await fs.rm(projectPath, { recursive: true, force: true });\n logger.debug(`Cleaned up Claude project folder: ${projectPath}`);\n } catch (err) {\n logger.debug(`Could not clean up Claude project folder ${projectPath}: ${err}`);\n }\n }\n }\n } catch (err) {\n // Ignore errors - Claude projects directory might not exist\n logger.debug(`Could not clean up Claude project folders: ${err}`);\n }\n }\n\n /**\n * Get the temp directory path\n */\n getTempDir(): string | null {\n return this.tempDir;\n }\n}","/**\n * Curated collection of productivity tips for standup report generation\n * These tips rotate during the 2-4 minute analysis period to provide value while waiting\n */\n\nexport interface StandupTip {\n text: string;\n category: 'productivity' | 'feature' | 'workflow' | 'collaboration' | 'analysis' | 'claude';\n}\n\n/**\n * Get all available standup tips\n * Tips are carefully curated to be:\n * - Actionable and practical\n * - Relevant to developer productivity\n * - Educational about devark features\n * - Concise (fit on one line)\n */\nexport function getStandupTips(): StandupTip[] {\n return [\n // Productivity Tips\n {\n text: '🎯 Focus tip: Batch similar tasks together for better flow state',\n category: 'productivity'\n },\n {\n text: '⏰ Time-box difficult problems - take a break if stuck for 30+ minutes',\n category: 'productivity'\n },\n \n {\n text: '📊 Track your energy levels to schedule complex work at peak times',\n category: 'productivity'\n },\n {\n text: '🚫 Block distractions during deep work - use focus mode on your devices',\n category: 'productivity'\n },\n {\n text: '✅ Start with a quick win to build momentum for the day',\n category: 'productivity'\n },\n\n // DevArk Feature Tips\n {\n text: '💡 Use hooks for automatic session capture without manual uploads',\n category: 'feature'\n },\n {\n text: '📈 View your productivity patterns at app.devark.ai/dashboard',\n category: 'feature'\n },\n {\n text: '📧 Setup DevArk cloud account to get Weekly recaps and Daily standup emails',\n category: 'feature'\n },\n {\n text: '📱 Install sub-agents for specialized work',\n category: 'feature'\n },\n {\n text: '🔐 When using Cloud Your sessions are sanitized - sensitive data never leaves your machine',\n category: 'feature'\n },\n \n {\n text: '📋 Generate local reports without cloud upload using the main menu',\n category: 'feature'\n },\n\n // Claude Code Tips\n {\n text: '🤖 Clear, specific prompts lead to better AI assistance',\n category: 'claude'\n },\n {\n text: '💬 Break complex tasks into smaller, focused conversations',\n category: 'claude'\n },\n {\n text: '🔍 To give Claude Better context use @ and pin point to the files you want to modify',\n category: 'claude'\n },\n {\n text: '📚 Provide context about your project structure for better help',\n category: 'claude'\n },\n {\n text: '🎯 Be specific about requirements - examples help Claude understand',\n category: 'claude'\n },\n {\n text: '💡 Claude can explain code, not just write it - ask \"why\" questions',\n category: 'claude'\n },\n\n // Workflow Optimization\n {\n text: '🔄 Commit frequently with clear messages for better session tracking',\n category: 'workflow'\n },\n {\n text: '🏗️ Set up your dev environment once, save the setup script',\n category: 'workflow'\n },\n {\n text: '⚡ Learn keyboard shortcuts - they compound into huge time savings',\n category: 'workflow'\n },\n {\n text: '🔧 Automate repetitive tasks - even 5-minute tasks add up',\n category: 'workflow'\n },\n {\n text: '📦 Keep dependencies updated regularly to avoid big migrations',\n category: 'workflow'\n },\n {\n text: '🧪 Write tests as you code - debugging is harder than preventing bugs',\n category: 'workflow'\n },\n\n // Collaboration Tips\n {\n text: '👥 Share your standup reports with your team for transparency',\n category: 'collaboration'\n },\n {\n text: '💬 Over-communicate in remote teams - assume nothing is obvious',\n category: 'collaboration'\n },\n \n {\n text: '🤝 Pair program on complex problems - two minds are better than one',\n category: 'collaboration'\n },\n {\n text: '📊 Share your wins and learnings - everyone benefits from knowledge',\n category: 'collaboration'\n },\n\n // Analysis Quality Tips\n {\n text: '📈 Longer prompts with clear goals produce better AI insights',\n category: 'analysis'\n },\n \n {\n text: '🎯 Define success criteria before starting work for clearer reports',\n category: 'analysis'\n },\n \n {\n text: '💡 Include \"why\" in your commits for richer standup summaries',\n category: 'analysis'\n }\n ];\n}\n\n/**\n * Get a random selection of tips\n * @param count Number of tips to return\n * @param categories Optional filter by categories\n */\nexport function getRandomTips(\n count: number,\n categories?: StandupTip['category'][]\n): StandupTip[] {\n let tips = getStandupTips();\n\n // Filter by categories if specified\n if (categories && categories.length > 0) {\n tips = tips.filter(tip => categories.includes(tip.category));\n }\n\n // Shuffle and return requested count\n const shuffled = [...tips].sort(() => Math.random() - 0.5);\n return shuffled.slice(0, Math.min(count, shuffled.length));\n}\n\n/**\n * Get tips in a rotating sequence\n * Ensures good variety by cycling through categories\n */\nexport function getTipsForRotation(): string[] {\n const tips = getStandupTips();\n\n // Group by category\n const byCategory: Record<string, StandupTip[]> = {};\n tips.forEach(tip => {\n if (!byCategory[tip.category]) {\n byCategory[tip.category] = [];\n }\n byCategory[tip.category].push(tip);\n });\n\n // Build rotation ensuring category variety\n const rotation: string[] = [];\n const categories = Object.keys(byCategory);\n let maxTipsPerCategory = 0;\n\n // Find max tips in any category\n categories.forEach(cat => {\n if (byCategory[cat].length > maxTipsPerCategory) {\n maxTipsPerCategory = byCategory[cat].length;\n }\n });\n\n // Round-robin through categories\n for (let i = 0; i < maxTipsPerCategory; i++) {\n categories.forEach(cat => {\n if (byCategory[cat][i]) {\n rotation.push(byCategory[cat][i].text);\n }\n });\n }\n\n return rotation;\n}","/**\n * Rotating tips display mechanism for long-running operations\n * Provides engaging content during wait times with smooth transitions\n */\n\nimport chalk from 'chalk';\nimport { getTipsForRotation } from './standup-tips';\n\nexport class RotatingTips {\n private tips: string[];\n private currentIndex: number = 0;\n private interval: NodeJS.Timeout | null = null;\n private isRunning: boolean = false;\n private lastLineLength: number = 0;\n\n constructor(tips?: string[]) {\n this.tips = tips || getTipsForRotation();\n // Shuffle tips for variety\n this.shuffleTips();\n }\n\n /**\n * Shuffle tips array for random order\n */\n private shuffleTips(): void {\n for (let i = this.tips.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [this.tips[i], this.tips[j]] = [this.tips[j], this.tips[i]];\n }\n }\n\n /**\n * Clear the current line in the terminal\n */\n private clearLine(): void {\n if (this.lastLineLength > 0) {\n process.stdout.write('\\r' + ' '.repeat(this.lastLineLength) + '\\r');\n }\n }\n\n /**\n * Display the current tip\n */\n private displayTip(): void {\n this.clearLine();\n\n const tip = this.tips[this.currentIndex];\n const output = `${chalk.gray('Tip:')} ${tip}`;\n\n // Track line length for proper clearing\n // Remove ANSI escape codes to get actual character count\n this.lastLineLength = output.replace(/\\x1b\\[[0-9;]*m/g, '').length;\n\n process.stdout.write(output);\n }\n\n /**\n * Move to next tip\n */\n private nextTip(): void {\n this.currentIndex = (this.currentIndex + 1) % this.tips.length;\n // If we've cycled through all tips, reshuffle\n if (this.currentIndex === 0) {\n this.shuffleTips();\n }\n }\n\n /**\n * Start rotating tips\n * @param intervalMs - Time between tip changes (default: 4000ms)\n */\n start(intervalMs: number = 4000): void {\n if (this.isRunning) {\n return;\n }\n\n this.isRunning = true;\n\n // Display first tip immediately\n this.displayTip();\n\n // Set up tip rotation\n this.interval = setInterval(() => {\n if (this.isRunning) {\n this.nextTip();\n this.displayTip();\n }\n }, intervalMs);\n }\n\n /**\n * Stop rotating tips and clear the line\n */\n stop(): void {\n if (!this.isRunning) {\n return;\n }\n\n this.isRunning = false;\n\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n\n this.clearLine();\n }\n\n /**\n * Pause rotation (keeps current tip displayed)\n */\n pause(): void {\n if (!this.isRunning) {\n return;\n }\n\n this.isRunning = false;\n\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n }\n\n /**\n * Resume rotation\n */\n resume(intervalMs: number = 4000): void {\n if (this.isRunning) {\n return;\n }\n\n this.start(intervalMs);\n }\n\n /**\n * Display a static message (replaces tip)\n */\n showMessage(message: string): void {\n this.clearLine();\n const output = `${chalk.green('✓')} ${message}`;\n this.lastLineLength = output.replace(/\\x1b\\[[0-9;]*m/g, '').length;\n process.stdout.write(output);\n }\n\n /**\n * Get current tip being displayed\n */\n getCurrentTip(): string {\n return this.tips[this.currentIndex];\n }\n\n /**\n * Add a custom tip to the rotation\n */\n addTip(tip: string): void {\n this.tips.push(tip);\n }\n\n /**\n * Replace all tips with new ones\n */\n setTips(tips: string[]): void {\n this.tips = tips;\n this.currentIndex = 0;\n this.shuffleTips();\n }\n}\n\n/**\n * Convenience function to create and start rotating tips\n * Returns a function to stop the rotation\n */\nexport function startRotatingTips(\n tips?: string[],\n intervalMs: number = 4000\n): () => void {\n const rotatingTips = new RotatingTips(tips);\n rotatingTips.start(intervalMs);\n\n return () => rotatingTips.stop();\n}\n\n/**\n * Display tips with a header message\n */\nexport class RotatingTipsWithHeader {\n private rotatingTips: RotatingTips;\n private headerMessage: string;\n private headerShown: boolean = false;\n\n constructor(headerMessage: string, tips?: string[]) {\n this.headerMessage = headerMessage;\n this.rotatingTips = new RotatingTips(tips);\n }\n\n /**\n * Start showing header and tips\n */\n start(tipIntervalMs: number = 4000): void {\n if (!this.headerShown) {\n console.log(chalk.cyan(this.headerMessage));\n console.log(chalk.gray('─'.repeat(50)));\n console.log(); // Empty line for tips\n this.headerShown = true;\n }\n this.rotatingTips.start(tipIntervalMs);\n }\n\n /**\n * Stop and clear\n */\n stop(): void {\n this.rotatingTips.stop();\n }\n\n /**\n * Show completion message\n */\n complete(message: string): void {\n this.rotatingTips.showMessage(message);\n console.log(); // New line after completion\n }\n}","import chalk from 'chalk';\nimport { requireAuth } from '../lib/auth/token';\nimport { createSpinner } from '../lib/ui';\nimport { DevArkError } from '../utils/errors';\nimport { logger } from '../utils/logger';\nimport { readClaudeSessions } from '../lib/readers/claude';\nimport { SessionData } from '../lib/readers/types';\nimport { executeClaude, checkClaudeInstalled } from '../utils/claude-executor';\nimport { extractProjectName } from '../lib/claude-project-parser';\nimport {\n getYesterdayWorkingDay,\n formatDuration,\n buildStandupPrompt,\n getClaudeSystemPrompt,\n groupSessionsByProject\n} from '../lib/standup-utils';\nimport { StandupTempManager } from '../lib/standup-temp-manager';\nimport { RotatingTipsWithHeader } from '../lib/ui/rotating-tips';\nimport path from 'path';\nimport fs from 'fs/promises';\n\ninterface StandupData {\n yesterday: {\n date: string;\n projects: Array<{\n name: string;\n accomplishments: string[];\n duration: string;\n }>;\n };\n todayFocus: string[];\n blockers?: string[];\n}\n\nexport async function standup(options?: { skipAuth?: boolean }): Promise<void> {\n // Skip auth check if explicitly requested (for first-time onboarding)\n if (!options?.skipAuth) {\n await requireAuth();\n }\n\n const spinner = createSpinner('Reading your local Claude Code sessions...').start();\n\n try {\n logger.debug('Starting Claude-powered standup generation...');\n\n // Read local Claude sessions for the last 3 days (relevant for standup)\n const endDate = new Date();\n const startDate = new Date();\n startDate.setDate(startDate.getDate() - 3);\n\n logger.debug(`Reading sessions from ${startDate.toISOString()} to ${endDate.toISOString()}`);\n const claudeSessions = await readClaudeSessions({ since: startDate });\n\n if (!claudeSessions || claudeSessions.length === 0) {\n spinner.fail('No sessions found');\n console.log(chalk.yellow('\\nNo Claude Code sessions found in the last 3 days.'));\n console.log(chalk.gray('Start coding with Claude Code and then run this command again!'));\n return;\n }\n\n spinner.succeed(`Found ${claudeSessions.length} sessions from the last 3 days`);\n logger.debug(`Found ${claudeSessions.length} Claude sessions`);\n\n // Prepare temp directory with session data\n const tempManager = new StandupTempManager();\n const yesterday = getYesterdayWorkingDay();\n\n // CRITICAL: Filter out today's sessions - only show PAST work\n // Use local date string to avoid timezone issues\n const today = new Date();\n const todayStr = getLocalDateString(today);\n const pastSessions = claudeSessions.filter(s =>\n getLocalDateString(s.timestamp) !== todayStr\n );\n\n // If no past sessions, show \"nothing\" message\n if (pastSessions.length === 0) {\n spinner.succeed('All sessions are from today - no past work to report');\n console.log(chalk.yellow('\\nNo completed work to report yet.'));\n console.log(chalk.gray('Come back tomorrow to see today\\'s standup summary!'));\n return;\n }\n\n // Find actual date with sessions (might not be yesterday)\n const yesterdayStr = getLocalDateString(yesterday);\n const yesterdaySessions = pastSessions.filter(s =>\n getLocalDateString(s.timestamp) === yesterdayStr\n );\n\n let actualTargetDate = yesterday;\n if (yesterdaySessions.length === 0) {\n // No sessions yesterday, find most recent PAST day with sessions\n const sortedSessions = pastSessions.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n if (sortedSessions.length > 0) {\n actualTargetDate = new Date(sortedSessions[0].timestamp);\n // Set to start of day to match date comparison\n actualTargetDate.setHours(0, 0, 0, 0);\n }\n }\n\n const tempDir = await tempManager.prepareTempDirectory(pastSessions, actualTargetDate);\n\n // Create the standup analysis prompt with actual date\n const standupPrompt = buildStandupPrompt(tempDir, actualTargetDate);\n\n // Check for Claude Code installation\n const claudeCheck = await checkClaudeInstalled();\n if (!claudeCheck.installed) {\n console.log(chalk.yellow('\\n⚠️ Claude Code is not installed'));\n console.log(chalk.gray('Using basic analysis instead...'));\n const standupData = await fallbackAnalysis(pastSessions, actualTargetDate);\n displayStandupSummary(standupData);\n\n // Clean up temp directory\n await tempManager.cleanup();\n return;\n }\n\n // Show analysis is starting\n console.log();\n console.log(chalk.cyan('🤖 Analyzing your work with Claude Code...'));\n\n // Show accurate count for actual target date\n const actualDateStr = getLocalDateString(actualTargetDate);\n const actualSessions = pastSessions.filter(s =>\n getLocalDateString(s.timestamp) === actualDateStr\n );\n\n const actualSessionsByProject = groupSessionsByProject(actualSessions);\n console.log(chalk.gray(`📁 Analyzing ${actualSessions.length} sessions from ${Object.keys(actualSessionsByProject).length} projects (${actualTargetDate.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' })})`));\n console.log();\n\n // Start rotating productivity tips during analysis\n const tipsDisplay = new RotatingTipsWithHeader(\n 'While we analyze your sessions, here are some productivity tips:',\n );\n tipsDisplay.start(6000); // Rotate tips every 6 seconds for better readability\n\n // Execute Claude to analyze the sessions\n let standupData: StandupData | null = null;\n\n const claudeMessages: string[] = [];\n\n try {\n await executeClaude(standupPrompt, {\n systemPrompt: getClaudeSystemPrompt(),\n cwd: tempDir, // Use temp directory so Claude can access the session files\n claudePath: claudeCheck.path, // Use the found Claude path\n onStreamEvent: (event) => {\n // Capture what Claude is saying\n if (event.type === 'assistant' && event.message?.content) {\n for (const content of event.message.content) {\n if (content.type === 'text' && content.text) {\n claudeMessages.push(content.text);\n logger.debug(`Claude says: ${content.text.substring(0, 200)}`);\n }\n }\n }\n },\n onComplete: async (code) => {\n logger.debug(`Claude execution completed with code: ${code}`);\n\n // Log what Claude actually said\n const fullOutput = claudeMessages.join('\\n');\n if (claudeMessages.length > 0) {\n logger.debug('Claude full output:', fullOutput);\n }\n\n if (code === 0 && fullOutput) {\n // Try to parse Claude's response as JSON using delimiters\n try {\n // Look for JSON between the delimiters\n const startDelimiter = '----JSON START----';\n const endDelimiter = '----JSON END----';\n\n const startIndex = fullOutput.indexOf(startDelimiter);\n const endIndex = fullOutput.indexOf(endDelimiter);\n\n if (startIndex !== -1 && endIndex !== -1 && startIndex < endIndex) {\n // Extract JSON between the delimiters\n const jsonStr = fullOutput.substring(\n startIndex + startDelimiter.length,\n endIndex\n ).trim();\n\n logger.debug(`Extracted JSON between delimiters: ${jsonStr.substring(0, 200)}`);\n standupData = JSON.parse(jsonStr);\n\n // Write the JSON to file for consistency\n const outputPath = path.join(tempDir, 'standup-output.json');\n await fs.writeFile(outputPath, JSON.stringify(standupData, null, 2));\n\n // Stop tips and show completion\n tipsDisplay.stop();\n console.log(chalk.green('\\n✓ Claude Code analysis complete!'));\n logger.debug('Successfully parsed standup data from Claude response');\n } else {\n tipsDisplay.stop();\n if (startIndex === -1) {\n logger.debug('JSON START delimiter not found in Claude response');\n }\n if (endIndex === -1) {\n logger.debug('JSON END delimiter not found in Claude response');\n }\n if (startIndex !== -1 && endIndex !== -1 && startIndex >= endIndex) {\n logger.debug(`Invalid delimiter positions: start=${startIndex}, end=${endIndex}`);\n }\n logger.debug(`Full Claude response for debugging: ${fullOutput}`);\n console.log(chalk.yellow('\\n⚠️ Claude did not return JSON with expected delimiters'));\n console.log(chalk.gray('Try running with --debug flag to see Claude\\'s full response'));\n }\n } catch (err) {\n tipsDisplay.stop();\n logger.debug(`Could not parse Claude output as JSON: ${err}`);\n console.log(chalk.yellow('\\n⚠️ Claude response was not valid JSON'));\n\n // Check if we at least found the delimiters\n const hasStartDelimiter = fullOutput.includes('----JSON START----');\n const hasEndDelimiter = fullOutput.includes('----JSON END----');\n\n if (hasStartDelimiter && hasEndDelimiter) {\n logger.debug('Delimiters found but JSON parsing failed');\n console.log(chalk.gray('JSON delimiters found but content was malformed'));\n } else {\n logger.debug(`Missing delimiters - Start: ${hasStartDelimiter}, End: ${hasEndDelimiter}`);\n }\n\n // Log the actual response for debugging\n if (fullOutput.length < 1000) {\n logger.debug(`Claude response: ${fullOutput}`);\n } else {\n logger.debug(`Claude response (truncated): ${fullOutput.substring(0, 1000)}...`);\n }\n }\n } else if (code !== 0) {\n tipsDisplay.stop();\n console.log(chalk.yellow('\\n⚠️ Claude analysis had an issue'));\n }\n }\n });\n } catch (error) {\n tipsDisplay.stop();\n logger.error('Failed to execute Claude:', error);\n console.log(chalk.yellow(`\\n⚠️ Could not run Claude: ${error instanceof Error ? error.message : 'Unknown error'}`));\n }\n\n // If no standup data was generated, use fallback\n if (!standupData) {\n logger.debug('No standup data generated, using fallback');\n standupData = await fallbackAnalysis(pastSessions, actualTargetDate);\n } else {\n // Calculate durations locally for consistency\n standupData = enrichWithLocalDurations(standupData, pastSessions, actualTargetDate);\n }\n\n // Clean up temp directory\n await tempManager.cleanup();\n\n // Display the standup summary\n if (standupData) {\n displayStandupSummary(standupData);\n } else {\n console.log(chalk.yellow('\\n⚠️ Could not generate standup summary'));\n console.log(chalk.gray('Please try again or check your Claude Code installation'));\n }\n\n } catch (error) {\n spinner.fail('Failed to generate standup summary');\n\n logger.error('Standup generation failed with error:', error);\n logger.error('Error stack:', error instanceof Error ? error.stack : 'No stack trace');\n\n if (error instanceof DevArkError) {\n throw error;\n }\n\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n throw new DevArkError(`Failed to generate standup summary: ${errorMessage}`, 'STANDUP_ERROR');\n }\n}\n\n// Helper functions moved to ../lib/standup-utils.ts\n// buildStandupPrompt also moved to standup-utils.ts\n\nasync function fallbackAnalysis(sessions: SessionData[], targetDate: Date): Promise<StandupData> {\n // Enhanced fallback analysis when Claude isn't available\n const yesterdayStr = getLocalDateString(targetDate);\n const todayStr = getLocalDateString(new Date());\n\n // CRITICAL: Filter out today's sessions to avoid showing current work\n const pastSessions = sessions.filter(s => {\n const sessionDate = getLocalDateString(s.timestamp);\n return sessionDate !== todayStr; // Exclude today's sessions\n });\n\n const yesterdaySessions = pastSessions.filter(s =>\n getLocalDateString(s.timestamp) === yesterdayStr\n );\n\n // If no work yesterday, find the most recent PAST work (not today)\n let recentSessions = yesterdaySessions;\n let actualDate = targetDate;\n\n if (yesterdaySessions.length === 0) {\n // Find the most recent day with work (excluding today)\n const sortedSessions = pastSessions.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n if (sortedSessions.length > 0) {\n actualDate = sortedSessions[0].timestamp;\n const recentDay = getLocalDateString(actualDate);\n recentSessions = pastSessions.filter(s =>\n getLocalDateString(s.timestamp) === recentDay\n );\n }\n }\n\n const projectWork = new Map<string, { sessions: SessionData[], duration: number }>();\n\n for (const session of recentSessions) {\n const projectName = extractProjectName(session.projectPath);\n if (!projectWork.has(projectName)) {\n projectWork.set(projectName, { sessions: [], duration: 0 });\n }\n const work = projectWork.get(projectName)!;\n work.sessions.push(session);\n // Use actual duration if available, otherwise estimate\n work.duration += session.duration || (session.messages.length * 120); // 2 minutes per message average\n }\n\n const projects = Array.from(projectWork.entries()).map(([name, work]) => {\n // Try to extract meaningful accomplishments from metadata\n const accomplishments: string[] = [];\n\n for (const session of work.sessions) {\n const fileCount = session.metadata?.files_edited || 0;\n const langs = session.metadata?.languages || [];\n\n // Try to create accomplishments based on available data\n if (fileCount > 0) {\n // Create accomplishment based on files and languages\n const langStr = langs.length > 0 ? langs.join(', ') : 'various files';\n accomplishments.push(`Modified ${fileCount} ${langStr} files`);\n } else {\n // Generic accomplishment based on session duration\n const minutes = Math.round(session.duration / 60);\n if (minutes > 30) {\n accomplishments.push(`Extended development session (${minutes} minutes)`);\n } else {\n accomplishments.push(`Quick fixes and updates (${minutes} minutes)`);\n }\n }\n }\n\n // Remove duplicates and limit to top 3\n const uniqueAccomplishments = Array.from(new Set(accomplishments)).slice(0, 3);\n\n // If we still don't have accomplishments, add generic ones\n if (uniqueAccomplishments.length === 0) {\n uniqueAccomplishments.push(`Development work on ${name}`);\n }\n\n const durationStr = formatDuration(work.duration);\n\n return {\n name,\n accomplishments: uniqueAccomplishments,\n duration: durationStr\n };\n });\n\n // Generate smarter suggestions based on recent activity patterns\n const allProjects = new Set<string>();\n const recentLanguages = new Set<string>();\n\n sessions.forEach(s => {\n allProjects.add(extractProjectName(s.projectPath));\n if (s.metadata?.languages) {\n s.metadata.languages.forEach(lang => recentLanguages.add(lang));\n }\n });\n\n const todayFocus: string[] = [];\n\n // Add project-specific focus\n if (projects.length > 0) {\n const topProject = projects[0].name;\n todayFocus.push(`Continue development on ${topProject}`);\n }\n\n // Add language/tech specific focus if detected\n if (recentLanguages.has('TypeScript') || recentLanguages.has('JavaScript')) {\n todayFocus.push('Complete pending TypeScript/JavaScript features');\n }\n\n // Add general development tasks\n if (sessions.some(s => s.metadata?.files_edited && s.metadata.files_edited > 10)) {\n todayFocus.push('Review and test recent changes');\n }\n\n // Add collaboration tasks if multiple projects\n if (allProjects.size > 2) {\n todayFocus.push('Sync with team on multi-project progress');\n }\n\n // Ensure we always have at least 2 focus items\n if (todayFocus.length < 2) {\n todayFocus.push('Address any outstanding pull request feedback');\n todayFocus.push('Update project documentation');\n }\n\n return {\n yesterday: {\n date: actualDate.toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'short',\n day: 'numeric'\n }),\n projects\n },\n todayFocus: todayFocus.slice(0, 3) // Limit to 3 focus items\n };\n}\n\nfunction displayStandupSummary(data: StandupData): void {\n console.log(chalk.cyan('\\n📋 Daily Standup Summary'));\n console.log(chalk.gray('═══════════════════════════════\\n'));\n\n // Yesterday's accomplishments\n console.log(chalk.yellow(`WHAT I ACCOMPLISHED (${data.yesterday.date})`));\n console.log(chalk.gray('─────────────────────────────'));\n\n if (data.yesterday.projects.length === 0) {\n console.log(chalk.gray(' No sessions recorded for this day'));\n console.log(chalk.dim(' (Check recent work in your project folders)\\n'));\n } else {\n for (const project of data.yesterday.projects) {\n console.log(chalk.white(`\\n ${chalk.bold(project.name)} ${chalk.gray(`(${project.duration})`)}`));\n\n for (const accomplishment of project.accomplishments) {\n console.log(chalk.gray(` • ${accomplishment}`));\n }\n }\n }\n\n // Today's focus\n console.log(chalk.yellow('\\n\\nSUGGESTED FOCUS FOR TODAY'));\n console.log(chalk.gray('─────────────────────────────'));\n\n if (data.todayFocus.length === 0) {\n console.log(chalk.gray(' No specific plans identified\\n'));\n } else {\n console.log();\n for (const item of data.todayFocus) {\n console.log(chalk.gray(` • ${item}`));\n }\n }\n\n // Blockers (if any)\n if (data.blockers && data.blockers.length > 0) {\n console.log(chalk.red('\\n\\nBLOCKERS'));\n console.log(chalk.gray('─────────────────────────────'));\n console.log();\n for (const blocker of data.blockers) {\n console.log(chalk.gray(` ⚠️ ${blocker}`));\n }\n }\n\n console.log(chalk.gray('\\n═══════════════════════════════'));\n console.log(chalk.yellow('\\n💡 Tip: Stop wasting tokens and time!'));\n console.log(chalk.cyan(' Switch to Cloud Mode for automated daily summaries!'));\n console.log();\n}\n\n/**\n * Get local date string (YYYY-MM-DD) from a Date object\n * Uses local timezone to avoid UTC conversion issues\n */\nfunction getLocalDateString(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\n/**\n * Normalize project name for comparison (lowercase, trim)\n */\nfunction normalizeProjectName(name: string): string {\n return name.toLowerCase().trim();\n}\n\n/**\n * Check if two project names match (case-insensitive, with substring matching)\n */\nfunction projectNamesMatch(name1: string, name2: string): boolean {\n const n1 = normalizeProjectName(name1);\n const n2 = normalizeProjectName(name2);\n return n1 === n2 || n1.includes(n2) || n2.includes(n1);\n}\n\n/**\n * Enrich standup data with locally calculated durations\n * This ensures consistent time reporting across runs\n */\nfunction enrichWithLocalDurations(\n standupData: StandupData,\n sessions: SessionData[],\n targetDate: Date\n): StandupData {\n // Filter sessions for the target date using LOCAL timezone\n const targetDateStr = getLocalDateString(targetDate);\n const targetSessions = sessions.filter(s =>\n getLocalDateString(s.timestamp) === targetDateStr\n );\n\n // Group sessions by project and handle parallel sessions\n const projectSessions = new Map<string, SessionData[]>();\n\n for (const session of targetSessions) {\n const projectName = extractProjectName(session.projectPath);\n if (!projectSessions.has(projectName)) {\n projectSessions.set(projectName, []);\n }\n projectSessions.get(projectName)!.push(session);\n }\n\n // Calculate durations with parallel session detection\n const projectDurations = new Map<string, number>();\n\n for (const [projectName, sessions] of projectSessions.entries()) {\n // Sort sessions by start time\n const sortedSessions = sessions.sort((a, b) =>\n a.timestamp.getTime() - b.timestamp.getTime()\n );\n\n let totalDuration = 0;\n let lastEndTime = 0;\n\n for (const session of sortedSessions) {\n const sessionStart = session.timestamp.getTime();\n const sessionEnd = sessionStart + (session.duration || 0) * 1000;\n\n if (sessionStart < lastEndTime) {\n // Sessions overlap - only count non-overlapping time\n const overlap = lastEndTime - sessionStart;\n const actualDuration = Math.max(0, (session.duration || 0) * 1000 - overlap);\n totalDuration += actualDuration / 1000;\n lastEndTime = Math.max(lastEndTime, sessionEnd);\n } else {\n // No overlap - count full duration\n totalDuration += session.duration || 0;\n lastEndTime = sessionEnd;\n }\n }\n\n projectDurations.set(projectName, totalDuration);\n }\n\n // Update the standup data with calculated durations\n // Try both exact and fuzzy matching for project names\n if (standupData.yesterday && standupData.yesterday.projects) {\n for (const project of standupData.yesterday.projects) {\n // First try exact match\n let totalSeconds = projectDurations.get(project.name);\n\n // If no exact match, try to find a similar project name (case-insensitive)\n if (totalSeconds === undefined) {\n // Check if Claude's project name matches any local project name\n for (const [localProjectName, duration] of projectDurations.entries()) {\n if (projectNamesMatch(localProjectName, project.name)) {\n totalSeconds = duration;\n logger.debug(`Matched Claude project \"${project.name}\" to local project \"${localProjectName}\"`);\n break;\n }\n }\n\n // If still no match, log for debugging\n if (totalSeconds === undefined) {\n logger.debug(`No duration found for project \"${project.name}\". Available projects: ${Array.from(projectDurations.keys()).join(', ')}`);\n totalSeconds = 0;\n }\n }\n\n project.duration = formatDuration(totalSeconds);\n }\n }\n\n // Also ensure any projects found locally but not in Claude's response are added\n // This handles cases where Claude might miss a project\n const claudeProjectNames = new Set(\n standupData.yesterday?.projects?.map(p => p.name) || []\n );\n\n for (const [localProjectName, duration] of projectDurations.entries()) {\n // Check if this project is missing from Claude's response (case-insensitive)\n let found = false;\n for (const claudeProject of claudeProjectNames) {\n if (projectNamesMatch(localProjectName, claudeProject)) {\n found = true;\n break;\n }\n }\n\n if (!found && duration > 0) {\n // Add the missing project to the standup data\n logger.debug(`Adding missing project \"${localProjectName}\" with duration ${duration} seconds`);\n if (!standupData.yesterday.projects) {\n standupData.yesterday.projects = [];\n }\n standupData.yesterday.projects.push({\n name: localProjectName,\n accomplishments: [`Development work on ${localProjectName}`],\n duration: formatDuration(duration)\n });\n }\n }\n\n return standupData;\n}","import inquirer from 'inquirer';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport { colors, padRight } from './styles';\nimport { formatDuration, createSpinner } from '../ui';\nimport { logger } from '../../utils/logger';\nimport { readClaudeSessions } from '../readers/claude';\nimport { formatRelativeTime, parseProjectName } from './project-display';\n\n/**\n * Session identifier information for memory-efficient passing\n * Instead of passing full session data, we pass identifiers to re-read later\n */\nexport interface SelectedSessionInfo {\n projectPath: string; // Claude folder path (e.g., ~/.claude/projects/-home-user-devark)\n sessionFile: string; // JSONL filename\n displayName: string; // Project name for UI display\n duration: number; // Duration in seconds for UI display\n timestamp: Date; // Session timestamp for UI display\n messageCount: number; // Number of messages for UI display\n}\n\ninterface SessionGroup {\n label: string;\n sessions: SessionInfo[];\n}\n\ninterface SessionInfo {\n projectPath: string;\n sessionFile: string;\n displayName: string;\n summary?: string; // Session title/summary if available\n duration: number;\n timestamp: Date;\n messageCount: number;\n timeRange: string;\n}\n\n/**\n * Show interactive session selector without requiring authentication\n * Reads sessions directly from ~/.claude/projects/\n * Returns session identifiers for memory-efficient processing\n */\nexport async function showSessionSelector(): Promise<SelectedSessionInfo[]> {\n const claudePath = path.join(os.homedir(), '.claude', 'projects');\n \n // Check if Claude directory exists\n try {\n await fs.access(claudePath);\n } catch {\n console.log(colors.warning('\\nNo Claude Code sessions found.'));\n console.log(colors.subdued('Make sure you have used Claude Code at least once.'));\n return [];\n }\n \n // Show spinner while loading sessions\n const spinner = createSpinner('Looking for Claude Code sessions...').start();\n \n try {\n // Read all available sessions\n const allSessions = await readAvailableSessions(claudePath);\n \n if (allSessions.length === 0) {\n spinner.fail(colors.warning('No sessions longer than 4 minutes found in the last 7 days.'));\n console.log(colors.subdued('Sessions must be at least 4 minutes long to be uploaded.'));\n return [];\n }\n \n spinner.succeed(colors.success(`Found Claude Code sessions`));\n console.log('');\n \n // Group sessions by time period\n const grouped = groupSessionsByTime(allSessions);\n \n // Show selection UI with better formatting\n const { selectionMode } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectionMode',\n message: 'How would you like to select sessions?',\n choices: [\n {\n name: `🕐 Analyze today's sessions (${getTodaySessionsInfo(grouped)})`,\n value: 'today',\n disabled: !hasTodaySessions(grouped) ? 'No sessions today' : false\n },\n {\n name: `🔍 Select specific sessions`,\n value: 'manual'\n },\n {\n name: `❌ Cancel`,\n value: 'cancel'\n }\n ]\n }\n ]);\n \n if (selectionMode === 'cancel') {\n return [];\n }\n \n if (selectionMode === 'today') {\n // Return all of today's sessions\n const todayGroup = grouped.find(g => g.label === 'Today');\n return todayGroup ? todayGroup.sessions : [];\n }\n \n // Manual selection mode\n return await selectSessionsManually(grouped);\n } catch (error) {\n spinner.fail(colors.error('Failed to load sessions'));\n logger.error('Error loading sessions:', error);\n return [];\n }\n}\n\n/**\n * Quick helper to select today's sessions only\n */\nexport async function selectTodaysSessions(): Promise<SelectedSessionInfo[]> {\n const claudePath = path.join(os.homedir(), '.claude', 'projects');\n \n try {\n await fs.access(claudePath);\n } catch {\n return [];\n }\n \n const spinner = createSpinner('Loading today\\'s sessions...').start();\n \n try {\n const allSessions = await readAvailableSessions(claudePath);\n const grouped = groupSessionsByTime(allSessions);\n const todayGroup = grouped.find(g => g.label === 'Today');\n \n if (todayGroup && todayGroup.sessions.length > 0) {\n spinner.succeed(colors.success(`Found ${todayGroup.sessions.length} sessions today (4+ minutes)`));\n } else {\n spinner.info(colors.subdued('No sessions longer than 4 minutes found today'));\n }\n \n return todayGroup ? todayGroup.sessions : [];\n } catch (error) {\n spinner.fail(colors.error('Failed to load sessions'));\n logger.error('Error loading today\\'s sessions:', error);\n return [];\n }\n}\n\n/**\n * Read all available sessions from Claude projects directory\n */\nasync function readAvailableSessions(_claudePath: string): Promise<SessionInfo[]> {\n const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\n const MIN_DURATION_SECONDS = 240; // 4 minutes minimum\n \n try {\n // Use the optimized reader with date filtering\n const claudeSessions = await readClaudeSessions({ since: sevenDaysAgo });\n \n // Filter out sessions shorter than 4 minutes\n const validSessions = claudeSessions.filter(session => session.duration >= MIN_DURATION_SECONDS);\n \n // Log if sessions were filtered\n const filteredCount = claudeSessions.length - validSessions.length;\n if (filteredCount > 0) {\n logger.debug(`Filtered out ${filteredCount} session(s) shorter than 4 minutes`);\n }\n \n // Convert SessionData to SessionInfo format\n const sessions: SessionInfo[] = validSessions.map(session => {\n // Extract display name from project path\n const displayName = parseProjectName(session.projectPath);\n \n // Calculate time range from messages\n let timeRange = '';\n if (session.messages.length > 0) {\n const firstMsg = session.messages[0];\n const lastMsg = session.messages[session.messages.length - 1];\n timeRange = `${firstMsg.timestamp.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}-${lastMsg.timestamp.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}`;\n }\n \n // Extract summary if available (would need to be added to SessionData if needed)\n // For now, we'll leave it undefined\n const summary = undefined;\n \n return {\n projectPath: session.sourceFile?.claudeProjectPath || '',\n sessionFile: session.sourceFile?.sessionFile || '',\n displayName,\n summary,\n duration: session.duration,\n timestamp: session.timestamp,\n messageCount: session.messages.length,\n timeRange\n };\n }).filter(s => s.projectPath && s.sessionFile); // Filter out any sessions without source info\n \n // Sort by timestamp, newest first\n return sessions.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n } catch (error) {\n logger.error('Error reading Claude sessions:', error);\n return [];\n }\n}\n\n/**\n * Group sessions by time period\n */\nfunction groupSessionsByTime(sessions: SessionInfo[]): SessionGroup[] {\n const now = new Date();\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);\n const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);\n \n const groups: SessionGroup[] = [\n { label: 'Today', sessions: [] },\n { label: 'Yesterday', sessions: [] },\n { label: 'Last 7 days', sessions: [] },\n { label: 'Older', sessions: [] }\n ];\n \n for (const session of sessions) {\n if (session.timestamp >= today) {\n groups[0].sessions.push(session);\n } else if (session.timestamp >= yesterday) {\n groups[1].sessions.push(session);\n } else if (session.timestamp >= weekAgo) {\n groups[2].sessions.push(session);\n } else {\n groups[3].sessions.push(session);\n }\n }\n \n // Filter out empty groups\n return groups.filter(g => g.sessions.length > 0);\n}\n\n/**\n * Get summary info for today's sessions\n */\nfunction getTodaySessionsInfo(groups: SessionGroup[]): string {\n const todayGroup = groups.find(g => g.label === 'Today');\n if (!todayGroup || todayGroup.sessions.length === 0) {\n return 'no sessions';\n }\n \n const sessionCount = todayGroup.sessions.length;\n \n return `${sessionCount} session${sessionCount !== 1 ? 's' : ''}`;\n}\n\n/**\n * Check if there are sessions today\n */\nfunction hasTodaySessions(groups: SessionGroup[]): boolean {\n const todayGroup = groups.find(g => g.label === 'Today');\n return todayGroup ? todayGroup.sessions.length > 0 : false;\n}\n\n/**\n * Manual session selection with checkboxes\n */\nasync function selectSessionsManually(groups: SessionGroup[]): Promise<SelectedSessionInfo[]> {\n const choices: any[] = [];\n \n for (const group of groups) {\n // Calculate group totals\n const totalDuration = group.sessions.reduce((sum, s) => sum + s.duration, 0);\n const sessionCount = group.sessions.length;\n const sessionText = sessionCount === 1 ? 'session' : 'sessions';\n \n // Add enhanced group separator with counts\n const groupHeader = `── ${group.label} (${sessionCount} ${sessionText}, ${formatDuration(totalDuration)}) ──`;\n choices.push(new inquirer.Separator(colors.accent(`\\n${groupHeader}`)));\n \n // Add table header for first group\n if (group === groups[0]) {\n const header = \n colors.dim(padRight('Created', 12)) +\n colors.dim(padRight('Duration', 10)) +\n colors.dim(padRight('Messages', 10)) +\n colors.dim('Project');\n choices.push(new inquirer.Separator(header));\n choices.push(new inquirer.Separator(colors.dim('─'.repeat(50))));\n }\n \n // Add sessions in group\n for (const session of group.sessions) {\n // Format as single-line table row\n const label = \n colors.subdued(padRight(formatRelativeTime(session.timestamp), 12)) +\n colors.accent(padRight(formatDuration(session.duration), 10)) +\n colors.dim(padRight(`${session.messageCount}`, 10)) +\n colors.primary(session.displayName);\n \n choices.push({\n name: label,\n value: session,\n checked: false\n });\n }\n }\n \n const { selected } = await inquirer.prompt({\n type: 'checkbox',\n name: 'selected',\n message: 'Select sessions to send (Space to select, Enter to confirm):',\n choices,\n pageSize: 15,\n loop: false,\n validate: (selections) => {\n if (Array.isArray(selections) && selections.length === 0) {\n return 'Please select at least one session';\n }\n return true;\n }\n });\n \n return selected;\n}","import inquirer from 'inquirer';\nimport { colors, icons, box } from './styles';\n\n/**\n * Display privacy notice and get user confirmation for cloud mode\n * Returns true if user accepts, false if they decline\n */\nexport async function showPrivacyNotice(): Promise<boolean> {\n console.clear();\n \n // Header\n console.log(colors.primary(box.doubleTopLeft + box.doubleHorizontal.repeat(58) + box.doubleTopRight));\n console.log(\n colors.primary(box.doubleVertical) + \n colors.highlight(' Setting up devark cloud mode... ') +\n colors.primary(box.doubleVertical)\n );\n console.log(colors.primary(box.tLeft + box.horizontal.repeat(58) + box.tRight));\n console.log('');\n \n // Advantages section\n console.log(colors.accent(' Cloud Mode Advantages:'));\n console.log(colors.success(` ${icons.check} Uses 0 tokens (our infrastructure)`));\n console.log(colors.success(` ${icons.check} Weekly recaps & Daily standup emails`));\n console.log(colors.success(` ${icons.check} Optimization insights & coaching plan`));\n console.log(colors.success(` ${icons.check} Interactive dashboard`));\n console.log('');\n \n // Privacy section\n console.log(colors.primary(box.tLeft + box.horizontal.repeat(58) + box.tRight));\n console.log('');\n console.log(colors.accent(' 🔒 Privacy Notice:'));\n console.log('');\n console.log(' We take privacy seriously, devark cloud will:');\n console.log(colors.success(` ${icons.check} Analyze sessions on our infrastructure`));\n console.log(colors.success(` ${icons.check} Your code and personal data never leaves your machine`));\n console.log('');\n console.log(colors.subdued(' Your code and sensitive information stay private.'));\n console.log('');\n console.log(colors.subdued(' Read our privacy policy: ') + colors.primary('https://devark.ai/privacy'));\n console.log('');\n console.log(colors.primary(box.bottomLeft + box.horizontal.repeat(58) + box.bottomRight));\n console.log('');\n \n // Confirmation prompt\n const { accept } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'accept',\n message: 'Accept and continue with cloud setup',\n default: true\n }\n ]);\n\n return accept;\n}\n\n/**\n * Show a brief privacy reminder (for users who have seen it before)\n */\nexport async function showPrivacyReminder(): Promise<boolean> {\n console.log('');\n console.log(colors.accent('🔒 Privacy Reminder:'));\n console.log(colors.subdued('• Cloud mode uses our infrastructure (0 tokens)'));\n console.log(colors.subdued('• We store anonymized metrics only'));\n console.log(colors.subdued('• Your code remains private'));\n console.log(colors.subdued('• Privacy policy: https://devark.ai/privacy'));\n console.log('');\n \n const { proceed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'proceed',\n message: 'Continue with cloud setup?',\n default: true\n }\n ]);\n \n return proceed;\n}","import inquirer from 'inquirer';\nimport { colors } from './styles';\nimport { auth } from '../../commands/auth';\nimport { sendWithTimeout } from '../../commands/send';\nimport { showSessionSelector, SelectedSessionInfo } from './session-selector';\nimport { showPrivacyPreview } from './privacy-preview';\nimport { MessageSanitizer } from '../message-sanitizer';\nimport { getDashboardUrl } from '../config';\nimport { displayError } from '../../utils/errors';\nimport { DevArkError } from '../../utils/errors';\nimport { isNetworkError } from '../errors/network-errors';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport open from 'open';\nimport chalk from 'chalk';\n\n/**\n * Helper function to show connection error help messages\n */\nfunction showConnectionErrorHelp(error: unknown): void {\n if (error instanceof DevArkError) {\n if (error.code === 'CONNECTION_REFUSED' || \n error.code === 'NETWORK_ERROR' ||\n error.code === 'SERVER_NOT_FOUND' ||\n error.code === 'CONNECTION_FAILED') {\n // Network errors are handled below\n }\n } else if (error instanceof Error && isNetworkError(error)) {\n console.log(chalk.red('\\n❌ Cannot connect to the server'));\n console.log(chalk.yellow('Please ensure the devark server is accessible.'));\n }\n}\n\n/**\n * Guided cloud setup flow for first-time users\n * NEW FLOW: Privacy Notice → Session Selection → Privacy Preview → Authentication → Upload\n * Users see privacy notice first, then see concrete sessions BEFORE being asked to authenticate\n */\nexport async function guidedCloudSetup(): Promise<void> {\n // Get version for logo display\n const pkg = require('../../../package.json');\n const version = process.env.SIMULATE_OLD_VERSION || pkg.version;\n\n // Step 0: Show privacy notice first\n console.clear();\n const { showLogo } = await import('../ui');\n await showLogo(version);\n\n const { showPrivacyNotice } = await import('./privacy-notice');\n const accepted = await showPrivacyNotice();\n\n if (!accepted) {\n console.log(colors.warning('\\nSetup cancelled.'));\n console.log(colors.subdued('You can set up cloud mode later from the main menu.'));\n return;\n }\n\n // Step 1: Session Selection (NO AUTH REQUIRED)\n console.clear();\n await showLogo(version);\n console.log(colors.accent('\\n👀 Step 1: Let\\'s See What You\\'ve Been Building\\n'));\n\n console.log(colors.primary('Take a peek at your recent Claude Code sessions - no commitment required.'));\n console.log(colors.subdued('Browse freely! We\\'ll only ask for authentication if you decide to proceed.\\n'));\n \n // Show session selector - works without auth\n const selectedSessions = await showSessionSelector();\n \n if (selectedSessions.length === 0) {\n console.log(colors.warning('\\n⚠ No sessions selected'));\n console.log(colors.subdued('You can set up cloud mode later when you have sessions to analyze.'));\n return;\n }\n \n console.log(colors.success(`\\n✓ ${selectedSessions.length} session(s) selected`));\n \n // Step 2: Privacy Preview - Show what will be redacted\n console.clear();\n await showLogo(version);\n console.log(colors.accent('\\n🔒 Step 2: Privacy Preview\\n'));\n \n console.log(colors.primary('Your code never leaves your machine - we only analyze patterns and redacted metadata.'));\n console.log(colors.subdued('This is open source - you can verify exactly what we redact. Your actual code stays private.\\n'));\n \n // Process sessions to show redaction preview\n const apiSessions = await processSessionsForPreview(selectedSessions);\n \n // Show privacy preview with actual redaction counts and session context\n const proceed = await showPrivacyPreview(apiSessions, selectedSessions);\n \n if (!proceed) {\n console.log(colors.warning('\\nSetup cancelled.'));\n console.log(colors.subdued('Your sessions remain on your local machine.'));\n return;\n }\n \n // Step 3: Just-in-time Authentication\n console.clear();\n await showLogo(version);\n console.log(colors.accent('\\n🔐 Step 3: Authentication\\n'));\n \n console.log(colors.primary('Now we need to authenticate to upload your sessions.'));\n console.log(colors.subdued('This is a one-time setup using your GitHub account.\\n'));\n \n console.log(colors.info('Authenticating with GitHub...'));\n \n try {\n await auth({ wizardMode: true });\n } catch (error) {\n // Display the actual error details\n displayError(error);\n \n // Show connection-specific help if applicable\n showConnectionErrorHelp(error);\n \n // Pause so user can read the error\n console.log('Press Enter to continue...');\n await inquirer.prompt([{ type: 'input', name: 'continue', message: '' }]);\n \n return;\n }\n \n // Step 4: Upload Sessions\n console.clear();\n await showLogo(version);\n console.log(colors.accent('\\n📤 Uploading Your Sessions\\n'));\n \n // Show privacy processing message\n console.log(colors.dim('Preparing sessions for privacy-safe upload...'));\n \n // Use the send command with selected sessions, skipping the action menu since we already confirmed\n try {\n await sendWithTimeout({ selectedSessions, skipActionMenu: true });\n \n // Show dashboard link after successful upload\n console.log('');\n console.log(colors.primary('🎉 Your sessions have been uploaded successfully!'));\n console.log('');\n console.log(colors.accent('Your AI analysis is now processing. You can view insights at:'));\n console.log(colors.primary(getDashboardUrl()));\n console.log('');\n \n // Prompt to view dashboard\n const { viewDashboard } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'viewDashboard',\n message: 'Would you like to view your dashboard? (Y/n)',\n default: true,\n },\n ]);\n \n if (viewDashboard) {\n console.log(colors.info('Opening dashboard in your browser...'));\n await open(getDashboardUrl());\n console.log('');\n console.log(colors.subdued('Take a moment to explore your productivity insights!'));\n console.log('');\n \n // Brief pause to let user see the message\n await new Promise(resolve => setTimeout(resolve, 2000));\n }\n \n // After dashboard viewing, offer hooks setup\n const { setupHooks } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'setupHooks',\n message: 'Would you like to enable automatic session sync?',\n default: true,\n },\n ]);\n \n if (setupHooks) {\n console.clear();\n await showLogo(version);\n console.log(colors.accent('\\n🔧 Optional: Configure Auto-sync\\n'));\n \n const hooksInstalled = await showHooksManagementMenuGuided();\n \n if (hooksInstalled) {\n console.log(colors.success('\\n✓ Auto-sync enabled!'));\n console.log(colors.subdued('Your future Claude Code sessions will be automatically synced.'));\n } else {\n console.log(colors.muted('\\n○ Auto-sync skipped'));\n console.log(colors.subdued('You can enable this later from the main menu.'));\n }\n }\n } catch (error) {\n // Display detailed error information\n displayError(error);\n \n // Show connection-specific help if applicable\n showConnectionErrorHelp(error);\n \n console.log(colors.subdued('\\nYou can try again from the main menu after resolving the issue.'));\n \n // Pause so user can read the error\n console.log('Press Enter to continue...');\n await inquirer.prompt([{ type: 'input', name: 'continue', message: '' }]);\n \n return;\n }\n \n // Final success message\n console.clear();\n await showLogo(version);\n console.log(colors.success('\\n🎉 Cloud Setup Complete!\\n'));\n \n console.log(colors.primary('Your devark is now active!'));\n console.log('');\n console.log(colors.success(' ✓ Sessions uploaded and being analyzed'));\n console.log(colors.success(' ✓ Dashboard ready with your productivity insights'));\n console.log(colors.success(' ✓ Cloud authentication successful'));\n \n console.log('');\n console.log(colors.accent('Dashboard URL:'));\n console.log(colors.primary(getDashboardUrl()));\n console.log('');\n console.log(colors.subdued('Press Enter to continue...'));\n await inquirer.prompt([{ type: 'input', name: 'continue', message: '' }]);\n \n // Return control to the calling function (main-menu.ts will handle the menu)\n}\n\n/**\n * Process selected sessions to generate API format for preview\n * Re-reads the session files and sanitizes them for privacy preview\n */\nasync function processSessionsForPreview(selectedInfo: SelectedSessionInfo[]): Promise<any[]> {\n const sanitizer = new MessageSanitizer();\n const apiSessions = [];\n \n for (const info of selectedInfo) {\n try {\n const filePath = path.join(info.projectPath, info.sessionFile);\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.trim().split('\\n');\n \n const messages: any[] = [];\n let metadata: any = null;\n \n // Parse session file to extract messages\n for (const line of lines) {\n if (!line.trim()) continue;\n \n try {\n const data = JSON.parse(line);\n \n // Extract metadata from first valid entry\n if (!metadata && data.sessionId) {\n metadata = {\n sessionId: data.sessionId,\n cwd: data.cwd,\n timestamp: data.timestamp,\n };\n }\n \n // Collect messages\n if (data.message) {\n messages.push({\n role: data.message.role,\n content: data.message.content,\n timestamp: data.timestamp,\n });\n }\n } catch {\n // Skip invalid JSON lines\n }\n }\n \n // Sanitize messages for privacy\n const sanitizedMessages = sanitizer.sanitizeMessages(messages);\n \n // Create API session format\n apiSessions.push({\n tool: 'claude',\n timestamp: info.timestamp.toISOString(),\n duration: info.duration,\n data: {\n projectName: info.displayName,\n messageSummary: JSON.stringify(sanitizedMessages),\n messageCount: messages.length,\n },\n });\n } catch (error) {\n // Skip sessions that can't be read\n console.log(colors.warning(`Failed to process session: ${info.sessionFile}`));\n }\n }\n \n return apiSessions;\n}\n\n/**\n * Show hooks management in guided mode\n */\nasync function showHooksManagementMenuGuided(): Promise<boolean> {\n const { showHooksManagementMenu: showHooks } = await import('./hooks-menu');\n const result = await showHooks(true); // Pass guided mode flag\n return result ?? false; // Default to false if void\n}","import inquirer from 'inquirer';\nimport { colors, box } from './styles';\nimport { setCustomPersonality, getStatusLinePersonality } from '../config';\nimport { showSuccess, showInfo } from '../ui';\nimport { logger } from '../../utils/logger';\n\n/**\n * Display educational information about custom personalities\n */\nfunction displayEducationalHeader(): void {\n console.log(colors.accent('\\n✨ Create Custom Personality\\n'));\n \n console.log(colors.subdued('Define your own unique coaching style!\\n'));\n \n console.log(colors.info('Examples of Custom Personalities:'));\n console.log(colors.subdued(' • Yoda - \"Wisdom in your prompts, you must have\"'));\n console.log(colors.subdued(' • Morpheus - \"Your prompt shows you the door, details open it\"'));\n console.log(colors.subdued(' • Bob Ross - \"Happy little contexts make beautiful prompts\"'));\n console.log(colors.subdued(' • Socrates - \"What is a prompt without self-examination?\"'));\n console.log('');\n \n console.log(colors.info('How it works:'));\n console.log(colors.subdued(' 1. Choose a name for your personality'));\n console.log(colors.subdued(' 2. Describe how it should critique prompts'));\n console.log(colors.subdued(' 3. Optionally define custom templates'));\n console.log(colors.subdued(' 4. Your personality will transform feedback accordingly'));\n console.log('');\n \n console.log(box.horizontal.repeat(60));\n console.log('');\n}\n\n/**\n * Get example templates for a personality style\n */\nfunction getExampleTemplates(name: string, style: string): {\n poor: string;\n fair: string;\n good: string;\n excellent: string;\n} {\n // Generate contextual examples based on the personality\n const lowerName = name.toLowerCase();\n const lowerStyle = style.toLowerCase();\n \n // Check for specific known personalities\n if (lowerName.includes('yoda') || lowerStyle.includes('yoda')) {\n return {\n poor: 'Much to learn, you have. Context, missing it is!',\n fair: 'Progress, I see. But complete, your prompt is not.',\n good: 'Strong with the Force, this prompt is. Polish it, you must.',\n excellent: 'Mastery achieved, you have! Proud, I am!'\n };\n }\n \n if (lowerName.includes('morpheus') || lowerStyle.includes('matrix')) {\n return {\n poor: 'You think that\\'s a prompt you\\'re writing? Add reality!',\n fair: 'You\\'re beginning to believe. Now see the whole Matrix.',\n good: 'You\\'re the One... just need to dodge those edge cases.',\n excellent: 'Welcome to the real world. This prompt has no spoon!'\n };\n }\n \n if (lowerName.includes('bob ross') || lowerStyle.includes('painting')) {\n return {\n poor: 'We need a happy foundation. Let\\'s add some context trees!',\n fair: 'Looking nice! Now let\\'s blend in some details.',\n good: 'Beautiful work! Just needs a touch of titanium white.',\n excellent: 'A masterpiece! Every prompt needs a friend like this!'\n };\n }\n \n // Default templates with placeholder for custom personality\n return {\n poor: `${name} says: This needs work - add more context!`,\n fair: `${name} says: Getting better - keep adding details!`,\n good: `${name} says: Good work - almost there!`,\n excellent: `${name} says: Excellent! Perfect prompting!`\n };\n}\n\n/**\n * Create a custom personality through interactive prompts\n */\nexport async function createCustomPersonality(): Promise<void> {\n console.clear();\n displayEducationalHeader();\n\n try {\n // Step 1: Get personality name\n const { name } = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'What should we call your personality?',\n validate: (input: string) => {\n if (!input.trim()) {\n return 'Please enter a name';\n }\n if (input.length > 20) {\n return 'Name should be 20 characters or less';\n }\n return true;\n }\n }\n ]);\n\n console.log('');\n\n // Step 2: Get personality style description\n const { description } = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: 'How should this personality critique prompts?',\n default: `Like ${name} would speak`,\n validate: (input: string) => {\n if (!input.trim()) {\n return 'Please describe the personality style';\n }\n if (input.length > 100) {\n return 'Description should be 100 characters or less';\n }\n return true;\n }\n }\n ]);\n\n console.log('');\n\n // Step 3: Ask if they want custom templates\n const { wantsTemplates } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'wantsTemplates',\n message: 'Would you like to define custom feedback templates?',\n default: false\n }\n ]);\n\n let templates;\n if (wantsTemplates) {\n console.log('');\n console.log(colors.info('Define feedback for different score ranges:'));\n console.log(colors.subdued('(Press Enter to use suggested templates)\\n'));\n\n const examples = getExampleTemplates(name, description);\n\n // Get templates for each score range\n const templatePrompts = await inquirer.prompt([\n {\n type: 'input',\n name: 'poor',\n message: 'Poor (0-40):',\n default: examples.poor,\n validate: (input: string) => input.length <= 100 || 'Keep it under 100 characters'\n },\n {\n type: 'input',\n name: 'fair',\n message: 'Fair (41-60):',\n default: examples.fair,\n validate: (input: string) => input.length <= 100 || 'Keep it under 100 characters'\n },\n {\n type: 'input',\n name: 'good',\n message: 'Good (61-80):',\n default: examples.good,\n validate: (input: string) => input.length <= 100 || 'Keep it under 100 characters'\n },\n {\n type: 'input',\n name: 'excellent',\n message: 'Excellent (81-100):',\n default: examples.excellent,\n validate: (input: string) => input.length <= 100 || 'Keep it under 100 characters'\n }\n ]);\n\n templates = templatePrompts;\n }\n\n console.log('');\n console.log(box.horizontal.repeat(60));\n console.log('');\n \n // Preview the personality\n console.log(colors.highlight('Preview Your Personality:'));\n console.log('');\n console.log(`${colors.accent('Name:')} ${name}`);\n console.log(`${colors.accent('Style:')} ${description}`);\n \n if (templates) {\n console.log('');\n console.log(colors.accent('Sample Feedback:'));\n console.log(colors.dim(` Poor: \"${templates.poor}\"`));\n console.log(colors.dim(` Fair: \"${templates.fair}\"`));\n console.log(colors.dim(` Good: \"${templates.good}\"`));\n console.log(colors.dim(` Excellent: \"${templates.excellent}\"`));\n } else {\n console.log('');\n console.log(colors.subdued('AI will generate feedback in this personality style'));\n }\n \n console.log('');\n console.log(box.horizontal.repeat(60));\n console.log('');\n\n // Confirm creation\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Create this personality?',\n default: true\n }\n ]);\n\n if (!confirm) {\n console.log(colors.muted('\\nPersonality creation cancelled'));\n return;\n }\n\n // Save the custom personality\n setCustomPersonality({\n name,\n description,\n templates\n });\n\n console.log('');\n showSuccess(`Custom personality \"${name}\" created and activated!`);\n console.log('');\n console.log(colors.primary('✨ Your custom personality is now active!'));\n console.log(colors.dim(' The status line will now use this personality'));\n console.log(colors.dim(' You can switch personalities anytime from the menu'));\n console.log('');\n \n } catch (error) {\n console.log('');\n logger.error('Failed to create custom personality:', error);\n showInfo('Personality creation cancelled');\n }\n}\n\n/**\n * Edit existing custom personality\n */\nexport async function editCustomPersonality(): Promise<void> {\n const config = getStatusLinePersonality();\n \n if (!config.customPersonality) {\n console.log('');\n showInfo('No custom personality found. Create one first!');\n return;\n }\n\n console.clear();\n console.log(colors.accent('\\n📝 Edit Custom Personality\\n'));\n \n // Show current personality\n console.log(colors.info('Current Personality:'));\n console.log(` ${colors.accent('Name:')} ${config.customPersonality.name}`);\n console.log(` ${colors.accent('Style:')} ${config.customPersonality.description}`);\n \n if (config.customPersonality.templates) {\n console.log('');\n console.log(colors.info('Current Templates:'));\n console.log(colors.dim(` Poor: \"${config.customPersonality.templates.poor}\"`));\n console.log(colors.dim(` Fair: \"${config.customPersonality.templates.fair}\"`));\n console.log(colors.dim(` Good: \"${config.customPersonality.templates.good}\"`));\n console.log(colors.dim(` Excellent: \"${config.customPersonality.templates.excellent}\"`));\n }\n \n console.log('');\n console.log(box.horizontal.repeat(60));\n console.log('');\n\n // Ask what to edit\n const { editChoice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'editChoice',\n message: 'What would you like to edit?',\n choices: [\n { name: 'Edit Name & Style', value: 'basic' },\n { name: 'Edit Templates', value: 'templates' },\n { name: 'Replace Everything', value: 'replace' },\n { name: '← Cancel', value: 'cancel' }\n ]\n }\n ]);\n\n if (editChoice === 'cancel') {\n return;\n }\n\n if (editChoice === 'replace') {\n await createCustomPersonality();\n return;\n }\n\n if (editChoice === 'basic') {\n const updates = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Personality name:',\n default: config.customPersonality.name,\n validate: (input: string) => {\n if (!input.trim()) return 'Please enter a name';\n if (input.length > 20) return 'Name should be 20 characters or less';\n return true;\n }\n },\n {\n type: 'input',\n name: 'description',\n message: 'Personality style:',\n default: config.customPersonality.description,\n validate: (input: string) => {\n if (!input.trim()) return 'Please describe the personality style';\n if (input.length > 100) return 'Description should be 100 characters or less';\n return true;\n }\n }\n ]);\n\n setCustomPersonality({\n ...config.customPersonality,\n ...updates\n });\n\n console.log('');\n showSuccess('Personality updated successfully!');\n }\n\n if (editChoice === 'templates') {\n const currentTemplates = config.customPersonality.templates || \n getExampleTemplates(config.customPersonality.name, config.customPersonality.description);\n\n const newTemplates = await inquirer.prompt([\n {\n type: 'input',\n name: 'poor',\n message: 'Poor (0-40):',\n default: currentTemplates.poor,\n validate: (input: string) => input.length <= 100 || 'Keep it under 100 characters'\n },\n {\n type: 'input',\n name: 'fair',\n message: 'Fair (41-60):',\n default: currentTemplates.fair,\n validate: (input: string) => input.length <= 100 || 'Keep it under 100 characters'\n },\n {\n type: 'input',\n name: 'good',\n message: 'Good (61-80):',\n default: currentTemplates.good,\n validate: (input: string) => input.length <= 100 || 'Keep it under 100 characters'\n },\n {\n type: 'input',\n name: 'excellent',\n message: 'Excellent (81-100):',\n default: currentTemplates.excellent,\n validate: (input: string) => input.length <= 100 || 'Keep it under 100 characters'\n }\n ]);\n\n setCustomPersonality({\n ...config.customPersonality,\n templates: newTemplates\n });\n\n console.log('');\n showSuccess('Templates updated successfully!');\n }\n}","import inquirer from 'inquirer';\nimport ora from 'ora';\nimport { colors, box } from './styles';\nimport { \n getStatusLinePersonality,\n getPersonalityDisplayName,\n getPersonalityIcon,\n getPersonalitySystemPrompt\n} from '../personality-manager';\nimport { showInfo } from '../ui';\nimport { \n runPersonalityTest,\n STANDARD_TEST_PROMPTS\n} from '../personality-test-engine';\nimport { PromptAnalyzer } from '../prompt-analyzer';\n\n/**\n * Display personality details header\n */\nfunction displayPersonalityHeader(): void {\n const config = getStatusLinePersonality();\n const name = getPersonalityDisplayName(config.personality);\n const icon = getPersonalityIcon(config.personality);\n \n console.log(colors.accent('\\n🧪 Testing Personality System\\n'));\n console.log(`Active Personality: ${icon} ${colors.highlight(name)}`);\n \n // Show custom personality details if applicable\n if (config.personality === 'custom' && config.customPersonality) {\n console.log(colors.subdued(`Custom Name: ${config.customPersonality.name}`));\n console.log(colors.subdued(`Style: ${config.customPersonality.description}`));\n \n if (config.customPersonality.templates) {\n console.log('');\n console.log(colors.info('Custom Templates Defined:'));\n console.log(colors.subdued(' ✓ Templates for all score ranges'));\n }\n }\n \n console.log('');\n console.log(box.horizontal.repeat(60));\n console.log('');\n}\n\n/**\n * Test with sample prompts using real Claude SDK\n */\nasync function testSamplePrompts(): Promise<void> {\n console.log(colors.info('Testing with Claude AI (Real Analysis):\\n'));\n console.log(colors.subdued('This will make actual calls to your local Claude Code...\\n'));\n \n const config = getStatusLinePersonality();\n const personalityIcon = getPersonalityIcon(config.personality);\n \n // Create spinner\n const spinner = ora({\n text: 'Initializing Claude SDK...',\n color: 'cyan'\n });\n \n try {\n // Run tests with real Claude\n spinner.start();\n const results = await runPersonalityTest(STANDARD_TEST_PROMPTS, {\n verbose: false,\n personality: config.personality,\n onProgress: (message) => {\n spinner.text = message;\n }\n });\n spinner.stop();\n \n // Display results\n for (const result of results) {\n console.log(`${result.emoji} ${colors.accent(result.aiQuality.charAt(0).toUpperCase() + result.aiQuality.slice(1))} (${result.aiScore}/100)`);\n console.log(colors.subdued(` Prompt: \"${result.prompt.substring(0, 50)}${result.prompt.length > 50 ? '...' : ''}\"`));\n console.log(colors.subdued(` Context: ${result.promptDescription}`));\n console.log('');\n \n if (result.error) {\n console.log(colors.error(` Error: ${result.error}`));\n } else {\n console.log(colors.info(' Claude\\'s Analysis:'));\n console.log(colors.subdued(` Original: \"${result.aiSuggestion}\"`));\n console.log('');\n console.log(colors.info(' With Personality:'));\n console.log(` ${personalityIcon} ${result.emoji} ${result.aiScore}/100 | ${result.personalityTransformed}`);\n console.log('');\n console.log(colors.dim(` Processing time: ${(result.processingTime / 1000).toFixed(1)}s`));\n }\n \n console.log('');\n console.log(box.horizontal.repeat(60));\n console.log('');\n }\n \n // Summary\n const successCount = results.filter(r => !r.error).length;\n const totalTime = results.reduce((sum, r) => sum + r.processingTime, 0);\n \n console.log(colors.success(`✅ Completed ${successCount}/${results.length} tests`));\n console.log(colors.dim(`Total time: ${(totalTime / 1000).toFixed(1)}s`));\n \n } catch (error) {\n spinner.stop();\n console.log(colors.error('\\n❌ Test failed:'), error);\n }\n}\n\n/**\n * Test with custom prompt using real Claude SDK\n */\nasync function testCustomPrompt(): Promise<void> {\n console.log(colors.info('Test with Your Own Prompt:\\n'));\n \n const { customPrompt } = await inquirer.prompt([\n {\n type: 'input',\n name: 'customPrompt',\n message: 'Enter a test prompt:',\n validate: (input: string) => {\n if (!input.trim()) {\n return 'Please enter a prompt to test';\n }\n return true;\n }\n }\n ]);\n \n console.log('');\n \n const config = getStatusLinePersonality();\n const personalityIcon = getPersonalityIcon(config.personality);\n \n // Create spinner\n const spinner = ora({\n text: 'Analyzing with Claude...',\n color: 'cyan'\n }).start();\n \n try {\n // Analyze with real Claude\n const analyzer = new PromptAnalyzer();\n const startTime = Date.now();\n \n const analysis = await analyzer.analyze(customPrompt, {\n verbose: false,\n timeout: 15000\n });\n \n const processingTime = Date.now() - startTime;\n spinner.stop();\n \n // Get personality transformation\n const transformed = analysis.suggestion; // This already has personality applied from the analyzer\n \n // Display results\n const emoji = analysis.score <= 40 ? '🔴' : analysis.score <= 60 ? '🟠' : analysis.score <= 80 ? '🟡' : '🟢';\n const quality = analysis.quality.charAt(0).toUpperCase() + analysis.quality.slice(1);\n \n console.log(`${emoji} ${colors.accent(quality)} (${analysis.score}/100)`);\n console.log('');\n console.log(colors.info('Claude\\'s Analysis:'));\n console.log(colors.subdued(` Original: \"${analysis.suggestion}\"`));\n console.log('');\n console.log(colors.info('Status Line Will Show:'));\n console.log(`${personalityIcon} ${emoji} ${analysis.score}/100 | ${transformed}`);\n console.log('');\n console.log(colors.dim(`Processing time: ${(processingTime / 1000).toFixed(1)}s`));\n console.log('');\n \n } catch (error) {\n spinner.stop();\n console.log(colors.error('\\n❌ Analysis failed:'), error);\n }\n}\n\n/**\n * Show system prompt for verification\n */\nfunction showSystemPrompt(): void {\n console.log(colors.info('System Prompt Being Sent to Claude:\\n'));\n \n const systemPrompt = getPersonalitySystemPrompt();\n \n if (systemPrompt) {\n console.log(colors.subdued(systemPrompt));\n } else {\n console.log(colors.subdued('(No personality-specific system prompt - using default)'));\n }\n \n console.log('');\n}\n\n/**\n * Main interactive personality tester\n */\nexport async function interactivePersonalityTester(): Promise<void> {\n console.clear();\n displayPersonalityHeader();\n \n // Show system prompt for custom personalities\n const config = getStatusLinePersonality();\n if (config.personality === 'custom') {\n showSystemPrompt();\n console.log(box.horizontal.repeat(60));\n console.log('');\n }\n \n console.log(colors.warning('⚠️ Tests will make real calls to your local Claude Code SDK\\n'));\n \n let shouldContinue = true;\n \n while (shouldContinue) {\n const { testChoice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'testChoice',\n message: 'What would you like to test?',\n choices: [\n {\n name: '🤖 Test with sample prompts (4 calls to Claude Code)',\n value: 'samples'\n },\n {\n name: '✍️ Test with your own prompt (1 call to Claude Code)',\n value: 'custom'\n },\n {\n name: '🔍 Show system prompt details',\n value: 'system'\n },\n new inquirer.Separator(),\n {\n name: '← Back to personality menu',\n value: 'back'\n }\n ]\n }\n ]);\n \n console.log('');\n \n switch (testChoice) {\n case 'samples':\n await testSamplePrompts();\n await promptToContinue();\n console.clear();\n displayPersonalityHeader();\n break;\n \n case 'custom':\n await testCustomPrompt();\n await promptToContinue();\n console.clear();\n displayPersonalityHeader();\n break;\n \n case 'system':\n showSystemPrompt();\n await promptToContinue();\n console.clear();\n displayPersonalityHeader();\n break;\n \n case 'back':\n shouldContinue = false;\n break;\n }\n }\n \n // Summary\n console.log(colors.success('\\n✅ Personality Test Complete!\\n'));\n \n const personality = getPersonalityDisplayName(config.personality);\n console.log(colors.subdued(`The ${personality} personality is active and working.`));\n \n if (config.personality === 'custom') {\n console.log(colors.subdued('Your custom personality templates are being applied.'));\n console.log(colors.subdued('The personality style is included in Claude\\'s system prompt.'));\n }\n \n console.log('');\n showInfo('The status line will use this personality for all prompts');\n}\n\n/**\n * Wait for user to continue\n */\nasync function promptToContinue(): Promise<void> {\n console.log('');\n await inquirer.prompt({\n type: 'input',\n name: 'continue',\n message: 'Press Enter to continue...',\n default: ''\n });\n}","/**\n * CCUsage Configuration Manager\n * Manages the integration of ccusage metrics with devark statusline\n */\n\nimport { logger } from '../utils/logger';\nimport { readGlobalSettings, writeGlobalSettings } from './claude-settings-reader';\n\nexport interface CCUsageConfig {\n enabled: boolean;\n lastChecked?: Date;\n version?: string;\n}\n\n/**\n * Get the current ccusage configuration\n */\nexport async function getCCUsageConfig(): Promise<CCUsageConfig> {\n try {\n const settings = await readGlobalSettings();\n \n // Check if ccusage is enabled in the statusline command\n const statusLineCommand = settings?.statusLine?.command || '';\n const isEnabled = statusLineCommand.includes('--with-usage');\n \n return {\n enabled: isEnabled,\n lastChecked: new Date()\n };\n } catch (error) {\n logger.error('Error getting ccusage config:', error);\n return {\n enabled: false\n };\n }\n}\n\n/**\n * Enable ccusage integration\n */\nexport async function enableCCUsage(): Promise<void> {\n try {\n logger.debug('Enabling ccusage integration');\n \n const settings = await readGlobalSettings();\n if (!settings) {\n throw new Error('No settings found');\n }\n \n // Update the statusline command to include --with-usage\n if (settings.statusLine?.command) {\n const baseCommand = settings.statusLine.command.replace(/ --with-usage.*$/, '');\n settings.statusLine.command = `${baseCommand} --with-usage`;\n \n await writeGlobalSettings(settings);\n logger.debug('ccusage integration enabled');\n } else {\n throw new Error('Status line not installed');\n }\n } catch (error) {\n logger.error('Error enabling ccusage:', error);\n throw new Error(`Failed to enable ccusage: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Disable ccusage integration\n */\nexport async function disableCCUsage(): Promise<void> {\n try {\n logger.debug('Disabling ccusage integration');\n \n const settings = await readGlobalSettings();\n if (!settings) {\n throw new Error('No settings found');\n }\n \n // Remove --with-usage flag from statusline command\n if (settings.statusLine?.command) {\n settings.statusLine.command = settings.statusLine.command.replace(/ --with-usage.*$/, '');\n \n await writeGlobalSettings(settings);\n logger.debug('ccusage integration disabled');\n }\n } catch (error) {\n logger.error('Error disabling ccusage:', error);\n throw new Error(`Failed to disable ccusage: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n","import inquirer from 'inquirer';\nimport { colors, box } from './styles';\nimport {\n getStatusLineStatus,\n installStatusLine,\n uninstallStatusLine,\n hasStatusLineBackup,\n getBackupDetails,\n detectExistingStatusLine\n} from '../status-line-manager';\nimport { showSuccess, showError, showInfo } from '../ui';\nimport { logger } from '../../utils/logger';\nimport { sendTelemetryUpdate } from '../telemetry';\n\n// Adapter types for menu compatibility\ninterface StatusLineConfig {\n state: 'NOT_INSTALLED' | 'PARTIALLY_INSTALLED' | 'FULLY_INSTALLED';\n hookInstalled?: boolean;\n displayInstalled?: boolean;\n analysisCount?: number;\n hasAnalyzeHook?: boolean;\n hasStatusLine?: boolean;\n}\n\n// Adapter function to get status line config for menu\nasync function detectStatusLineState(): Promise<StatusLineConfig> {\n const status = await getStatusLineStatus();\n \n let state: StatusLineConfig['state'];\n if (status === 'installed') {\n state = 'FULLY_INSTALLED';\n } else if (status === 'partial') {\n state = 'PARTIALLY_INSTALLED';\n } else {\n state = 'NOT_INSTALLED';\n }\n \n const isInstalled = status !== 'not-installed';\n return {\n state,\n hookInstalled: isInstalled,\n displayInstalled: isInstalled,\n hasAnalyzeHook: isInstalled,\n hasStatusLine: isInstalled,\n analysisCount: 0 // Would need to check for actual analysis files\n };\n}\n\n// Stub for stats function that was removed\nasync function getStatusLineStats(): Promise<{ \n analysisCount: number; \n lastAnalysis?: Date;\n averageScore?: number;\n}> {\n // Check if analysis files exist\n return {\n analysisCount: 0,\n lastAnalysis: undefined,\n averageScore: undefined\n };\n}\n\nimport { \n getStatusLinePersonality, \n setStatusLinePersonality,\n getPersonalityDisplayName,\n getPersonalityIcon \n} from '../personality-manager';\nimport { createCustomPersonality, editCustomPersonality } from './personality-creator';\nimport { interactivePersonalityTester } from './personality-tester';\nimport { \n getCCUsageConfig, \n enableCCUsage, \n disableCCUsage \n} from '../ccusage-config-manager';\n\n/**\n * Display educational header about status line\n */\nasync function displayEducationalHeader(config: StatusLineConfig): Promise<void> {\n console.log(colors.accent('\\n🚀 Status Line - Strategic Co-pilot'));\n console.log(colors.highlight(' Strategic guidance to move your project forward\\n'));\n \n console.log(colors.subdued('Analyzes your prompts in Claude Code and provides'));\n console.log(colors.subdued('strategic guidance to keep you productive.\\n'));\n \n // Show personality if status line is installed\n if (config.state === 'FULLY_INSTALLED') {\n const personality = getStatusLinePersonality();\n const personalityIcon = getPersonalityIcon(personality.personality);\n const personalityName = getPersonalityDisplayName(personality.personality);\n console.log(`${personalityIcon} Personality: ${colors.accent(personalityName)}`);\n \n // Check and display ccusage status\n const ccusageConfig = await getCCUsageConfig();\n if (ccusageConfig.enabled) {\n console.log(`💰 Usage Metrics: ${colors.success('Enabled (powered by ccusage)')}`);\n }\n }\n \n // Show backup information if exists\n if (hasStatusLineBackup()) {\n const backup = getBackupDetails();\n if (backup) {\n console.log('');\n console.log(`📦 ${colors.info('Backed up status line:')}`);\n console.log(colors.subdued(` Command: ${backup.command}`));\n if (backup.date) {\n const backupDate = new Date(backup.date);\n console.log(colors.subdued(` Saved on: ${backupDate.toLocaleDateString()}`));\n }\n }\n }\n \n // Show component status if partially installed\n if (config.state === 'PARTIALLY_INSTALLED') {\n console.log('');\n console.log(colors.subdued('Components:'));\n const hookStatus = config.hasAnalyzeHook ? '✓' : '✗';\n const displayStatus = config.hasStatusLine ? '✓' : '✗';\n console.log(colors.subdued(` ${hookStatus} UserPromptSubmit hook`));\n console.log(colors.subdued(` ${displayStatus} Status line display`));\n }\n \n // Show example or stats\n if (config.state === 'FULLY_INSTALLED') {\n const stats = await getStatusLineStats();\n if (stats.analysisCount > 0) {\n console.log('');\n console.log(colors.subdued('Your Statistics:'));\n console.log(colors.subdued(` • Prompts analyzed: ${colors.accent(stats.analysisCount.toString())}`));\n if (stats.averageScore !== undefined) {\n console.log(colors.subdued(` • Average score: ${colors.accent(stats.averageScore.toString() + '/100')}`));\n }\n if (stats.lastAnalysis) {\n const timeAgo = getTimeAgo(stats.lastAnalysis);\n console.log(colors.subdued(` • Last analysis: ${timeAgo}`));\n }\n }\n } else {\n console.log(colors.info('✨ What you\\'ll get:'));\n console.log(colors.subdued(' • Prompt quality analysis and improvement tips'));\n console.log(colors.subdued(' • Strategic guidance in Claude Code status line'));\n console.log(colors.subdued(' • Choose from multiple coach personalities'));\n console.log(colors.subdued(' • Uses your Claude Code locally for prompt analysis'));\n }\n \n console.log('');\n console.log(colors.dim('📖 Learn more: https://github.com/devark/devark-cli#status-line'));\n console.log('');\n console.log(box.horizontal.repeat(60));\n console.log('');\n}\n\n/**\n * Get human-readable time ago string\n */\nfunction getTimeAgo(date: Date): string {\n const now = new Date();\n const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);\n \n if (seconds < 60) return 'just now';\n if (seconds < 3600) return `${Math.floor(seconds / 60)} minutes ago`;\n if (seconds < 86400) return `${Math.floor(seconds / 3600)} hours ago`;\n return `${Math.floor(seconds / 86400)} days ago`;\n}\n\n/**\n * Install status line with confirmation\n */\nasync function performInstallation(): Promise<void> {\n console.clear();\n \n // Show what will be installed\n console.log(colors.highlight('\\n🚀 Installing Strategic Co-pilot\\n'));\n \n // Check for existing status line\n const existingStatusLine = await detectExistingStatusLine();\n if (existingStatusLine && existingStatusLine.command) {\n console.log(colors.warning('⚠️ Existing status line detected!\\n'));\n console.log(colors.info('Current status line:'));\n console.log(colors.subdued(` Command: ${existingStatusLine.command}`));\n console.log('');\n console.log(colors.success('📦 We\\'ll save it so you can restore it later'));\n console.log('');\n }\n \n console.log(colors.success('What you\\'ll get:'));\n console.log('');\n console.log(colors.primary(' ✓ Strategic guidance') + colors.subdued(' on your development approach'));\n console.log(colors.primary(' ✓ Actionable next steps') + colors.subdued(' to keep moving forward'));\n console.log(colors.primary(' ✓ Choose your advisor') + colors.subdued(' (Gordon/DevArk/Custom)'));\n console.log('');\n \n console.log(colors.info('Technical setup:'));\n console.log(colors.dim(' • UserPromptSubmit hook for analysis'));\n console.log(colors.dim(' • Status line display in Claude Code'));\n console.log(colors.dim(' • Installation path: ~/.claude/settings.json'));\n console.log('');\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: existingStatusLine ? 'Replace existing status line and proceed? (Don\\'t worry, you can restore it later)' : 'Proceed with installation?',\n default: true\n }\n ]);\n\n if (!confirm) {\n console.log(colors.muted('\\nInstallation cancelled'));\n return;\n }\n\n try {\n // Show progress\n console.log('');\n console.log(colors.muted('Installing...'));\n \n // Perform installation\n await installStatusLine();\n\n // After successful installation, update telemetry (cloud users only)\n await sendTelemetryUpdate(); // This checks for auth internally\n\n // Success message\n console.log('');\n showSuccess('Strategic Co-pilot activated!');\n console.log('');\n console.log(colors.highlight('🚀 Quick Start:'));\n console.log('');\n console.log(colors.success(' 1. Submit any prompt') + colors.subdued(' in Claude Code'));\n console.log(colors.success(' 2. Watch Claude Code status line') + colors.subdued(' for strategic guidance'));\n console.log(colors.success(' 3. Follow the advice') + colors.subdued(' to move forward effectively!'));\n console.log('');\n console.log(colors.accent(' 💡 Pro tip:') + colors.subdued(' Ask for a complex feature and watch'));\n console.log(colors.subdued(' your co-pilot suggest a strategic approach!'));\n console.log('');\n \n } catch (error) {\n console.log('');\n showError('Failed to install status line');\n if (error instanceof Error) {\n console.log(colors.dim(` ${error.message}`));\n }\n logger.error('Status line installation failed:', error);\n }\n}\n\n/**\n * Fix partially installed status line\n */\nasync function performFix(config: StatusLineConfig): Promise<void> {\n console.clear();\n \n // Show what's broken\n console.log(colors.warning('\\n🔧 Fixing Strategic Co-pilot Installation\\n'));\n \n console.log('Current state:');\n console.log('');\n \n const hookStatus = config.hasAnalyzeHook ? '✓' : '✗';\n const displayStatus = config.hasStatusLine ? '✓' : '✗';\n \n console.log(` ${hookStatus} UserPromptSubmit hook: ${config.hasAnalyzeHook ? 'Installed' : 'Missing'}`);\n console.log(` ${displayStatus} Status line display: ${config.hasStatusLine ? 'Installed' : 'Missing'}`);\n console.log('');\n\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Fix the installation?',\n default: true\n }\n ]);\n\n if (!confirm) {\n console.log(colors.muted('\\nFix cancelled'));\n return;\n }\n\n try {\n console.log('');\n console.log(colors.muted('Fixing installation...'));\n \n // Reinstall everything\n await installStatusLine();\n \n console.log('');\n showSuccess('Strategic Co-pilot fixed successfully!');\n console.log('');\n \n } catch (error) {\n console.log('');\n showError('Failed to fix status line');\n if (error instanceof Error) {\n console.log(colors.dim(` ${error.message}`));\n }\n logger.error('Status line fix failed:', error);\n }\n}\n\n/**\n * Uninstall status line with confirmation\n */\nasync function performUninstall(): Promise<void> {\n console.clear();\n \n // Show what will be removed\n console.log(colors.warning('\\n⚠️ Uninstalling Strategic Co-pilot\\n'));\n \n console.log('This will remove:');\n console.log('');\n console.log(` • UserPromptSubmit hook`);\n console.log(` • Status line display`);\n console.log('');\n console.log(colors.subdued('Your analysis history will be preserved'));\n console.log('');\n \n // Check if there's a backup to restore\n let restoreBackup = false;\n if (hasStatusLineBackup()) {\n const backup = getBackupDetails();\n if (backup && backup.command) {\n console.log(colors.info('📦 Found backed up status line:'));\n console.log(colors.subdued(` ${backup.command}`));\n if (backup.date) {\n const backupDate = new Date(backup.date);\n console.log(colors.subdued(` Saved on: ${backupDate.toLocaleDateString()}`));\n }\n console.log('');\n \n const { restoreChoice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'restoreChoice',\n message: 'What would you like to do?',\n choices: [\n { name: 'Remove devark and restore original status line', value: 'restore' },\n { name: 'Remove devark completely (no status line)', value: 'remove' },\n { name: 'Cancel', value: 'cancel' }\n ]\n }\n ]);\n \n if (restoreChoice === 'cancel') {\n console.log(colors.muted('\\nUninstall cancelled'));\n return;\n }\n \n restoreBackup = (restoreChoice === 'restore');\n }\n } else {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: colors.warning('Are you sure you want to uninstall?'),\n default: false\n }\n ]);\n\n if (!confirm) {\n console.log(colors.muted('\\nUninstall cancelled'));\n return;\n }\n }\n\n try {\n console.log('');\n console.log(colors.muted('Uninstalling...'));\n \n // Perform uninstallation with optional restore\n await uninstallStatusLine(restoreBackup);\n\n // After successful uninstall, update telemetry (cloud users only)\n await sendTelemetryUpdate(); // This checks for auth internally\n\n console.log('');\n if (restoreBackup) {\n showSuccess('Original status line restored');\n console.log(colors.dim(' Your previous status line is now active'));\n } else {\n showInfo('Strategic Co-pilot uninstalled');\n console.log(colors.dim(' You can reinstall it anytime from the menu'));\n }\n console.log('');\n \n } catch (error) {\n console.log('');\n showError('Failed to uninstall status line');\n if (error instanceof Error) {\n console.log(colors.dim(` ${error.message}`));\n }\n logger.error('Status line uninstallation failed:', error);\n }\n}\n\n/**\n * Manage personality settings\n */\nasync function managePersonality(): Promise<void> {\n console.clear();\n \n const personality = getStatusLinePersonality();\n const currentPersonality = personality.personality;\n const currentName = getPersonalityDisplayName(currentPersonality);\n const currentIcon = getPersonalityIcon(currentPersonality);\n \n console.log(colors.accent('\\n🎭 Manage Status Line Personality\\n'));\n console.log(`Current: ${currentIcon} ${colors.highlight(currentName)}\\n`);\n \n // Build choices with current status indicators\n const choices = [\n {\n name: '🧪 Test Current Personality',\n value: 'test'\n },\n new inquirer.Separator(),\n {\n name: `🔥 Gordon ${currentPersonality === 'gordon' ? colors.success('(Active)') : ''}`,\n value: 'gordon',\n disabled: currentPersonality === 'gordon' ? 'Currently active' : false\n },\n {\n name: `💜 DevArk ${currentPersonality === 'devark' ? colors.success('(Active)') : ''}`,\n value: 'devark',\n disabled: currentPersonality === 'devark' ? 'Currently active' : false\n },\n new inquirer.Separator(),\n {\n name: '✨ Create Custom Personality',\n value: 'create-custom'\n }\n ];\n \n // Add edit option if custom personality exists\n if (personality.customPersonality) {\n const customName = personality.customPersonality.name;\n choices.push({\n name: `📝 Edit Custom: \"${customName}\" ${currentPersonality === 'custom' ? colors.success('(Active)') : ''}`,\n value: 'edit-custom'\n });\n \n // Add activate option if not currently active\n if (currentPersonality !== 'custom') {\n choices.push({\n name: `✨ Activate Custom: \"${customName}\"`,\n value: 'custom'\n });\n }\n }\n \n choices.push(\n new inquirer.Separator(),\n {\n name: '← Back',\n value: 'back'\n }\n );\n \n const { choice } = await inquirer.prompt([\n {\n type: 'list',\n name: 'choice',\n message: 'Choose a personality:',\n choices,\n pageSize: 10\n }\n ]);\n \n switch (choice) {\n case 'test':\n await interactivePersonalityTester();\n break;\n \n case 'gordon':\n case 'devark':\n setStatusLinePersonality(choice);\n console.log('');\n showSuccess(`Personality switched to ${getPersonalityDisplayName(choice)}!`);\n console.log(colors.dim('\\n The status line will now use this personality style'));\n await promptToContinue();\n break;\n \n case 'custom':\n if (personality.customPersonality) {\n setStatusLinePersonality('custom');\n console.log('');\n showSuccess(`Activated custom personality \"${personality.customPersonality.name}\"!`);\n console.log(colors.dim('\\n The status line will now use your custom style'));\n await promptToContinue();\n }\n break;\n \n case 'create-custom':\n await createCustomPersonality();\n await promptToContinue();\n break;\n \n case 'edit-custom':\n await editCustomPersonality();\n await promptToContinue();\n break;\n \n case 'back':\n // Return to main menu\n break;\n }\n}\n\n/**\n * Wait for user to press Enter\n */\nasync function promptToContinue(): Promise<void> {\n await inquirer.prompt({\n type: 'input',\n name: 'continue',\n message: 'Press Enter to continue...',\n default: ''\n });\n}\n\n/**\n * Main status line management menu\n */\nexport async function showStatusLineMenu(): Promise<void> {\n let shouldContinue = true;\n\n while (shouldContinue) {\n console.clear();\n \n // Get current status\n const config = await detectStatusLineState();\n \n // Display header with current status\n await displayEducationalHeader(config);\n\n // Build menu choices based on state\n const choices = [];\n \n if (config.state === 'NOT_INSTALLED') {\n choices.push({\n name: `🚀 Install Strategic Co-pilot`,\n value: 'install'\n });\n } else if (config.state === 'PARTIALLY_INSTALLED') {\n choices.push({\n name: `⚠️ Fix Strategic Co-pilot Installation`,\n value: 'fix'\n });\n choices.push({\n name: `❌ Uninstall Strategic Co-pilot`,\n value: 'uninstall'\n });\n } else if (config.state === 'FULLY_INSTALLED') {\n choices.push({\n name: `✅ Strategic Co-pilot Active (Reinstall)`,\n value: 'reinstall'\n });\n \n // Add ccusage toggle option\n const ccusageConfig = await getCCUsageConfig();\n \n if (ccusageConfig.enabled) {\n choices.push({\n name: `💰 Disable token usage metrics (ccusage)`,\n value: 'disable-ccusage'\n });\n } else {\n choices.push({\n name: `💰 Enable token usage metrics (ccusage)`,\n value: 'enable-ccusage'\n });\n }\n \n choices.push({\n name: `🎭 Manage Personality`,\n value: 'personality'\n });\n choices.push({\n name: `🧪 Test Personality System`,\n value: 'test-quick'\n });\n choices.push({\n name: `❌ Uninstall Strategic Co-pilot`,\n value: 'uninstall'\n });\n }\n \n choices.push(\n new inquirer.Separator(),\n {\n name: '← Back to main menu',\n value: 'back'\n }\n );\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to do?',\n choices,\n pageSize: 10\n }\n ]);\n\n switch (action) {\n case 'install':\n await performInstallation();\n await promptToContinue();\n break;\n \n case 'fix':\n await performFix(config);\n await promptToContinue();\n break;\n \n case 'reinstall':\n await performInstallation();\n await promptToContinue();\n break;\n \n case 'enable-ccusage':\n try {\n console.log('');\n console.log(colors.muted('Enabling ccusage integration...'));\n await enableCCUsage();\n console.log('');\n showSuccess('ccusage metrics enabled!');\n console.log(colors.dim('\\n Token usage will now appear in your status line'));\n console.log(colors.dim(' Powered by ccusage 🙌 - npmjs.com/package/ccusage'));\n console.log(colors.dim(' Note: ccusage may take a moment to calculate on first use'));\n } catch (error) {\n console.log('');\n showError('Failed to enable ccusage');\n if (error instanceof Error) {\n console.log(colors.dim(` ${error.message}`));\n }\n }\n await promptToContinue();\n break;\n \n case 'disable-ccusage':\n try {\n console.log('');\n console.log(colors.muted('Disabling ccusage integration...'));\n await disableCCUsage();\n console.log('');\n showInfo('ccusage metrics disabled');\n console.log(colors.dim('\\n Token usage will no longer appear in status line'));\n } catch (error) {\n console.log('');\n showError('Failed to disable ccusage');\n if (error instanceof Error) {\n console.log(colors.dim(` ${error.message}`));\n }\n }\n await promptToContinue();\n break;\n \n case 'personality':\n await managePersonality();\n break;\n \n case 'test-quick':\n await interactivePersonalityTester();\n await promptToContinue();\n break;\n \n case 'uninstall':\n await performUninstall();\n await promptToContinue();\n break;\n \n case 'back':\n shouldContinue = false;\n break;\n }\n }\n}","import inquirer from 'inquirer';\nimport { colors } from './styles';\nimport { discoverProjects } from '../claude-core';\nimport { showSessionSelector, SelectedSessionInfo } from './session-selector';\nimport { readClaudeSessions } from '../readers/claude';\nimport { parseProjectName } from './project-display';\nimport { createSpinner } from '../ui';\n\nexport type ManualSyncOption = \n | { type: 'selected'; sessions: SelectedSessionInfo[] }\n | { type: 'time-based'; days: number; sessions: SelectedSessionInfo[] }\n | { type: 'projects'; projects: string[] }\n | { type: 'all' }\n | { type: 'cancel' };\n\n/**\n * Show the manual sync menu and return the user's choice\n */\nexport async function showManualSyncMenu(): Promise<ManualSyncOption> {\n console.log('');\n console.log(colors.primary('Manual sync to cloud'));\n console.log(colors.subdued('─'.repeat(20)));\n console.log('');\n \n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to sync?',\n choices: [\n { name: `🎯 Select specific sessions`, value: 'select' },\n { name: `📅 Last 7 days`, value: 'last7' },\n { name: `📅 Last 14 days`, value: 'last14' },\n { name: `📁 Select projects to sync`, value: 'projects' },\n { name: `🌍 Sync all projects`, value: 'all' },\n { name: `↩️ Back`, value: 'cancel' }\n ]\n }\n ]);\n \n switch (action) {\n case 'select': {\n // Use existing session selector\n const selectedSessions = await showSessionSelector();\n \n if (selectedSessions.length === 0) {\n console.log(colors.warning('\\nNo sessions selected.'));\n return { type: 'cancel' };\n }\n \n // No need to re-read! The selector already gave us everything we need\n return { type: 'selected', sessions: selectedSessions };\n }\n \n case 'projects': {\n // Show project selector\n const projects = await discoverProjects();\n \n if (projects.length === 0) {\n console.log(colors.warning('\\nNo Claude projects found.'));\n return { type: 'cancel' };\n }\n \n const { selected } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selected',\n message: 'Select projects to sync:',\n choices: projects.map(p => ({\n name: `${p.name} ${colors.subdued(`(${p.sessions} sessions${p.isActive ? '' : ', inactive'})`)}`,\n value: p.claudePath,\n checked: false\n })),\n validate: (input) => {\n if (input.length === 0) {\n return 'Please select at least one project';\n }\n return true;\n }\n }\n ]);\n \n return { type: 'projects', projects: selected };\n }\n \n case 'last7': {\n // Sync last 7 days\n const days = 7;\n const sinceDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n \n const spinner = createSpinner(`Loading sessions from the last ${days} days...`).start();\n \n try {\n const sessions = await readClaudeSessions({ since: sinceDate });\n \n // Filter out sessions shorter than 4 minutes (240 seconds)\n const validSessions = sessions.filter(s => s.duration >= 240);\n \n if (validSessions.length === 0) {\n spinner.fail(colors.warning(`No sessions longer than 4 minutes found in the last ${days} days.`));\n return { type: 'cancel' };\n }\n \n spinner.succeed(colors.success(`Found ${validSessions.length} sessions from the last ${days} days`));\n \n // Convert to SelectedSessionInfo format\n const selectedSessions: SelectedSessionInfo[] = validSessions.map(session => ({\n projectPath: session.sourceFile?.claudeProjectPath || '',\n sessionFile: session.sourceFile?.sessionFile || '',\n displayName: parseProjectName(session.projectPath),\n duration: session.duration,\n timestamp: session.timestamp,\n messageCount: session.messages.length\n })).filter(s => s.projectPath && s.sessionFile);\n \n console.log('');\n console.log(colors.info(`This will sync ${selectedSessions.length} sessions from the last ${days} days.`));\n \n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `Continue with syncing ${selectedSessions.length} sessions?`,\n default: true\n }\n ]);\n \n if (!confirm) {\n return { type: 'cancel' };\n }\n \n return { type: 'time-based', days, sessions: selectedSessions };\n } catch (error) {\n spinner.fail(colors.error('Failed to load sessions'));\n return { type: 'cancel' };\n }\n }\n \n case 'last14': {\n // Sync last 14 days\n const days = 14;\n const sinceDate = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n \n const spinner = createSpinner(`Loading sessions from the last ${days} days...`).start();\n \n try {\n const sessions = await readClaudeSessions({ since: sinceDate });\n \n // Filter out sessions shorter than 4 minutes (240 seconds)\n const validSessions = sessions.filter(s => s.duration >= 240);\n \n if (validSessions.length === 0) {\n spinner.fail(colors.warning(`No sessions longer than 4 minutes found in the last ${days} days.`));\n return { type: 'cancel' };\n }\n \n spinner.succeed(colors.success(`Found ${validSessions.length} sessions from the last ${days} days`));\n \n // Convert to SelectedSessionInfo format\n const selectedSessions: SelectedSessionInfo[] = validSessions.map(session => ({\n projectPath: session.sourceFile?.claudeProjectPath || '',\n sessionFile: session.sourceFile?.sessionFile || '',\n displayName: parseProjectName(session.projectPath),\n duration: session.duration,\n timestamp: session.timestamp,\n messageCount: session.messages.length\n })).filter(s => s.projectPath && s.sessionFile);\n \n console.log('');\n console.log(colors.info(`This will sync ${selectedSessions.length} sessions from the last ${days} days.`));\n \n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: `Continue with syncing ${selectedSessions.length} sessions?`,\n default: true\n }\n ]);\n \n if (!confirm) {\n return { type: 'cancel' };\n }\n \n return { type: 'time-based', days, sessions: selectedSessions };\n } catch (error) {\n spinner.fail(colors.error('Failed to load sessions'));\n return { type: 'cancel' };\n }\n }\n \n case 'all': {\n // Confirm syncing all\n const projects = await discoverProjects();\n const totalSessions = projects.reduce((sum, p) => sum + p.sessions, 0);\n \n console.log('');\n console.log(colors.info(`This will sync ${totalSessions} sessions from ${projects.length} projects.`));\n \n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Continue with syncing all projects?',\n default: true\n }\n ]);\n \n if (!confirm) {\n return { type: 'cancel' };\n }\n \n return { type: 'all' };\n }\n \n default:\n return { type: 'cancel' };\n }\n}","import chalk from 'chalk';\nimport { countCursorMessages } from '../lib/readers/cursor';\nimport { createSpinner } from '../lib/ui';\nimport { DevArkError } from '../utils/errors';\nimport { logger } from '../utils/logger';\n\nexport async function cursorStats(): Promise<void> {\n const spinner = createSpinner('Fetching Cursor IDE stats...').start();\n\n try {\n const stats = await countCursorMessages();\n\n spinner.succeed('Cursor stats loaded!');\n\n console.log(chalk.cyan('\\n💬 Your Cursor IDE Stats'));\n console.log(chalk.gray('═══════════════════════════════\\n'));\n\n console.log(chalk.cyan(`📊 Total Conversations: ${chalk.bold(stats.conversationCount)}`));\n console.log(chalk.cyan(`💬 Total Messages: ${chalk.bold(stats.totalMessages)}`));\n console.log(chalk.gray(` • User Messages: ${chalk.bold(stats.userMessages)}`));\n console.log(chalk.gray(` • Assistant Messages: ${chalk.bold(stats.assistantMessages)}`));\n\n // Calculate some interesting stats\n if (stats.conversationCount > 0) {\n const avgMessagesPerConvo = Math.round(stats.totalMessages / stats.conversationCount);\n const assistantRatio = Math.round((stats.assistantMessages / stats.totalMessages) * 100);\n\n console.log(chalk.gray('\\n═══════════════════════════════\\n'));\n console.log(chalk.cyan('📈 Insights:'));\n console.log(chalk.gray(` • Average messages per conversation: ${chalk.bold(avgMessagesPerConvo)}`));\n console.log(chalk.gray(` • Assistant response ratio: ${chalk.bold(assistantRatio + '%')}`));\n }\n\n console.log(chalk.gray('\\n═══════════════════════════════\\n'));\n\n // Motivational message based on usage\n if (stats.conversationCount === 0) {\n console.log(chalk.yellow('💡 Start coding with Cursor to track your conversations!'));\n } else if (stats.conversationCount < 10) {\n console.log(chalk.cyan('🌱 Getting started with Cursor! Keep exploring.'));\n } else if (stats.conversationCount < 100) {\n console.log(chalk.green('🚀 Building momentum! You\\'re learning fast.'));\n } else if (stats.conversationCount < 1000) {\n console.log(chalk.magenta('⚡ Power user! You\\'re mastering AI-assisted development.'));\n } else {\n console.log(chalk.red('🔥 LEGENDARY! You\\'re an AI-coding expert!'));\n }\n\n console.log('');\n\n } catch (error) {\n spinner.fail('Failed to fetch Cursor stats');\n\n if (error instanceof DevArkError) {\n if (error.code === 'CURSOR_NOT_FOUND') {\n console.log(chalk.yellow('\\n💡 Cursor IDE not detected on this system.'));\n console.log(chalk.gray(' Install Cursor to track your AI conversations.'));\n console.log(chalk.gray(' Download: https://cursor.sh\\n'));\n return;\n }\n throw error;\n }\n\n logger.error('Failed to fetch Cursor stats', error);\n throw new DevArkError(\n 'Failed to fetch Cursor statistics. Please try again.',\n 'CURSOR_STATS_FAILED'\n );\n }\n}\n","import { SubAgentName } from './constants';\n\n/**\n * Templates for devark sub-agents\n * These are installed to ~/.claude/agents/ for local analysis with Claude Code\n */\nexport const SUB_AGENT_TEMPLATES: Record<SubAgentName, string> = {\n 'devark-session-analyzer.md': `---\nname: devark-session-analyzer\ndescription: Use this agent when you need to analyze Claude Code session data from the .devark-temp/ directory. This agent quickly extracts specific metrics like productivity patterns, tool usage, or accomplishments from pre-fetched session files.\\n\\nExamples:\\n<example>\\nContext: Orchestrator needs productivity metrics from sessions.\\nuser: \"Analyze productivity metrics from .devark-temp/ sessions\"\\nassistant: \"I'll analyze the session files to extract productivity metrics.\"\\n<commentary>\\nThe agent reads pre-fetched session files and extracts requested metrics.\\n</commentary>\\n</example>\ntools: Read, TodoWrite\nmodel: inherit\n---\n\nYou are a focused session data analyzer. You ONLY analyze pre-fetched devark session files from the .devark-temp/ directory.\n\nCRITICAL RULES:\n- ONLY use the Read tool to read files from .devark-temp/\n- Do NOT use Bash, Write, Grep, LS, or any other tools\n- Do NOT try to create scripts or programs\n- Do NOT try to access ~/.claude/projects/ or any other directories\n- Files start with '-' (like '-home-user-...') - this is normal, use full paths with ./\n\nYour workflow is simple:\n\n1. **Read the manifest**: Start with .devark-temp/manifest.json to see what sessions are available\n\n2. **Read session files**: Read the JSONL files listed in the manifest (they are in .devark-temp/)\n - Each line in a JSONL file is a separate JSON object\n - Look for timestamps, messages, and tool usage data\n\n3. **Extract requested metrics**: Based on what was asked, extract:\n - Session counts and durations\n - Tool usage (Read, Write, Edit, Bash operations)\n - Key accomplishments from messages\n - Time patterns (when sessions occurred)\n - Project distribution\n\n4. **Return structured results**: Provide clear, concise answers with the specific data requested\n\nRemember:\n- Be fast and focused - don't over-analyze\n- Work only with files in .devark-temp/\n- Return results quickly without creating visualizations\n- If you can't read a file, skip it and continue with others\n\nYour goal is to quickly extract and return the specific metrics requested from the pre-fetched session data.`,\n\n'devark-report-generator.md': `---\nname: devark-report-generator\ndescription: Use this agent when you need to generate comprehensive, professional reports from AI Coding analysis (devark) data. This includes creating daily standups, weekly progress reports, monthly reviews, quarterly retrospectives, and custom time-range reports with executive summaries, detailed analysis, and multiple export formats.\\n\\nExamples:\\n<example>\\nContext: User needs a weekly progress report for their team.\\nuser: \"Generate a weekly progress report from my devark data\"\\nassistant: \"I'll use the devark-report-generator agent to create a comprehensive weekly progress report.\"\\n<commentary>\\nThe user needs a formal progress report, which is the primary function of the report-generator agent.\\n</commentary>\\n</example>\\n<example>\\nContext: User wants a monthly productivity review.\\nuser: \"Create a detailed monthly productivity review with recommendations\"\\nassistant: \"Let me use the devark-report-generator agent to generate a comprehensive monthly review with insights and recommendations.\"\\n<commentary>\\nGenerating detailed productivity reviews with recommendations is exactly what this agent specializes in.\\n</commentary>\\n</example>\ntools: Read, TodoWrite \nmodel: inherit\n---\n\nYou are an expert report data analyst specializing in creating structured productivity data that delivers maximum insight in minimum space.\n\nYou will generate structured JSON data that captures only the most essential AI coding productivity insights.\n\nIMPORTANT: Check if STATUS LINE INSTALLED is mentioned in the input.\n\nWhen generating reports, you will:\n\n1. **Output structured JSON data ONLY**:\n - CRITICAL: Return ONLY a JSON object matching the ReportData structure\n - Do NOT include any explanations, markdown, or HTML\n - Do NOT use Write tool - just OUTPUT (respond) the JSON\n - No markers, no commentary, ONLY the JSON object\n\n2. **Structure the data with these exact sections**:\n - **metadata**: totalSessions, dataProcessed, activeDevelopment, projects, generatedAt, dateRange\n - **executiveSummary**: Array of 3-4 bullet points (strings)\n - **activityDistribution**: Object with activity types as keys and percentages as values\n - **keyAccomplishments**: Array of 5-6 strings\n - **promptQuality**: Object with methodology, breakdown (excellent/good/fair/poor %), insights, averageScore\n - **projectBreakdown**: Array of project objects with name, sessions, largestSession, focus\n - **reportGeneration**: Object with duration, apiTime, turns, estimatedCost, sessionId\n\n3. **Output format**:\n - Return ONLY the JSON object\n - The orchestrator will capture and process your output\n - NO other formats needed\n\n4. **Data generation principles**:\n - Be extremely concise in text fields\n - Use clear, actionable strings for summaries and accomplishments\n - Provide exact percentages for distributions\n - Calculate accurate averages and totals\n - Focus on key findings only\n\n5. **CRITICAL JSON REQUIREMENTS**:\n You MUST return data matching this exact structure:\n \n {\n \"metadata\": {\n \"totalSessions\": 0,\n \"dataProcessed\": \"0MB\",\n \"activeDevelopment\": \"0 hours\",\n \"projects\": 0,\n \"generatedAt\": \"ISO timestamp\",\n \"dateRange\": \"Date range string\"\n },\n \"executiveSummary\": [\n \"First key insight or summary point\",\n \"Second key insight or summary point\",\n \"Third key insight or summary point\",\n \"Fourth key insight if needed\"\n ],\n \"activityDistribution\": {\n \"Coding\": 45,\n \"Debugging\": 20,\n \"Testing\": 15,\n \"Documentation\": 10,\n \"Refactoring\": 10\n },\n \"keyAccomplishments\": [\n \"First major accomplishment\",\n \"Second major accomplishment\",\n \"Third major accomplishment\",\n \"Fourth major accomplishment\",\n \"Fifth major accomplishment if significant\"\n ],\n \"promptQuality\": {\n \"methodology\": \"Brief description of how prompts were analyzed\",\n \"breakdown\": {\n \"excellent\": 25,\n \"good\": 45,\n \"fair\": 20,\n \"poor\": 10\n },\n \"insights\": \"Key insight about prompt quality patterns\",\n \"averageScore\": 72\n },\n \"projectBreakdown\": [\n {\n \"name\": \"Project Name\",\n \"sessions\": 12,\n \"largestSession\": \"2.5 hours\",\n \"focus\": \"Feature development\"\n }\n ],\n \"reportGeneration\": {\n \"duration\": \"45s\",\n \"apiTime\": \"42s\",\n \"turns\": 3,\n \"estimatedCost\": 0.15,\n \"sessionId\": \"session-id-here\"\n }\n }\n\n Example values shown above. Replace with actual calculated data\n\nPROMPT QUALITY DATA:\n- Always analyze prompt quality and provide methodology, breakdown percentages, insights, and average score\n- IF STATUS LINE INSTALLED = No is mentioned, include a note in the insights field about the status line benefits\n- Focus on actionable insights about prompt patterns\n\n6. **What to EXCLUDE from the data**:\n - HTML or styling information\n - Verbose explanations in data fields\n - Any markup or formatting codes\n - Commentary or analysis outside the structured fields\n\nRemember: Return ONLY the JSON object with the exact structure shown. No HTML, no markers, no explanations.\n\nCRITICAL OUTPUT REQUIREMENT:\n- Return ONLY the JSON object\n- Start with { and end with }\n- Use proper JSON syntax (quoted keys, proper types)\n- No text before or after the JSON\n- No markers like === REPORT START ===\n- Just pure JSON data\n\nThe template engine will handle all HTML generation and styling.`\n};\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\nimport { DEVARK_SUB_AGENTS, SubAgentName } from './constants';\nimport { SUB_AGENT_TEMPLATES } from './templates';\nimport { logger } from '../../utils/logger';\nimport { icons } from '../ui/styles';\n\n/**\n * Get the path to the Claude Code sub-agents directory\n */\nexport function getSubAgentsDirectory(): string {\n return path.join(os.homedir(), '.claude', 'agents');\n}\n\n/**\n * Get the full path for a specific sub-agent\n */\nexport function getSubAgentPath(name: SubAgentName): string {\n return path.join(getSubAgentsDirectory(), name);\n}\n\n/**\n * Ensure the sub-agents directory exists\n */\nexport async function ensureSubAgentsDirectory(): Promise<void> {\n const dir = getSubAgentsDirectory();\n try {\n await fs.mkdir(dir, { recursive: true });\n logger.debug('Sub-agents directory ensured', { path: dir });\n } catch (error) {\n logger.error('Failed to create sub-agents directory', error);\n throw new Error(`Failed to create sub-agents directory: ${error}`);\n }\n}\n\n/**\n * Check which sub-agents are currently installed\n */\nexport async function checkInstalledSubAgents(): Promise<{\n installed: SubAgentName[];\n missing: SubAgentName[];\n total: number;\n}> {\n const dir = getSubAgentsDirectory();\n \n try {\n await fs.access(dir);\n const files = await fs.readdir(dir);\n \n const installed = DEVARK_SUB_AGENTS.filter(agent => \n files.includes(agent)\n ) as SubAgentName[];\n \n const missing = DEVARK_SUB_AGENTS.filter(agent => \n !files.includes(agent)\n ) as SubAgentName[];\n \n return {\n installed,\n missing,\n total: DEVARK_SUB_AGENTS.length\n };\n } catch {\n // Directory doesn't exist or can't be accessed\n return {\n installed: [],\n missing: [...DEVARK_SUB_AGENTS] as SubAgentName[],\n total: DEVARK_SUB_AGENTS.length\n };\n }\n}\n\n/**\n * Install a single sub-agent\n */\nexport async function installSubAgent(name: SubAgentName): Promise<void> {\n const content = SUB_AGENT_TEMPLATES[name];\n if (!content) {\n throw new Error(`No template found for sub-agent: ${name}`);\n }\n \n const filePath = getSubAgentPath(name);\n await fs.writeFile(filePath, content, 'utf-8');\n logger.debug('Sub-agent installed', { name, path: filePath });\n}\n\n/**\n * Install all missing sub-agents with progress reporting\n */\nexport async function installSubAgents(options?: {\n force?: boolean;\n onProgress?: (message: string) => void;\n}): Promise<{\n installed: SubAgentName[];\n skipped: SubAgentName[];\n failed: SubAgentName[];\n}> {\n const { force = false, onProgress } = options || {};\n \n // Ensure directory exists\n await ensureSubAgentsDirectory();\n \n // Check current state\n const status = await checkInstalledSubAgents();\n const toInstall = force ? DEVARK_SUB_AGENTS : status.missing;\n \n const results = {\n installed: [] as SubAgentName[],\n skipped: [] as SubAgentName[],\n failed: [] as SubAgentName[]\n };\n \n // Skip if all installed and not forcing\n if (!force && status.missing.length === 0) {\n onProgress?.(`${icons.check} All sub-agents already installed`);\n results.skipped = status.installed;\n return results;\n }\n \n onProgress?.(`Installing ${toInstall.length} sub-agents to ~/.claude/agents/`);\n \n for (const agent of toInstall) {\n try {\n // Check if exists and not forcing\n if (!force && status.installed.includes(agent)) {\n results.skipped.push(agent);\n onProgress?.(` ${icons.check} ${agent} (already installed)`);\n continue;\n }\n \n // Install the sub-agent\n await installSubAgent(agent);\n results.installed.push(agent);\n onProgress?.(` ${icons.success} ${agent}`);\n } catch (error) {\n results.failed.push(agent);\n onProgress?.(` ${icons.error} ${agent} - ${error}`);\n logger.error(`Failed to install sub-agent ${agent}`, error);\n }\n }\n \n // Summary\n if (results.installed.length > 0) {\n onProgress?.(`\\n${icons.check} Successfully installed ${results.installed.length} sub-agents`);\n }\n \n if (results.failed.length > 0) {\n onProgress?.(`${icons.warning} Failed to install ${results.failed.length} sub-agents`);\n }\n \n return results;\n}\n\n/**\n * Remove a single sub-agent\n */\nexport async function removeSubAgent(name: SubAgentName): Promise<void> {\n const filePath = getSubAgentPath(name);\n try {\n await fs.unlink(filePath);\n logger.debug('Sub-agent removed', { name, path: filePath });\n } catch (error) {\n if ((error as any).code !== 'ENOENT') {\n throw error;\n }\n // File doesn't exist, that's ok\n }\n}\n\n/**\n * Remove all devark sub-agents\n */\nexport async function removeAllSubAgents(): Promise<number> {\n let removed = 0;\n for (const agent of DEVARK_SUB_AGENTS) {\n try {\n await removeSubAgent(agent);\n removed++;\n } catch (error) {\n logger.error(`Failed to remove sub-agent ${agent}`, error);\n }\n }\n return removed;\n}\n\n/**\n * Remove selected sub-agents\n */\nexport async function removeSelectedSubAgents(\n agents: SubAgentName[],\n options?: {\n onProgress?: (message: string) => void;\n }\n): Promise<{\n removed: SubAgentName[];\n failed: SubAgentName[];\n}> {\n const { onProgress } = options || {};\n const results = {\n removed: [] as SubAgentName[],\n failed: [] as SubAgentName[]\n };\n \n onProgress?.(`Removing ${agents.length} sub-agents...`);\n \n for (const agent of agents) {\n try {\n await removeSubAgent(agent);\n results.removed.push(agent);\n onProgress?.(` ${icons.success} Removed ${agent}`);\n } catch (error) {\n results.failed.push(agent);\n onProgress?.(` ${icons.error} Failed to remove ${agent}`);\n logger.error(`Failed to remove sub-agent ${agent}`, error);\n }\n }\n \n // Summary\n if (results.removed.length > 0) {\n onProgress?.(`\\n${icons.check} Successfully removed ${results.removed.length} sub-agents`);\n }\n \n if (results.failed.length > 0) {\n onProgress?.(`${icons.warning} Failed to remove ${results.failed.length} sub-agents`);\n }\n \n return results;\n}\n\n/**\n * Get detailed status of all sub-agents\n */\nexport async function getSubAgentStatus(): Promise<{\n directory: string;\n exists: boolean;\n installed: SubAgentName[];\n missing: SubAgentName[];\n total: number;\n percentage: number;\n}> {\n const dir = getSubAgentsDirectory();\n const status = await checkInstalledSubAgents();\n \n let exists = false;\n try {\n await fs.access(dir);\n exists = true;\n } catch {\n exists = false;\n }\n \n const percentage = Math.round((status.installed.length / status.total) * 100);\n \n return {\n directory: dir,\n exists,\n ...status,\n percentage\n };\n}","import { colors, icons, box, padRight, getTerminalWidth } from './styles';\nimport { formatRelativeTime, createActivityGraph } from './project-display';\n\nexport interface SelectableProject {\n id: string;\n name: string;\n path: string;\n sessions: number;\n lastActivity: Date | string;\n selected: boolean;\n isActive?: boolean;\n}\n\nexport interface SelectorOptions {\n multiSelect?: boolean;\n showSearch?: boolean;\n showStats?: boolean;\n maxHeight?: number;\n title?: string;\n showTokenLimit?: boolean;\n tokenLimit?: number;\n estimateUsage?: boolean;\n}\n\n/**\n * Create a beautiful interactive project selector\n */\nexport function createProjectSelector(\n projects: SelectableProject[],\n cursorIndex: number,\n searchTerm: string = '',\n options: SelectorOptions = {}\n): string {\n const width = Math.min(getTerminalWidth(), 100);\n const maxHeight = options.maxHeight || 20;\n const showSearch = options.showSearch !== false;\n const showStats = options.showStats !== false;\n const multiSelect = options.multiSelect !== false;\n \n const lines: string[] = [];\n \n // Header\n const title = options.title || 'SELECT PROJECTS';\n lines.push(colors.primary(box.doubleTopLeft + box.doubleHorizontal.repeat(width - 2) + box.doubleTopRight));\n \n const titleText = ` ${icons.folder} ${title} `;\n const titlePadding = Math.floor((width - titleText.length) / 2);\n lines.push(\n colors.primary(box.doubleVertical) +\n ' '.repeat(titlePadding) +\n colors.highlight(titleText) +\n ' '.repeat(width - titlePadding - titleText.length - 2) +\n colors.primary(box.doubleVertical)\n );\n \n // Search box\n if (showSearch) {\n lines.push(colors.primary(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n const searchIcon = '🔍';\n const searchPrompt = searchTerm || 'Press / to filter...';\n const searchColor = searchTerm ? colors.highlight : colors.dim;\n \n const searchLine = \n colors.primary(box.vertical) + ' ' +\n searchIcon + ' ' +\n searchColor(padRight(searchPrompt, width - 10)) + ' ' +\n colors.primary(box.vertical);\n \n lines.push(searchLine);\n }\n \n // Separator\n lines.push(colors.primary(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n // Filter projects\n const filteredProjects = searchTerm\n ? projects.filter(p => \n p.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n p.path.toLowerCase().includes(searchTerm.toLowerCase())\n )\n : projects;\n \n // Calculate max sessions for activity graph\n const maxSessions = Math.max(...filteredProjects.map(p => p.sessions), 1);\n \n // Project list with scrolling\n const visibleStart = Math.max(0, Math.min(cursorIndex - Math.floor(maxHeight / 2), filteredProjects.length - maxHeight));\n const visibleEnd = Math.min(visibleStart + maxHeight, filteredProjects.length);\n const visibleProjects = filteredProjects.slice(visibleStart, visibleEnd);\n \n // Column headers\n if (showStats) {\n const headers = \n colors.primary(box.vertical) + ' ' +\n colors.dim(padRight('', 3)) + // Checkbox column\n colors.dim(padRight('PROJECT', 30)) +\n colors.dim(padRight('SESSIONS', 10)) +\n colors.dim(padRight('', 25)) +\n colors.dim(padRight('LAST ACTIVITY', 15)) +\n ' ' + colors.primary(box.vertical);\n \n lines.push(headers);\n lines.push(colors.dim(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n }\n \n // Project rows\n visibleProjects.forEach((project, index) => {\n const globalIndex = visibleStart + index;\n const isCursor = globalIndex === cursorIndex;\n \n let row = colors.primary(box.vertical) + ' ';\n \n // Cursor indicator\n if (isCursor) {\n row += colors.accent('▶ ');\n } else {\n row += ' ';\n }\n \n // Checkbox for multi-select\n if (multiSelect) {\n const checkbox = project.selected \n ? colors.success('[✓]')\n : colors.muted('[ ]');\n row += checkbox + ' ';\n }\n \n // Project name with activity indicator\n const nameIcon = project.isActive ? icons.fire : icons.folder;\n const nameColor = isCursor \n ? colors.highlight\n : project.isActive \n ? colors.success\n : colors.primary;\n const projectName = project.name.length > 26 ? project.name.substring(0, 26) + '...' : project.name;\n row += nameIcon + ' ' + nameColor(padRight(projectName, 27)) + ' ';\n \n if (showStats) {\n // Session count with color coding\n const sessionColor = project.sessions > 50 \n ? colors.success\n : project.sessions > 10\n ? colors.primary\n : colors.muted;\n const sessionText = project.sessions.toString();\n row += sessionColor(padRight(sessionText, 10));\n \n // Activity graph\n const activityBar = createActivityGraph(project.sessions, maxSessions, 20);\n row += activityBar + ' ';\n \n // Last activity\n const timeText = formatRelativeTime(project.lastActivity);\n const timeColor = timeText === 'just now'\n ? colors.success\n : timeText.includes('h ago')\n ? colors.primary\n : colors.muted;\n row += timeColor(padRight(timeText, 15));\n } else {\n // Compact view - just name and basic info\n const info = colors.dim(` (${project.sessions} sessions)`);\n row += info;\n }\n \n // Pad to width\n // eslint-disable-next-line no-control-regex\n const cleanRow = row.replace(/\\u001b\\[[0-9;]*m/g, '');\n const padding = Math.max(0, width - cleanRow.length - 3);\n row += ' '.repeat(padding) + ' ' + colors.primary(box.vertical);\n \n lines.push(row);\n });\n \n // Scroll indicator if needed\n if (filteredProjects.length > maxHeight) {\n lines.push(colors.dim(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n const scrollInfo = `Showing ${visibleStart + 1}-${visibleEnd} of ${filteredProjects.length}`;\n const scrollBar = createScrollBar(cursorIndex, filteredProjects.length, 20);\n const scrollLine = \n colors.primary(box.vertical) + ' ' +\n colors.dim(scrollInfo) + ' ' +\n scrollBar +\n ' '.repeat(width - scrollInfo.length - 28) +\n colors.primary(box.vertical);\n \n lines.push(scrollLine);\n }\n \n // Token usage estimate (cloud mode)\n if (options.showTokenLimit && options.tokenLimit && options.estimateUsage) {\n lines.push(colors.dim(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n // Calculate total monthly estimate for selected projects\n const selectedProjects = projects.filter(p => p.selected);\n let totalMonthlyEstimate = 0;\n \n // Check if projects have monthlyEstimate property\n selectedProjects.forEach(p => {\n if ('monthlyEstimate' in p) {\n totalMonthlyEstimate += (p as any).monthlyEstimate;\n } else {\n // Fallback: estimate as weekly average × 4.3\n const weeklyAvg = Math.round(p.sessions / 4.3);\n totalMonthlyEstimate += Math.round(weeklyAvg * 4.3);\n }\n });\n \n const usageColor = totalMonthlyEstimate <= options.tokenLimit \n ? colors.success\n : totalMonthlyEstimate <= options.tokenLimit * 1.2\n ? colors.warning\n : colors.error;\n \n const usageText = `Estimated: ${totalMonthlyEstimate} sessions/month`;\n const limitText = `Limit: ${options.tokenLimit}/month`;\n const statusIcon = totalMonthlyEstimate <= options.tokenLimit ? icons.success : icons.warning;\n \n const usageLine = \n colors.primary(box.vertical) + ' ' +\n statusIcon + ' ' +\n usageColor(usageText) + ' ' +\n colors.dim('|') + ' ' +\n colors.muted(limitText) +\n ' '.repeat(Math.max(0, width - usageText.length - limitText.length - 15)) +\n colors.primary(box.vertical);\n \n lines.push(usageLine);\n }\n \n // Bottom border\n lines.push(colors.primary(box.doubleBottomLeft + box.doubleHorizontal.repeat(width - 2) + box.doubleBottomRight));\n \n // Selection summary\n const selectedCount = projects.filter(p => p.selected).length;\n if (multiSelect) {\n lines.push('');\n lines.push(\n colors.dim(' Selected: ') +\n colors.highlight(`${selectedCount} project${selectedCount !== 1 ? 's' : ''}`) +\n colors.dim(' | ') +\n colors.muted('Space: toggle') +\n colors.dim(' | ') +\n colors.muted('A: select all') +\n colors.dim(' | ') +\n colors.muted('Enter: confirm')\n );\n } else {\n lines.push('');\n lines.push(\n colors.dim(' Navigate: ') +\n colors.muted('↑↓') +\n colors.dim(' | ') +\n colors.muted('Search: /') +\n colors.dim(' | ') +\n colors.muted('Select: Enter') +\n colors.dim(' | ') +\n colors.muted('Cancel: Esc')\n );\n }\n \n return lines.join('\\n');\n}\n\n/**\n * Create a scroll bar indicator\n */\nfunction createScrollBar(position: number, total: number, width: number = 10): string {\n const ratio = position / Math.max(total - 1, 1);\n const indicatorPosition = Math.floor(ratio * (width - 1));\n \n let bar = '';\n for (let i = 0; i < width; i++) {\n if (i === indicatorPosition) {\n bar += colors.accent('●');\n } else {\n bar += colors.dim('─');\n }\n }\n \n return `[${bar}]`;\n}\n\n\n/**\n * Create a project detail card for selection preview\n */\nexport function createProjectPreview(project: SelectableProject): string {\n const width = Math.min(getTerminalWidth(), 50);\n const lines: string[] = [];\n \n // Border and title\n lines.push(colors.accent(box.topLeft + box.horizontal.repeat(width - 2) + box.topRight));\n \n const title = ` ${icons.info} PROJECT DETAILS `;\n const titlePadding = Math.floor((width - title.length) / 2);\n lines.push(\n colors.accent(box.vertical) +\n ' '.repeat(titlePadding) +\n colors.highlight(title) +\n ' '.repeat(width - titlePadding - title.length - 2) +\n colors.accent(box.vertical)\n );\n \n lines.push(colors.accent(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n // Details\n const details = [\n { label: 'Name', value: project.name, icon: icons.folder },\n { label: 'Path', value: project.path, icon: icons.file },\n { label: 'Sessions', value: project.sessions.toString(), icon: icons.chart },\n { label: 'Last Active', value: formatRelativeTime(project.lastActivity), icon: icons.clock },\n { label: 'Status', value: project.isActive ? 'Active' : 'Idle', icon: project.isActive ? icons.fire : icons.clock },\n ];\n \n details.forEach(detail => {\n const line = \n colors.accent(box.vertical) + ' ' +\n detail.icon + ' ' +\n colors.muted(padRight(detail.label + ':', 12)) +\n colors.primary(detail.value) +\n ' '.repeat(Math.max(0, width - detail.label.length - detail.value.length - 20)) +\n colors.accent(box.vertical);\n \n lines.push(line);\n });\n \n // Bottom border\n lines.push(colors.accent(box.bottomLeft + box.horizontal.repeat(width - 2) + box.bottomRight));\n \n return lines.join('\\n');\n}\n\n/**\n * Create a bulk action menu\n */\nexport function createBulkActionMenu(\n selectedCount: number,\n actions: Array<{ id: string; label: string; icon?: string; dangerous?: boolean }>\n): string {\n const width = Math.min(getTerminalWidth(), 60);\n const lines: string[] = [];\n \n // Header\n const borderColor = colors.warning;\n lines.push(borderColor(box.doubleTopLeft + box.doubleHorizontal.repeat(width - 2) + box.doubleTopRight));\n \n const title = ` ${icons.sparkles} BULK ACTIONS (${selectedCount} selected) `;\n const titlePadding = Math.floor((width - title.length) / 2);\n lines.push(\n borderColor(box.doubleVertical) +\n ' '.repeat(titlePadding) +\n colors.highlight(title) +\n ' '.repeat(width - titlePadding - title.length - 2) +\n borderColor(box.doubleVertical)\n );\n \n lines.push(borderColor(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n // Actions\n actions.forEach((action, index) => {\n const icon = action.icon || icons.bullet;\n const color = action.dangerous ? colors.error : colors.primary;\n const key = (index + 1).toString();\n \n const actionLine = \n borderColor(box.vertical) + ' ' +\n colors.muted(`[${key}]`) + ' ' +\n icon + ' ' +\n color(action.label) +\n ' '.repeat(Math.max(0, width - action.label.length - 12)) +\n borderColor(box.vertical);\n \n lines.push(actionLine);\n });\n \n // Bottom\n lines.push(borderColor(box.doubleBottomLeft + box.doubleHorizontal.repeat(width - 2) + box.doubleBottomRight));\n \n return lines.join('\\n');\n}","import inquirer from 'inquirer';\nimport { SelectableProject, createProjectSelector, SelectorOptions } from './project-selector';\nimport { colors } from './styles';\nimport readline from 'readline';\n\n// Type declaration for checkbox-plus prompt (optional external package)\n// This extends inquirer v12's QuestionMap for the dynamic prompt registration\ndeclare module 'inquirer' {\n interface QuestionMap {\n 'checkbox-plus': {\n type: 'checkbox-plus';\n name: string;\n message: string;\n searchable?: boolean;\n highlight?: boolean;\n pageSize?: number;\n source?: (answersSoFar: any, input: string) => Promise<Array<{\n name: string;\n value: string;\n checked?: boolean;\n short?: string;\n }>>;\n choices?: Array<{\n name: string;\n value: string;\n checked?: boolean;\n short?: string;\n }>;\n };\n }\n}\n\ninterface InteractiveSelectorOptions extends SelectorOptions {\n projects: SelectableProject[];\n initialSelected?: string[];\n}\n\n/**\n * Interactive project selector with custom keyboard handling\n * Uses readline for reliable cross-platform input capture\n */\nexport async function interactiveProjectSelector(\n options: InteractiveSelectorOptions\n): Promise<SelectableProject[]> {\n const { projects, initialSelected = [], ...selectorOptions } = options;\n \n if (projects.length === 0) {\n return [];\n }\n \n // Initialize selection state\n let selectedProjects = projects.map(p => ({\n ...p,\n selected: initialSelected.includes(p.id) || p.selected\n }));\n \n let cursorIndex = 0;\n let searchTerm = '';\n \n return new Promise((resolve) => {\n // Set up readline interface for raw keyboard input\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n \n // Enable raw mode for single keypress detection\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n \n // Helper function to render the UI\n const render = () => {\n // Clear screen and move cursor to top\n process.stdout.write('\\u001b[2J\\u001b[H');\n \n // Filter projects based on search\n const filteredProjects = searchTerm\n ? selectedProjects.filter(p => \n p.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n p.path.toLowerCase().includes(searchTerm.toLowerCase())\n )\n : selectedProjects;\n \n // Adjust cursor if it's out of bounds\n if (cursorIndex >= filteredProjects.length) {\n cursorIndex = Math.max(0, filteredProjects.length - 1);\n }\n \n // Display the selector UI\n console.log(createProjectSelector(\n filteredProjects.length > 0 ? filteredProjects : selectedProjects,\n cursorIndex,\n searchTerm,\n selectorOptions\n ));\n \n // Display help text at bottom\n console.log(colors.hint('\\n[↑↓/jk] Navigate [Space] Toggle [a] All [n] None [/] Search [Enter] Confirm [q/Esc] Cancel'));\n };\n \n // Initial render\n render();\n \n // Handle search mode\n let searchMode = false;\n let searchBuffer = '';\n \n // Keyboard input handler\n const handleKeypress = (str: string, key: any) => {\n if (searchMode) {\n // Handle search mode input\n if (key && key.name === 'escape') {\n searchMode = false;\n searchTerm = searchBuffer = '';\n render();\n } else if (key && key.name === 'return') {\n searchMode = false;\n searchTerm = searchBuffer;\n cursorIndex = 0;\n render();\n } else if (key && key.name === 'backspace') {\n searchBuffer = searchBuffer.slice(0, -1);\n searchTerm = searchBuffer;\n render();\n process.stdout.write(colors.accent(`\\nSearch: ${searchBuffer}_`));\n } else if (str && str.length === 1 && str.charCodeAt(0) >= 32) {\n searchBuffer += str;\n searchTerm = searchBuffer;\n render();\n process.stdout.write(colors.accent(`\\nSearch: ${searchBuffer}_`));\n }\n return;\n }\n \n // Get filtered projects for navigation\n const filteredProjects = searchTerm\n ? selectedProjects.filter(p => \n p.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\n p.path.toLowerCase().includes(searchTerm.toLowerCase())\n )\n : selectedProjects;\n \n // Handle normal mode input\n if (key && key.name === 'escape') {\n // Cancel and exit\n cleanup();\n resolve([]);\n } else if (key && key.name === 'return') {\n // Confirm selection\n cleanup();\n resolve(selectedProjects.filter(p => p.selected));\n } else if (key && (key.name === 'up' || str === 'k')) {\n // Move cursor up\n cursorIndex = Math.max(cursorIndex - 1, 0);\n render();\n } else if (key && (key.name === 'down' || str === 'j')) {\n // Move cursor down\n cursorIndex = Math.min(cursorIndex + 1, Math.max(0, filteredProjects.length - 1));\n render();\n } else if (str === ' ') {\n // Toggle current selection\n if (filteredProjects[cursorIndex]) {\n const projectId = filteredProjects[cursorIndex].id;\n selectedProjects = selectedProjects.map(p => \n p.id === projectId ? { ...p, selected: !p.selected } : p\n );\n render();\n }\n } else if (str === 'a' || str === 'A') {\n // Select all\n selectedProjects = selectedProjects.map(p => ({ ...p, selected: true }));\n render();\n } else if (str === 'n' || str === 'N') {\n // Select none\n selectedProjects = selectedProjects.map(p => ({ ...p, selected: false }));\n render();\n } else if (str === '/' || str === 's' || str === 'S') {\n // Enter search mode\n searchMode = true;\n searchBuffer = '';\n render();\n process.stdout.write(colors.accent('\\nSearch: _'));\n } else if (str === 'c' || str === 'C') {\n // Clear search\n searchTerm = '';\n cursorIndex = 0;\n render();\n } else if (str === 'q' || str === 'Q') {\n // Quit/cancel\n cleanup();\n resolve([]);\n } else if (str === '?' || str === 'h' || str === 'H') {\n // Show help\n process.stdout.write('\\u001b[2J\\u001b[H');\n console.log(colors.accent('\\n--- Project Selector Help ---\\n'));\n console.log('Navigation:');\n console.log(' ↑/k Move up');\n console.log(' ↓/j Move down');\n console.log('\\nSelection:');\n console.log(' Space Toggle current project');\n console.log(' a Select all projects');\n console.log(' n Deselect all projects');\n console.log('\\nSearch:');\n console.log(' / or s Start search');\n console.log(' c Clear search');\n console.log(' Esc Cancel search (while searching)');\n console.log(' Enter Apply search (while searching)');\n console.log('\\nActions:');\n console.log(' Enter Confirm selection');\n console.log(' q/Esc Cancel and exit');\n console.log(' ?/h Show this help');\n console.log(colors.subdued('\\nPress any key to continue...'));\n \n // Wait for any key then re-render\n process.stdin.once('keypress', () => {\n render();\n });\n }\n };\n \n // Cleanup function\n const cleanup = () => {\n process.stdin.removeListener('keypress', handleKeypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n rl.close();\n };\n \n // Set up keypress listener\n readline.emitKeypressEvents(process.stdin);\n process.stdin.on('keypress', handleKeypress);\n });\n}\n\n/**\n * Simple checkbox-based project selector (fallback)\n * Enhanced with better formatting and search capability\n */\nexport async function simpleProjectSelector(\n projects: SelectableProject[],\n message: string = 'Select projects:'\n): Promise<SelectableProject[]> {\n if (projects.length === 0) {\n return [];\n }\n \n // Format project choices with proper alignment and colors\n const maxNameLength = Math.max(...projects.map(p => p.name.length));\n const choices = projects.map(p => {\n const paddedName = p.name.padEnd(maxNameLength);\n const sessionInfo = `${p.sessions} session${p.sessions !== 1 ? 's' : ''}`;\n const pathInfo = colors.subdued(` (${p.path})`);\n \n return {\n name: `${paddedName} ${colors.accent(sessionInfo)}${pathInfo}`,\n value: p.id,\n checked: p.selected,\n short: p.name // Display short name after selection\n };\n });\n \n // Add search capability with inquirer-autocomplete-prompt if available\n // Otherwise fall back to standard checkbox\n try {\n // Try to use searchable checkbox (requires inquirer-checkbox-plus-prompt)\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const CheckboxPlusPrompt = require('inquirer-checkbox-plus-prompt');\n inquirer.registerPrompt('checkbox-plus', CheckboxPlusPrompt);\n \n // Cast to any is required here because inquirer-checkbox-plus-prompt is an optional\n // external package that may not be installed, and inquirer v12's types don't know about it\n const { selected } = await ((inquirer.prompt as any)([\n {\n type: 'checkbox-plus',\n name: 'selected',\n message: `${message} ${colors.hint('(Type to search, Space to select, Enter to confirm)')}`,\n searchable: true,\n highlight: true,\n pageSize: 15,\n source: async (_answersSoFar: any, input: string) => {\n if (!input) return choices;\n \n const searchTerm = input.toLowerCase();\n return choices.filter(choice => {\n const project = projects.find(p => p.id === choice.value);\n return project && (\n project.name.toLowerCase().includes(searchTerm) ||\n project.path.toLowerCase().includes(searchTerm)\n );\n });\n }\n }\n ]) as Promise<{ selected: string[] }>);\n \n return projects.filter(p => selected.includes(p.id));\n } catch (e) {\n // Fall back to standard checkbox prompt if enhanced version not available\n const { selected } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selected',\n message: `${message} ${colors.hint('(Space to select, Enter to confirm)')}`,\n choices,\n pageSize: 15,\n loop: false\n }\n ]);\n \n return projects.filter(p => selected.includes(p.id));\n }\n}","import { PromptContext, OrchestratedPrompt } from '../../types/prompts';\n\n/**\n * Build an orchestrated prompt that guides Claude through multi-phase analysis\n * using the installed devark sub-agents\n */\nexport function buildOrchestratedPrompt(context: PromptContext): OrchestratedPrompt {\n const { timeframe, days, projectPaths, projectNames } = context;\n \n // Build the project list for the prompt\n const projectList = projectPaths.map((path, i) => \n `- ${projectNames[i]}: ${path}`\n ).join('\\n');\n\n // Create the timeframe description\n const timeframeDesc = days === 1 ? 'the last 24 hours' : `the last ${days} days`;\n\n // Separate system prompt for behavioral instructions\n const systemPrompt = `You are a devark ORCHESTRATOR coordinating batch analysis.\n\nCRITICAL RULES:\n- DO NOT analyze session files yourself - delegate ALL analysis to sub-agents\n- DO NOT use Grep, Read (except manifest), or other analysis tools on session files\n- Batch sessions to limit parallel agents (MAX 9 agents total)\n- Your role: Read manifest → Launch batch analyzers → Collect results → Launch report generator → Capture and output HTML\n\nBATCHING REQUIREMENTS:\n- NEVER launch more than 9 agents total\n- For 17 sessions: Use 2-3 agents MAX (each handling 6-9 sessions)\n- Launch ALL agents in ONE message with multiple Task calls\n- Do NOT launch agents one by one - they must be parallel\n- WRONG: 17 sessions = 17 agents ❌\n- RIGHT: 17 sessions = 2-3 agents ✓\n\nREPORT HANDLING:\n- Report generator will output a JSON object with report data\n- You MUST capture this JSON and OUTPUT it yourself as a code block\n- The JSON will be automatically processed by the template engine\n- The system will handle converting JSON to HTML and saving it\n\nEXECUTION FLOW:\n1. Read manifest.json to discover session files\n2. Group sessions into batches (max 9 batches)\n3. Launch ALL batch analyzers in parallel (one message, multiple Task calls)\n4. Collect all analysis results\n5. Launch report generator with aggregated data\n6. When report generator outputs JSON, OUTPUT it again yourself in a code block\n\nCOMMUNICATION:\n- Announce batching strategy clearly\n- Show how many agents are being launched\n- Keep updates concise`;\n\n // Main prompt focused on the task\n const prompt = `Analyze my Claude Code sessions from ${timeframeDesc} using devark sub-agents.\n\nProjects to analyze:\n${projectList}\n\nExecute this streamlined workflow using per-session analysis:\n\n## Phase 1 - Discovery (3 seconds)\nRead .devark-temp/manifest.json to understand:\n- Total sessions available\n- Session files and their sizes\n- Projects involved\n\nOutput: \"Found X sessions across Y projects, launching parallel analyzers...\"\n\n## Phase 2 - Parallel Batch Analysis (20 seconds)\nGroup sessions into batches and launch parallel analyzers (MAX 9 agents):\n\nBATCHING STRATEGY (MAX 9 AGENTS TOTAL):\n- If 1-9 sessions: 1 agent handles ALL sessions\n- If 10-18 sessions: 2 agents, each handles 5-9 sessions\n- If 19-27 sessions: 3 agents, each handles 6-9 sessions\n- If 28-45 sessions: 5 agents, each handles 6-9 sessions\n- If >45 sessions: 9 agents, split evenly (5-10 sessions each)\n\nFor each batch of sessions, launch:\nTask(subagent_type=\"devark-session-analyzer\", \n description=\"Analyze batch of [X] sessions\",\n prompt=\"You are analyzing a BATCH of Claude Code session files.\n\nFILES TO ANALYZE: \n[List the specific .devark-temp/filename for each session in this batch]\n[Include isLarge flag for each file]\n\nINSTRUCTIONS:\n1. Process EACH file in your batch sequentially\n2. For each file:\n - If isLarge=true: Sample with limit:50 \n - If isLarge=false: Read the full file\n3. Extract from EACH session:\n\nSESSION METADATA:\n- Timestamp/date of session\n- Duration (if available)\n- Project name\n- Number of interactions\n\nACTIVITY ANALYSIS:\n- Primary activity type:\n * Development (new features/implementation)\n * Debugging (fixing errors/troubleshooting)\n * Refactoring (code cleanup/restructuring)\n * Code Review (analyzing existing code)\n * Learning (tutorials/understanding)\n * Research (exploring options/documentation)\n * Planning (architecture/design)\n * Testing (writing tests/validation)\n\nACCOMPLISHMENTS:\n- Specific features implemented\n- Bugs fixed\n- Code improvements made\n- Problems solved\n- Key decisions made\n\nPROMPT QUALITY:\n- Rate each session: poor/fair/good/excellent\n- Assign numerical score (0-100):\n * Excellent (90-100): Clear, specific, great context, examples provided\n * Good (70-89): Generally clear with minor gaps\n * Fair (50-69): Somewhat vague or missing context\n * Poor (0-49): Very vague or confusing\n- Consider:\n * Clarity of requirements\n * Context provided (files, examples)\n * Outcome achievement\n * Number of clarifications needed\n- Provide specific insights about prompt patterns\n\nRETURN FORMAT (JSON array for your batch):\n[\n {\n 'session_file': 'filename1',\n 'timestamp': 'ISO date',\n 'duration_minutes': number,\n 'project': 'project name',\n 'activity_type': 'primary activity',\n 'accomplishments': ['list', 'of', 'achievements'],\n 'prompt_quality': 'poor/fair/good/excellent',\n 'prompt_score': number (0-100),\n 'prompt_insights': 'specific observations',\n 'notable_patterns': 'any interesting patterns'\n },\n // ... one object for each session in your batch\n]\n\nCRITICAL: Process ALL files in your batch. Return an array with one object per session.\")\n\nIMPORTANT:\n- Group sessions into batches based on the strategy above\n- Launch ALL batch analyzers in ONE message with multiple Task calls (max 9)\n- Each agent processes their entire batch of sessions\n- All agents work in parallel - DO NOT wait between launches\n- Examples:\n * 17 sessions = 2 agents, each handling 8-9 sessions\n * 25 sessions = 3 agents, each handling 8-9 sessions \n * 57 sessions = 9 agents, each handling 6-7 sessions\n\n## Phase 3 - Report Generation (10 seconds)\nAfter collecting ALL session analysis results, launch the report generator:\n\nTask(subagent_type=\"devark-report-generator\",\n description=\"Generate JSON report data from session analyses\",\n prompt=\"Generate comprehensive report data from the session analysis results.\n\nINPUT: You will receive arrays of session analysis results from the batch analyzers.\nSTATUS LINE INSTALLED: ${context.statusLineInstalled ? 'Yes' : 'No'}\n\nYOUR TASK:\n1. Flatten and aggregate all session data\n2. Calculate overall metrics and statistics\n3. OUTPUT a JSON object with the report data\n\nYou must return a JSON object with this structure:\n{\n 'metadata': {\n 'totalSessions': number,\n 'dataProcessed': 'size string',\n 'activeDevelopment': 'hours string',\n 'projects': number,\n 'generatedAt': 'ISO timestamp',\n 'dateRange': 'date range string'\n },\n 'executiveSummary': ['3-4 key insights'],\n 'activityDistribution': {\n 'Development': percentage,\n 'Debugging': percentage,\n 'Testing': percentage,\n // etc...\n },\n 'keyAccomplishments': ['5-6 major accomplishments'],\n 'promptQuality': {\n 'methodology': 'how prompts were analyzed',\n 'breakdown': {\n 'excellent': percentage,\n 'good': percentage,\n 'fair': percentage,\n 'poor': percentage\n },\n 'insights': 'key insight about prompt patterns',\n 'averageScore': number (0-100)\n },\n 'projectBreakdown': [\n {\n 'name': 'project name',\n 'sessions': count,\n 'largestSession': 'duration',\n 'focus': 'main activity'\n }\n ]\n}\n\nCRITICAL INSTRUCTIONS:\n- Return ONLY the JSON object\n- Do NOT use Write tool - just OUTPUT the JSON\n- Do NOT include HTML, markers, or explanations\n- Calculate prompt quality from session analyses\n- Return pure JSON to the orchestrator\")\n\nIMPORTANT: The report generator outputs JSON to you. You then OUTPUT it again in a code block.\n\n## Critical Performance Rules\n- Phase 1: Read manifest (3 seconds)\n- Phase 2: Launch batch analyzers (MAX 9 agents, 5 seconds to launch, 20-30 seconds to run)\n- Phase 3: Launch report generator (5 seconds)\n- Total time: ~35-45 seconds regardless of session count\n\nKEY POINTS:\n- Batch sessions to limit parallel agents (max 9)\n- All batch analyzers launch IN ONE MESSAGE with multiple Task calls\n- Each agent handles 5-10 sessions (not just one)\n- Report generator outputs JSON data\n- Orchestrator OUTPUTS the JSON again in a code block\n- The system automatically converts JSON to HTML and saves it`;\n\n // Build a shorter, more user-friendly command for display\n const displayCommand = `claude \"Analyze my Claude Code sessions from ${timeframeDesc} using devark sub-agents...\"`;\n \n return {\n prompt,\n systemPrompt, // Include system prompt for behavioral instructions\n command: displayCommand, // Show abbreviated version in UI\n description: `Comprehensive ${timeframe} analysis across ${projectNames.length} project${projectNames.length > 1 ? 's' : ''}`\n };\n}\n\n/**\n * Build a simple command for quick analysis without full orchestration\n */\nexport function buildSimplePrompt(context: PromptContext): string {\n const { timeframe, projectNames } = context;\n \n const projectList = projectNames.join(', ');\n \n return `@devark-report-generator analyze my coding sessions from the last ${timeframe} for projects: ${projectList}. Focus on productivity insights and key accomplishments.`;\n}\n\n/**\n * Get the full command with proper escaping for clipboard/terminal\n */\nexport function getExecutableCommand(prompt: string): string {\n // Escape for shell execution\n const escaped = prompt\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\$/g, '\\\\$')\n .replace(/`/g, '\\\\`')\n .replace(/\\n/g, '\\\\n');\n \n return `claude \"${escaped}\"`;\n}","import { readFileSync } from 'fs';\nimport { join } from 'path';\nimport type { ReportData } from '../types/report-data';\n\nexport class ReportTemplateEngine {\n private template: string = '';\n \n // Activity color mapping - aligned with devark-react-router\n private readonly ACTIVITY_COLORS: Record<string, string> = {\n 'debugging': '#ef4444',\n 'feature development': '#10b981',\n 'feature': '#10b981',\n 'development': '#10b981',\n 'refactoring': '#3b82f6',\n 'planning': '#eab308',\n 'architecture': '#8b5cf6',\n 'architecture & planning': '#8b5cf6',\n 'research': '#8b5cf6',\n 'learning': '#06b6d4',\n 'testing': '#f97316',\n 'integration': '#3b82f6',\n 'integration & testing': '#3b82f6',\n 'review': '#ec4899',\n 'optimization': '#10b981',\n 'debugging & optimization': '#ef4444',\n 'coding': '#10b981',\n 'documentation': '#8b5cf6',\n 'default': '#6b7280'\n };\n\n async loadTemplate(): Promise<void> {\n // Look for template in multiple locations to support both development and NPX usage\n const possiblePaths = [\n // NPX package - template is directly in dist/ (tsup bundles everything to dist/index.js)\n join(__dirname, 'report-template.html'),\n // NPX package - alternative location\n join(__dirname, '..', 'report-template.html'),\n // NPX package - old location for compatibility\n join(__dirname, '..', 'templates', 'report-template.html'),\n // Development - template is in src/templates\n join(process.cwd(), 'src', 'templates', 'report-template.html'),\n join(process.cwd(), 'devark-cli', 'src', 'templates', 'report-template.html'),\n // Fallback paths\n join(__dirname, '..', '..', 'src', 'templates', 'report-template.html'),\n join(__dirname, '..', '..', 'dist', 'report-template.html'),\n ];\n \n // Debug logging\n if (process.env.DEVARK_DEBUG === '1') {\n console.log('[DEBUG] Looking for template file...');\n console.log('[DEBUG] __dirname:', __dirname);\n console.log('[DEBUG] process.cwd():', process.cwd());\n }\n \n let templatePath: string | null = null;\n for (const path of possiblePaths) {\n try {\n this.template = readFileSync(path, 'utf-8');\n templatePath = path;\n if (process.env.DEVARK_DEBUG === '1') {\n console.log('[DEBUG] ✓ Found template at:', path);\n }\n break;\n } catch (err) {\n if (process.env.DEVARK_DEBUG === '1') {\n console.log('[DEBUG] ✗ Not found at:', path);\n }\n }\n }\n \n if (!templatePath) {\n const errorMsg = `Could not find report template file. Searched in:\\n${possiblePaths.join('\\n')}`;\n throw new Error(errorMsg);\n }\n }\n\n generateReport(data: ReportData): string {\n if (!this.template) {\n throw new Error('Template not loaded. Call loadTemplate() first.');\n }\n\n let html = this.template;\n\n // Replace all metadata fields\n html = html.replace(/{{metadata\\.dateRange}}/g, data.metadata.dateRange);\n html = html.replace(/{{metadata\\.totalSessions}}/g, data.metadata.totalSessions.toString());\n html = html.replace(/{{metadata\\.dataProcessed}}/g, data.metadata.dataProcessed);\n html = html.replace(/{{metadata\\.activeDevelopment}}/g, data.metadata.activeDevelopment);\n html = html.replace(/{{metadata\\.projects}}/g, data.metadata.projects.toString());\n html = html.replace(/{{metadata\\.generatedAt}}/g, data.metadata.generatedAt);\n\n // Generate executive summary list\n const executiveSummaryHtml = data.executiveSummary\n .map((item: string) => ` <li>${item}</li>`)\n .join('\\n');\n html = html.replace('{{executiveSummary}}', executiveSummaryHtml);\n\n // Generate activity distribution bars with proper styling\n const activityBarsHtml = Object.entries(data.activityDistribution)\n .map(([activity, percentage]) => {\n const colorKey = activity.toLowerCase();\n const color = this.ACTIVITY_COLORS[colorKey] || this.ACTIVITY_COLORS.default;\n const cssClass = `activity-${colorKey.replace(/[\\s&]/g, '-')}`;\n \n return ` <div class=\"activity-item\">\n <div class=\"activity-header\">\n <span class=\"activity-name\">${activity}</span>\n <span class=\"activity-percentage\">${percentage}%</span>\n </div>\n <div class=\"activity-bar\">\n <div class=\"activity-fill ${cssClass}\" style=\"width: ${percentage}%; background: ${color};\"></div>\n </div>\n </div>`;\n })\n .join('\\n');\n html = html.replace('{{activityBars}}', activityBarsHtml);\n\n // Generate key accomplishments list\n const keyAccomplishmentsHtml = data.keyAccomplishments\n .map((item: string) => ` <li>${item}</li>`)\n .join('\\n');\n html = html.replace('{{keyAccomplishments}}', keyAccomplishmentsHtml);\n\n // Generate project breakdown cards with improved structure\n const projectCardsHtml = data.projectBreakdown && data.projectBreakdown.length > 0\n ? data.projectBreakdown\n .map((project: any) => ` <div class=\"project-card\">\n <div class=\"project-header\">\n <span class=\"project-name\">${project.name}</span>\n <span class=\"session-count\">${project.sessions} sessions</span>\n </div>\n <div class=\"project-stats\">Largest: ${project.largestSession}</div>\n <p class=\"project-focus\">${project.focus}</p>\n </div>`)\n .join('\\n')\n : '';\n html = html.replace('{{projectCards}}', projectCardsHtml);\n\n // Replace prompt quality analysis with all fields\n if (data.promptQuality) {\n html = html.replace(/{{promptQuality\\.averageScore}}/g, (data.promptQuality.averageScore || 0).toString());\n html = html.replace(/{{promptQuality\\.breakdown\\.excellent}}/g, (data.promptQuality.breakdown?.excellent || 0).toString());\n html = html.replace(/{{promptQuality\\.breakdown\\.good}}/g, (data.promptQuality.breakdown?.good || 0).toString());\n html = html.replace(/{{promptQuality\\.breakdown\\.fair}}/g, (data.promptQuality.breakdown?.fair || 0).toString());\n html = html.replace(/{{promptQuality\\.breakdown\\.poor}}/g, (data.promptQuality.breakdown?.poor || 0).toString());\n } else {\n // Default values when promptQuality is not provided\n html = html.replace(/{{promptQuality\\.averageScore}}/g, '0');\n html = html.replace(/{{promptQuality\\.breakdown\\.excellent}}/g, '0');\n html = html.replace(/{{promptQuality\\.breakdown\\.good}}/g, '0');\n html = html.replace(/{{promptQuality\\.breakdown\\.fair}}/g, '0');\n html = html.replace(/{{promptQuality\\.breakdown\\.poor}}/g, '0');\n }\n html = html.replace(/{{promptQuality\\.methodology}}/g, data.promptQuality?.methodology || '');\n html = html.replace(/{{promptQuality\\.insights}}/g, data.promptQuality?.insights || '');\n\n // Replace report generation stats\n html = html.replace(/{{reportGeneration\\.duration}}/g, data.reportGeneration.duration);\n html = html.replace(/{{reportGeneration\\.apiTime}}/g, data.reportGeneration.apiTime);\n html = html.replace(/{{reportGeneration\\.turns}}/g, data.reportGeneration.turns.toString());\n html = html.replace(/{{reportGeneration\\.estimatedCost}}/g, data.reportGeneration.estimatedCost.toFixed(2));\n\n // Handle optional sections (timeline and recommendations)\n // For now, remove these placeholders if not implemented\n html = html.replace('{{timeline}}', '');\n html = html.replace('{{recommendations}}', '');\n\n return html;\n }\n}","import { promises as fs, existsSync } from 'fs';\nimport path from 'path';\nimport { colors, icons } from './ui/styles';\nimport { logger } from '../utils/logger';\nimport { parseProjectName } from './ui/project-display';\nimport { ReportTemplateEngine } from './report-template-engine';\nimport type { ReportData } from '../types/report-data';\n\n/**\n * Execution statistics from Claude\n */\ninterface ExecutionStats {\n duration_ms: number;\n duration_api_ms: number;\n num_turns: number;\n total_cost_usd: number;\n session_id: string;\n subtype: string;\n is_error: boolean;\n}\n\n/**\n * Report generation result\n */\nexport interface ReportResult {\n success: boolean;\n reportPath?: string;\n reportContent?: string;\n executionStats?: ExecutionStats;\n error?: string;\n}\n\n/**\n * Generate a unique report filename by checking for existing files\n * and appending an incremental suffix if needed\n */\nfunction getUniqueReportFilename(basePath: string): string {\n const dateStr = new Date().toISOString().split('T')[0];\n const baseFilename = `devark-report-${dateStr}`;\n \n // Check if base filename exists\n let filename = `${baseFilename}.html`;\n let fullPath = path.join(basePath, filename);\n \n if (!existsSync(fullPath)) {\n return fullPath;\n }\n \n // If it exists, try with incremental suffixes\n let counter = 1;\n while (counter < 100) { // Reasonable upper limit\n filename = `${baseFilename}-${counter}.html`;\n fullPath = path.join(basePath, filename);\n \n if (!existsSync(fullPath)) {\n return fullPath;\n }\n \n counter++;\n }\n \n // Fallback: use timestamp if somehow we have 100+ reports\n const timestamp = Date.now();\n filename = `${baseFilename}-${timestamp}.html`;\n return path.join(basePath, filename);\n}\n\n/**\n * Handles JSON report generation, processing, and saving\n */\nexport class ReportGenerator {\n private reportData: ReportData | null = null;\n private capturingJson: boolean = false;\n private jsonBuffer: string = '';\n private reportFilePath: string = '';\n private executionStats: ExecutionStats | null = null;\n private templateEngine: ReportTemplateEngine;\n\n constructor() {\n this.templateEngine = new ReportTemplateEngine();\n }\n\n /**\n * Start capturing report content\n */\n public startCapture(): void {\n this.capturingJson = true;\n this.jsonBuffer = '';\n this.reportData = null;\n console.log();\n console.log(colors.highlight('🚀 TEMPLATE-BASED REPORT GENERATOR v0.6.0'));\n console.log(colors.muted(' Using new JSON → Template engine (no direct HTML generation)'));\n console.log();\n console.log(colors.success('📝 Generating report data...'));\n }\n\n /**\n * Process a message that may contain JSON report data\n */\n public processMessage(text: string): void {\n // Try to detect JSON object in the message\n const jsonMatch = text.match(/\\{[\\s\\S]*\\}/);\n \n if (jsonMatch) {\n try {\n // Attempt to parse the JSON\n const parsedData = JSON.parse(jsonMatch[0]) as ReportData;\n \n // Validate that it has the expected structure\n if (parsedData.metadata && parsedData.executiveSummary && parsedData.activityDistribution) {\n this.reportData = parsedData;\n this.capturingJson = false;\n console.log(colors.success('✅ JSON data captured (template engine will format)'));\n logger.debug('Captured report data:', parsedData);\n \n // Store the report path for later\n this.reportFilePath = getUniqueReportFilename(process.cwd());\n console.log(colors.dim(`[DEBUG] Will save report to: ${this.reportFilePath} after stats are available`));\n } else {\n // Not the expected structure, might be capturing multi-line JSON\n if (this.capturingJson) {\n this.jsonBuffer += text;\n }\n }\n } catch (e) {\n // Not valid JSON yet, might be partial\n if (this.capturingJson) {\n this.jsonBuffer += text;\n \n // Try to parse accumulated buffer\n const bufferMatch = this.jsonBuffer.match(/\\{[\\s\\S]*\\}/);\n if (bufferMatch) {\n try {\n const parsedData = JSON.parse(bufferMatch[0]) as ReportData;\n if (parsedData.metadata && parsedData.executiveSummary) {\n this.reportData = parsedData;\n this.capturingJson = false;\n this.jsonBuffer = '';\n console.log(colors.success('✅ JSON data captured (template engine will format)'));\n this.reportFilePath = getUniqueReportFilename(process.cwd());\n }\n } catch {\n // Still not complete, continue capturing\n console.log(colors.muted(`Capturing report data... (${(this.jsonBuffer.length / 1024).toFixed(1)} KB)`));\n }\n }\n }\n }\n } else if (this.capturingJson) {\n // No JSON detected but we're capturing, add to buffer\n this.jsonBuffer += text;\n console.log(colors.muted(`Capturing report data... (${(this.jsonBuffer.length / 1024).toFixed(1)} KB)`));\n }\n }\n\n /**\n * Set execution statistics for the report\n */\n public setExecutionStats(stats: ExecutionStats): void {\n this.executionStats = stats;\n logger.debug('Set execution stats for report:', stats);\n }\n\n /**\n * Check if we're currently capturing a report\n */\n public isCapturing(): boolean {\n return this.capturingJson;\n }\n\n /**\n * Check if we have report data ready to save\n */\n public hasReport(): boolean {\n return this.reportData !== null && this.reportFilePath.length > 0;\n }\n\n /**\n * Format duration in milliseconds to human readable\n */\n private formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n \n if (minutes > 0) {\n return `${minutes}m ${remainingSeconds}s`;\n }\n return `${seconds}s`;\n }\n\n /**\n * Generate HTML from JSON data and save the report\n */\n public async saveReport(): Promise<ReportResult> {\n if (!this.hasReport() || !this.reportData) {\n return {\n success: false,\n error: 'No report data to save'\n };\n }\n\n console.log(colors.dim('[DEBUG] Processing report with template engine v0.6.0...'));\n \n try {\n // Load the template\n console.log(colors.info('🔧 Loading HTML template...'));\n await this.templateEngine.loadTemplate();\n console.log(colors.success('✅ Template loaded, injecting data...'));\n \n // If we have execution stats, update the report data\n if (this.executionStats) {\n this.reportData.reportGeneration = {\n duration: this.formatDuration(this.executionStats.duration_ms),\n apiTime: this.formatDuration(this.executionStats.duration_api_ms),\n turns: this.executionStats.num_turns,\n estimatedCost: this.executionStats.total_cost_usd,\n sessionId: this.executionStats.session_id\n };\n }\n \n // Generate HTML from the template and data\n const htmlContent = this.templateEngine.generateReport(this.reportData);\n \n // Save the HTML report\n await fs.writeFile(this.reportFilePath, htmlContent);\n const reportFile = parseProjectName(this.reportFilePath);\n console.log(colors.success(`✅ Template-based report saved as: ${reportFile}`));\n console.log(colors.muted(` Size: ${(htmlContent.length / 1024).toFixed(2)} KB`));\n \n return {\n success: true,\n reportPath: this.reportFilePath,\n reportContent: htmlContent,\n executionStats: this.executionStats || undefined\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.log(colors.error(`❌ Failed to save report: ${errorMessage}`));\n \n return {\n success: false,\n error: errorMessage\n };\n }\n }\n\n /**\n * Display completion message with stats\n */\n public displayCompletionMessage(): void {\n if (!this.reportFilePath) return;\n\n const reportFile = parseProjectName(this.reportFilePath);\n \n console.log(colors.success(`${icons.check} Template-based report generation complete! (v0.6.0)`));\n console.log(colors.info(`📁 Report saved as: ${reportFile}`));\n console.log(colors.muted(`📂 Location: ${this.reportFilePath}`));\n console.log();\n console.log(colors.highlight(`🌐 Open in browser:`));\n console.log(colors.accent(` file://${this.reportFilePath}`));\n \n // Display execution stats if available\n if (this.executionStats) {\n console.log();\n this.displayExecutionStats();\n }\n }\n\n /**\n * Display execution statistics\n */\n private displayExecutionStats(): void {\n if (!this.executionStats) return;\n\n console.log(colors.highlight('📊 Execution Statistics:'));\n console.log(colors.muted(' ⏱️ Duration: ') + colors.accent(this.formatDuration(this.executionStats.duration_ms)));\n console.log(colors.muted(' 🚀 API Time: ') + colors.accent(this.formatDuration(this.executionStats.duration_api_ms)));\n console.log(colors.muted(' 🔄 Turns Used: ') + colors.accent(this.executionStats.num_turns.toString()));\n console.log(colors.muted(' 💰 Cost: ') + colors.accent(`$${this.executionStats.total_cost_usd.toFixed(4)}`));\n \n // Show session ID only if present\n if (this.executionStats.session_id) {\n const shortSessionId = this.executionStats.session_id.length > 12 \n ? this.executionStats.session_id.substring(0, 12) + '...' \n : this.executionStats.session_id;\n console.log(colors.muted(' 🆔 Session: ') + colors.dim(shortSessionId));\n }\n \n // Add status indicator based on result type\n if (this.executionStats.subtype === 'error_max_turns') {\n console.log(colors.warning(' ⚠️ Status: Maximum turns reached'));\n } else if (this.executionStats.subtype === 'error_during_execution') {\n console.log(colors.error(' ❌ Status: Error during execution'));\n }\n }\n}","import { colors, icons, progress as progressChars, padRight, getTerminalWidth } from './styles';\n\n/**\n * Spinner animation frames\n */\nconst spinners = {\n dots: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n dots2: ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'],\n line: ['─', '\\\\', '|', '/'],\n circle: ['◐', '◓', '◑', '◒'],\n box: ['▖', '▘', '▝', '▗'],\n arc: ['◜', '◠', '◝', '◞', '◡', '◟'],\n bounce: ['⠁', '⠂', '⠄', '⡀', '⢀', '⠠', '⠐', '⠈'],\n pulse: ['▁', '▃', '▄', '▅', '▆', '▇', '█', '▇', '▆', '▅', '▄', '▃'],\n wave: ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█', '▇', '▆', '▅', '▄', '▃', '▂'],\n arrow: ['←', '↖', '↑', '↗', '→', '↘', '↓', '↙'],\n bouncingBar: ['[ ]', '[= ]', '[== ]', '[=== ]', '[ ===]', '[ ==]', '[ =]', '[ ]'],\n clock: ['🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛'],\n};\n\n/**\n * Create an animated spinner\n */\nexport class Spinner {\n private frames: string[];\n private currentFrame: number = 0;\n private message: string;\n private color: typeof colors[keyof typeof colors];\n \n constructor(\n type: keyof typeof spinners = 'dots',\n message: string = 'Loading...',\n color: typeof colors[keyof typeof colors] = colors.primary\n ) {\n this.frames = spinners[type] || spinners.dots;\n this.message = message;\n this.color = color;\n }\n \n next(): string {\n const frame = this.frames[this.currentFrame];\n this.currentFrame = (this.currentFrame + 1) % this.frames.length;\n return this.color(frame) + ' ' + colors.primary(this.message);\n }\n \n setMessage(message: string): void {\n this.message = message;\n }\n}\n\n/**\n * Create a beautiful progress bar\n */\nexport function createProgressBar(\n current: number,\n total: number,\n options?: {\n width?: number;\n showPercentage?: boolean;\n showNumbers?: boolean;\n label?: string;\n gradient?: boolean;\n style?: 'default' | 'blocks' | 'smooth' | 'ascii';\n }\n): string {\n const width = options?.width || Math.min(getTerminalWidth() - 20, 40);\n const percentage = Math.min(100, Math.round((current / total) * 100));\n const filled = Math.floor((percentage / 100) * width);\n \n let bar = '';\n \n switch (options?.style) {\n case 'blocks':\n // Block-style progress bar\n for (let i = 0; i < width; i++) {\n if (i < filled) {\n bar += progressChars.full;\n } else if (i === filled && percentage % (100 / width) !== 0) {\n // Partial block for more precision\n const partial = (percentage % (100 / width)) / (100 / width);\n if (partial > 0.75) bar += progressChars.three_quarters;\n else if (partial > 0.5) bar += progressChars.half;\n else if (partial > 0.25) bar += progressChars.quarter;\n else bar += progressChars.empty;\n } else {\n bar += progressChars.empty;\n }\n }\n break;\n \n case 'smooth': {\n // Smooth gradient bar\n const smoothChars = ['░', '▒', '▓', '█'];\n for (let i = 0; i < width; i++) {\n const position = i / width;\n const fillRatio = percentage / 100;\n if (position < fillRatio) {\n const intensity = Math.min(1, (fillRatio - position) * 4);\n const charIndex = Math.floor(intensity * (smoothChars.length - 1));\n bar += smoothChars[charIndex];\n } else {\n bar += smoothChars[0];\n }\n }\n break;\n }\n \n case 'ascii':\n // ASCII-only progress bar\n bar = '[' + '='.repeat(filled) + '>' + ' '.repeat(Math.max(0, width - filled - 1)) + ']';\n break;\n \n default:\n // Default Unicode bar\n for (let i = 0; i < width; i++) {\n if (i < filled) {\n bar += '█';\n } else {\n bar += '░';\n }\n }\n }\n \n // Apply color gradient if requested\n if (options?.gradient) {\n let coloredBar = '';\n for (let i = 0; i < bar.length; i++) {\n const position = i / bar.length;\n if (position < 0.33) {\n coloredBar += colors.error(bar[i]);\n } else if (position < 0.66) {\n coloredBar += colors.warning(bar[i]);\n } else {\n coloredBar += colors.success(bar[i]);\n }\n }\n bar = coloredBar;\n } else {\n // Standard coloring based on percentage\n if (percentage < 33) {\n bar = colors.error(bar);\n } else if (percentage < 66) {\n bar = colors.warning(bar);\n } else {\n bar = colors.success(bar);\n }\n }\n \n // Build the complete progress display\n let display = '';\n \n if (options?.label) {\n display += colors.primary(options.label) + ' ';\n }\n \n display += bar;\n \n if (options?.showPercentage !== false) {\n display += ' ' + colors.highlight(`${percentage}%`);\n }\n \n if (options?.showNumbers) {\n display += colors.dim(` (${current}/${total})`);\n }\n \n return display;\n}\n\n/**\n * Create a multi-progress display for concurrent operations\n */\nexport function createMultiProgress(\n items: Array<{\n label: string;\n current: number;\n total: number;\n status?: 'active' | 'completed' | 'error' | 'pending';\n }>,\n options?: {\n width?: number;\n showPercentage?: boolean;\n }\n): string {\n const width = options?.width || 30;\n const lines: string[] = [];\n \n // Find the longest label for alignment\n const maxLabelLength = Math.max(...items.map(item => item.label.length));\n \n items.forEach(item => {\n const percentage = Math.round((item.current / item.total) * 100);\n const filled = Math.floor((percentage / 100) * width);\n \n // Status icon\n let statusIcon = '';\n switch (item.status) {\n case 'completed':\n statusIcon = colors.success(icons.check);\n break;\n case 'error':\n statusIcon = colors.error(icons.error);\n break;\n case 'active':\n statusIcon = colors.primary(icons.loading);\n break;\n case 'pending':\n statusIcon = colors.dim(icons.clock);\n break;\n default:\n statusIcon = colors.primary(icons.bullet);\n }\n \n // Label\n const label = padRight(item.label, maxLabelLength);\n \n // Progress bar\n let bar = '';\n for (let i = 0; i < width; i++) {\n if (i < filled) {\n bar += progressChars.full;\n } else {\n bar += progressChars.empty;\n }\n }\n \n // Color based on status\n if (item.status === 'completed') {\n bar = colors.success(bar);\n } else if (item.status === 'error') {\n bar = colors.error(bar);\n } else if (item.status === 'active') {\n bar = colors.primary(bar);\n } else {\n bar = colors.dim(bar);\n }\n \n // Percentage\n const percentageText = options?.showPercentage !== false\n ? ' ' + colors.highlight(`${percentage}%`)\n : '';\n \n lines.push(`${statusIcon} ${colors.primary(label)} ${bar}${percentageText}`);\n });\n \n return lines.join('\\n');\n}\n\n/**\n * Create step-by-step progress indicator\n */\nexport function createStepProgress(\n steps: Array<{\n label: string;\n status: 'pending' | 'active' | 'completed' | 'error' | 'skipped';\n description?: string;\n }>,\n options?: {\n showNumbers?: boolean;\n compact?: boolean;\n }\n): string {\n const lines: string[] = [];\n const totalSteps = steps.length;\n const completedSteps = steps.filter(s => s.status === 'completed').length;\n \n // Header\n if (!options?.compact) {\n const progressBar = createProgressBar(completedSteps, totalSteps, {\n width: 30,\n showNumbers: true,\n style: 'blocks',\n });\n \n lines.push(colors.highlight('Progress: ') + progressBar);\n lines.push('');\n }\n \n // Steps\n steps.forEach((step, index) => {\n const stepNumber = options?.showNumbers !== false ? `${index + 1}. ` : '';\n \n // Status icon and color\n let icon = '';\n let labelColor = colors.primary;\n let descColor = colors.dim;\n \n switch (step.status) {\n case 'completed':\n icon = colors.success(icons.check);\n labelColor = colors.success;\n break;\n case 'active':\n icon = colors.primary(icons.loading);\n labelColor = colors.highlight;\n descColor = colors.primary;\n break;\n case 'error':\n icon = colors.error(icons.error);\n labelColor = colors.error;\n descColor = colors.error;\n break;\n case 'skipped':\n icon = colors.dim(icons.arrow);\n labelColor = colors.dim;\n break;\n case 'pending':\n default:\n icon = colors.dim(icons.bullet);\n labelColor = colors.dim;\n }\n \n // Step line\n let stepLine = `${icon} ${colors.dim(stepNumber)}${labelColor(step.label)}`;\n \n // Add description on same line if compact\n if (options?.compact && step.description) {\n stepLine += colors.dim(' - ') + descColor(step.description);\n }\n \n lines.push(stepLine);\n \n // Add description on new line if not compact\n if (!options?.compact && step.description && step.status !== 'pending') {\n lines.push(` ${descColor(step.description)}`);\n }\n \n // Add connector line between steps (except after last)\n if (!options?.compact && index < steps.length - 1) {\n const connector = step.status === 'completed' ? colors.success('│') : colors.dim('│');\n lines.push(` ${connector}`);\n }\n });\n \n return lines.join('\\n');\n}\n\n/**\n * Create a loading animation with dots\n */\nexport class LoadingDots {\n private dots = 0;\n private maxDots = 3;\n private message: string;\n \n constructor(message: string = 'Loading') {\n this.message = message;\n }\n \n next(): string {\n this.dots = (this.dots + 1) % (this.maxDots + 1);\n return colors.primary(this.message) + colors.dim('.'.repeat(this.dots)) + ' '.repeat(this.maxDots - this.dots);\n }\n \n setMessage(message: string): void {\n this.message = message;\n }\n}\n\n/**\n * Create an indeterminate progress bar (for unknown total)\n */\nexport class IndeterminateProgress {\n private position = 0;\n private width: number;\n private barWidth = 10;\n private direction = 1;\n \n constructor(width: number = 40) {\n this.width = width;\n }\n \n next(): string {\n // Create the bar\n let bar = '';\n for (let i = 0; i < this.width; i++) {\n if (i >= this.position && i < this.position + this.barWidth) {\n bar += progressChars.full;\n } else {\n bar += progressChars.empty;\n }\n }\n \n // Update position\n this.position += this.direction;\n if (this.position + this.barWidth >= this.width || this.position <= 0) {\n this.direction *= -1;\n }\n \n return '[' + colors.primary(bar) + ']';\n }\n}\n\n/**\n * Create a download/upload progress display\n */\nexport function createTransferProgress(\n bytesTransferred: number,\n totalBytes: number,\n bytesPerSecond: number,\n options?: {\n label?: string;\n showSpeed?: boolean;\n showETA?: boolean;\n }\n): string {\n const lines: string[] = [];\n \n // Format bytes\n const formatBytes = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n };\n \n // Calculate ETA\n const remainingBytes = totalBytes - bytesTransferred;\n const etaSeconds = bytesPerSecond > 0 ? Math.floor(remainingBytes / bytesPerSecond) : 0;\n const etaMinutes = Math.floor(etaSeconds / 60);\n const etaText = etaMinutes > 0 \n ? `${etaMinutes}m ${etaSeconds % 60}s`\n : `${etaSeconds}s`;\n \n // Progress bar\n const progressBar = createProgressBar(bytesTransferred, totalBytes, {\n width: 40,\n showPercentage: true,\n style: 'blocks',\n });\n \n // Main line\n let mainLine = '';\n if (options?.label) {\n mainLine += colors.primary(options.label) + ' ';\n }\n mainLine += progressBar;\n lines.push(mainLine);\n \n // Details line\n const detailParts: string[] = [];\n \n // Bytes transferred\n detailParts.push(\n colors.dim(`${formatBytes(bytesTransferred)} / ${formatBytes(totalBytes)}`)\n );\n \n // Speed\n if (options?.showSpeed !== false && bytesPerSecond > 0) {\n detailParts.push(\n colors.primary(`${formatBytes(bytesPerSecond)}/s`)\n );\n }\n \n // ETA\n if (options?.showETA !== false && etaSeconds > 0) {\n detailParts.push(\n colors.dim(`ETA: ${etaText}`)\n );\n }\n \n if (detailParts.length > 0) {\n lines.push(' ' + detailParts.join(' | '));\n }\n \n return lines.join('\\n');\n}\n\n/**\n * Create a circular progress indicator (ASCII art)\n */\nexport function createCircularProgress(\n percentage: number,\n options?: {\n size?: 'small' | 'medium' | 'large';\n showPercentage?: boolean;\n }\n): string {\n const size = options?.size || 'medium';\n const lines: string[] = [];\n \n // Simple ASCII circular progress\n // const segments = 8;\n // const filled = Math.floor((percentage / 100) * segments);\n \n const segmentChars = ['○', '◔', '◑', '◕', '●'];\n const charIndex = Math.floor((percentage / 100) * (segmentChars.length - 1));\n \n if (size === 'small') {\n // Single character representation\n return colors.primary(segmentChars[charIndex]);\n }\n \n // Medium/large circular display\n const circle = ['⢀', '⢠', '⢰', '⢸', '⢼', '⢾', '⢿', '⢷', '⢯', '⢟', '⢏', '⢇', '⢃', '⢁'];\n const circleIndex = Math.floor((percentage / 100) * circle.length);\n \n if (size === 'medium') {\n const char = circle[Math.min(circleIndex, circle.length - 1)];\n return colors.primary(char) + ' ' + colors.highlight(`${percentage}%`);\n }\n \n // Large ASCII art circle (simplified)\n lines.push(' ╭───╮');\n lines.push(` │ ${colors.highlight(percentage.toString().padStart(3))}% │`);\n lines.push(' ╰───╯');\n \n return lines.join('\\n');\n}","import { executeClaude, ClaudeStreamEvent, ClaudeExecutorOptions } from '../utils/claude-executor';\nimport { ReportGenerator } from './report-generator';\nimport { colors, icons } from './ui/styles';\nimport { Spinner } from './ui/progress';\nimport { logger } from '../utils/logger';\n\n/**\n * Format a timestamp for display\n */\nfunction formatTimestamp(date: Date): string {\n const hours = date.getHours().toString().padStart(2, '0');\n const minutes = date.getMinutes().toString().padStart(2, '0');\n const seconds = date.getSeconds().toString().padStart(2, '0');\n return `[${hours}:${minutes}:${seconds}]`;\n}\n\n/**\n * Get elapsed time between two dates in seconds\n */\nfunction getElapsedSeconds(start: Date, end: Date): string {\n const elapsed = Math.floor((end.getTime() - start.getTime()) / 1000);\n return `+${elapsed}s`;\n}\n\n/**\n * Execute Claude with the orchestrated prompt for report generation\n * This maintains backward compatibility with the old executeClaudePrompt\n */\nexport async function executeClaudePrompt(\n prompt: string,\n options?: {\n systemPrompt?: string;\n cwd?: string;\n claudePath?: string;\n onStart?: () => void;\n onError?: (error: Error) => void;\n onComplete?: (code: number) => void;\n }\n): Promise<void> {\n const reportGenerator = new ReportGenerator();\n let spinner: Spinner | null = null;\n let spinnerInterval: NodeJS.Timeout | null = null;\n let lastResponseTime: Date | null = null;\n let messageCount = 0;\n let hasShownThinking = false;\n\n console.log(colors.muted(`Prompt length: ${prompt.length} characters`));\n console.log();\n console.log(colors.accent('Starting Claude analysis...'));\n console.log(colors.muted('This will take approximately 4-5 minutes.'));\n console.log();\n console.log(colors.highlight('━'.repeat(60)));\n console.log();\n\n // Create a custom stream event handler\n const handleStreamEvent = (event: ClaudeStreamEvent) => {\n const now = new Date();\n \n switch (event.type) {\n case 'system':\n if (event.subtype === 'init') {\n console.log(colors.dim(formatTimestamp(now)) + ' ' + colors.muted('Claude is initializing...'));\n \n // Start spinner on a new line\n spinner = new Spinner('dots2', 'Processing...', colors.primary);\n spinnerInterval = setInterval(() => {\n process.stdout.write('\\r' + spinner!.next() + ' ');\n }, 100);\n }\n break;\n\n case 'user':\n // User messages might contain tool results\n if (event.message?.content) {\n for (const content of event.message.content) {\n if (content.type === 'tool_result') {\n // Clear spinner and show tool result\n if (spinnerInterval) {\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n }\n \n const isError = content.is_error || false;\n \n if (isError) {\n // Don't show tool failures - they're usually expected (file not found, etc.)\n // Only show in debug mode\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim(formatTimestamp(now)) + ' ❌ ' + colors.error('Tool failed'));\n }\n } else {\n console.log(colors.dim(formatTimestamp(now)) + ' ✓ ' + colors.success('Tool completed'));\n \n // Show brief result preview in debug mode\n if (process.env.DEVARK_DEBUG && content.content) {\n const resultPreview = String(content.content).slice(0, 100);\n console.log(colors.dim(` Result: ${resultPreview}${resultPreview.length >= 100 ? '...' : ''}`));\n }\n }\n \n // Update spinner\n if (spinner) {\n spinner.setMessage('Processing tool results...');\n }\n \n if (spinnerInterval && spinner) {\n process.stdout.write(spinner.next() + ' ');\n }\n }\n }\n }\n break;\n\n case 'assistant':\n // This is the full assistant message in verbose mode\n if (event.message?.content) {\n for (const content of event.message.content) {\n if (content.type === 'text' && content.text) {\n messageCount++;\n \n // Clear spinner line before writing message\n if (spinnerInterval) {\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n }\n \n // Show timestamp and elapsed time since last response\n let timeInfo = colors.dim(formatTimestamp(now));\n if (lastResponseTime) {\n timeInfo += ' ' + colors.dim(getElapsedSeconds(lastResponseTime, now));\n }\n \n if (!hasShownThinking) {\n console.log(timeInfo + ' ' + colors.muted('Claude is responding...'));\n hasShownThinking = true;\n }\n \n // Process the message through report generator\n reportGenerator.processMessage(content.text);\n \n // If not capturing report, show the message\n if (!reportGenerator.isCapturing()) {\n const lines = content.text.split('\\n');\n console.log(timeInfo + ' ' + colors.accent('━━━'));\n lines.forEach((line: string) => {\n console.log(' ' + line);\n });\n console.log();\n }\n \n lastResponseTime = now;\n \n // Update spinner message\n if (spinner) {\n spinner.setMessage(`Waiting for next response... (${messageCount} messages so far)`);\n }\n \n // Restart spinner on new line\n if (spinnerInterval) {\n process.stdout.write(spinner!.next() + ' ');\n }\n } else if (content.type === 'tool_use') {\n // Handle tool use in assistant message\n if (spinnerInterval) {\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n }\n \n const toolName = content.name || 'Unknown tool';\n \n // Special handling for Task tool to show sub-agent\n if (toolName === 'Task' && content.input?.subagent_type) {\n const subagentType = content.input.subagent_type;\n console.log(colors.dim(formatTimestamp(now)) + ' 🚀 ' + colors.accent(`Launching sub-agent: ${subagentType}...`));\n \n // Start capturing when report generator is launched\n if (subagentType === 'devark-report-generator') {\n reportGenerator.startCapture();\n }\n } else {\n console.log(colors.dim(formatTimestamp(now)) + ' 🔧 ' + colors.primary(`Calling ${toolName}...`));\n }\n \n // Show tool input if in debug mode\n if (process.env.DEVARK_DEBUG && content.input) {\n const inputPreview = JSON.stringify(content.input).slice(0, 200);\n console.log(colors.dim(` Input: ${inputPreview}${inputPreview.length >= 200 ? '...' : ''}`));\n }\n \n // Update spinner\n if (spinner) {\n spinner.setMessage(`Running ${toolName}...`);\n }\n \n if (spinnerInterval && spinner) {\n process.stdout.write(spinner.next() + ' ');\n }\n }\n }\n }\n break;\n\n case 'result':\n // Capture execution stats from result message\n if (event.subtype && (event.subtype === 'success' || event.subtype === 'error_max_turns' || event.subtype === 'error_during_execution')) {\n const executionStats = {\n duration_ms: event.duration_ms || 0,\n duration_api_ms: event.duration_api_ms || 0,\n num_turns: event.num_turns || 0,\n total_cost_usd: event.total_cost_usd || 0,\n session_id: event.session_id || '',\n subtype: event.subtype,\n is_error: event.is_error || false\n };\n \n reportGenerator.setExecutionStats(executionStats);\n logger.debug('Captured execution stats:', executionStats);\n }\n \n // Final result message - clear spinner before showing\n if (spinnerInterval) {\n clearInterval(spinnerInterval);\n spinnerInterval = null;\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n }\n \n if (event.result && !event.message) {\n console.log(colors.dim(formatTimestamp(now)) + ' ' + colors.success('Final result:'));\n console.log(event.result);\n }\n break;\n\n case 'message_start':\n if (spinnerInterval) {\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n }\n console.log(colors.dim(formatTimestamp(now)) + ' ' + colors.muted('Claude is starting...'));\n if (spinnerInterval && spinner) {\n process.stdout.write(spinner.next() + ' ');\n }\n break;\n\n case 'content_block_start':\n if (!hasShownThinking) {\n if (spinnerInterval) {\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n }\n console.log(colors.dim(formatTimestamp(now)) + ' ' + colors.muted('Claude is thinking...'));\n hasShownThinking = true;\n if (spinnerInterval && spinner) {\n process.stdout.write(spinner.next() + ' ');\n }\n }\n break;\n\n case 'content_block_delta':\n // This is for non-verbose streaming\n if (event.delta?.type === 'text_delta' && event.delta?.text) {\n if (spinnerInterval) {\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n }\n process.stdout.write(event.delta.text);\n }\n break;\n\n case 'message_stop':\n // Message complete - don't clear spinner\n if (!spinnerInterval && spinner) {\n // Restart spinner if it was stopped\n spinnerInterval = setInterval(() => {\n process.stdout.write('\\r' + spinner!.next() + ' ');\n }, 100);\n }\n break;\n\n default:\n // Log unhandled message types for debugging\n logger.debug(`Unhandled message type: ${event.type}`, { \n type: event.type, \n subtype: event.subtype,\n hasMessage: !!event.message,\n hasContent: !!event.content,\n });\n \n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim(`[DEBUG] ${formatTimestamp(now)} Unhandled: type=${event.type}`));\n }\n }\n };\n\n // Store the exit code for later use\n let exitCode = 0;\n \n // Promise that resolves when the report display is complete\n const reportDisplayCompleteResolve: { resolve?: () => void } = {};\n const reportDisplayComplete: Promise<void> = new Promise<void>(resolve => {\n reportDisplayCompleteResolve.resolve = resolve;\n });\n \n // Execute Claude with stream event handling\n const claudeOptions: ClaudeExecutorOptions = {\n systemPrompt: options?.systemPrompt,\n cwd: options?.cwd,\n claudePath: options?.claudePath,\n onStreamEvent: handleStreamEvent,\n onStart: options?.onStart,\n onError: options?.onError,\n onComplete: async (code) => {\n // Store the exit code\n exitCode = code;\n \n // Clean up spinner if it's still running\n if (spinnerInterval) {\n clearInterval(spinnerInterval);\n spinnerInterval = null;\n process.stdout.write('\\r' + ' '.repeat(80) + '\\r');\n }\n\n // Debug logging to understand report capture status\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim(`[DEBUG] Checking for captured report...`));\n console.log(colors.dim(`[DEBUG] hasReport: ${reportGenerator.hasReport()}`));\n console.log(colors.dim(`[DEBUG] isCapturing: ${reportGenerator.isCapturing()}`));\n }\n \n // Save the report if we have one\n if (reportGenerator.hasReport()) {\n const result = await reportGenerator.saveReport();\n \n console.log();\n console.log(colors.highlight('━'.repeat(60)));\n console.log();\n \n if (result.success) {\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim(`[DEBUG] Report saved successfully`));\n }\n reportGenerator.displayCompletionMessage();\n } else {\n console.log(colors.warning(`${icons.warning} Report generation failed: ${result.error}`));\n }\n } else {\n console.log();\n console.log(colors.highlight('━'.repeat(60)));\n console.log();\n \n // Check if an HTML file was created anyway (by the old 3-agent system)\n const fs = await import('fs').then(m => m.promises);\n const files = await fs.readdir(process.cwd());\n const htmlFiles = files.filter(f => f.startsWith('devark-report-') && f.endsWith('.html'));\n \n if (htmlFiles.length > 0) {\n console.log(colors.success(`${icons.check} Report generation complete!`));\n console.log(colors.info(`📁 Report saved as: ${htmlFiles[htmlFiles.length - 1]}`));\n console.log(colors.muted(`📂 Location: ${process.cwd()}/${htmlFiles[htmlFiles.length - 1]}`));\n console.log();\n console.log(colors.highlight(`🌐 Open in browser:`));\n console.log(colors.accent(` file://${process.cwd()}/${htmlFiles[htmlFiles.length - 1]}`));\n } else {\n console.log(colors.warning(`${icons.warning} Analysis complete but no report was generated`));\n console.log(colors.muted(`Claude may not have output the report in the expected format`));\n }\n }\n \n // Signal that report display is complete\n if (reportDisplayCompleteResolve.resolve) {\n reportDisplayCompleteResolve.resolve();\n }\n \n // Don't call the original onComplete here - we'll do it after waiting for user input\n }\n };\n\n await executeClaude(prompt, claudeOptions);\n \n // Wait for the report display to complete\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim('[DEBUG] Waiting for report display to complete...'));\n }\n await reportDisplayComplete;\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim('[DEBUG] Report display complete'));\n }\n \n // Now handle the \"Press Enter to continue\" prompt synchronously\n // This happens AFTER the report is displayed but BEFORE returning to the menu\n \n // Check if we showed a report\n const fs = await import('fs').then(m => m.promises);\n const files = await fs.readdir(process.cwd());\n const htmlFiles = files.filter(f => f.startsWith('devark-report-') && f.endsWith('.html'));\n \n if (reportGenerator.hasReport() || htmlFiles.length > 0) {\n // We showed a report, so wait for user input\n console.log();\n console.log(colors.muted('Press Enter to continue...'));\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim('[DEBUG] Setting up raw stdin handler...'));\n \n // Check stdin state before we start\n console.log(colors.dim(`[DEBUG] stdin.isTTY: ${process.stdin.isTTY}`));\n console.log(colors.dim(`[DEBUG] stdin.readable: ${process.stdin.readable}`));\n console.log(colors.dim(`[DEBUG] stdin.readableFlowing: ${process.stdin.readableFlowing}`));\n console.log(colors.dim(`[DEBUG] stdin.isPaused: ${process.stdin.isPaused()}`));\n }\n \n // Clear any pending data first\n if (process.stdin.readable && !process.stdin.isPaused()) {\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim('[DEBUG] Draining any pending stdin data...'));\n }\n let chunk;\n while ((chunk = process.stdin.read()) !== null) {\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim(`[DEBUG] Drained: ${chunk.toString('hex')}`));\n }\n }\n }\n \n // Wait for ENTER key specifically\n await new Promise<void>(resolve => {\n try {\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim('[DEBUG] Enabling raw mode...'));\n }\n process.stdin.setRawMode(true);\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim('[DEBUG] Resuming stdin...'));\n }\n process.stdin.resume();\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim('[DEBUG] Waiting for Enter key...'));\n }\n \n const handleKeyPress = (data: Buffer | any) => {\n // Simple console.log without colors to avoid formatting issues\n if (process.env.DEVARK_DEBUG) {\n console.log('[DEBUG] Raw data received, type:', typeof data);\n console.log('[DEBUG] Data length:', data.length);\n }\n \n if (data.length > 0) {\n // Try multiple ways to get the byte value\n const str = data.toString();\n const charCode = str.charCodeAt(0);\n \n if (process.env.DEVARK_DEBUG) {\n console.log('[DEBUG] String:', JSON.stringify(str));\n console.log('[DEBUG] CharCode at 0:', charCode);\n console.log('[DEBUG] Is Buffer?', Buffer.isBuffer(data));\n }\n \n // Check if it's Enter key using string comparison or charCode\n // \"\\r\" is carriage return (Enter on most systems)\n // \"\\n\" is line feed (Enter on some systems)\n if (str === '\\r' || str === '\\n' || charCode === 13 || charCode === 10) {\n if (process.env.DEVARK_DEBUG) {\n console.log('[DEBUG] Enter key detected!');\n }\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener('data', handleKeyPress);\n resolve();\n } else if (charCode === 3) {\n if (process.env.DEVARK_DEBUG) {\n console.log('[DEBUG] Ctrl+C detected, exiting...');\n }\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener('data', handleKeyPress);\n process.exit(0);\n } else {\n if (process.env.DEVARK_DEBUG) {\n console.log('[DEBUG] Key ignored, waiting for Enter. CharCode was:', charCode);\n }\n }\n } else {\n if (process.env.DEVARK_DEBUG) {\n console.log('[DEBUG] Empty data received');\n }\n }\n };\n \n process.stdin.on('data', handleKeyPress);\n } catch (err) {\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.error(`[DEBUG] Error setting up stdin: ${err}`));\n console.log(colors.error(`[DEBUG] Stack: ${err instanceof Error ? err.stack : 'N/A'}`));\n }\n // Resolve anyway to prevent hanging\n resolve();\n }\n });\n }\n \n // Now call the original onComplete callback if provided\n if (options?.onComplete) {\n if (process.env.DEVARK_DEBUG) {\n console.log(colors.dim('[DEBUG] Calling original onComplete callback...'));\n }\n options.onComplete(exitCode);\n }\n}","import inquirer from 'inquirer';\nimport { colors, icons, box, format } from './styles';\nimport { discoverProjects, ClaudeProject } from '../claude-core';\nimport { SelectableProject } from './project-selector';\nimport { interactiveProjectSelector } from './interactive-project-selector';\nimport { buildOrchestratedPrompt, getExecutableCommand } from '../prompts/orchestrator';\nimport { PromptContext } from '../../types/prompts';\nimport { checkClaudeInstalled } from '../../utils/claude-executor';\nimport { executeClaudePrompt } from '../report-executor';\nimport { getStatusLineStatus } from '../status-line-manager';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { getTempDirectoryPath } from '../temp-directories';\n\ninterface TimeframeOption {\n name: string;\n value: string;\n days?: number;\n}\n\n/**\n * Display explanation about local report generation\n */\nfunction showLocalReportExplanation(): void {\n console.clear();\n \n // Main header with box drawing\n const headerText = ' Generate Local Report ';\n const headerWidth = 60;\n const headerPadding = Math.floor((headerWidth - headerText.length) / 2);\n const headerLine = box.horizontal.repeat(headerPadding) + headerText + box.horizontal.repeat(headerWidth - headerPadding - headerText.length);\n \n console.log('\\n' + colors.accent(box.horizontal.repeat(2) + headerLine + box.horizontal.repeat(2)));\n console.log();\n \n // Section 1: How it works\n console.log(colors.primary(format.bold('How Local Reports Work')));\n console.log(colors.highlight('Local reports use Claude Code to quickly analyze your sessions'));\n console.log(colors.highlight('and generate a HTML report with key insights,'));\n console.log(colors.highlight('keeping your data 100% private on your machine.'));\n console.log();\n \n // Section 2: What's included\n console.log(colors.primary(format.bold('Report Contents:')));\n console.log(` ${icons.bullet} ${colors.accent('Executive Summary')} - 3-4 key points`);\n console.log(` ${icons.bullet} ${colors.accent('Top 3 Projects')} - Time invested`);\n console.log(` ${icons.bullet} ${colors.accent('Key Accomplishments')} - 2-3 highlights`);\n console.log(` ${icons.bullet} ${colors.accent('Productivity Insight')} - 1 main observation`);\n console.log(` ${icons.bullet} ${colors.accent('Quick Stats')} - Total hours & sessions`);\n console.log();\n \n // Section 3: Privacy note\n console.log(colors.success(`${icons.lock} ${format.bold('100% Private')}`));\n console.log(colors.muted('All analysis happens locally using your Claude Code tokens.'));\n console.log(colors.muted('No data is sent to devark servers in local mode.'));\n console.log();\n \n // Section 4: First-time user guidance\n console.log(colors.primary(format.bold('👋 First Time? Start Small!')));\n console.log(colors.accent(' 📅 Try \"Last 24 hours\" - faster analysis (2-4 minutes)'));\n console.log(colors.accent(' 📁 Select just 1 project - easier to review results'));\n console.log(colors.muted(' You can always generate larger reports once you like what you see!'));\n console.log();\n \n // Bottom border\n console.log(colors.muted(box.horizontal.repeat(62)));\n console.log();\n}\n\n/**\n * Prompt for timeframe selection\n */\nasync function selectTimeframe(): Promise<{ timeframe: string; days: number }> {\n const timeframeOptions: TimeframeOption[] = [\n { name: 'Last 24 hours (Recommended for first time) - ~2-4 minutes', value: '24h', days: 1 },\n { name: 'Last 7 days - ~5-8 minutes', value: '7d', days: 7 },\n { name: 'Last 30 days - ~8-15 minutes', value: '30d', days: 30 },\n { name: 'Custom range', value: 'custom' }\n ];\n \n const { timeframe } = await inquirer.prompt([\n {\n type: 'list',\n name: 'timeframe',\n message: 'Select timeframe:',\n choices: timeframeOptions\n }\n ]);\n \n if (timeframe === 'custom') {\n const { days } = await inquirer.prompt([\n {\n type: 'number',\n name: 'days',\n message: 'Enter number of days to analyze:',\n default: 14,\n validate: (input) => {\n if (!input || input < 1 || input > 365) {\n return 'Please enter a number between 1 and 365';\n }\n return true;\n }\n }\n ]);\n return { timeframe: `${days}d`, days };\n }\n \n const selected = timeframeOptions.find(opt => opt.value === timeframe);\n return { timeframe, days: selected?.days || 7 };\n}\n\n/**\n * Convert ClaudeProject to SelectableProject for the UI\n */\nfunction toSelectableProjects(\n projects: ClaudeProject[], \n previouslySelected: string[]\n): SelectableProject[] {\n return projects.map(p => ({\n id: p.claudePath,\n name: p.name,\n path: p.actualPath,\n sessions: p.sessions,\n lastActivity: p.lastActivity || new Date(),\n selected: previouslySelected.includes(p.claudePath),\n isActive: p.isActive\n }));\n}\n\n/**\n * Main interactive function for generating local reports\n */\n/**\n * Show sub-agents management menu\n */\nasync function showSubAgentsManagement(): Promise<void> {\n const { installSubAgents, removeAllSubAgents } = await import('../sub-agents/manager');\n const { installSubAgentsInteractive } = await import('./sub-agents-installer');\n\n console.log('🤖 Sub-Agents Management');\n console.log('Current status: ✓ Installed\\n');\n\n const { action } = await inquirer.prompt([{\n type: 'list',\n name: 'action',\n message: 'What would you like to do?',\n choices: [\n 'Update sub-agents',\n 'Reinstall sub-agents',\n 'Uninstall sub-agents',\n '← Back'\n ]\n }]);\n\n // Handle management actions\n switch(action) {\n case 'Update sub-agents':\n console.log(colors.info('\\nUpdating sub-agents...'));\n // Update is essentially reinstall with force\n await installSubAgents({ force: true });\n console.log(colors.success('Sub-agents updated successfully!'));\n break;\n\n case 'Reinstall sub-agents':\n console.log(colors.info('\\nReinstalling sub-agents...'));\n // First remove all, then install\n await removeAllSubAgents();\n await installSubAgentsInteractive();\n console.log(colors.success('Sub-agents reinstalled successfully!'));\n break;\n\n case 'Uninstall sub-agents': {\n const { confirmUninstall } = await inquirer.prompt([{\n type: 'confirm',\n name: 'confirmUninstall',\n message: colors.warning('Are you sure you want to uninstall all sub-agents?'),\n default: false\n }]);\n\n if (confirmUninstall) {\n console.log(colors.info('\\nUninstalling sub-agents...'));\n await removeAllSubAgents();\n console.log(colors.success('Sub-agents uninstalled successfully!'));\n }\n break;\n }\n }\n}\n\nexport async function generateLocalReportInteractive(): Promise<void> {\n // Check if sub-agents are installed\n const { checkInstalledSubAgents } = await import('../sub-agents/manager');\n const subAgentStatus = await checkInstalledSubAgents();\n\n if (subAgentStatus.missing.length > 0) {\n // Sub-agents are missing, prompt to install\n console.clear();\n console.log('📊 Generate Local Report\\n');\n console.log('This feature requires devark sub-agents to be installed.');\n console.log('Sub-agents are local AI components that analyze your sessions.\\n');\n console.log('Current status: Not installed\\n');\n console.log('This is a one-time installation (~2 minutes).\\n');\n\n const { install } = await inquirer.prompt([{\n type: 'confirm',\n name: 'install',\n message: 'Install sub-agents and continue?',\n default: true\n }]);\n\n if (install) {\n const { installSubAgentsInteractive } = await import('./sub-agents-installer');\n await installSubAgentsInteractive();\n\n // Check if installation was successful\n const newStatus = await checkInstalledSubAgents();\n if (newStatus.missing.length === 0) {\n console.log();\n const { continueReport } = await inquirer.prompt([{\n type: 'confirm',\n name: 'continueReport',\n message: 'Sub-agents installed! Would you like to generate your report now?',\n default: true\n }]);\n\n if (!continueReport) {\n return;\n }\n } else {\n console.log(colors.warning('\\nSub-agent installation was incomplete. Please try again.'));\n return;\n }\n } else {\n return;\n }\n } else {\n // Sub-agents are installed, offer management option\n console.clear();\n console.log('📊 Generate Local Report\\n');\n console.log(colors.success('✓ Sub-agents installed\\n'));\n\n const { action } = await inquirer.prompt([{\n type: 'list',\n name: 'action',\n message: 'Select an option:',\n choices: [\n 'Continue to report generation',\n new inquirer.Separator('───────────────────'),\n 'Manage sub-agents',\n '← Back to main menu'\n ]\n }]);\n\n switch(action) {\n case 'Manage sub-agents':\n await showSubAgentsManagement();\n // Show the menu again after management\n await generateLocalReportInteractive();\n return;\n\n case '← Back to main menu':\n return;\n\n // Continue to report generation is handled by falling through\n }\n }\n \n // Show explanation\n showLocalReportExplanation();\n \n // Step 1: Select timeframe\n console.log(colors.accent('Step 1: Select Timeframe'));\n console.log();\n const { timeframe, days } = await selectTimeframe();\n console.log();\n \n // Step 2: Discover and select projects\n console.log(colors.accent('Step 2: Select Projects to Include'));\n console.log(colors.muted('Discovering Claude Code projects...'));\n console.log();\n \n // Add processing time guidance\n if (days === 1) {\n console.log(colors.info('💡 Tip: For 24-hour reports, selecting 1-2 projects gives the best experience'));\n } else if (days <= 7) {\n console.log(colors.info('💡 Tip: Multiple projects are fine, but expect longer processing time'));\n } else {\n console.log(colors.warning('💡 Tip: 30-day reports with many projects can take 10-15+ minutes'));\n }\n console.log();\n \n const allProjects = await discoverProjects();\n \n if (allProjects.length === 0) {\n console.log(colors.warning(`${icons.warning} No Claude Code projects found`));\n console.log(colors.muted('Start a Claude Code session to begin tracking.'));\n return;\n }\n \n // Filter projects by timeframe (only show projects with recent activity)\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - days);\n \n const recentProjects = allProjects.filter(p => \n p.lastActivity && p.lastActivity >= cutoffDate\n );\n \n if (recentProjects.length === 0) {\n console.log(colors.warning(`${icons.warning} No projects with activity in the last ${days} days`));\n console.log(colors.muted('Try selecting a longer timeframe.'));\n return;\n }\n \n // Convert to selectable format (no previous selection persistence for local reports)\n const selectableProjects = toSelectableProjects(recentProjects, []);\n \n // Show project selector\n const selectedProjects = await interactiveProjectSelector({\n projects: selectableProjects,\n multiSelect: true,\n title: `SELECT PROJECTS (${recentProjects.length} with recent activity)`,\n showStats: true\n });\n \n if (selectedProjects.length === 0) {\n console.log(colors.warning('\\nNo projects selected. Report generation cancelled.'));\n return;\n }\n \n // Step 3: Generate report\n console.clear();\n console.log(colors.accent('\\n--- Generating Report ---'));\n console.log();\n console.log(colors.info(`Timeframe: ${timeframe}`));\n console.log(colors.info(`Projects: ${selectedProjects.length} selected`));\n selectedProjects.forEach(p => {\n console.log(colors.muted(` ${icons.folder} ${p.name}`));\n });\n console.log();\n console.log(colors.warning('📍 Report will be saved in your current directory'));\n \n // Show dynamic time estimate based on selections\n let estimatedTime: string;\n if (days === 1 && selectedProjects.length === 1) {\n estimatedTime = '~2-4 minutes';\n } else if (days === 1 && selectedProjects.length <= 3) {\n estimatedTime = '~3-6 minutes';\n } else if (days <= 7 && selectedProjects.length <= 3) {\n estimatedTime = '~5-8 minutes';\n } else if (days <= 30 && selectedProjects.length <= 3) {\n estimatedTime = '~8-12 minutes';\n } else {\n estimatedTime = '~10-20 minutes';\n }\n \n console.log(colors.muted(` Estimated generation time: ${estimatedTime}`));\n console.log();\n \n // Check if status line is installed for the report recommendation\n const statusLineStatus = await getStatusLineStatus();\n const isStatusLineInstalled = statusLineStatus === 'installed';\n \n // Build the orchestrated prompt\n const promptContext: PromptContext = {\n timeframe,\n days,\n projectPaths: selectedProjects.map(p => p.id),\n projectNames: selectedProjects.map(p => p.name),\n statusLineInstalled: isStatusLineInstalled\n };\n \n const orchestrated = buildOrchestratedPrompt(promptContext);\n const executableCommand = getExecutableCommand(orchestrated.prompt);\n \n console.log(colors.primary('Generated Command:'));\n console.log();\n console.log(colors.accent('This command will orchestrate devark sub-agents to:'));\n console.log(colors.highlight(' 1. Fetch and organize your Claude Code sessions into chunks'));\n console.log(colors.highlight(` 2. Run ${days > 1 ? `${Math.min(days, 7)} parallel analyzers` : '1 analyzer'} to extract patterns`));\n console.log(colors.highlight(' 3. Generate a concise HTML report'));\n if (days > 1) {\n console.log();\n console.log(colors.success(` ⚡ Parallel execution: ${Math.min(days, 7)} sub-agents analyzers will run simultaneously!`));\n }\n console.log();\n \n // Check if Claude is installed for the recommended option\n const claudeCheck = await checkClaudeInstalled();\n \n // Build choices based on Claude availability\n const choices = [];\n if (claudeCheck.installed) {\n choices.push({ name: '🚀 Generate with Claude (Recommended)', value: 'execute' });\n }\n choices.push(\n { name: '📋 Copy command to clipboard', value: 'copy-full' },\n { name: '👁️ View full prompt', value: 'view' },\n { name: '↩️ Return to menu', value: 'return' }\n );\n \n // Show Claude not installed message if needed \n if (!claudeCheck.installed) {\n console.log(colors.muted('Claude CLI not available - using copy-to-clipboard method'));\n console.log();\n }\n \n // Prompt to copy command or return\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to do?',\n choices\n }\n ]);\n \n if (action === 'execute') {\n // Pre-fetch session files before executing Claude\n console.log();\n console.log(colors.accent('Pre-fetching session data...'));\n \n // Get the temp report directory that will be used as cwd\n const tempReportDir = getTempDirectoryPath('PRODUCTIVITY_REPORT');\n \n try {\n // Create temp directory for session files within the report directory\n const tempDir = path.join(tempReportDir, '.devark-temp');\n \n // Remove old temp directory if it exists\n try {\n await fs.rm(tempDir, { recursive: true, force: true });\n } catch {\n // Directory might not exist, that's fine\n }\n \n // Create fresh temp directory\n await fs.mkdir(tempDir, { recursive: true });\n console.log(colors.info(`📁 Created temp directory: ${tempDir}`));\n \n // Get Claude projects directory\n const claudeProjectsPath = path.join(os.homedir(), '.claude', 'projects');\n \n // Copy relevant session files\n let copiedFiles = 0;\n let totalSessions = 0;\n const manifest: any = {\n generated: new Date().toISOString(),\n timeframe: timeframe,\n timeframeDays: days,\n projects: [],\n sessionFiles: []\n };\n \n // Process each selected project\n for (const project of selectedProjects) {\n // Extract Claude folder name from the project ID\n // On Windows: project.id is like C:\\Users\\97254\\.claude\\projects\\C--devark-devark-cli\n // On Mac/Linux: project.id is like ~/.claude/projects/-home-user-projects-devark\n \n let sourceDir: string;\n let claudeFolderName: string;\n \n if (process.platform === 'win32') {\n // On Windows, project.id is already the full path\n sourceDir = project.id;\n // Extract just the folder name for prefixing files\n claudeFolderName = path.basename(project.id);\n } else {\n // On Mac/Linux, extract the folder name and join with base path\n claudeFolderName = project.id.split('/').pop() || '';\n sourceDir = path.join(claudeProjectsPath, claudeFolderName);\n }\n \n try {\n // Read all JSONL files from this project\n const files = await fs.readdir(sourceDir);\n const jsonlFiles = files.filter(f => f.endsWith('.jsonl'));\n \n let projectSessionCount = 0;\n \n // Check each session file\n for (const file of jsonlFiles) {\n const sourceFile = path.join(sourceDir, file);\n \n // Quick check if session is within timeframe\n const fileStat = await fs.stat(sourceFile);\n const since = new Date();\n since.setDate(since.getDate() - days);\n \n if (fileStat.mtime >= since) {\n // Copy file to temp directory with project prefix\n const destFile = path.join(tempDir, `${claudeFolderName}_${file}`);\n await fs.copyFile(sourceFile, destFile);\n \n copiedFiles++;\n projectSessionCount++;\n \n // Add to manifest with size information\n const sizeKB = parseFloat((fileStat.size / 1024).toFixed(2));\n manifest.sessionFiles.push({\n file: `${claudeFolderName}_${file}`,\n project: project.name,\n originalPath: sourceFile,\n modified: fileStat.mtime.toISOString(),\n sizeKB: sizeKB,\n isLarge: fileStat.size > 100000, // Files > 100KB are considered large\n readStrategy: fileStat.size > 100000 ? 'read_partial' : 'read_full'\n });\n }\n }\n \n // Add project info to manifest\n manifest.projects.push({\n name: project.name,\n path: project.path,\n claudePath: project.id,\n sessionCount: projectSessionCount\n });\n \n totalSessions += projectSessionCount;\n } catch (err) {\n console.log(colors.warning(`⚠️ Could not access project: ${project.name}`));\n console.log(colors.muted(` ${err instanceof Error ? err.message : String(err)}`));\n }\n }\n \n manifest.totalSessions = totalSessions;\n \n console.log(colors.success(`✓ Copied ${copiedFiles} session files from selected projects`));\n \n // Save lightweight manifest\n const manifestPath = path.join(tempDir, 'manifest.json');\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));\n \n // Verify manifest was created\n try {\n const stats = await fs.stat(manifestPath);\n const fileSize = (stats.size / 1024).toFixed(2);\n console.log(colors.success(`✅ Manifest created successfully (${fileSize} KB)`));\n console.log(colors.muted(` Sessions ready for analysis in: ${tempDir}`));\n } catch (verifyError) {\n // Manifest doesn't exist - critical error\n console.log(colors.error(`❌ CRITICAL: Failed to create manifest at ${manifestPath}`));\n console.log(colors.error(` Error: ${verifyError instanceof Error ? verifyError.message : String(verifyError)}`));\n console.log();\n console.log(colors.warning('Report generation cannot continue without the manifest.'));\n process.exit(1);\n }\n \n console.log();\n \n // Update the prompt to reference the temp directory\n const updatedPrompt = orchestrated.prompt.replace(\n 'Projects to analyze:',\n `Session files have been copied to: .devark-temp/\\nManifest available at: .devark-temp/manifest.json\\n\\nProjects to analyze:`\n );\n \n // Execute directly with Claude\n console.log(colors.muted(`Using orchestrated prompt (${updatedPrompt.length} characters)`));\n console.log(colors.muted(`System prompt adds behavioral instructions (${orchestrated.systemPrompt.length} characters)`));\n \n // Ensure temp report directory exists (already defined above)\n await fs.mkdir(tempReportDir, { recursive: true }).catch(() => {});\n \n await executeClaudePrompt(updatedPrompt, {\n systemPrompt: orchestrated.systemPrompt, // Pass the system prompt\n cwd: tempReportDir, // Use temp directory to isolate report generation sessions\n claudePath: claudeCheck.path, // Pass the found Claude path\n onComplete: async (code) => {\n console.log(colors.muted(`Claude completed with exit code: ${code}`));\n \n // Clean up temp directory\n try {\n const tempDir = path.join(tempReportDir, '.devark-temp');\n await fs.rm(tempDir, { recursive: true, force: true });\n console.log(colors.muted('Cleaned up temporary session files'));\n } catch (e) {\n // Ignore cleanup errors\n }\n },\n onError: (error) => {\n console.log();\n console.log(colors.error(`${icons.error} Failed to execute Claude: ${error.message}`));\n \n // Show detailed error for debugging\n if (process.env.DEVARK_DEBUG || error.stack) {\n console.log(colors.muted('Error details:'));\n console.log(colors.muted(error.stack || error.toString()));\n }\n \n console.log();\n console.log(colors.info('Please use the copy command option instead.'));\n console.log();\n \n // Show the command for manual execution\n console.log(colors.info('Command to run manually:'));\n console.log(colors.highlight(executableCommand));\n console.log();\n \n // Clean up temp directory before exiting\n const tempDir = path.join(tempReportDir, '.devark-temp');\n fs.rm(tempDir, { recursive: true, force: true }).catch(() => {\n // Ignore cleanup errors\n });\n \n // Exit gracefully without recursive call\n console.log(colors.muted('Report generation failed. Please try copying the command above.'));\n }\n });\n } catch (error) {\n // This should only happen if there's an error starting Claude\n console.log();\n console.log(colors.error(`Failed to start Claude: ${error instanceof Error ? error.message : String(error)}`));\n \n // Show detailed error for debugging\n if (process.env.DEVARK_DEBUG || (error instanceof Error && error.stack)) {\n console.log(colors.muted('Error details:'));\n console.log(colors.muted(error instanceof Error ? error.stack : String(error)));\n }\n \n console.log();\n console.log(colors.info('Please use the copy command option instead.'));\n console.log();\n \n // Show the command for manual execution\n console.log(colors.info('Command to run manually:'));\n console.log(colors.highlight(executableCommand));\n console.log();\n \n // Clean up temp directory before exiting\n const tempDir = path.join(tempReportDir, '.devark-temp');\n await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {\n // Ignore cleanup errors\n });\n \n // Exit gracefully without recursive call\n console.log(colors.muted('Report generation failed. Please try copying the command above.'));\n return;\n }\n } else if (action === 'copy-full') {\n // Try to copy full command to clipboard\n try {\n const { execSync } = await import('child_process');\n if (process.platform === 'darwin') {\n execSync(`echo '${executableCommand.replace(/'/g, \"'\\\\''\")}' | pbcopy`);\n console.log(colors.success('\\n✓ Full orchestrated command copied to clipboard!'));\n } else if (process.platform === 'win32') {\n execSync(`echo ${executableCommand} | clip`);\n console.log(colors.success('\\n✓ Full orchestrated command copied to clipboard!'));\n } else {\n console.log(colors.info('\\nCommand:'));\n console.log(colors.highlight(executableCommand));\n }\n } catch {\n console.log(colors.info('\\nCommand:'));\n console.log(colors.highlight(executableCommand));\n }\n \n // Exit after copying\n console.log();\n console.log(colors.accent('👋 Ready to generate your report!'));\n console.log(colors.muted('Run the command in your terminal to start the analysis.'));\n console.log(colors.warning(`📁 Report will be saved as: devark-report-${new Date().toISOString().split('T')[0]}.pdf`));\n process.exit(0);\n } else if (action === 'view') {\n // Show the full prompt\n console.log();\n console.log(colors.accent('=== Full Orchestrated Prompt ==='));\n console.log();\n console.log(colors.highlight(orchestrated.prompt));\n console.log();\n console.log(colors.muted('Press any key to return...'));\n \n // Wait for user input\n await new Promise(resolve => {\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.once('data', () => {\n process.stdin.setRawMode(false);\n resolve(void 0);\n });\n });\n \n // Re-run the generator\n return generateLocalReportInteractive();\n }\n}","import inquirer from 'inquirer';\nimport { colors, icons, box, format } from './styles';\nimport { installSubAgents, getSubAgentStatus, removeSelectedSubAgents, removeAllSubAgents } from '../sub-agents/manager';\nimport { SubAgentName } from '../sub-agents/constants';\n\n/**\n * Display explanation about what sub-agents are and their benefits\n */\nfunction showSubAgentExplanation(): void {\n console.clear();\n \n // Main header with box drawing\n const headerText = ' Managing Local Sub-Agents ';\n const headerWidth = 60;\n const headerPadding = Math.floor((headerWidth - headerText.length) / 2);\n const headerLine = box.horizontal.repeat(headerPadding) + headerText + box.horizontal.repeat(headerWidth - headerPadding - headerText.length);\n \n console.log('\\n' + colors.accent(box.horizontal.repeat(2) + headerLine + box.horizontal.repeat(2)));\n console.log();\n \n // Section 1: What are sub-agents?\n console.log(colors.primary(format.bold('What are Claude Code sub-agents?')));\n console.log(colors.highlight('Sub-agents are specialized helpers you can install to extend'));\n console.log(colors.highlight('Claude Code\\'s capabilities. They\\'re like plugins that give Claude'));\n console.log(colors.highlight('new skills and knowledge for specific tasks.'));\n console.log();\n console.log(colors.dim('Learn more: ') + colors.info(format.underline('https://docs.anthropic.com/en/docs/claude-code/sub-agents')));\n console.log();\n \n // Section divider\n console.log(colors.accent(box.horizontal.repeat(2) + ' How devark Uses Sub-Agents ' + box.horizontal.repeat(29)));\n console.log();\n \n console.log(colors.highlight('devark uses 2 sub-agents to quickly'));\n console.log(colors.highlight('generate concise productivity reports from your coding sessions:'));\n console.log();\n \n // Phase 1 - Analysis\n console.log(colors.primary(format.bold('Phase 1 - In Parallel Session Analysis:')));\n console.log(` ${icons.bullet} ${colors.accent(format.bold('@devark-session-analyzer'))}`);\n console.log(` ${colors.dim(icons.arrow)} Analyzes your Claude Code sessions`);\n console.log(` ${colors.dim(icons.arrow)} Extracts productivity patterns and metrics`);\n console.log();\n \n // Phase 2 - Report Generation\n console.log(colors.primary(format.bold('Phase 2 - Report Generation:')));\n console.log(` ${icons.bullet} ${colors.accent(format.bold('@devark-report-generator'))}`);\n console.log(` ${colors.dim(icons.arrow)} Creates concise HTML report`);\n console.log();\n \n // Bottom border\n console.log(colors.dim(box.horizontal.repeat(62)));\n console.log();\n}\n\n/**\n * Display current installation status and determine if we should proceed\n */\nasync function showInstallationStatus(): Promise<{\n status: Awaited<ReturnType<typeof getSubAgentStatus>>;\n shouldProceed: boolean;\n isReinstall: boolean;\n}> {\n const status = await getSubAgentStatus();\n \n if (status.installed.length === status.total) {\n console.log(colors.success('✓ All sub-agents are already installed!'));\n console.log(colors.dim(`Location: ${status.directory}`));\n console.log();\n console.log(colors.highlight('You can re-install to get the latest versions or fix any issues.'));\n return { status, shouldProceed: true, isReinstall: true };\n }\n \n console.log(colors.accent('Installation Details:'));\n console.log(`Location: ${colors.dim(status.directory)}`);\n console.log(`Status: ${colors.highlight(`${status.installed.length}/${status.total}`)} installed`);\n \n if (status.missing.length > 0) {\n console.log(`\\nSub-agents to install (${status.missing.length}):`);\n status.missing.forEach(agent => {\n console.log(` ${icons.bullet} ${agent.replace('.md', '')}`);\n });\n }\n \n return { status, shouldProceed: true, isReinstall: false };\n}\n\n/**\n * Prompt user for confirmation to install\n */\nasync function confirmInstallation(isReinstall: boolean = false): Promise<boolean> {\n const message = isReinstall \n ? 'Do you want to re-install/update the sub-agents?'\n : 'Do you want to install the sub-agents?';\n \n const { confirm } = await inquirer.prompt([{\n type: 'confirm',\n name: 'confirm',\n message,\n default: true\n }]);\n \n return confirm;\n}\n\n/**\n * Display installation results\n */\nfunction showInstallationResults(result: Awaited<ReturnType<typeof installSubAgents>>): void {\n if (result.installed.length > 0) {\n console.log(colors.success('\\n✅ Sub-agents installation complete!'));\n console.log(colors.dim('\\nYou can now use these sub-agents in Claude Code with @ mentions.'));\n } else if (result.skipped.length > 0 && result.failed.length === 0) {\n console.log(colors.success('\\n✓ All sub-agents are already installed!'));\n } else if (result.failed.length > 0) {\n console.log(colors.warning('\\n⚠️ Some sub-agents failed to install. Please check permissions.'));\n if (result.failed.length < 5) {\n console.log(colors.dim('\\nFailed to install:'));\n result.failed.forEach(agent => {\n console.log(colors.dim(` • ${agent}`));\n });\n }\n }\n}\n\n/**\n * Show management menu for sub-agents\n */\nasync function showManagementMenu(status: Awaited<ReturnType<typeof getSubAgentStatus>>): Promise<string> {\n const choices = [];\n \n if (status.installed.length < status.total) {\n choices.push({\n name: `${icons.plus} Install missing sub-agents (${status.missing.length} to install)`,\n value: 'install'\n });\n }\n \n if (status.installed.length === status.total) {\n choices.push({\n name: `${icons.refresh} Re-install/Update all sub-agents`,\n value: 'reinstall'\n });\n }\n \n if (status.installed.length > 0) {\n choices.push({\n name: `${icons.minus} Remove selected sub-agents`,\n value: 'remove-selected'\n });\n \n choices.push({\n name: `${icons.cross} Remove all sub-agents`,\n value: 'remove-all'\n });\n }\n \n choices.push({\n name: `${icons.arrow} Back to main menu`,\n value: 'back'\n });\n \n const { action } = await inquirer.prompt([{\n type: 'list',\n name: 'action',\n message: 'What would you like to do?',\n choices\n }]);\n \n return action;\n}\n\n/**\n * Handle selective removal of sub-agents\n */\nasync function handleSelectiveRemoval(status: Awaited<ReturnType<typeof getSubAgentStatus>>): Promise<void> {\n if (status.installed.length === 0) {\n console.log(colors.warning('\\nNo sub-agents are currently installed.'));\n return;\n }\n \n const choices = status.installed.map(agent => ({\n name: agent.replace('.md', ''),\n value: agent,\n checked: false\n }));\n \n const { selected } = await inquirer.prompt([{\n type: 'checkbox',\n name: 'selected',\n message: 'Select sub-agents to remove:',\n choices,\n validate: (input) => {\n if (input.length === 0) {\n return 'Please select at least one sub-agent to remove';\n }\n return true;\n }\n }]);\n \n if (selected.length === 0) {\n console.log(colors.warning('\\nNo sub-agents selected.'));\n return;\n }\n \n // Confirm removal\n const { confirm } = await inquirer.prompt([{\n type: 'confirm',\n name: 'confirm',\n message: `Remove ${selected.length} sub-agent${selected.length > 1 ? 's' : ''}?`,\n default: false\n }]);\n \n if (!confirm) {\n console.log(colors.warning('\\nRemoval cancelled.'));\n return;\n }\n \n // Perform removal\n console.log('\\nRemoving selected sub-agents...');\n const result = await removeSelectedSubAgents(\n selected as SubAgentName[],\n { onProgress: (message) => console.log(message) }\n );\n \n if (result.removed.length > 0) {\n console.log(colors.success(`\\n✅ Successfully removed ${result.removed.length} sub-agent${result.removed.length > 1 ? 's' : ''}.`));\n }\n \n if (result.failed.length > 0) {\n console.log(colors.error(`\\n⚠️ Failed to remove ${result.failed.length} sub-agent${result.failed.length > 1 ? 's' : ''}.`));\n }\n}\n\n/**\n * Handle removal of all sub-agents\n */\nasync function handleRemoveAll(): Promise<void> {\n // Single confirmation for removing all\n const { confirm } = await inquirer.prompt([{\n type: 'confirm',\n name: 'confirm',\n message: colors.warning('Are you sure you want to remove ALL 2 devark sub-agents?'),\n default: false\n }]);\n \n if (!confirm) {\n console.log(colors.warning('\\nRemoval cancelled.'));\n return;\n }\n \n console.log('\\nRemoving all sub-agents...');\n const removed = await removeAllSubAgents();\n \n if (removed > 0) {\n console.log(colors.success(`\\n✅ Successfully removed ${removed} sub-agent${removed > 1 ? 's' : ''}.`));\n } else {\n console.log(colors.warning('\\nNo sub-agents were removed.'));\n }\n}\n\n/**\n * Prompt user to generate a local report after first-time installation\n */\nasync function promptForLocalReport(): Promise<boolean> {\n console.log();\n console.log(colors.success('✨ Great! Your sub-agents are ready.'));\n console.log();\n \n const { generateReport } = await inquirer.prompt([{\n type: 'confirm',\n name: 'generateReport',\n message: 'Would you like to generate a local devark report now?',\n default: true\n }]);\n \n return generateReport;\n}\n\n/**\n * Main interactive management flow for sub-agents\n */\nexport async function installSubAgentsInteractive(): Promise<void> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n // Show explanation about sub-agents\n showSubAgentExplanation();\n \n // Check and display current status\n const { status } = await showInstallationStatus();\n \n // Show management menu\n const action = await showManagementMenu(status);\n \n switch (action) {\n case 'install':\n case 'reinstall': {\n const isReinstall = action === 'reinstall';\n const confirmed = await confirmInstallation(isReinstall);\n \n if (confirmed) {\n const actionText = isReinstall ? 'Re-installing' : 'Installing';\n console.log(`\\n${actionText} sub-agents...`);\n const result = await installSubAgents({\n force: isReinstall,\n onProgress: (message) => console.log(message)\n });\n showInstallationResults(result);\n \n // If this is a fresh install (not reinstall) and all agents installed successfully\n // Also check that we actually installed agents (not just skipped because they were already there)\n if (!isReinstall && result.installed.length > 0 && result.failed.length === 0 && \n (result.installed.length + result.skipped.length) === 2) {\n const shouldGenerateReport = await promptForLocalReport();\n if (shouldGenerateReport) {\n // Import and run the local report generator\n const { generateLocalReportInteractive } = await import('./local-report-generator');\n await generateLocalReportInteractive();\n return; // Exit the sub-agent installer after report generation\n }\n }\n } else {\n console.log(colors.warning('\\nInstallation cancelled.'));\n }\n break;\n }\n \n case 'remove-selected':\n await handleSelectiveRemoval(status);\n break;\n \n case 'remove-all':\n await handleRemoveAll();\n break;\n \n case 'back':\n return;\n }\n \n // Clear and refresh menu\n console.clear();\n }\n}","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { sendWithTimeout } from './commands/send';\nimport { config } from './commands/config';\nimport { logout } from './commands/logout';\nimport { privacy } from './commands/privacy';\nimport { createAnalyzePromptCommand } from './commands/analyze-prompt';\nimport { createStatuslineCommand } from './commands/statusline';\nimport { createTestPersonalityCommand } from './commands/test-personality';\nimport { installAutoSync } from './commands/install-auto-sync';\nimport { showLogo } from './lib/ui';\nimport { handleError } from './utils/errors';\nimport { logger } from './utils/logger';\nimport { detectSetupState } from './lib/detector';\nimport { showMainMenu } from './lib/ui/main-menu';\nimport { colors } from './lib/ui/styles';\n\n// Import package.json for version info\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst pkg = require('../package.json');\n\n// Check for package updates and store the info\nlet packageUpdateInfo: { current: string; latest: string } | null = null;\nconst isSilent = process.argv.includes('--silent');\n\nif (!isSilent) {\n // Support simulation for testing\n const simulatedVersion = process.env.SIMULATE_OLD_VERSION;\n const displayPkg = simulatedVersion \n ? { ...pkg, name: 'devark-cli', version: simulatedVersion }\n : pkg;\n\n // Use update-notifier to check for package updates (async)\n (async () => {\n let notifier: any;\n try {\n const updateNotifierModule = await import('update-notifier');\n const updateNotifier = updateNotifierModule.default || updateNotifierModule;\n notifier = updateNotifier({\n pkg: displayPkg,\n updateCheckInterval: simulatedVersion ? 0 : 1000 * 60 * 60, // Check immediately in simulation, otherwise hourly\n shouldNotifyInNpmScript: true\n });\n } catch (error) {\n // Silently fail if update-notifier is not available\n notifier = { update: null };\n }\n\n // Store package update info if available\n if (notifier.update) {\n packageUpdateInfo = {\n current: notifier.update.current,\n latest: notifier.update.latest\n };\n } else if (simulatedVersion) {\n // Force package update info in simulation mode\n packageUpdateInfo = {\n current: simulatedVersion,\n latest: pkg.version\n };\n }\n })().catch(() => {\n // Silently ignore any update check failures\n });\n}\n\n// Store version for UI components\nexport const currentVersion = process.env.SIMULATE_OLD_VERSION || pkg.version;\n\nconst program = new Command();\n\nprogram\n .name('devark')\n .description('Track your building journey with devark')\n .version(currentVersion)\n .option('-v, --verbose', 'Enable verbose logging')\n .helpOption(false) // Disable default help\n .hook('preAction', async (thisCommand) => {\n // Enable debug logging if verbose flag is set\n const options = thisCommand.opts();\n if (options.verbose) {\n logger.setLevel('debug');\n }\n // Skip logo in silent mode - check command line args directly since --silent is command-specific\n const isSilent = process.argv.includes('--silent');\n // Skip logo for hook commands (statusline, etc.)\n const isHookCommand = process.argv[2] === 'statusline';\n // Only show logo if a command is specified (not the default interactive menu)\n const hasCommand = process.argv.length > 2 && !process.argv[2].startsWith('-');\n if (!isSilent && !isHookCommand && hasCommand) {\n await showLogo(currentVersion);\n }\n });\n\n// Hidden command for hooks - not shown in help\nprogram\n .command('send', { hidden: true })\n .description('Send session data from current project to devark')\n .option('-d, --dry', 'Show what would be sent without uploading')\n .option('-a, --all', 'Send sessions from all projects (default: current project only)')\n .option('--silent', 'Run in silent mode (for hook execution)')\n .option('--background', 'Run upload in background (for hooks)')\n .option('--hook-trigger <type>', 'Hook that triggered this command (sessionstart, precompact, sessionend)')\n .option('--hook-version <version>', 'Hook version (for tracking hook updates)')\n .option('--test', 'Test mode for hook validation (exits without processing)')\n .option('--claude-project-dir <dir>', 'Claude project directory from $CLAUDE_PROJECT_DIR')\n .action(async (options) => {\n try {\n await sendWithTimeout(options);\n } catch (error) {\n handleError(error);\n }\n });\n\n// Auth command - shown in help for direct cloud setup\nprogram\n .command('auth', { hidden: true })\n .description('Sign in with GitHub to enable cloud sync, web dashboard, and streak tracking')\n .action(async () => {\n try {\n // Use the guided cloud setup wizard for complete experience\n const { guidedCloudSetup } = await import('./lib/ui/cloud-setup-wizard');\n await guidedCloudSetup();\n } catch (error) {\n handleError(error);\n }\n });\n\n// Hidden command for advanced users\nprogram\n .command('config', { hidden: true })\n .description('Manage devark configuration')\n .option('-l, --list', 'List all configuration values')\n .option('-s, --set <key=value>', 'Set a configuration value')\n .option('-g, --get <key>', 'Get a configuration value')\n .action(async (options) => {\n try {\n await config(options);\n } catch (error) {\n handleError(error);\n }\n });\n\nprogram\n .command('logout', { hidden: true })\n .description('Clear authentication and logout')\n .action(async () => {\n try {\n await logout();\n } catch (error) {\n handleError(error);\n }\n });\n\n// Hidden command for advanced users\nprogram\n .command('privacy', { hidden: true })\n .description('Preview and review data privacy (see what gets sent)')\n .option('-e, --export <path>', 'Export sanitized data to file')\n .action(async (options) => {\n try {\n await privacy(options);\n } catch (error) {\n handleError(error);\n }\n });\n\n// Add analyze-prompt command (hidden - for hook use)\nprogram.addCommand(createAnalyzePromptCommand());\n\n// Add statusline command (hidden - for Claude Code status line)\nprogram.addCommand(createStatuslineCommand());\n\n// Add test-personality command (hidden - for debugging)\nprogram.addCommand(createTestPersonalityCommand());\n\n// Add install-auto-sync command for direct access to auto-sync configuration\nprogram\n .command('install-auto-sync')\n .description('Configure automatic session sync (Claude Code hooks)')\n .action(async () => {\n try {\n await installAutoSync();\n } catch (error) {\n handleError(error);\n }\n });\n\n// Custom help function\nfunction showHelp(): void {\n console.log('');\n console.log('Usage: npx devark-cli');\n console.log('');\n console.log('Track your building journey with devark');\n console.log('');\n console.log('Main usage:');\n console.log(' npx devark-cli Interactive menu (recommended)');\n console.log('');\n console.log('Quick actions:');\n console.log(' npx devark-cli auth Sign in to enable cloud sync & web dashboard');\n console.log(' npx devark-cli install-auto-sync Configure automatic session sync');\n console.log(' npx devark-cli send Manually sync sessions to cloud');\n console.log(' npx devark-cli privacy Preview what data gets sent (privacy first!)');\n console.log('');\n console.log('For hooks (automatic sync):');\n console.log(' npx devark-cli send --silent Used by Claude Code hooks');\n console.log('');\n console.log('Learn more at: https://devark.ai');\n console.log('');\n process.exit(0);\n}\n\n// Handle --help flag\nif (process.argv.includes('--help') || process.argv.includes('-h')) {\n showHelp();\n}\n\n// Custom help handler for commander\nprogram.on('option:help', showHelp);\n\n// Show interactive menu when no command is provided\nprogram.action(async () => {\n let state;\n \n try {\n // Try to detect current setup state\n state = await detectSetupState();\n } catch (error) {\n // If detection fails, show menu with ERROR state\n logger.debug('State detection failed:', error);\n state = {\n state: 'ERROR' as const,\n hasConfig: false,\n hasAuth: false,\n hasAgents: false,\n agentCount: 0,\n totalAgents: 8,\n hasHooks: false,\n hasStatusLine: false,\n statusLineStatus: 'not-installed' as const,\n trackingMode: 'none' as const,\n trackedProjectCount: 0,\n errors: [error instanceof Error ? error.message : 'Unknown error']\n };\n }\n \n // Always show the interactive menu, even on error\n try {\n await showMainMenu(state, packageUpdateInfo);\n } catch (menuError) {\n // Only if menu itself fails, show simple fallback\n console.error(colors.error('\\nFailed to display interactive menu'));\n console.log(colors.subdued('Run \"npx devark-cli\" to get started'));\n \n if (menuError instanceof Error) {\n logger.debug('Menu display error:', menuError);\n }\n }\n});\n\nprogram.parseAsync(process.argv).catch(handleError);","import chalk from 'chalk';\nimport {\n getAllConfig,\n getConfigValue,\n setApiUrl,\n setPreference,\n getConfigPath,\n getCliPath,\n setCliPath,\n} from '../lib/config';\nimport { showSuccess, showInfo } from '../lib/ui';\nimport { DevArkError } from '../utils/errors';\nimport { validateUrl } from '../lib/input-validator';\n\ninterface ConfigOptions {\n list?: boolean;\n set?: string;\n get?: string;\n}\n\nexport async function config(options: ConfigOptions): Promise<void> {\n if (options.list) {\n // List all configuration\n const allConfig = getAllConfig();\n \n console.log(chalk.cyan('\\n⚙️ devark Configuration'));\n console.log(chalk.gray('═══════════════════════════════\\n'));\n \n console.log(chalk.cyan('Config File:'), getConfigPath());\n console.log(chalk.cyan('API URL:'), allConfig.apiUrl);\n console.log(chalk.cyan('CLI Path:'), getCliPath());\n console.log(chalk.cyan('Token:'), allConfig.token ? '<redacted>' : chalk.gray('Not set'));\n console.log(chalk.cyan('Last Sync:'), allConfig.lastSync || chalk.gray('Never'));\n \n if (allConfig.preferences) {\n console.log(chalk.cyan('\\nPreferences:'));\n Object.entries(allConfig.preferences).forEach(([key, value]) => {\n console.log(` ${chalk.gray(key)}:`, value);\n });\n }\n \n return;\n }\n \n if (options.get) {\n // Get specific configuration value\n const validKeys = ['apiUrl', 'token', 'lastSync', 'preferences'];\n \n if (!validKeys.includes(options.get)) {\n throw new DevArkError(\n `Invalid configuration key. Valid keys: ${validKeys.join(', ')}`,\n 'INVALID_CONFIG_KEY'\n );\n }\n \n const value = getConfigValue(options.get as any);\n \n if (value === undefined) {\n showInfo(`${options.get}: Not set`);\n } else if (typeof value === 'object') {\n console.log(`${options.get}:`, JSON.stringify(value, null, 2));\n } else {\n console.log(`${options.get}: ${value}`);\n }\n \n return;\n }\n \n if (options.set) {\n // Set configuration value\n const [key, ...valueParts] = options.set.split('=');\n const value = valueParts.join('=');\n \n if (!key || !value) {\n throw new DevArkError(\n 'Invalid format. Use: --set key=value',\n 'INVALID_FORMAT'\n );\n }\n \n switch (key) {\n case 'apiUrl': {\n // Validate URL using secure validator\n const validatedUrl = validateUrl(value);\n setApiUrl(validatedUrl);\n showSuccess(`API URL set to: ${validatedUrl}`);\n break;\n }\n \n case 'preferences.colorScheme':\n if (!['default', 'minimal'].includes(value)) {\n throw new DevArkError(\n 'Invalid color scheme. Use: default or minimal',\n 'INVALID_VALUE'\n );\n }\n setPreference('colorScheme', value as 'default' | 'minimal');\n showSuccess(`Color scheme set to: ${value}`);\n break;\n \n case 'preferences.verboseOutput': {\n const boolValue = value.toLowerCase() === 'true';\n setPreference('verboseOutput', boolValue);\n showSuccess(`Verbose output set to: ${boolValue}`);\n break;\n }\n \n case 'cliPath':\n setCliPath(value);\n showSuccess(`CLI path set to: ${value}`);\n showInfo('Remember to reinstall hooks after changing the CLI path');\n break;\n \n default:\n throw new DevArkError(\n `Cannot set '${key}'. Configurable keys: apiUrl, cliPath, preferences.colorScheme, preferences.verboseOutput`,\n 'INVALID_CONFIG_KEY'\n );\n }\n \n return;\n }\n \n // No options provided, show help\n console.log(chalk.cyan('\\n⚙️ devark Configuration'));\n console.log(chalk.gray('\\nUsage:'));\n console.log(' devark config --list List all configuration');\n console.log(' devark config --get <key> Get a configuration value');\n console.log(' devark config --set <key=value> Set a configuration value');\n console.log(chalk.gray('\\nExamples:'));\n console.log(' devark config --list');\n console.log(' devark config --get apiUrl');\n console.log(' devark config --set apiUrl=https://api.devark.ai');\n console.log(' devark config --set cliPath=\"/path/to/devark.js\"');\n console.log(' devark config --set preferences.colorScheme=minimal');\n}","import inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { clearToken } from '../lib/config';\nimport { showSuccess, showInfo } from '../lib/ui';\n\nexport async function logout(): Promise<void> {\n console.log(chalk.yellow('\\n⚠️ Logout from devark cloud ☁️'));\n console.log(chalk.gray('This will remove your authentication token.\\n'));\n \n const { confirmLogout } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmLogout',\n message: 'Are you sure you want to logout?',\n default: false,\n },\n ]);\n \n if (!confirmLogout) {\n showInfo('Logout cancelled. You are still logged in.');\n return;\n }\n \n await clearToken();\n showSuccess('Logged out successfully!');\n \n console.log(chalk.gray('\\nTo use devark again, run: npx devark-cli'));\n}","import chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport { readClaudeSessions } from '../lib/readers/claude';\nimport { MessageSanitizer } from '../lib/message-sanitizer';\nimport { getLastSync } from '../lib/config';\nimport { getHookMode, getTrackedProjects } from '../lib/claude-settings-reader';\nimport { formatDuration, showInfo, showWarning, showSuccess } from '../lib/ui';\nimport { logger } from '../utils/logger';\n\ninterface PrivacyOptions {\n export?: string; // Export path for sanitized data\n since?: string; // Date filter\n}\n\n/**\n * Privacy command - allows users to preview what data will be sent\n */\nexport async function privacy(options: PrivacyOptions): Promise<void> {\n console.clear();\n console.log(chalk.cyan('\\n🔒 Privacy & Data Preview\\n'));\n console.log(chalk.gray('See exactly what devark sends to the cloud'));\n console.log(chalk.gray('─'.repeat(50)));\n console.log('');\n\n // Menu options\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to review?',\n choices: [\n { name: '📊 Preview next upload (see what will be sent)', value: 'preview' },\n { name: '🔍 View sample redaction (before/after examples)', value: 'sample' },\n { name: '📈 Show redaction statistics', value: 'stats' },\n { name: '💾 Export sanitized data to file', value: 'export' },\n { name: '📚 Learn about privacy protection', value: 'learn' },\n { name: '← Back to main menu', value: 'back' },\n ],\n },\n ]);\n\n switch (action) {\n case 'preview':\n await previewNextUpload();\n break;\n case 'sample':\n await showSampleRedaction();\n break;\n case 'stats':\n await showRedactionStats();\n break;\n case 'export':\n await exportSanitizedData(options.export);\n break;\n case 'learn':\n await showPrivacyInfo();\n break;\n case 'back':\n return;\n }\n\n // Ask if they want to see more\n console.log('');\n const { continueReview } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'continueReview',\n message: 'Continue reviewing privacy options?',\n default: true,\n },\n ]);\n\n if (continueReview) {\n await privacy(options);\n }\n}\n\nasync function previewNextUpload(): Promise<void> {\n console.log(chalk.cyan('\\n📊 Preview Next Upload\\n'));\n\n // Get sessions that would be sent\n const sinceDate = getLastSync() || new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\n const sessions = await readClaudeSessions({ since: sinceDate });\n\n // Filter by tracked projects\n const trackingMode = await getHookMode();\n const trackedProjects = await getTrackedProjects();\n \n let filteredSessions = sessions;\n if (trackingMode === 'selected' && trackedProjects.length > 0) {\n filteredSessions = sessions.filter(session => {\n return trackedProjects.some(tracked => {\n const sessionPath = path.normalize(session.projectPath).toLowerCase();\n const trackedPath = path.normalize(tracked).toLowerCase();\n return sessionPath === trackedPath || sessionPath.startsWith(trackedPath + path.sep);\n });\n });\n }\n\n if (filteredSessions.length === 0) {\n showWarning('No sessions found to upload');\n showInfo('Use Claude Code to create some sessions first');\n return;\n }\n\n const totalDuration = filteredSessions.reduce((sum, s) => sum + s.duration, 0);\n \n console.log(chalk.green(`✓ Found ${filteredSessions.length} sessions (${formatDuration(totalDuration)} total)`));\n console.log('');\n\n // Sanitize and analyze\n const sanitizer = new MessageSanitizer();\n const totalRedactions = {\n codeBlocks: 0,\n credentials: 0,\n envVars: 0,\n paths: 0,\n urls: 0,\n emails: 0,\n };\n\n filteredSessions.forEach(session => {\n const sanitized = sanitizer.sanitizeMessages(session.messages);\n sanitized.forEach(msg => {\n if (msg.metadata?.redactedItems) {\n Object.entries(msg.metadata.redactedItems).forEach(([key, value]) => {\n totalRedactions[key as keyof typeof totalRedactions] += value as number;\n });\n }\n });\n });\n\n // Show what will be redacted\n console.log(chalk.yellow('🔒 Privacy Protection Summary:'));\n console.log('');\n \n const redactionLines = [\n { label: 'Code blocks removed', count: totalRedactions.codeBlocks, icon: '📝' },\n { label: 'Credentials masked', count: totalRedactions.credentials, icon: '🔑' },\n { label: 'File paths hidden', count: totalRedactions.paths, icon: '📁' },\n { label: 'URLs redacted', count: totalRedactions.urls, icon: '🌐' },\n { label: 'Env variables removed', count: totalRedactions.envVars, icon: '🔧' },\n { label: 'Emails hidden', count: totalRedactions.emails, icon: '📧' },\n ];\n\n redactionLines.forEach(line => {\n if (line.count > 0) {\n console.log(` ${line.icon} ${line.count} ${line.label}`);\n }\n });\n\n const totalRedacted = Object.values(totalRedactions).reduce((a, b) => a + b, 0);\n console.log('');\n console.log(chalk.green(` Total: ${totalRedacted} sensitive items will be redacted`));\n console.log('');\n\n // Show sample sanitized message\n const sampleSession = filteredSessions[0];\n const sanitizedSample = sanitizer.sanitizeMessages(sampleSession.messages.slice(0, 1));\n \n if (sanitizedSample.length > 0) {\n console.log(chalk.yellow('📝 Sample Sanitized Message:'));\n console.log(chalk.gray('─'.repeat(50)));\n const sampleContent = sanitizedSample[0].content;\n const preview = sampleContent.length > 300 \n ? sampleContent.substring(0, 300) + '...' \n : sampleContent;\n console.log(chalk.gray(preview));\n console.log(chalk.gray('─'.repeat(50)));\n }\n}\n\nasync function showSampleRedaction(): Promise<void> {\n console.log(chalk.cyan('\\n🔍 Sample Redaction Examples\\n'));\n \n const examples = [\n {\n title: 'API Keys & Tokens',\n before: 'const apiKey = \"sk-proj-abc123xyz789...\";',\n after: 'const apiKey = \"[CREDENTIAL_1]\";',\n },\n {\n title: 'File Paths',\n before: 'Error in /Users/john/projects/app/src/index.js',\n after: 'Error in [PATH_1]',\n },\n {\n title: 'Code Blocks',\n before: '```javascript\\nfunction getData() {\\n return fetch(url);\\n}\\n```',\n after: '[CODE_BLOCK_1: javascript]',\n },\n {\n title: 'URLs & Endpoints',\n before: 'Connect to https://api.myapp.com/v1/users',\n after: 'Connect to [API_URL]',\n },\n {\n title: 'Environment Variables',\n before: 'Set $DATABASE_URL and $API_KEY',\n after: 'Set [ENV_VAR_1] and [ENV_VAR_2]',\n },\n {\n title: 'Email Addresses',\n before: 'Contact admin@company.com for help',\n after: 'Contact [EMAIL_1] for help',\n },\n ];\n\n examples.forEach(example => {\n console.log(chalk.yellow(`${example.title}:`));\n console.log(chalk.red(` Before: ${example.before}`));\n console.log(chalk.green(` After: ${example.after}`));\n console.log('');\n });\n\n console.log(chalk.dim('Your actual code and sensitive data never leave your machine.'));\n}\n\nasync function showRedactionStats(): Promise<void> {\n console.log(chalk.cyan('\\n📈 Redaction Statistics\\n'));\n\n // Get all sessions from last 30 days\n const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);\n const sessions = await readClaudeSessions({ since: thirtyDaysAgo });\n\n if (sessions.length === 0) {\n showWarning('No sessions found in the last 30 days');\n return;\n }\n\n // Analyze all sessions\n const sanitizer = new MessageSanitizer();\n const stats = {\n totalSessions: sessions.length,\n totalMessages: 0,\n totalRedactions: 0,\n byType: {\n codeBlocks: 0,\n credentials: 0,\n envVars: 0,\n paths: 0,\n urls: 0,\n emails: 0,\n },\n };\n\n sessions.forEach(session => {\n const sanitized = sanitizer.sanitizeMessages(session.messages);\n stats.totalMessages += sanitized.length;\n \n sanitized.forEach(msg => {\n if (msg.metadata?.redactedItems) {\n Object.entries(msg.metadata.redactedItems).forEach(([key, value]) => {\n const count = value as number;\n stats.byType[key as keyof typeof stats.byType] += count;\n stats.totalRedactions += count;\n });\n }\n });\n });\n\n console.log(chalk.green('Last 30 Days Summary:'));\n console.log('');\n console.log(` 📊 Sessions analyzed: ${stats.totalSessions}`);\n console.log(` 💬 Messages processed: ${stats.totalMessages}`);\n console.log(` 🔒 Items redacted: ${stats.totalRedactions}`);\n console.log('');\n \n console.log(chalk.yellow('Redaction Breakdown:'));\n Object.entries(stats.byType).forEach(([type, count]) => {\n if (count > 0) {\n const percentage = ((count / stats.totalRedactions) * 100).toFixed(1);\n const label = type.replace(/([A-Z])/g, ' $1').toLowerCase();\n console.log(` • ${label}: ${count} (${percentage}%)`);\n }\n });\n}\n\nasync function exportSanitizedData(exportPath?: string): Promise<void> {\n console.log(chalk.cyan('\\n💾 Export Sanitized Data\\n'));\n\n // Get sessions\n const sinceDate = getLastSync() || new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\n const sessions = await readClaudeSessions({ since: sinceDate });\n\n if (sessions.length === 0) {\n showWarning('No sessions found to export');\n return;\n }\n\n // Sanitize all sessions\n const sanitizer = new MessageSanitizer();\n const sanitizedData = sessions.map(session => ({\n projectPath: '[REDACTED]',\n timestamp: session.timestamp,\n duration: session.duration,\n messages: sanitizer.sanitizeMessages(session.messages),\n }));\n\n // Determine export path\n const defaultPath = `devark-sanitized-${new Date().toISOString().split('T')[0]}.json`;\n const finalPath = exportPath || defaultPath;\n\n // Write to file\n try {\n await fs.writeFile(finalPath, JSON.stringify(sanitizedData, null, 2));\n showSuccess(`Sanitized data exported to: ${finalPath}`);\n console.log(chalk.dim('You can review this file to see exactly what would be sent.'));\n } catch (error) {\n logger.error('Failed to export data:', error);\n showWarning('Failed to export data. Check permissions and try again.');\n }\n}\n\nasync function showPrivacyInfo(): Promise<void> {\n console.log(chalk.cyan('\\n📚 Privacy Protection Information\\n'));\n \n console.log(chalk.yellow('How devark protects your privacy:'));\n console.log('');\n \n console.log(chalk.green('✓ Local Processing'));\n console.log(' All data sanitization happens on your machine.');\n console.log(' Your actual code never leaves your computer.');\n console.log('');\n \n console.log(chalk.green('✓ Automatic Redaction'));\n console.log(' Sensitive information is automatically removed:');\n console.log(' • Source code and snippets');\n console.log(' • API keys and credentials');\n console.log(' • File paths and URLs');\n console.log(' • Email addresses');\n console.log(' • Environment variables');\n console.log('');\n \n console.log(chalk.green('✓ What We Track'));\n console.log(' • Session duration and timestamps');\n console.log(' • Natural language conversations');\n console.log(' • Programming topics discussed');\n console.log(' • Error descriptions (without code)');\n console.log('');\n \n console.log(chalk.green('✓ What We Never See'));\n console.log(' • Your actual source code');\n console.log(' • File contents');\n console.log(' • Passwords or secrets');\n console.log(' • Personal file paths');\n console.log(' • Company-specific data');\n console.log('');\n \n console.log(chalk.dim('Learn more: https://devark.ai/privacy'));\n}","import { Command } from 'commander';\nimport { PromptAnalyzer } from '../lib/prompt-analyzer';\nimport { logger } from '../utils/logger';\nimport { colors } from '../lib/ui/styles';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport { extractConversationContext, extractSessionMetadata, DEFAULT_CONVERSATION_TURNS_TO_EXTRACT_AS_CONTEXT } from '../lib/session-context-extractor';\nimport { getStatusLinePersonality } from '../lib/personality-manager';\nimport { getLoadingMessage } from '../types/loading-state';\nimport { SessionMetadata } from '../lib/prompt-analyzer';\n\n/**\n * Read stdin with a timeout\n */\nasync function readStdin(timeoutMs: number = 1000): Promise<string | null> {\n return new Promise((resolve) => {\n let input = '';\n let hasData = false;\n \n // Set timeout to check if stdin has data\n const timeout = setTimeout(() => {\n if (!hasData) {\n resolve(null); // No stdin data\n }\n }, timeoutMs);\n \n process.stdin.setEncoding('utf8');\n \n process.stdin.on('readable', () => {\n let chunk;\n while ((chunk = process.stdin.read()) !== null) {\n hasData = true;\n input += chunk;\n }\n });\n \n process.stdin.on('end', () => {\n clearTimeout(timeout);\n resolve(hasData ? input : null);\n });\n });\n}\n\n/**\n * Analyze a prompt for quality and provide feedback\n * This command is designed to be called from Claude Code hooks\n * Can accept input via stdin (for hooks) or command-line arguments\n */\nexport function createAnalyzePromptCommand(): Command {\n const command = new Command('analyze-prompt')\n .description('Analyze prompt quality and provide improvement suggestions')\n .option('--session-id <id>', 'Claude Code session ID')\n .option('--prompt <text>', 'The prompt text to analyze')\n .option('--timeout <ms>', 'Analysis timeout in milliseconds', '10000')\n .option('--verbose', 'Show detailed output', false)\n .option('--silent', 'Silent mode for hook execution', false)\n .option('--stdin', 'Read input from stdin (auto-detected for hooks)', false)\n .option('--background-mode', 'Background processing mode (internal use)', false)\n .option('--context <text>', 'Conversation context for analysis')\n .action(async (options) => {\n let { sessionId, prompt } = options;\n const { context: providedContext } = options;\n const { timeout, verbose, silent, backgroundMode } = options;\n let transcriptPath: string | undefined;\n\n // Enable debug logging if verbose mode\n if (verbose) {\n process.env.DEBUG_PERSONALITY = 'true';\n }\n\n // In silent or background mode, suppress all console output\n if (silent || backgroundMode) {\n console.log = () => {};\n console.error = () => {};\n }\n\n try {\n // Skip stdin check in background mode (prompt already provided)\n if (!backgroundMode && (!prompt || options.stdin)) {\n const stdinData = await readStdin();\n \n if (stdinData) {\n try {\n // Parse JSON input from Claude Code hook\n const hookData = JSON.parse(stdinData);\n prompt = hookData.prompt || prompt;\n sessionId = hookData.session_id || sessionId;\n transcriptPath = hookData.transcript_path;\n \n logger.debug('Received hook input via stdin:', {\n sessionId: hookData.session_id,\n promptLength: hookData.prompt?.length,\n transcriptPath: hookData.transcript_path\n });\n \n // Log to debug file for testing\n const homeDir = process.env.HOME || process.env.USERPROFILE;\n if (!homeDir) {\n logger.warn('Unable to determine home directory for debug logging');\n return;\n }\n const logDir = path.join(homeDir, '.devark');\n await fs.mkdir(logDir, { recursive: true }).catch(() => {});\n const logFile = path.join(logDir, 'hook-debug.log');\n const timestamp = new Date().toISOString();\n await fs.appendFile(logFile, `\\n[${timestamp}] analyze-prompt received:\\n`).catch(() => {});\n await fs.appendFile(logFile, ` Session: ${sessionId}\\n`).catch(() => {});\n await fs.appendFile(logFile, ` Prompt preview: ${prompt?.substring(0, 50)}...\\n`).catch(() => {});\n } catch (parseError) {\n // If not JSON, treat as plain text prompt\n if (!prompt) {\n prompt = stdinData.trim();\n logger.debug('Received plain text prompt via stdin');\n }\n }\n }\n }\n\n // Validate inputs\n if (!prompt) {\n if (!silent) {\n console.error(colors.error('Error: No prompt provided (use --prompt or provide via stdin)'));\n }\n logger.error('analyze-prompt called without prompt');\n process.exit(1);\n }\n\n // Extract conversation context from transcript if available, or use provided context\n let conversationContext: string | undefined = providedContext;\n let sessionMetadata: SessionMetadata | undefined;\n \n if (transcriptPath) {\n try {\n // Extract conversation context if not provided\n if (!conversationContext) {\n conversationContext = await extractConversationContext(transcriptPath, DEFAULT_CONVERSATION_TURNS_TO_EXTRACT_AS_CONTEXT) || undefined;\n if (conversationContext) {\n logger.debug('Extracted conversation context', {\n length: conversationContext.length,\n preview: conversationContext.substring(0, 100)\n });\n }\n }\n \n // Always extract session metadata when we have a transcript\n sessionMetadata = await extractSessionMetadata(transcriptPath, prompt);\n logger.debug('Extracted session metadata', sessionMetadata);\n \n } catch (error) {\n logger.debug('Could not extract context or metadata from transcript:', error);\n }\n } else if (conversationContext) {\n logger.debug('Using provided conversation context', {\n length: conversationContext.length,\n preview: conversationContext.substring(0, 100)\n });\n \n // Create minimal metadata when no transcript available\n sessionMetadata = {\n isFirstPrompt: false, // Assume not first if context provided\n hasImages: /\\[\\d+\\s+image\\s+attachments?\\]/i.test(prompt),\n imageCount: 0\n };\n \n const imageMatch = prompt.match(/\\[(\\d+)\\s+image\\s+attachments?\\]/i);\n if (imageMatch) {\n sessionMetadata.imageCount = parseInt(imageMatch[1], 10);\n }\n }\n\n logger.debug('Starting prompt analysis', {\n sessionId,\n promptLength: prompt.length,\n timeout,\n hasContext: !!conversationContext\n });\n\n // Create analyzer instance (no Claude CLI check needed - using SDK)\n const analyzer = new PromptAnalyzer();\n\n // Analyze the prompt using Claude SDK\n const startTime = Date.now();\n \n if (!silent && verbose) {\n console.log(colors.muted('Analyzing prompt quality...'));\n }\n\n // In silent mode (hook), spawn background process and exit immediately\n if (silent && sessionId) {\n logger.debug('Hook mode detected - spawning background analysis');\n \n // Import spawn for background processing\n const { spawn } = await import('child_process');\n \n // Write a loading state immediately for instant feedback\n const homeDir = process.env.HOME || process.env.USERPROFILE;\n if (!homeDir) {\n logger.warn('Unable to determine home directory for pending analysis');\n return;\n }\n const pendingPath = path.join(homeDir, '.devark', 'analyzed-prompts', `${sessionId}.json`);\n const personality = getStatusLinePersonality();\n const customName = personality.personality === 'custom' ? personality.customPersonality?.name : undefined;\n const pendingState = {\n status: 'loading', // Must be 'loading' for statusline to recognize it\n timestamp: new Date().toISOString(),\n sessionId,\n personality: personality.personality,\n message: getLoadingMessage(personality.personality, customName)\n };\n \n await fs.writeFile(pendingPath, JSON.stringify(pendingState, null, 2)).catch(() => {});\n logger.debug('Written loading state, spawning background process');\n \n // Prepare arguments for background process\n // Use process.argv[1] which is the script being executed\n const scriptPath = process.argv[1];\n const backgroundArgs = [\n scriptPath,\n 'analyze-prompt',\n '--prompt', prompt,\n '--session-id', sessionId,\n '--timeout', timeout,\n '--background-mode' // Special flag to indicate background processing\n ];\n \n // Add conversation context if available\n if (conversationContext) {\n backgroundArgs.push('--context', conversationContext);\n }\n \n // Spawn detached background process\n const child = spawn('node', backgroundArgs, {\n detached: true,\n stdio: 'ignore',\n env: { ...process.env, DEVARK_BACKGROUND: 'true' }\n });\n \n // Unref to allow parent to exit\n child.unref();\n \n logger.debug('Background analysis spawned, exiting hook');\n process.exit(0); // Exit immediately to avoid timeout\n }\n\n // Normal mode or background mode - perform full analysis\n const analysis = await analyzer.analyze(prompt, {\n sessionId,\n timeout: parseInt(timeout),\n verbose,\n conversationContext,\n sessionMetadata\n });\n\n const duration = Date.now() - startTime;\n logger.debug(`Analysis completed in ${duration}ms`, analysis);\n\n // Output results based on mode\n if (!silent) {\n if (verbose) {\n // Detailed output for testing\n console.log();\n console.log(colors.highlight('=== Prompt Analysis Results ==='));\n console.log();\n console.log(colors.accent(`Quality: ${analysis.quality.toUpperCase()}`));\n console.log(colors.info(`Score: ${analysis.score}/100`));\n \n if (analysis.missing.length > 0) {\n console.log(colors.warning('Missing:'));\n analysis.missing.forEach(item => {\n console.log(colors.muted(` - ${item}`));\n });\n }\n \n console.log(colors.primary(`Suggestion: ${analysis.suggestion}`));\n console.log();\n if (sessionId) {\n console.log(colors.dim(`Session ID: ${sessionId}`));\n }\n console.log(colors.dim(`Analysis time: ${duration}ms`));\n } else {\n // Concise output for normal use\n const qualityColor = \n analysis.quality === 'excellent' ? colors.success :\n analysis.quality === 'good' ? colors.primary :\n analysis.quality === 'fair' ? colors.warning :\n colors.error;\n \n console.log(qualityColor(`[${analysis.quality.toUpperCase()}] ${analysis.suggestion}`));\n }\n }\n\n // Success exit\n process.exit(0);\n\n } catch (error) {\n logger.error('Error analyzing prompt:', error);\n \n // Write error state to the session file so statusline doesn't hang on loading\n if (sessionId) {\n const errorAnalysis = {\n quality: 'fair' as const,\n missing: ['error occurred'],\n suggestion: 'Analysis temporarily unavailable - please try again',\n score: 50,\n contextualEmoji: '⚠️',\n timestamp: new Date().toISOString(),\n sessionId,\n originalPrompt: prompt?.substring(0, 100) || '',\n promotionalTip: ''\n };\n \n const homeDir = process.env.HOME || process.env.USERPROFILE;\n if (!homeDir) {\n logger.warn('Unable to determine home directory for analysis storage');\n return;\n }\n const logDir = path.join(homeDir, '.devark', 'analyzed-prompts');\n const sessionPath = path.join(logDir, `${sessionId}.json`);\n \n try {\n await fs.mkdir(logDir, { recursive: true });\n await fs.writeFile(sessionPath, JSON.stringify(errorAnalysis, null, 2), 'utf8');\n logger.debug('Wrote error state to session file');\n } catch (writeError) {\n logger.error('Failed to write error state:', writeError);\n }\n }\n \n if (!silent) {\n console.error(colors.error('Failed to analyze prompt'));\n if (verbose && error instanceof Error) {\n console.error(colors.dim(error.message));\n }\n }\n \n // Exit with error code\n process.exit(1);\n }\n });\n\n return command;\n}\n\n/**\n * Direct execution entry point for testing\n */\nexport async function analyzePrompt(\n promptText: string,\n options?: {\n sessionId?: string;\n timeout?: number;\n verbose?: boolean;\n }\n): Promise<void> {\n const analyzer = new PromptAnalyzer();\n \n const analysis = await analyzer.analyze(promptText, {\n sessionId: options?.sessionId,\n timeout: options?.timeout || 10000,\n verbose: options?.verbose\n });\n\n // Display results\n console.log();\n console.log(colors.highlight('Prompt Analysis:'));\n console.log(colors.accent(` Quality: ${analysis.quality}`));\n console.log(colors.info(` Score: ${analysis.score}/100`));\n \n if (analysis.missing.length > 0) {\n console.log(colors.warning(' Missing:'));\n analysis.missing.forEach(item => {\n console.log(colors.muted(` - ${item}`));\n });\n }\n \n console.log(colors.primary(` Suggestion: ${analysis.suggestion}`));\n}","/**\n * Session context extractor that reuses existing parsing logic\n * Extracts conversation context from a Claude session file\n */\n\nimport { ClaudeFileSystem } from './claude-fs';\nimport { logger } from '../utils/logger';\nimport { SessionMetadata } from './prompt-analyzer';\n\n/**\n * Number of conversation turns to extract for context when analyzing prompts\n * Each turn is a user-assistant message pair\n * Increase for more context, decrease for faster analysis\n */\nexport const DEFAULT_CONVERSATION_TURNS_TO_EXTRACT_AS_CONTEXT = 10;\n\n/**\n * Extract conversation context including first message and recent turns\n * Returns formatted conversation history with original mission and current context\n */\nexport async function extractConversationContext(\n transcriptPath: string,\n turnsToExtract: number = DEFAULT_CONVERSATION_TURNS_TO_EXTRACT_AS_CONTEXT\n): Promise<string | null> {\n try {\n // Normalize path (handle ~/ expansion)\n const normalizedPath = transcriptPath.replace(/^~\\//, `${process.env.HOME}/`);\n \n // Use existing file system abstraction\n const fs = new ClaudeFileSystem();\n const content = await fs.readSessionFile(normalizedPath);\n \n // Parse JSONL content\n const lines = content.trim().split('\\n');\n let firstUserMessage: { role: string; content: string } | null = null;\n const recentMessages: Array<{ role: string; content: string }> = [];\n \n // First pass: Find the very first user message (original mission)\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line) continue;\n \n try {\n const data = JSON.parse(line);\n \n // Check if this is the first user message\n if (data.message && data.message.role === 'user' && !data.isMeta) {\n // Extract text content from the message\n let messageContent: string = '';\n const content = data.message.content;\n \n if (typeof content === 'string') {\n messageContent = content;\n } else if (Array.isArray(content)) {\n messageContent = content\n .filter((item: any) => item.type === 'text')\n .map((item: any) => item.text)\n .join('\\n');\n }\n \n // Skip command-related messages\n if (messageContent && \n !messageContent.includes('<command-name>') && \n !messageContent.includes('Caveat: The messages below were generated')) {\n firstUserMessage = {\n role: 'user',\n content: messageContent.substring(0, 500) // Limit to 500 chars\n };\n break;\n }\n }\n } catch (error) {\n continue;\n }\n }\n \n // Second pass: Read lines in reverse to collect recent messages\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i].trim();\n if (!line) continue;\n \n try {\n const data = JSON.parse(line);\n \n // Check if this line contains a message (user or assistant)\n if (data.message && (data.message.role === 'assistant' || data.message.role === 'user')) {\n // Skip meta messages and command messages\n if (data.isMeta) continue;\n \n // Extract text content from the message\n let messageContent: string = '';\n const content = data.message.content;\n \n if (typeof content === 'string') {\n messageContent = content;\n } else if (Array.isArray(content)) {\n // Extract text from content array\n messageContent = content\n .filter((item: any) => item.type === 'text')\n .map((item: any) => item.text)\n .join('\\n');\n }\n \n // Skip empty messages or command-related messages\n if (messageContent && \n !messageContent.includes('<command-name>') && \n !messageContent.includes('Caveat: The messages below were generated')) {\n recentMessages.unshift({\n role: data.message.role,\n content: messageContent.substring(0, 400) // Slightly smaller for recent to save tokens\n });\n \n // Stop when we have enough conversation turns\n // Count pairs - we want roughly turnsToExtract exchanges\n const assistantCount = recentMessages.filter(m => m.role === 'assistant').length;\n const userCount = recentMessages.filter(m => m.role === 'user').length;\n const minCount = Math.min(assistantCount, userCount);\n \n if (minCount >= turnsToExtract) {\n break;\n }\n }\n }\n } catch (error) {\n // Skip invalid JSON lines\n continue;\n }\n }\n \n // Format the conversation context with both original mission and recent context\n if (!firstUserMessage && recentMessages.length === 0) {\n return null;\n }\n \n // Build conversation context string with clear sections\n const contextParts: string[] = [];\n \n // Add the original mission if we found it\n if (firstUserMessage) {\n contextParts.push(`ORIGINAL MISSION: ${firstUserMessage.content}`);\n }\n \n // Add recent conversation context if available\n if (recentMessages.length > 0) {\n contextParts.push('RECENT CONTEXT:');\n \n // Check if the first user message is duplicated in recent messages\n const firstMessageIsDuplicated = firstUserMessage && \n recentMessages.length > 0 && \n recentMessages.some(msg => \n msg.role === 'user' && \n msg.content === firstUserMessage.content);\n \n for (const msg of recentMessages) {\n // Skip the first user message if it's the same as the original mission\n if (firstMessageIsDuplicated && firstUserMessage && msg.role === 'user' && msg.content === firstUserMessage.content) {\n continue;\n }\n \n const roleLabel = msg.role === 'assistant' ? 'Previous Assistant' : 'Previous User';\n contextParts.push(`${roleLabel}: ${msg.content}`);\n }\n }\n \n const conversationContext = contextParts.join('\\n\\n');\n \n logger.debug('Extracted conversation context', {\n hasOriginalMission: !!firstUserMessage,\n recentMessageCount: recentMessages.length,\n contextLength: conversationContext.length,\n preview: conversationContext.substring(0, 200)\n });\n \n return conversationContext;\n \n } catch (error) {\n logger.debug('Failed to extract conversation context from transcript:', error);\n return null;\n }\n}\n\n/**\n * Extract metadata about the session for better context awareness\n * @param transcriptPath - Path to the Claude session JSONL file\n * @param currentPrompt - The current prompt being analyzed\n * @returns SessionMetadata with information about the session state\n */\nexport async function extractSessionMetadata(\n transcriptPath: string,\n currentPrompt: string\n): Promise<SessionMetadata> {\n const metadata: SessionMetadata = {\n messageNumber: 1,\n totalMessages: 0,\n isFirstPrompt: true,\n hasImages: false,\n imageCount: 0,\n lastAssistantEndsWithQuestion: false,\n truncatedMessages: 0\n };\n\n try {\n // Normalize path (handle ~/ expansion)\n const normalizedPath = transcriptPath.replace(/^~\\//, `${process.env.HOME}/`);\n \n // Use existing file system abstraction\n const fs = new ClaudeFileSystem();\n const content = await fs.readSessionFile(normalizedPath);\n \n // Parse JSONL content\n const lines = content.trim().split('\\n');\n let userMessageCount = 0;\n let assistantMessageCount = 0;\n let lastAssistantMessage = '';\n let truncatedCount = 0;\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line) continue;\n \n try {\n const data = JSON.parse(line);\n \n // Skip meta messages\n if (data.isMeta) continue;\n \n // Count messages\n if (data.message) {\n if (data.message.role === 'user') {\n userMessageCount++;\n } else if (data.message.role === 'assistant') {\n assistantMessageCount++;\n \n // Extract last assistant message text\n let messageContent: string = '';\n const content = data.message.content;\n \n if (typeof content === 'string') {\n messageContent = content;\n } else if (Array.isArray(content)) {\n messageContent = content\n .filter((item: any) => item.type === 'text')\n .map((item: any) => item.text)\n .join('\\n');\n }\n \n if (messageContent) {\n lastAssistantMessage = messageContent;\n \n // Check if message was likely truncated (ends with ellipsis or has truncation marker)\n if (messageContent.includes('...') && messageContent.length > 350) {\n truncatedCount++;\n }\n }\n }\n }\n } catch (error) {\n continue;\n }\n }\n \n // Set metadata based on what we found\n metadata.totalMessages = userMessageCount + assistantMessageCount;\n metadata.messageNumber = userMessageCount + 1; // Next user message number\n metadata.isFirstPrompt = userMessageCount === 0;\n metadata.truncatedMessages = truncatedCount;\n \n // Check if last assistant message ends with a question\n if (lastAssistantMessage) {\n // Look for question patterns at the end of the message\n const questionPatterns = [\n /\\?\\s*$/, // Ends with question mark\n /\\bor\\s+\\w+\\?\\s*$/i, // \"...or X?\"\n /\\bwhich\\s+\\w+.*\\?\\s*$/i, // \"which one?\"\n /\\bwhat\\s+\\w+.*\\?\\s*$/i, // \"what do you think?\"\n /\\bshould\\s+\\w+.*\\?\\s*$/i, // \"should we...?\"\n /\\bdo\\s+you\\s+\\w+.*\\?\\s*$/i // \"do you want...?\"\n ];\n \n metadata.lastAssistantEndsWithQuestion = questionPatterns.some(pattern => \n pattern.test(lastAssistantMessage.slice(-200)) // Check last 200 chars\n );\n }\n \n // Check if current prompt contains images\n const imageIndicators = [\n /\\[\\d+\\s+image\\s+attachments?\\]/i,\n /see\\s+(the\\s+)?image/i,\n /as\\s+shown/i,\n /in\\s+the\\s+screenshot/i,\n /above\\s+image/i,\n /attached\\s+image/i\n ];\n \n metadata.hasImages = imageIndicators.some(pattern => pattern.test(currentPrompt));\n \n // Count images if present\n const imageMatch = currentPrompt.match(/\\[(\\d+)\\s+image\\s+attachments?\\]/i);\n if (imageMatch) {\n metadata.imageCount = parseInt(imageMatch[1], 10);\n } else if (metadata.hasImages) {\n metadata.imageCount = 1; // Assume at least one if indicators present\n }\n \n logger.debug('Extracted session metadata', metadata);\n \n return metadata;\n \n } catch (error) {\n logger.debug('Failed to extract session metadata:', error);\n // Return default metadata on error\n return metadata;\n }\n}","import { Command } from 'commander';\nimport { readFileSync, existsSync, appendFileSync } from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { PromptAnalysis } from '../lib/prompt-analyzer';\nimport { logger } from '../utils/logger';\nimport { transformSuggestion, getStatusLinePersonality, getPersonalityDisplayName } from '../lib/personality-manager';\nimport { isLoadingState, isStaleLoadingState, LoadingState, getLoadingMessage } from '../types/loading-state';\nimport { getCCUsageMetrics } from '../lib/ccusage-integration';\n\n/**\n * Output format types for the statusline\n */\ntype OutputFormat = 'compact' | 'detailed' | 'emoji' | 'minimal' | 'json';\n\n/**\n * Debug logging function - writes directly to file\n */\nfunction debugLog(message: string): void {\n try {\n const homeDir = os.homedir();\n const debugFile = path.join(homeDir, '.devark', 'statusline-debug.log');\n const timestamp = new Date().toISOString();\n appendFileSync(debugFile, `[${timestamp}] ${message}\\n`);\n } catch (err) {\n // Silently fail if we can't write debug log\n }\n}\n\n/**\n * Get color-coded emoji based on score\n */\nfunction getScoreEmoji(score: number): string {\n if (score <= 40) return '🔴'; // Poor (0-40)\n if (score <= 60) return '🟠'; // Fair (41-60)\n if (score <= 80) return '🟡'; // Good (61-80)\n return '🟢'; // Excellent (81-100)\n}\n\n/**\n * Format the analysis for compact output (default)\n * Example: 🟢 85/100 | ✨ Great context! Consider adding expected output format\n * With actionableSteps: Adds second line with \"✅ TRY THIS:\" prefix\n * With ccusage: Adds usage metrics on additional line\n */\nfunction formatCompact(analysis: PromptAnalysis, ccusageOutput?: string | null): string {\n const score = analysis.score;\n let suggestion = analysis.suggestion;\n const actionableSteps = analysis.actionableSteps;\n\n // Handle recursion detection case\n if (suggestion.includes('Recursion prevented')) {\n return '🔄 Skip | Analysis loop prevented';\n }\n\n // Apply personality transformation to the suggestion\n const personality = getStatusLinePersonality();\n // Always apply personality transformation since we don't have 'standard' mode\n suggestion = transformSuggestion(suggestion, score, personality.personality);\n\n // Get appropriate emojis\n const scoreEmoji = getScoreEmoji(score);\n const contextEmoji = analysis.contextualEmoji || '💡'; // Use emoji from analysis or default\n\n // Get the personality name for attribution\n const personalityName = getPersonalityDisplayName(personality.personality);\n\n // Format the enhanced output with personality name before suggestion\n let output = `${scoreEmoji} ${score}/100 | ${contextEmoji} ${personalityName}: ${suggestion}`;\n\n // Add actionable steps on second line if present\n if (actionableSteps && actionableSteps.trim()) {\n output += `\\n✅ TRY THIS: ${actionableSteps}`;\n }\n\n // Add persisted promotional tip if it exists\n if (analysis.promotionalTip) {\n output += analysis.promotionalTip;\n }\n\n // Add ccusage metrics if available\n if (ccusageOutput) {\n output += '\\n' + ccusageOutput;\n }\n\n return output;\n}\n\n/**\n * Format the analysis for detailed output\n * Example: Quality: Good (75/100) | Missing: context | Improve: Add details\n */\nfunction formatDetailed(analysis: PromptAnalysis): string {\n const quality = analysis.quality.charAt(0).toUpperCase() + analysis.quality.slice(1);\n const score = analysis.score;\n const missing = analysis.missing.length > 0 ? analysis.missing.join(', ') : 'none';\n const suggestion = analysis.suggestion;\n \n // Handle recursion detection case\n if (suggestion.includes('Recursion prevented')) {\n return 'Status: Skip | Reason: Analysis loop prevented';\n }\n \n return `Quality: ${quality} (${score}/100) | Missing: ${missing} | Improve: ${suggestion}`;\n}\n\n/**\n * Format the analysis for emoji output\n * Example: 📊 Good (75) | 💡 Add context\n */\nfunction formatEmoji(analysis: PromptAnalysis): string {\n const qualityEmoji = {\n 'excellent': '🌟',\n 'good': '✅',\n 'fair': '⚠️',\n 'poor': '❌'\n }[analysis.quality] || '📊';\n \n const quality = analysis.quality.charAt(0).toUpperCase() + analysis.quality.slice(1);\n const score = analysis.score;\n const suggestion = analysis.suggestion;\n \n // Handle recursion detection case\n if (suggestion.includes('Recursion prevented')) {\n return '🔄 Skip | Analysis loop prevented';\n }\n \n return `${qualityEmoji} ${quality} (${score}) | 💡 ${suggestion}`;\n}\n\n/**\n * Format the analysis for minimal output\n * Example: Good • 75% • Add context\n */\nfunction formatMinimal(analysis: PromptAnalysis): string {\n const quality = analysis.quality.charAt(0).toUpperCase() + analysis.quality.slice(1);\n const score = analysis.score;\n const suggestion = analysis.suggestion;\n \n // Handle recursion detection case\n if (suggestion.includes('Recursion prevented')) {\n return 'Skip • Loop prevented';\n }\n \n // Shorten the suggestion for minimal format\n const shortSuggestion = suggestion.length > 30 \n ? suggestion.substring(0, 27) + '...' \n : suggestion;\n \n return `${quality} • ${score}% • ${shortSuggestion}`;\n}\n\n/**\n * Format loading state for display\n */\nfunction formatLoadingState(state: LoadingState, format: OutputFormat): string {\n // Check if state is stale (older than 5 minutes - 300 seconds)\n // We use a much longer timeout since analysis is async and results should persist\n if (isStaleLoadingState(state, 300000)) {\n logger.debug('Loading state is stale (>5 minutes old), returning empty');\n return '';\n }\n\n // Use the loading message from the state or generate based on personality\n // If we need to regenerate, check for custom personality name\n let message = state.message;\n if (!message) {\n const personality = getStatusLinePersonality();\n const customName = personality.personality === 'custom' ? personality.customPersonality?.name : undefined;\n message = getLoadingMessage(state.personality, customName);\n }\n\n switch (format) {\n case 'json':\n return JSON.stringify(state);\n case 'detailed':\n return `Status: Loading | ${message}`;\n case 'emoji':\n return `⏳ ${message}`;\n case 'minimal':\n return 'Loading...';\n case 'compact':\n default:\n return message;\n }\n}\n\n/**\n * Format the analysis based on the selected format\n */\nfunction formatAnalysis(analysis: PromptAnalysis, format: OutputFormat, ccusageOutput?: string | null): string {\n switch (format) {\n case 'json':\n // For JSON, include ccusage as separate field\n const jsonOutput: any = { ...analysis };\n if (ccusageOutput) {\n jsonOutput.ccusage = ccusageOutput;\n }\n return JSON.stringify(jsonOutput);\n case 'detailed':\n return formatDetailed(analysis);\n case 'emoji':\n return formatEmoji(analysis);\n case 'minimal':\n return formatMinimal(analysis);\n case 'compact':\n default:\n return formatCompact(analysis, ccusageOutput);\n }\n}\n\n/**\n * Read stdin with a timeout to get Claude Code context\n * Increased timeout to 500ms to allow Claude Code time to send session context\n */\nasync function readStdinWithTimeout(timeoutMs: number = 500): Promise<string | null> {\n return new Promise((resolve) => {\n let input = '';\n let hasData = false;\n let resolved = false;\n\n // Set timeout to return null if no data arrives\n // Increased from 50ms to 500ms to account for Claude Code's stdin piping\n const timeout = setTimeout(() => {\n if (!hasData && !resolved) {\n resolved = true;\n resolve(null);\n }\n }, timeoutMs);\n\n process.stdin.setEncoding('utf8');\n\n process.stdin.on('readable', () => {\n let chunk;\n while ((chunk = process.stdin.read()) !== null) {\n hasData = true;\n input += chunk;\n }\n });\n\n process.stdin.on('end', () => {\n clearTimeout(timeout);\n if (!resolved) {\n resolved = true;\n resolve(hasData ? input : null);\n }\n });\n\n // Handle error gracefully\n process.stdin.on('error', () => {\n clearTimeout(timeout);\n if (!resolved) {\n resolved = true;\n resolve(null);\n }\n });\n });\n}\n\n/**\n * Format default message for new sessions or when no analysis exists\n */\nfunction formatDefault(format: OutputFormat): string {\n // Get current personality for personalized message\n const personality = getStatusLinePersonality();\n\n // Get personality icon and name\n const personalityName = getPersonalityDisplayName(personality.personality);\n\n // Create unified message for all personalities\n const baseMessage = `💭 ${personalityName} is ready to analyze and improve your prompts`;\n\n switch (format) {\n case 'json':\n const jsonResult: any = { status: 'ready', message: baseMessage, personality: personality.personality };\n return JSON.stringify(jsonResult);\n case 'detailed':\n return `Status: Ready | ${baseMessage}`;\n case 'emoji':\n return `Ready`;\n case 'minimal':\n return 'Ready';\n case 'compact':\n default:\n return baseMessage;\n }\n}\n\n/**\n * Create the statusline command for displaying prompt analysis in Claude Code\n * This command is designed to be fast (<100ms) and fail gracefully\n */\nexport function createStatuslineCommand(): Command {\n const command = new Command('statusline')\n .description('Display prompt analysis in Claude Code status line (hidden command)')\n .option('-f, --format <type>', 'Output format: compact, detailed, emoji, minimal, json', 'compact')\n .option('--with-usage', 'Include ccusage metrics in output')\n .option('--stdin', 'Explicitly wait for stdin input from Claude Code', false)\n .action(async (options) => {\n const startTime = Date.now();\n\n try {\n debugLog('=== STATUSLINE START ===');\n debugLog(`Options: stdin=${options.stdin}, format=${options.format}`);\n\n // Try to read Claude Code context from stdin\n // Claude Code sends session context via stdin with session_id\n let currentSessionId: string | undefined;\n let claudeContext: any = null;\n\n // When --stdin is explicitly passed, use a longer timeout since Claude Code WILL send data\n const timeout = options.stdin ? 1000 : 500;\n debugLog(`Waiting for stdin with ${timeout}ms timeout`);\n const stdinData = await readStdinWithTimeout(timeout);\n\n // DEBUG: Log what we received from stdin\n if (stdinData) {\n debugLog(`Received stdin data (${stdinData.length} bytes): ${stdinData.substring(0, 300)}`);\n try {\n claudeContext = JSON.parse(stdinData);\n currentSessionId = claudeContext.session_id;\n debugLog(`Extracted session ID: ${currentSessionId}`);\n } catch (parseError) {\n debugLog(`Failed to parse stdin as JSON: ${parseError}`);\n }\n } else {\n debugLog('No stdin data received (timeout or no input)');\n }\n\n // Parse and validate format option\n const format = (options.format || 'compact').toLowerCase() as OutputFormat;\n const validFormats: OutputFormat[] = ['compact', 'detailed', 'emoji', 'minimal', 'json'];\n\n if (!validFormats.includes(format)) {\n // Invalid format, use default\n logger.debug(`Invalid format '${options.format}', using 'compact'`);\n options.format = 'compact';\n }\n\n // If no session ID from stdin, show default message\n if (!currentSessionId) {\n debugLog('DECISION: No session ID, showing default message');\n logger.debug('No session ID provided, showing default message');\n const output = formatDefault(format);\n debugLog(`DEFAULT OUTPUT: ${output.substring(0, 100)}`);\n process.stdout.write(output);\n process.exitCode = 0;\n return;\n }\n\n // Build path to session-specific analysis file\n const homeDir = os.homedir();\n const analysisFile = path.join(homeDir, '.devark', 'analyzed-prompts', `${currentSessionId}.json`);\n debugLog(`DECISION POINT: Looking for analysis file at: ${analysisFile}`);\n logger.debug(`Statusline looking for analysis file: ${analysisFile}`);\n\n // Check if file exists\n if (!existsSync(analysisFile)) {\n // No analysis for this session yet - show default message\n debugLog(`DECISION: File NOT found, showing default for session ${currentSessionId}`);\n logger.debug(`Analysis file NOT found for session ${currentSessionId}, showing default message`);\n const output = formatDefault(format);\n process.stdout.write(output);\n process.exitCode = 0;\n return;\n }\n\n // Read the analysis file synchronously for speed\n let content: string;\n try {\n content = readFileSync(analysisFile, 'utf8');\n } catch (readError) {\n // File exists but can't be read - return empty\n logger.debug('Failed to read analysis file:', readError);\n process.stdout.write('');\n process.exitCode = 0;\n return;\n }\n\n // Parse the JSON content\n let parsedContent: any;\n try {\n parsedContent = JSON.parse(content);\n } catch (parseError) {\n // Corrupted JSON - show error\n logger.debug('Failed to parse JSON:', parseError);\n process.stdout.write('[Error] Invalid data');\n process.exitCode = 0;\n return;\n }\n\n // Check if this is a loading state\n if (isLoadingState(parsedContent)) {\n logger.debug('Detected loading state');\n const output = formatLoadingState(parsedContent as LoadingState, format);\n process.stdout.write(output);\n process.exitCode = 0;\n return;\n }\n\n // Otherwise, treat as completed analysis\n const analysis = parsedContent as PromptAnalysis;\n\n // Validate the analysis has required fields\n if (!analysis.quality || typeof analysis.score !== 'number' || !analysis.suggestion) {\n logger.debug('Invalid analysis structure:', analysis);\n process.stdout.write('[Error] Invalid analysis data');\n process.exitCode = 0;\n return;\n }\n\n // No need to check session ID - we're reading the session-specific file\n\n // Get ccusage metrics if requested\n let ccusageOutput: string | null = null;\n if (options.withUsage && claudeContext) {\n // Wait for ccusage to complete (typically takes ~1s)\n const usageTimeout = 2000; // Give ccusage enough time to complete\n logger.debug(`Fetching ccusage metrics with ${usageTimeout}ms timeout`);\n\n try {\n ccusageOutput = await getCCUsageMetrics(claudeContext, usageTimeout);\n if (ccusageOutput) {\n logger.debug('Got ccusage metrics successfully');\n } else {\n logger.debug('No ccusage metrics returned');\n }\n } catch (err) {\n logger.debug('ccusage error:', err);\n ccusageOutput = null;\n }\n } else {\n // Debug why we're not calling ccusage\n debugLog(`Not calling ccusage - withUsage: ${options.withUsage}, hasContext: ${!!claudeContext}`);\n }\n\n // Format and output the analysis\n const output = formatAnalysis(analysis, format, ccusageOutput);\n debugLog(`SUCCESS: Outputting analysis (${output.length} bytes): ${output.substring(0, 150)}`);\n logger.debug(`Statusline about to output (${output.length} bytes): ${output.substring(0, 200)}`);\n process.stdout.write(output);\n\n // Log performance metrics\n const elapsed = Date.now() - startTime;\n debugLog(`COMPLETE: Rendered in ${elapsed}ms`);\n logger.debug(`Statusline rendered in ${elapsed}ms`);\n\n // Use exitCode instead of exit() to allow stdout buffer to flush on Windows\n process.exitCode = 0;\n\n } catch (error) {\n // Unexpected error - log but return empty to not break status line\n debugLog(`ERROR: ${error instanceof Error ? error.message : String(error)}`);\n logger.error('Unexpected error in statusline command:', error);\n process.stdout.write('');\n process.exitCode = 0;\n }\n });\n\n // Mark as hidden since this is for internal use\n // Note: Command.hidden might not be directly settable in some versions\n // The command is registered as hidden via the parent program instead\n\n return command;\n}","/**\n * CCUsage Integration Module\n * \n * This module integrates with ccusage (https://www.npmjs.com/package/ccusage)\n * to provide real-time token usage metrics for Claude Code sessions.\n * \n * Credit: Special thanks to the ccusage project for providing \n * comprehensive token tracking capabilities for Claude Code.\n */\n\nimport { spawn } from 'child_process';\nimport { logger } from '../utils/logger';\nimport os from 'os';\nimport path from 'path';\n\n// Cache for ccusage output to avoid repeated calls\ninterface CacheEntry {\n output: string | null;\n timestamp: number;\n}\n\nconst cache = new Map<string, CacheEntry>();\nconst CACHE_TTL = 30000; // 30 seconds cache\n\n/**\n * Get ccusage metrics for the current session\n * @param claudeContext - The full Claude Code context object\n * @param timeout - Maximum time to wait for ccusage response\n * @returns The ccusage output or null if unavailable\n */\nexport async function getCCUsageMetrics(\n claudeContext: any,\n timeout: number = 1500 // Default 1.5 seconds since ccusage takes ~1s to output\n): Promise<string | null> {\n logger.debug('getCCUsageMetrics called with timeout:', timeout);\n \n // No context, can't get metrics\n if (!claudeContext || !claudeContext.session_id) {\n logger.debug('No Claude context provided for ccusage');\n return null;\n }\n\n logger.debug('Claude context session_id:', claudeContext.session_id);\n\n // Check cache first\n const cacheKey = claudeContext.session_id;\n const cached = cache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < CACHE_TTL) {\n logger.debug('Using cached ccusage output:', cached.output);\n return cached.output;\n }\n \n logger.debug('No cache hit, calling ccusage...');\n\n // Set up cross-platform debug log path\n const debugLogPath = path.join(os.homedir(), '.devark', 'ccusage-debug.log');\n\n return new Promise((resolve) => {\n let output = '';\n let errorOutput = '';\n let timedOut = false;\n let processExited = false;\n\n // Set timeout\n const timeoutHandle = setTimeout(() => {\n timedOut = true;\n logger.debug(`ccusage timed out after ${timeout}ms`);\n const fs = require('fs');\n fs.appendFileSync(debugLogPath, `[${new Date().toISOString()}] TIMEOUT after ${timeout}ms - output so far: \"${output}\"\\n`);\n \n // On timeout, return the last successful result if available\n const existingCache = cache.get(cacheKey);\n if (existingCache && existingCache.output) {\n fs.appendFileSync(debugLogPath, `[${new Date().toISOString()}] Returning cached result after timeout\\n`);\n resolve(existingCache.output);\n } else {\n resolve(null);\n }\n }, timeout);\n\n try {\n // Debug logging to file\n const fs = require('fs');\n fs.appendFileSync(debugLogPath, `[${new Date().toISOString()}] Spawning ccusage process\\n`);\n \n // Spawn ccusage process using npx with @latest to ensure v16+\n const ccusage = spawn('npx', ['ccusage@latest', 'statusline'], {\n stdio: ['pipe', 'pipe', 'pipe'],\n shell: process.platform === 'win32'\n });\n\n // Send the full Claude context to stdin (ccusage expects all these fields)\n const inputData = JSON.stringify(claudeContext);\n fs.appendFileSync(debugLogPath, `[${new Date().toISOString()}] Sending data length: ${inputData.length}\\n`);\n ccusage.stdin.write(inputData);\n ccusage.stdin.end();\n\n // Capture stdout\n ccusage.stdout.on('data', (data) => {\n const chunk = data.toString();\n output += chunk;\n logger.debug('ccusage stdout:', chunk);\n });\n\n // Capture stderr\n ccusage.stderr.on('data', (data) => {\n const chunk = data.toString();\n errorOutput += chunk;\n logger.debug('ccusage stderr:', chunk);\n });\n\n // Handle process completion\n ccusage.on('close', (code) => {\n const fs = require('fs');\n fs.appendFileSync(debugLogPath, `[${new Date().toISOString()}] Process closed with code ${code}, timedOut: ${timedOut}, output: \"${output}\"\\n`);\n \n if (processExited) return;\n processExited = true;\n clearTimeout(timeoutHandle);\n \n if (timedOut) return;\n\n if (code === 0 && output && output.trim()) {\n // Success - cache and return the output\n const result = output.trim();\n cache.set(cacheKey, { output: result, timestamp: Date.now() });\n logger.debug('Successfully got ccusage output, length:', result.length);\n logger.debug('ccusage result:', result);\n resolve(result);\n } else {\n // Failed - log error if present\n logger.debug(`ccusage failed with code ${code}, output: \"${output}\", error: \"${errorOutput}\"`);\n if (errorOutput && !errorOutput.includes('npm warn')) {\n logger.debug('ccusage error details:', errorOutput);\n }\n // Don't cache failures - return the last successful result if available\n const existingCache = cache.get(cacheKey);\n if (existingCache && existingCache.output) {\n logger.debug('ccusage failed, returning last successful result');\n resolve(existingCache.output);\n } else {\n resolve(null);\n }\n }\n });\n\n // Handle process errors\n ccusage.on('error', (err) => {\n if (processExited) return;\n processExited = true;\n clearTimeout(timeoutHandle);\n \n if (timedOut) return;\n \n logger.debug('Failed to spawn ccusage:', err.message);\n // Don't cache failures - return last successful result if available\n const existingCache = cache.get(cacheKey);\n if (existingCache && existingCache.output) {\n logger.debug('ccusage error, returning last successful result');\n resolve(existingCache.output);\n } else {\n resolve(null);\n }\n });\n\n } catch (error) {\n clearTimeout(timeoutHandle);\n logger.debug('Error calling ccusage:', error);\n resolve(null);\n }\n });\n}\n\n/**\n * Clear the ccusage cache\n */\nexport function clearCCUsageCache(): void {\n cache.clear();\n}","/**\n * PHASE 6.1 UPDATE: Personality System Fixed\n * \n * The personality system now uses enhanced system prompts to guide Claude's\n * natural language generation instead of template substitution.\n * \n * Key changes:\n * - transformSuggestion() no longer replaces suggestions with templates\n * - Personalities influence HOW Claude writes, not REPLACE what Claude writes\n * - Each suggestion is unique and contextual while maintaining personality\n * - Gordon naturally uses kitchen metaphors without scripted phrases\n * - DevArk naturally uses dev metaphors without repetition\n */\n\nimport { Command } from 'commander';\nimport { colors } from '../lib/ui/styles';\nimport { \n getStatusLinePersonality, \n setStatusLinePersonality,\n getPersonalityDisplayName,\n getPersonalityIcon,\n getPersonalitySystemPrompt,\n transformSuggestion\n} from '../lib/personality-manager';\nimport { setCustomPersonality } from '../lib/config';\nimport { \n runPersonalityTest,\n STANDARD_TEST_PROMPTS\n} from '../lib/personality-test-engine';\n\n/**\n * Create the test-personality command for debugging personality system\n */\nexport function createTestPersonalityCommand(): Command {\n const command = new Command('test-personality')\n .description('Test and debug the personality system (hidden command)')\n .option('-p, --personality <type>', 'Test specific personality (gordon, devark, custom)')\n .option('-c, --create-custom', 'Create a test custom personality')\n .option('-a, --analyze', 'Analyze test prompts with current personality')\n .option('-v, --verbose', 'Show detailed debug output')\n .action(async (options) => {\n console.log(colors.accent('\\n🧪 Personality System Test\\n'));\n \n // Set debug mode for this session\n if (options.verbose) {\n process.env.DEBUG_PERSONALITY = 'true';\n console.log(colors.subdued('Debug mode enabled\\n'));\n }\n \n // Show current personality\n const currentConfig = getStatusLinePersonality();\n const currentName = getPersonalityDisplayName(currentConfig.personality);\n const currentIcon = getPersonalityIcon(currentConfig.personality);\n \n console.log(colors.info('Current Personality:'));\n console.log(` ${currentIcon} ${colors.highlight(currentName)}`);\n \n if (currentConfig.personality === 'custom' && currentConfig.customPersonality) {\n console.log(` Name: ${currentConfig.customPersonality.name}`);\n console.log(` Style: ${currentConfig.customPersonality.description}`);\n }\n console.log('');\n \n // Test creating a custom personality\n if (options.createCustom) {\n console.log(colors.info('Creating test custom personality...'));\n setCustomPersonality({\n name: 'Test Bot',\n description: 'Like a helpful robot assistant',\n templates: {\n poor: 'BEEP BOOP! ERROR: Context not found!',\n fair: 'PROCESSING... More data required for optimal output.',\n good: 'ANALYSIS COMPLETE: Quality acceptable. Minor optimizations suggested.',\n excellent: 'EXCELLENT! All parameters optimal. Executing with maximum efficiency!'\n }\n });\n console.log(colors.success('✅ Test custom personality created!'));\n console.log('');\n }\n \n // Test specific personality\n if (options.personality) {\n const validPersonalities = ['gordon', 'devark', 'custom'];\n if (!validPersonalities.includes(options.personality)) {\n console.log(colors.error('Invalid personality. Choose: gordon, devark, or custom'));\n process.exit(1);\n }\n \n console.log(colors.info(`Switching to ${options.personality} personality...`));\n setStatusLinePersonality(options.personality as any);\n console.log(colors.success('✅ Personality switched!'));\n console.log('');\n }\n \n // Show system prompt\n console.log(colors.info('System Prompt Addition:'));\n const systemPrompt = getPersonalitySystemPrompt();\n if (systemPrompt) {\n console.log(colors.subdued(systemPrompt));\n } else {\n console.log(colors.subdued(' (No personality-specific prompt)'));\n }\n console.log('');\n \n // Test transformation\n console.log(colors.info('Testing Suggestion Transformations:'));\n console.log('');\n \n const testScores = [25, 55, 75, 95];\n const originalSuggestion = 'Add more context to your prompt';\n \n for (const score of testScores) {\n const transformed = transformSuggestion(originalSuggestion, score);\n const emoji = score <= 40 ? '🔴' : score <= 60 ? '🟠' : score <= 80 ? '🟡' : '🟢';\n console.log(` ${emoji} Score ${score}: \"${transformed}\"`);\n }\n console.log('');\n \n // Analyze test prompts if requested\n if (options.analyze) {\n console.log(colors.info('Analyzing Test Prompts with Claude SDK:'));\n console.log(colors.subdued('(This will make actual calls to Claude Code)\\n'));\n \n // Use shared test engine\n const results = await runPersonalityTest(STANDARD_TEST_PROMPTS, {\n verbose: options.verbose,\n personality: currentConfig.personality,\n onProgress: (message) => {\n console.log(colors.subdued(message));\n }\n });\n \n // Display results\n for (const result of results) {\n console.log(colors.accent(`Prompt: \"${result.prompt.substring(0, 50)}...\"`));\n console.log(colors.subdued(` Context: ${result.promptDescription}`));\n \n if (result.error) {\n console.log(colors.error(` Error: ${result.error}`));\n } else {\n console.log(` Result: ${result.emoji} ${result.aiScore}/100 (${result.aiQuality})`);\n console.log(` AI Suggestion: \"${result.aiSuggestion}\"`);\n console.log(` With Personality: \"${result.personalityTransformed}\"`);\n console.log(colors.dim(` Processing: ${(result.processingTime / 1000).toFixed(1)}s`));\n }\n console.log('');\n }\n }\n \n // Summary\n console.log(colors.accent('Test Summary:'));\n console.log(colors.subdued('• Personality system is working correctly'));\n console.log(colors.subdued('• System prompts are being sent to Claude SDK'));\n console.log(colors.subdued('• Transformations are applied based on score ranges'));\n \n if (options.verbose) {\n console.log('');\n console.log(colors.subdued('Check the debug logs above for detailed information'));\n } else {\n console.log('');\n console.log(colors.subdued('Run with -v flag for detailed debug output'));\n }\n });\n \n return command;\n}","import { showHooksManagementMenu } from '../lib/ui/hooks-menu';\nimport { showLogo } from '../lib/ui';\nimport { showMainMenu } from '../lib/ui/main-menu';\nimport { detectSetupState } from '../lib/detector';\nimport { currentVersion } from '../index';\n\n/**\n * Command to directly open the auto-sync configuration menu\n * This provides a shortcut to the hooks management interface\n */\nexport async function installAutoSync(): Promise<void> {\n // Show logo for consistency with other commands\n await showLogo(currentVersion);\n \n // Go directly to the hooks management menu\n await showHooksManagementMenu();\n \n // After exiting hooks menu, show the main menu\n const state = await detectSetupState();\n await showMainMenu(state, null);\n}","import inquirer from 'inquirer';\nimport { StateDetails } from '../detector';\nimport { parseProjectName } from './project-display';\nimport { colors, icons } from './styles';\nimport { createStatusDashboard } from './status-sections';\nimport { generateMenuItems, MenuContext } from './menu-builder';\nimport { sendWithTimeout } from '../../commands/send';\nimport { status } from '../../commands/status';\nimport { auth } from '../../commands/auth';\nimport { logout } from '../../commands/logout';\nimport { displayError } from '../../utils/errors';\nimport { showHelpContent } from './help-content';\nimport open from 'open';\n\n// Helper to wait for Enter key\nasync function waitForEnter(): Promise<void> {\n await inquirer.prompt({\n type: 'input',\n name: 'continue',\n message: ' '\n });\n}\n\n// Helper to display package update notification\nfunction displayPackageUpdateNotification(packageUpdateInfo: { current: string; latest: string }): void {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const boxen = require('boxen');\n console.log(boxen(\n `Update available ${packageUpdateInfo.current} → ${packageUpdateInfo.latest}\\nRun \\`npx devark-cli@latest\\` to update`,\n {\n padding: 1,\n margin: 0,\n align: 'center',\n borderColor: 'yellow',\n borderStyle: 'round'\n }\n ));\n}\n\nexport async function showMainMenu(\n state: StateDetails, \n packageUpdateInfo?: { current: string; latest: string } | null\n): Promise<void> {\n // Get version from index.ts\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const pkg = require('../../../package.json');\n const version = process.env.SIMULATE_OLD_VERSION || pkg.version;\n \n // Handle FIRST_TIME and PARTIAL_SETUP states with welcome screen\n if (state.state === 'FIRST_TIME' || state.state === 'PARTIAL_SETUP') {\n // Clear console and show logo for first-time experience\n console.clear();\n const { showLogo } = await import('../ui');\n await showLogo(version);\n \n // Show package update notification if available\n if (packageUpdateInfo) {\n displayPackageUpdateNotification(packageUpdateInfo);\n }\n \n const { showFirstTimeWelcome, showSetupMessage } = await import('./first-time-welcome');\n const choice = await showFirstTimeWelcome();\n \n switch (choice) {\n case 'standup': {\n // Run standup command directly, skipping auth for first-time users\n const { standup } = await import('../../commands/standup');\n await standup({ skipAuth: true });\n\n // After standup completes, offer cloud setup if not authenticated\n const { isAuthenticated } = await import('../auth/token');\n if (!await isAuthenticated()) {\n console.log(); // Add spacing\n const { setupCloud } = await inquirer.prompt([{\n type: 'confirm',\n name: 'setupCloud',\n message: 'Enable cloud for daily email summaries?',\n default: true\n }]);\n\n if (setupCloud) {\n showSetupMessage('cloud');\n const { guidedCloudSetup } = await import('./cloud-setup-wizard');\n await guidedCloudSetup();\n }\n }\n break;\n }\n\n case 'local': {\n showSetupMessage('local');\n // Track that this is first-time setup\n const wasFirstTime = state.agentCount === 0;\n await manageAgents();\n \n // After agents installation, check if we should prompt for report\n // Get fresh state to check if agents were installed\n const { detectSetupState: detectStateAfterAgents } = await import('../detector');\n const stateAfterAgents = await detectStateAfterAgents();\n \n // If this was first-time and all agents are now installed\n if (wasFirstTime && stateAfterAgents.agentCount === stateAfterAgents.totalAgents) {\n // The prompt for report generation is already handled in sub-agents-installer.ts\n // when it detects a successful first-time installation\n }\n break;\n }\n \n case 'cloud': {\n showSetupMessage('cloud');\n // Start guided cloud setup flow\n const { guidedCloudSetup } = await import('./cloud-setup-wizard');\n await guidedCloudSetup();\n break;\n }\n \n case 'statusline': {\n const { showStatusLineMenu } = await import('./status-line-menu');\n await showStatusLineMenu();\n // Show welcome again after status line configuration\n await showMainMenu(state, packageUpdateInfo);\n return;\n }\n\n case 'exit':\n console.log(colors.muted('\\nGoodbye! 👋\\n'));\n process.exit(0);\n break;\n }\n \n // After setup, refresh state and show main menu\n const { detectSetupState } = await import('../detector');\n const newState = await detectSetupState();\n \n // If still FIRST_TIME or PARTIAL_SETUP (user cancelled), show welcome again\n if (newState.state === 'FIRST_TIME' || newState.state === 'PARTIAL_SETUP') {\n await showMainMenu(newState, packageUpdateInfo);\n } else {\n // Setup successful, show the main menu\n await showMainMenu(newState, packageUpdateInfo);\n }\n return;\n }\n \n // Regular main menu for non-FIRST_TIME states\n console.clear();\n // Show the logo after clearing console\n const { showLogo } = await import('../ui');\n await showLogo(version);\n \n // Show package update notification if available\n if (packageUpdateInfo) {\n displayPackageUpdateNotification(packageUpdateInfo);\n }\n \n // Show status dashboard with converted parameters\n const cloudStatus = {\n connected: state.hasAuth,\n hooksEnabled: state.hasHooks,\n syncStatus: 'synced' as const, // Not used anymore, kept for compatibility\n lastSync: state.lastSync,\n lastSyncProject: state.lastSyncProject,\n pendingChanges: 0,\n trackingMode: state.trackingMode,\n trackedProjectCount: state.trackedProjectCount\n };\n \n const installStatus: 'not-installed' | 'installed' | 'partial' = \n state.agentCount === 0 ? 'not-installed' :\n state.agentCount === state.totalAgents ? 'installed' :\n 'partial';\n \n const localEngine = {\n installStatus,\n subAgentsInstalled: state.agentCount,\n totalSubAgents: state.totalAgents,\n statusLineStatus: state.statusLineStatus,\n configPath: '~/.claude/config'\n };\n \n console.log(await createStatusDashboard(cloudStatus, localEngine));\n console.log('');\n \n // Build context-aware menu\n const context: MenuContext = {\n state: state.state,\n isAuthenticated: state.hasAuth,\n hasAgents: state.hasAgents,\n hasHooks: state.hasHooks,\n projectCount: state.projectCount,\n sessionCount: state.sessionCount,\n lastSync: state.lastSync || undefined,\n agentCount: state.agentCount,\n totalAgents: state.totalAgents\n };\n const menuItems = generateMenuItems(context);\n \n // Map menu items to inquirer choices, including separators\n const choices = menuItems\n .map(item => {\n if (item.separator) {\n // Use custom text if provided in label, otherwise use default separator line\n return new inquirer.Separator(item.label || '─────────────────────');\n }\n return {\n name: item.label,\n value: item.action || item.id, // Use action if available, otherwise id\n disabled: item.disabled\n };\n });\n \n // Add exit option\n choices.push({\n name: `${icons.cross} Exit`,\n value: 'exit',\n disabled: false\n });\n \n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to do?',\n choices,\n pageSize: 25, // Large enough to show all items without scrolling\n loop: false\n }\n ]);\n \n // Handle actions\n await handleMenuAction(action, state, packageUpdateInfo);\n}\n\nasync function handleMenuAction(\n action: string, \n state: StateDetails,\n packageUpdateInfo?: { current: string; latest: string } | null\n): Promise<void> {\n switch (action) {\n case 'auth':\n try {\n // For first-time users selecting cloud mode, show privacy notice first\n const { showPrivacyNotice: showNotice } = await import('./privacy-notice');\n const userAccepted = await showNotice();\n \n if (userAccepted) {\n console.log(colors.info('\\nAuthenticating with GitHub...'));\n await auth({});\n } else {\n console.log(colors.warning('\\nCloud setup cancelled.'));\n }\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n \n case 'send':\n try {\n await sendWithTimeout({ fromMenu: true });\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n \n case 'manual-sync':\n try {\n // Show manual sync menu\n const { showManualSyncMenu } = await import('./manual-sync-menu');\n const syncOption = await showManualSyncMenu();\n \n switch (syncOption.type) {\n case 'selected':\n // Send specific sessions - they're already in the right format!\n console.log(colors.info(`\\nSyncing ${syncOption.sessions.length} selected sessions...`));\n console.log(colors.dim('Preparing sessions for privacy-safe upload...'));\n \n await sendWithTimeout({ \n selectedSessions: syncOption.sessions,\n fromMenu: true\n });\n break;\n \n case 'time-based':\n // Send sessions from time-based selection\n console.log(colors.info(`\\nSyncing ${syncOption.sessions.length} sessions from the last ${syncOption.days} days...`));\n console.log(colors.dim('Preparing sessions for privacy-safe upload...'));\n \n await sendWithTimeout({ \n selectedSessions: syncOption.sessions,\n fromMenu: true\n });\n break;\n \n case 'projects': {\n // Send selected projects\n // Read sessions from selected projects\n const { readClaudeSessions } = await import('../readers/claude');\n const { analyzeProject } = await import('../claude-core');\n const projectSessions: any[] = [];\n \n for (const claudePath of syncOption.projects) {\n try {\n // Analyze the Claude project to get the actual path\n const dirName = parseProjectName(claudePath);\n const project = await analyzeProject(claudePath, dirName);\n \n if (!project) {\n console.log(colors.warning(`Failed to analyze project ${dirName}`));\n continue;\n }\n \n // Read sessions using the actual path for filtering\n const sessions = await readClaudeSessions({\n projectPath: project.actualPath\n });\n projectSessions.push(...sessions);\n console.log(colors.subdued(` • ${project.name}: ${sessions.length} sessions`));\n } catch (error) {\n console.log(colors.warning(`Failed to read sessions from ${parseProjectName(claudePath)}`));\n }\n }\n \n if (projectSessions.length > 0) {\n console.log(colors.success(`\\nTotal: ${projectSessions.length} sessions to sync`));\n console.log(colors.dim('Preparing sessions for privacy-safe upload...'));\n \n await sendWithTimeout({ \n selectedSessions: projectSessions.map(s => ({\n projectPath: s.sourceFile?.claudeProjectPath || s.projectPath,\n sessionFile: s.sourceFile?.sessionFile || '',\n displayName: parseProjectName(s.projectPath),\n timestamp: s.timestamp,\n duration: s.duration,\n messageCount: s.messages.length\n })),\n fromMenu: true\n });\n } else {\n console.log(colors.warning('No sessions found in selected projects'));\n }\n break;\n }\n \n case 'all':\n // Send all projects\n console.log(colors.info('\\nSyncing all projects...'));\n await sendWithTimeout({ all: true, fromMenu: true });\n break;\n \n case 'cancel':\n // User cancelled\n break;\n }\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n \n case 'status':\n try {\n await status();\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n\n case 'cursor-stats':\n try {\n const { cursorStats } = await import('../../commands/cursor-stats');\n await cursorStats();\n await waitForEnter();\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n \n case 'dashboard':\n if (state.cloudUrl) {\n console.log(colors.info(`Opening dashboard: ${state.cloudUrl}`));\n await open(state.cloudUrl);\n }\n break;\n\n case 'standup':\n try {\n // Use Claude Code analysis for standup\n const { standup } = await import('../../commands/standup');\n\n // Skip auth for local-only users (they don't need cloud)\n const skipAuth = !state.hasAuth;\n await standup({ skipAuth });\n await waitForEnter();\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n\n case 'report':\n try {\n // Check if sub-agents are installed first\n const { checkInstalledSubAgents } = await import('../sub-agents/manager');\n const subAgentStatus = await checkInstalledSubAgents();\n \n if (subAgentStatus.missing.length > 0) {\n // Sub-agents are missing, prompt to install\n console.clear();\n console.log(colors.warning('\\n⚠️ Sub-agents Required'));\n console.log(colors.muted('Local report generation requires devark sub-agents to be installed.'));\n console.log(colors.muted(`Currently missing: ${subAgentStatus.missing.length} of ${subAgentStatus.total} sub-agents`));\n console.log();\n \n const { confirm } = await inquirer.prompt([{\n type: 'confirm',\n name: 'confirm',\n message: 'Would you like to install them now?',\n default: true\n }]);\n \n if (confirm) {\n // Install the sub-agents\n const { installSubAgentsInteractive } = await import('./sub-agents-installer');\n await installSubAgentsInteractive();\n \n // After installation, check if they want to continue with report\n const newStatus = await checkInstalledSubAgents();\n if (newStatus.missing.length === 0) {\n console.log();\n const { continueReport } = await inquirer.prompt([{\n type: 'confirm',\n name: 'continueReport',\n message: 'Sub-agents installed! Would you like to generate your report now?',\n default: true\n }]);\n \n if (continueReport) {\n const { generateLocalReportInteractive } = await import('./local-report-generator');\n await generateLocalReportInteractive();\n }\n }\n } else {\n console.log(colors.info('\\nYou can install sub-agents later from the menu.'));\n await waitForEnter();\n }\n } else {\n // Sub-agents are installed, proceed with report generation\n const { generateLocalReportInteractive } = await import('./local-report-generator');\n await generateLocalReportInteractive();\n }\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n \n case 'install-agents':\n await manageAgents();\n break;\n \n case 'manage-hooks': {\n const { showHooksManagementMenu } = await import('./hooks-menu');\n await showHooksManagementMenu();\n break;\n }\n \n case 'status-line': {\n const { showStatusLineMenu } = await import('./status-line-menu');\n await showStatusLineMenu();\n break;\n }\n \n case 'install-hooks': {\n // Legacy support - redirect to new hooks management\n const { showHooksManagementMenu: showMenu } = await import('./hooks-menu');\n await showMenu();\n break;\n }\n \n case 'update-hooks': {\n // Legacy support - redirect to new hooks management\n const { showHooksManagementMenu: showMenuUpdate } = await import('./hooks-menu');\n await showMenuUpdate();\n break;\n }\n \n case 'switch-cloud':\n try {\n const { showPrivacyNotice } = await import('./privacy-notice');\n const accepted = await showPrivacyNotice();\n \n if (accepted) {\n console.log(colors.info('\\nAuthenticating with GitHub...'));\n await auth({});\n } else {\n console.log(colors.warning('\\nCloud setup cancelled.'));\n }\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n \n \n case 'logout':\n try {\n await logout();\n } catch (error) {\n displayError(error);\n await waitForEnter();\n }\n break;\n \n case 'help':\n showHelp();\n console.log('Press Enter to continue...');\n await inquirer.prompt([{ type: 'input', name: 'continue', message: '' }]);\n break;\n\n case 'exit':\n console.log(colors.muted('\\nGoodbye! 👋\\n'));\n process.exit(0);\n break;\n\n default:\n console.log(colors.warning(`Unknown action: ${action}`));\n }\n \n // Show menu again unless exiting\n if (action !== 'exit') {\n // For auth actions, auto-refresh without prompt (SSE handles the flow)\n if (action === 'auth' || action === 'switch-cloud') {\n // Only refresh if auth was successful (user didn't cancel)\n // The auth/switch-cloud handlers already show cancellation message\n const { detectSetupState } = await import('../detector');\n const newState = await detectSetupState();\n \n // Only show menu if state changed (successful auth)\n if (newState.hasAuth !== state.hasAuth || action === 'switch-cloud') {\n await showMainMenu(newState, packageUpdateInfo);\n } else {\n // Auth was cancelled or failed, return to menu\n await showMainMenu(newState, packageUpdateInfo);\n }\n } else {\n // For all other actions, refresh state and show menu again\n const { detectSetupState } = await import('../detector');\n const newState = await detectSetupState();\n await showMainMenu(newState, packageUpdateInfo);\n }\n }\n}\n\n\nasync function manageAgents(): Promise<void> {\n const { installSubAgentsInteractive } = await import('./sub-agents-installer');\n await installSubAgentsInteractive();\n}\n\nfunction showHelp(): void {\n showHelpContent();\n}","import { colors, icons, box, getTerminalWidth } from './styles';\n\ninterface CloudStatus {\n connected: boolean;\n hooksEnabled: boolean;\n syncStatus: 'synced' | 'syncing' | 'error' | 'offline';\n lastSync?: Date;\n lastSyncProject?: string;\n pendingChanges?: number;\n trackingMode?: 'all' | 'selected' | 'none';\n trackedProjectCount?: number;\n}\n\ninterface LocalEngine {\n installStatus: 'installed' | 'partial' | 'not-installed';\n subAgentsInstalled: number;\n totalSubAgents: number;\n statusLineStatus: 'installed' | 'partial' | 'not-installed';\n configPath?: string;\n}\n\n\n/**\n * Create a beautiful section box with title and content\n */\nexport function createSection(\n title: string,\n content: string[],\n options?: {\n width?: number;\n icon?: string;\n style?: 'single' | 'double' | 'rounded';\n color?: typeof colors[keyof typeof colors];\n }\n): string {\n const width = options?.width || Math.min(getTerminalWidth(), 80);\n const icon = options?.icon || icons.bullet;\n const style = options?.style || 'single';\n const color = options?.color || colors.primary;\n \n const lines: string[] = [];\n \n // Select box characters based on style\n const chars = style === 'double' \n ? {\n tl: box.doubleTopLeft,\n tr: box.doubleTopRight,\n bl: box.doubleBottomLeft,\n br: box.doubleBottomRight,\n h: box.doubleHorizontal,\n v: box.doubleVertical,\n }\n : {\n tl: box.topLeft,\n tr: box.topRight,\n bl: box.bottomLeft,\n br: box.bottomRight,\n h: box.horizontal,\n v: box.vertical,\n };\n \n // Top border with title\n const titleText = ` ${icon} ${title} `;\n // eslint-disable-next-line no-control-regex\n const titleLength = titleText.replace(/\\u001b\\[[0-9;]*m/g, '').length;\n const leftPadding = 3;\n const rightPadding = width - titleLength - leftPadding - 2;\n \n lines.push(\n color(chars.tl + chars.h.repeat(leftPadding)) +\n colors.highlight(titleText) +\n color(chars.h.repeat(Math.max(0, rightPadding)) + chars.tr)\n );\n \n // Content lines\n content.forEach(line => {\n // eslint-disable-next-line no-control-regex\n const cleanLine = line.replace(/\\u001b\\[[0-9;]*m/g, '');\n const padding = width - cleanLine.length - 4;\n lines.push(\n color(chars.v) + ' ' +\n line +\n ' '.repeat(Math.max(0, padding)) + ' ' +\n color(chars.v)\n );\n });\n \n // Bottom border\n lines.push(color(chars.bl + chars.h.repeat(width - 2) + chars.br));\n \n return lines.join('\\n');\n}\n\n/**\n * Create cloud status section\n */\nexport function createCloudStatusSection(status: CloudStatus): string {\n const content: string[] = [];\n \n // Connection status\n const connectionIcon = status.connected ? icons.success : icons.error;\n const connectionColor = status.connected ? colors.success : colors.error;\n const connectionText = status.connected ? 'Connected' : 'Disconnected';\n content.push(\n `${connectionIcon} ${colors.muted('Connection:')} ${connectionColor(connectionText)}`\n );\n \n // Auto-sync (hooks) status - show tracking mode details\n let hooksIcon = icons.cross;\n let hooksColor = colors.warning;\n let hooksText = 'Disabled';\n \n if (status.hooksEnabled && status.trackingMode) {\n hooksIcon = icons.check;\n hooksColor = colors.success;\n \n if (status.trackingMode === 'all') {\n hooksText = 'All projects';\n } else if (status.trackingMode === 'selected') {\n const count = status.trackedProjectCount || 0;\n hooksText = count === 1 ? 'Selected (1 project)' : `Selected (${count} projects)`;\n }\n }\n \n content.push(\n `${hooksIcon} ${colors.muted('Auto-sync (hooks):')} ${hooksColor(hooksText)}`\n );\n \n // Last sync time with project name\n let syncIcon = icons.clock;\n let syncColor = colors.primary;\n let syncText = 'Never synced';\n let syncProject = '';\n \n if (status.lastSync) {\n const timeSince = new Date().getTime() - status.lastSync.getTime();\n const minutes = Math.floor(timeSince / 60000);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n \n // Get the project name if available\n if (status.lastSyncProject) {\n syncProject = `${status.lastSyncProject} `;\n }\n \n if (days > 0) {\n syncText = days === 1 ? '1 day ago' : `${days} days ago`;\n syncIcon = icons.warning;\n syncColor = colors.warning;\n } else if (hours > 0) {\n syncText = hours === 1 ? '1 hour ago' : `${hours} hours ago`;\n syncIcon = icons.clock;\n syncColor = colors.primary;\n } else if (minutes === 0) {\n syncText = 'Just now';\n syncIcon = icons.check;\n syncColor = colors.success;\n } else {\n syncText = minutes === 1 ? '1 min ago' : `${minutes} min ago`;\n syncIcon = icons.check;\n syncColor = colors.success;\n }\n }\n \n const fullSyncText = syncProject ? `${syncProject}(${syncText})` : syncText;\n content.push(\n `${syncIcon} ${colors.muted('Last synced:')} ${syncColor(fullSyncText)}`\n )\n \n // Pending changes\n if (status.pendingChanges !== undefined && status.pendingChanges > 0) {\n content.push(\n `${icons.warning} ${colors.muted('Pending:')} ${colors.warning(status.pendingChanges + ' changes')}`\n );\n }\n \n return createSection('CLOUD SYNC STATUS', content, {\n icon: icons.cloud,\n style: 'double',\n color: status.connected ? colors.primary : colors.error,\n });\n}\n\n\n/**\n * Create local engine section with clearer descriptions\n */\nexport function createLocalEngineSection(engine: LocalEngine): string {\n const content: string[] = [];\n \n // Strategic Co-pilot (status-line) status - FIRST since it's real-time\n const coachIcon = engine.statusLineStatus === 'installed' ? icons.check :\n engine.statusLineStatus === 'partial' ? icons.warning : icons.cross;\n const coachColor = engine.statusLineStatus === 'installed' ? colors.success :\n engine.statusLineStatus === 'partial' ? colors.warning : colors.error;\n \n let coachStatus = '';\n if (engine.statusLineStatus === 'installed') {\n coachStatus = 'Active';\n } else if (engine.statusLineStatus === 'partial') {\n coachStatus = 'Partially installed';\n } else {\n coachStatus = 'Not installed';\n }\n \n content.push(\n `🚀 ${colors.muted('Strategic Co-pilot status line:')} ${coachIcon} ${coachColor(coachStatus)}`\n );\n \n // Add explanation if not installed\n if (engine.statusLineStatus !== 'installed') {\n content.push(\n colors.subdued(` → Live Guidance to move forward effectively`)\n );\n }\n \n // Report generators (sub-agents) status - SECOND\n const reportIcon = engine.installStatus === 'installed' ? icons.check : \n engine.installStatus === 'partial' ? icons.warning : icons.cross;\n const reportColor = engine.installStatus === 'installed' ? colors.success : \n engine.installStatus === 'partial' ? colors.warning : colors.error;\n \n let reportStatus = '';\n if (engine.installStatus === 'installed') {\n reportStatus = `Ready (${engine.subAgentsInstalled}/${engine.totalSubAgents} installed)`;\n } else if (engine.installStatus === 'partial') {\n reportStatus = `Incomplete (${engine.subAgentsInstalled}/${engine.totalSubAgents})`;\n } else {\n reportStatus = 'Not installed';\n }\n \n content.push(\n `📊 ${colors.muted('Report generators sub-agents:')} ${reportIcon} ${reportColor(reportStatus)}`\n );\n \n // Add explanation if not fully installed\n if (engine.installStatus !== 'installed') {\n content.push(\n colors.subdued(` → Generates local productivity reports`)\n );\n }\n \n // Determine overall status color based on installation state\n const sectionColor = (engine.installStatus === 'installed' && engine.statusLineStatus === 'installed') \n ? colors.primary \n : colors.warning;\n \n return createSection('Local Analysis Tools', content, {\n icon: '🤖',\n style: 'single',\n color: sectionColor,\n });\n}\n\n/**\n * Create a status dashboard with multiple sections\n */\nexport async function createStatusDashboard(\n cloud: CloudStatus,\n local: LocalEngine\n): Promise<string> {\n const sections: string[] = [];\n // Cloud status\n sections.push(createCloudStatusSection(cloud));\n sections.push('');\n\n // Local engine (Claude Code + sub-agents)\n sections.push(createLocalEngineSection(local));\n\n return sections.join('\\n');\n}\n\n/**\n * Create a compact status line for minimal display\n */\nexport function createCompactStatus(\n cloud: CloudStatus,\n local: LocalEngine\n): string {\n const parts: string[] = [];\n \n // Cloud indicator\n const cloudIcon = cloud.connected ? colors.success(icons.cloud) : colors.error(icons.cloud);\n parts.push(cloudIcon);\n \n // Sync status\n const syncIcon = cloud.syncStatus === 'synced' \n ? colors.success(icons.check)\n : cloud.syncStatus === 'syncing'\n ? colors.warning(icons.loading)\n : colors.error(icons.cross);\n parts.push(syncIcon);\n \n // Local engine\n const engineIcon = local.installStatus === 'installed'\n ? colors.success('🧠')\n : local.installStatus === 'partial'\n ? colors.warning('🧠')\n : colors.error('🧠');\n parts.push(engineIcon);\n \n return parts.join(' ');\n}","import { colors, icons, box, padRight, getTerminalWidth } from './styles';\n\n// Menu item labels - centralized for consistency\nconst MENU_LABELS = {\n STRATEGIC_COPILOT: '🚀 Status Line - Prompt feedback in Claude Code',\n STRATEGIC_COPILOT_DESC: 'Get strategic feedback on your prompts in the status line'\n};\n\nexport interface MenuItem {\n id: string;\n label: string;\n description?: string;\n icon?: string;\n action?: string; // Changed from function to string for action name\n shortcut?: string;\n disabled?: boolean;\n separator?: boolean;\n submenu?: MenuItem[];\n}\n\nexport interface MenuContext {\n state: string; // SetupState from detector\n isAuthenticated: boolean;\n hasAgents?: boolean;\n hasHooks?: boolean;\n projectCount?: number;\n sessionCount?: number;\n lastSync?: Date;\n agentCount?: number;\n totalAgents?: number;\n}\n\n/**\n * Generate consistent agent management label based on status\n */\nfunction getAgentManageLabel(agentCount?: number, totalAgents?: number): string {\n if (agentCount !== undefined && totalAgents !== undefined) {\n return `${icons.package} Manage local sub-agents (${agentCount}/${totalAgents} installed)`;\n }\n return `${icons.package} Manage local sub-agents`;\n}\n\n/**\n * Generate consistent report generation label\n */\nfunction getReportGenerateLabel(): string {\n return `${icons.chart} Generate local reports (install sub-agents)`;\n}\n\n\n/**\n * Generate context-aware menu items based on current state\n */\nexport function generateMenuItems(context: MenuContext): MenuItem[] {\n const items: MenuItem[] = [];\n \n // FIRST_TIME is now handled by the welcome screen in main-menu.ts\n // For ERROR state, show recovery options\n if (context.state === 'ERROR') {\n items.push({\n id: 'retry-setup',\n label: `${icons.refresh} Retry setup`,\n description: 'Try setting up devark again',\n icon: '',\n action: 'auth'\n });\n items.push({\n id: 'auth',\n label: `${icons.sparkles} Try cloud mode`,\n description: 'Authenticate with GitHub',\n icon: '',\n action: 'auth'\n });\n items.push({ separator: true } as MenuItem);\n items.push({\n id: 'help',\n label: `${icons.info} Get help`,\n description: 'Documentation and troubleshooting',\n icon: '',\n action: 'help'\n });\n return items;\n }\n\n // For LOCAL_ONLY state\n if (context.state === 'LOCAL_ONLY') {\n // Primary action - Standup (works without auth in local mode)\n items.push({\n id: 'standup',\n label: `📋 Today's standup`,\n action: 'standup'\n });\n\n items.push({ separator: true } as MenuItem);\n\n items.push({\n id: 'status-line',\n label: MENU_LABELS.STRATEGIC_COPILOT,\n description: MENU_LABELS.STRATEGIC_COPILOT_DESC,\n action: 'status-line'\n });\n\n // Separator between local and analysis tools\n items.push({ separator: true } as MenuItem);\n\n // Analysis tools\n items.push({\n id: 'report',\n label: getReportGenerateLabel(),\n action: 'report'\n });\n\n items.push({\n id: 'install-agents',\n label: getAgentManageLabel(context.agentCount, context.totalAgents),\n action: 'install-agents'\n });\n\n // Separator before cloud option\n items.push({ separator: true } as MenuItem);\n\n items.push({\n id: 'switch-cloud',\n label: `${icons.sparkles} Switch to cloud mode`,\n action: 'switch-cloud'\n });\n\n // Add cloud mode details as non-selectable items\n items.push({ separator: true, id: 'cloud-detail-local-1', label: ' ✓ Uses 0 tokens (our infrastructure)' } as MenuItem);\n items.push({ separator: true, id: 'cloud-detail-local-2', label: ' 📧 Weekly recaps & Daily standup emails' } as MenuItem);\n items.push({ separator: true, id: 'cloud-detail-local-3', label: ' 📊 Interactive dashboards' } as MenuItem);\n items.push({ separator: true, id: 'cloud-detail-local-4', label: ' 🎯 Optimization insights & coaching plans' } as MenuItem);\n }\n \n // For CLOUD states - simplified menu\n if (context.state === 'CLOUD_AUTO' || context.state === 'CLOUD_MANUAL' || context.state === 'CLOUD_ONLY') {\n // Primary actions\n items.push({\n id: 'standup',\n label: `📋 Today's standup`,\n action: 'standup'\n });\n\n items.push({ separator: true } as MenuItem);\n\n // Cloud features\n items.push({\n id: 'dashboard',\n label: `🌐 Open dashboard`,\n action: 'dashboard'\n });\n\n items.push({\n id: 'manual-sync',\n label: `🔄 Sync sessions manually`,\n action: 'manual-sync'\n });\n\n items.push({\n id: 'manage-hooks',\n label: `⚙️ Configure auto-sync (Claude Code hooks)`,\n action: 'manage-hooks'\n });\n\n items.push({ separator: true } as MenuItem);\n\n // Enhancement tools\n items.push({\n id: 'status-line',\n label: `💬 Install CC Co-Pilot (enhance your prompts)`,\n action: 'status-line'\n });\n\n items.push({\n id: 'report',\n label: getReportGenerateLabel(),\n action: 'report'\n });\n\n // Only show sub-agent management if they're installed\n if (context.agentCount && context.agentCount > 0) {\n items.push({\n id: 'install-agents',\n label: getAgentManageLabel(context.agentCount, context.totalAgents),\n action: 'install-agents'\n });\n }\n\n // Separator before logout\n items.push({ separator: true } as MenuItem);\n\n items.push({\n id: 'logout',\n label: `🚪 Logout`,\n action: 'logout'\n });\n }\n \n // For PARTIAL_SETUP state - no menu items needed\n // This state will be handled by showing the first-time welcome screen\n if (context.state === 'PARTIAL_SETUP') {\n // Return empty items - main-menu.ts will handle this by showing welcome screen\n return [];\n }\n \n // Common items for all states (except initial)\n if (context.state !== 'FIRST_TIME') {\n items.push({ separator: true } as MenuItem);\n items.push({\n id: 'help',\n label: `${icons.info} Help`,\n action: 'help'\n });\n }\n \n return items;\n}\n\n/**\n * Create a beautiful interactive menu display\n */\nexport function createMenu(\n items: MenuItem[],\n selectedIndex: number = 0,\n options?: {\n title?: string;\n width?: number;\n showShortcuts?: boolean;\n showDescriptions?: boolean;\n style?: 'compact' | 'detailed' | 'centered';\n }\n): string {\n const width = options?.width || Math.min(getTerminalWidth(), 80);\n const showShortcuts = options?.showShortcuts !== false;\n const showDescriptions = options?.showDescriptions !== false;\n const style = options?.style || 'detailed';\n \n const lines: string[] = [];\n \n // Title\n if (options?.title) {\n const titleText = ` ${icons.sparkles} ${options.title} ${icons.sparkles} `;\n // eslint-disable-next-line no-control-regex\n const titleWidth = titleText.replace(/\\u001b\\[[0-9;]*m/g, '').length;\n const padding = Math.floor((width - titleWidth) / 2);\n \n lines.push(colors.primary(box.topLeft + box.horizontal.repeat(width - 2) + box.topRight));\n lines.push(\n colors.primary(box.vertical) +\n ' '.repeat(padding) +\n colors.highlight(titleText) +\n ' '.repeat(width - padding - titleWidth - 2) +\n colors.primary(box.vertical)\n );\n lines.push(colors.primary(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n }\n \n // Menu items\n let currentIndex = 0;\n items.forEach((item) => {\n if (item.separator) {\n // Separator line\n lines.push(\n colors.dim(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight)\n );\n return;\n }\n \n const isSelected = currentIndex === selectedIndex;\n currentIndex++;\n \n // Build item display\n let itemLine = '';\n \n // Selection indicator\n if (isSelected) {\n itemLine += colors.accent('▶ ');\n } else {\n itemLine += ' ';\n }\n \n // Icon\n if (item.icon) {\n itemLine += item.icon + ' ';\n }\n \n // Label\n const labelColor = item.disabled \n ? colors.dim\n : isSelected \n ? colors.highlight\n : colors.primary;\n itemLine += labelColor(item.label);\n \n // Shortcut\n if (showShortcuts && item.shortcut) {\n const shortcutText = ` [${item.shortcut}]`;\n itemLine += colors.muted(shortcutText);\n }\n \n // Submenu indicator\n if (item.submenu) {\n itemLine += colors.muted(' ▶');\n }\n \n // Add to lines\n if (style === 'detailed' && showDescriptions && item.description) {\n // Two-line format with description\n const paddedLine = padRight(itemLine, width - 4);\n lines.push(\n colors.primary(box.vertical) + ' ' +\n paddedLine + ' ' +\n colors.primary(box.vertical)\n );\n \n const descLine = ' ' + colors.dim(item.description);\n const paddedDesc = padRight(descLine, width - 4);\n lines.push(\n colors.primary(box.vertical) + ' ' +\n paddedDesc + ' ' +\n colors.primary(box.vertical)\n );\n } else {\n // Single-line format\n const paddedLine = padRight(itemLine, width - 4);\n lines.push(\n colors.primary(box.vertical) + ' ' +\n paddedLine + ' ' +\n colors.primary(box.vertical)\n );\n }\n });\n \n // Bottom border\n lines.push(colors.primary(box.bottomLeft + box.horizontal.repeat(width - 2) + box.bottomRight));\n \n // Navigation hints\n if (style !== 'compact') {\n lines.push('');\n lines.push(\n colors.dim(' Navigate: ') +\n colors.muted('↑↓') +\n colors.dim(' Select: ') +\n colors.muted('Enter') +\n colors.dim(' Back: ') +\n colors.muted('Esc') +\n colors.dim(' Quit: ') +\n colors.muted('q')\n );\n }\n \n return lines.join('\\n');\n}\n\n/**\n * Create a breadcrumb navigation display\n */\nexport function createBreadcrumb(path: string[]): string {\n const parts = path.map((part, index) => {\n const isLast = index === path.length - 1;\n const text = isLast ? colors.highlight(part) : colors.muted(part);\n const separator = isLast ? '' : colors.dim(' › ');\n return text + separator;\n });\n \n return `${icons.folder} ${parts.join('')}`;\n}\n\n/**\n * Create a command palette style menu\n */\nexport function createCommandPalette(\n items: MenuItem[],\n searchTerm: string = '',\n selectedIndex: number = 0\n): string {\n const width = Math.min(getTerminalWidth(), 60);\n const lines: string[] = [];\n \n // Search box\n lines.push(colors.primary(box.topLeft + box.horizontal.repeat(width - 2) + box.topRight));\n \n const searchLine = \n colors.primary(box.vertical) + ' ' +\n icons.search + ' ' +\n colors.highlight(searchTerm) +\n colors.dim('|') +\n ' '.repeat(width - searchTerm.length - 8) +\n colors.primary(box.vertical);\n lines.push(searchLine);\n \n lines.push(colors.primary(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n // Filtered items\n const filteredItems = searchTerm\n ? items.filter(item => \n !item.separator && \n item.label.toLowerCase().includes(searchTerm.toLowerCase())\n )\n : items.filter(item => !item.separator);\n \n // Show up to 10 items\n const visibleItems = filteredItems.slice(0, 10);\n \n visibleItems.forEach((item, index) => {\n const isSelected = index === selectedIndex;\n \n let itemLine = isSelected ? colors.accent('▶ ') : ' ';\n \n if (item.icon) {\n itemLine += item.icon + ' ';\n }\n \n // Highlight matching parts\n if (searchTerm) {\n const regex = new RegExp(`(${searchTerm})`, 'gi');\n const highlighted = item.label.replace(regex, colors.accent('$1'));\n itemLine += isSelected ? colors.highlight(highlighted) : highlighted;\n } else {\n itemLine += isSelected ? colors.highlight(item.label) : colors.primary(item.label);\n }\n \n if (item.shortcut) {\n itemLine += colors.dim(` [${item.shortcut}]`);\n }\n \n const paddedLine = padRight(itemLine, width - 4);\n lines.push(\n colors.primary(box.vertical) + ' ' +\n paddedLine + ' ' +\n colors.primary(box.vertical)\n );\n });\n \n // Results count\n if (filteredItems.length > 10) {\n const moreText = `... and ${filteredItems.length - 10} more`;\n const paddedMore = padRight(' ' + colors.dim(moreText), width - 4);\n lines.push(\n colors.primary(box.vertical) + ' ' +\n paddedMore + ' ' +\n colors.primary(box.vertical)\n );\n }\n \n // Bottom border\n lines.push(colors.primary(box.bottomLeft + box.horizontal.repeat(width - 2) + box.bottomRight));\n \n return lines.join('\\n');\n}\n\n/**\n * Create a confirmation dialog\n */\nexport function createConfirmDialog(\n message: string,\n options?: {\n title?: string;\n confirmText?: string;\n cancelText?: string;\n dangerous?: boolean;\n }\n): string {\n const width = Math.min(getTerminalWidth(), 60);\n const lines: string[] = [];\n \n const title = options?.title || 'Confirm';\n const confirmText = options?.confirmText || 'Yes';\n const cancelText = options?.cancelText || 'No';\n const borderColor = options?.dangerous ? colors.error : colors.warning;\n \n // Top border\n lines.push(borderColor(box.doubleTopLeft + box.doubleHorizontal.repeat(width - 2) + box.doubleTopRight));\n \n // Title\n const titleIcon = options?.dangerous ? icons.warning : icons.info;\n const titleLine = ` ${titleIcon} ${title} `;\n const titlePadding = Math.floor((width - titleLine.length) / 2);\n lines.push(\n borderColor(box.doubleVertical) +\n ' '.repeat(titlePadding) +\n colors.highlight(titleLine) +\n ' '.repeat(width - titlePadding - titleLine.length - 2) +\n borderColor(box.doubleVertical)\n );\n \n lines.push(borderColor(box.tLeft + box.horizontal.repeat(width - 2) + box.tRight));\n \n // Message (word-wrapped)\n const words = message.split(' ');\n let currentLine = '';\n const maxLineLength = width - 6;\n \n words.forEach(word => {\n if ((currentLine + word).length > maxLineLength) {\n const paddedLine = padRight(' ' + currentLine, width - 4);\n lines.push(\n borderColor(box.vertical) + ' ' +\n colors.primary(paddedLine) + ' ' +\n borderColor(box.vertical)\n );\n currentLine = word + ' ';\n } else {\n currentLine += word + ' ';\n }\n });\n \n if (currentLine.trim()) {\n const paddedLine = padRight(' ' + currentLine.trim(), width - 4);\n lines.push(\n borderColor(box.vertical) + ' ' +\n colors.primary(paddedLine) + ' ' +\n borderColor(box.vertical)\n );\n }\n \n // Spacer\n lines.push(\n borderColor(box.vertical) + ' '.repeat(width - 2) + borderColor(box.vertical)\n );\n \n // Options\n const optionsLine = \n ` ${colors.success(`[Y] ${confirmText}`)} ${colors.error(`[N] ${cancelText}`)}`;\n const optionsPadding = Math.floor((width - 20) / 2);\n lines.push(\n borderColor(box.vertical) +\n ' '.repeat(optionsPadding) +\n optionsLine +\n ' '.repeat(width - optionsPadding - 20 - 2) +\n borderColor(box.vertical)\n );\n \n // Bottom border\n lines.push(borderColor(box.doubleBottomLeft + box.doubleHorizontal.repeat(width - 2) + box.doubleBottomRight));\n \n return lines.join('\\n');\n}","import chalk from 'chalk';\nimport { requireAuth } from '../lib/auth/token';\nimport { apiClient } from '../lib/api-client';\nimport { createSpinner, formatDuration, formatDate } from '../lib/ui';\nimport { DevArkError } from '../utils/errors';\nimport { logger } from '../utils/logger';\nimport { countCursorMessages } from '../lib/readers/cursor';\n\nexport async function status(): Promise<void> {\n await requireAuth();\n \n const spinner = createSpinner('Fetching your stats...').start();\n \n try {\n // Fetch streak info\n const streak = await apiClient.getStreak();\n \n // Validate that we received proper streak data\n if (!streak || typeof streak.current !== 'number' || isNaN(streak.current)) {\n throw new Error('Invalid streak data received from server');\n }\n \n spinner.succeed('Stats loaded!');\n \n // Display streak information\n console.log(chalk.cyan('\\n📊 Your devark Stats'));\n console.log(chalk.gray('═══════════════════════════════\\n'));\n \n // Current streak\n if (streak.current > 0) {\n console.log(chalk.green(`🔥 Current Streak: ${chalk.bold(streak.current)} days`));\n } else {\n console.log(chalk.yellow(`🔥 Current Streak: ${chalk.bold('0')} days`));\n console.log(chalk.gray(' Start building today!'));\n }\n \n // Longest streak\n console.log(chalk.cyan(`🏆 Longest Streak: ${chalk.bold(streak.longestStreak || 0)} days`));\n \n // Points and Daily Shippers Club info\n console.log(chalk.magenta(`⭐ Total Points: ${chalk.bold(streak.points || 0)}`));\n\n // Calculate and display next day's potential points\n if (streak.current >= 0 && streak.current < 7) {\n const nextDayPoints = Math.pow(2, streak.current + 1);\n console.log(chalk.dim(` Upload tomorrow for ${nextDayPoints} streak points!`));\n } else if (streak.current >= 7) {\n console.log(chalk.bold.green(` 🏆 Maximum streak points achieved! (128/day)`));\n }\n\n // Total sessions\n console.log(chalk.cyan(`📝 Total Sessions: ${chalk.bold(streak.totalSessions || 0)}`));\n \n // Today's sessions\n if (streak.todaySessions > 0) {\n console.log(chalk.green(`✅ Sessions Today: ${chalk.bold(streak.todaySessions)}`));\n } else {\n console.log(chalk.yellow(`⏰ Sessions Today: ${chalk.bold('0')} - Time to code!`));\n }\n \n console.log(chalk.gray('\\n═══════════════════════════════\\n'));\n \n // Fetch recent sessions\n try {\n const recentSessions = await apiClient.getRecentSessions(5);\n \n if (recentSessions.length > 0) {\n console.log(chalk.cyan('📅 Recent Sessions:'));\n \n recentSessions.forEach((session) => {\n const date = new Date(session.timestamp);\n const duration = formatDuration(session.duration);\n const project = session.projectName || 'Unknown Project';\n \n console.log(\n chalk.gray(` • ${formatDate(date)} - ${duration} - ${project}`)\n );\n });\n }\n } catch (error) {\n logger.debug('Failed to fetch recent sessions', error);\n // Don't fail the whole command if recent sessions fail\n }\n\n // Cursor IDE message count\n try {\n const cursorStats = await countCursorMessages();\n\n if (cursorStats.conversationCount > 0) {\n console.log(chalk.gray('\\n═══════════════════════════════\\n'));\n console.log(chalk.cyan('💬 Cursor IDE Stats:'));\n console.log(chalk.gray(` • Total Conversations: ${chalk.bold(cursorStats.conversationCount)}`));\n console.log(chalk.gray(` • Total Messages: ${chalk.bold(cursorStats.totalMessages)}`));\n console.log(chalk.gray(` • User Messages: ${chalk.bold(cursorStats.userMessages)}`));\n console.log(chalk.gray(` • Assistant Messages: ${chalk.bold(cursorStats.assistantMessages)}`));\n }\n } catch (error) {\n logger.debug('Failed to fetch Cursor stats', error);\n // Don't fail the whole command if Cursor stats fail\n }\n\n // Motivational messages based on streak (only show for valid data)\n console.log('');\n if (streak.current === 0) {\n console.log(chalk.yellow('💪 Ready to start your streak? Code with Claude Code and sync your sessions!'));\n } else if (streak.current < 7) {\n console.log(chalk.cyan('🌱 Keep going! You\\'re building momentum.'));\n } else if (streak.current < 30) {\n console.log(chalk.green('🚀 Amazing progress! You\\'re on fire!'));\n } else if (streak.current < 100) {\n console.log(chalk.magenta('🌟 Incredible dedication! You\\'re a coding machine!'));\n } else {\n console.log(chalk.red('🔥🔥🔥 LEGENDARY STREAK! You\\'re unstoppable!'));\n }\n \n } catch (error) {\n spinner.fail('Failed to fetch stats');\n \n if (error instanceof DevArkError) {\n throw error;\n }\n \n logger.error('Failed to fetch status', error);\n throw new DevArkError(\n 'Failed to fetch your stats. Please try again.',\n 'STATUS_FAILED'\n );\n }\n}","import { colors } from './styles';\n\n/**\n * Display the help content for devark\n * Shared between main menu and first-time welcome\n */\nexport function showHelpContent(): void {\n console.log('');\n console.log(colors.primary('📊 DevArk - Measure, Learn & Improve Your AI Coding'));\n console.log('');\n console.log(colors.subdued('Understand how you work with Claude Code. Track patterns, measure'));\n console.log(colors.subdued('productivity, and discover what makes your AI coding sessions effective.'));\n console.log('');\n console.log(colors.accent('🎯 Why Track Your AI Coding?'));\n console.log(' • ' + colors.highlight('Measure Patterns') + ' - See when and how you\\'re most productive');\n console.log(' • ' + colors.highlight('Learn From Data') + ' - Understand what makes sessions successful');\n console.log(' • ' + colors.highlight('Improve Workflow') + ' - Identify bottlenecks and optimize your process');\n console.log(' • ' + colors.highlight('Track Progress') + ' - Monitor project velocity and completion rates');\n console.log(' • ' + colors.highlight('Privacy First') + ' - Your code never leaves your machine, only metadata tracked');\n console.log('');\n console.log(colors.accent('🔄 Choose How to Analyze:'));\n console.log(' • ' + colors.success('Cloud Mode (Recommended)') + ' - Automatic tracking & insights');\n console.log(' └─ Dashboard with trends, patterns, and productivity metrics');\n console.log(' └─ Zero setup, GitHub auth, no tokens needed');\n console.log(' └─ ' + colors.highlight('NEW: Daily Shippers Club') + ' - Earn points for consistency!');\n console.log(' • ' + colors.info('Local Mode') + ' - Self-hosted analysis on your machine');\n console.log(' └─ Generate AI reports using Claude Code sub-agents');\n console.log(' └─ 100% offline, uses your Claude tokens');\n console.log('');\n console.log(colors.accent('🏆 Daily Shippers Club - Points System:'));\n console.log(' • ' + colors.highlight('🔥 Streak Points') + ' - Exponential rewards for daily consistency');\n console.log(' └─ Day 1: 2 pts, Day 2: 4 pts... Day 7+: 128 pts max');\n console.log(' • ' + colors.highlight('📊 Volume Bonus') + ' - 1 point per session uploaded (max 30/day)');\n console.log(' • ' + colors.highlight('🏅 Instant Feedback') + ' - See points earned after CLI uploads');\n console.log(' • ' + colors.highlight('📈 Compete') + ' - Check leaderboard at app.devark.ai');\n console.log(' • ' + colors.subdued('Note: Share sessions on the web for extra points'));\n console.log('');\n console.log(colors.accent('⚡ Getting Started:'));\n console.log(' 1. Run ' + colors.primary('npx devark-cli') + ' to open this menu');\n console.log(' 2. Choose your analysis mode (Cloud or Local)');\n console.log(' 3. Start coding with Claude - devark tracks automatically');\n console.log(' 4. Review insights to improve your AI coding workflow');\n console.log('');\n console.log(colors.accent('📚 Learn More:'));\n console.log(' • Documentation: ' + colors.primary('https://devark.ai'));\n console.log(' • View Dashboard: ' + colors.primary('https://app.devark.ai'));\n console.log(' • GitHub: ' + colors.primary('https://github.com/devark'));\n console.log('');\n}"],"mappings":"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","names":["chalk","fs","crypto","path","Conf","status","chalk","import_chalk","import_chalk","chalk","path","path","os","import_fs","import_path","import_os","fs","path","os","import_path","import_os","fs","path","import_fs","import_path","path","fs","config","import_fs","config","_a","status","readGlobalSettings","config","path","os","fs","import_promises","import_path","import_os","isDevArkCommand","fs","config","path","readSettingsFile","discoverProjects","import_fs","import_path","exports","module","apiClient","crypto","import_crypto","axios","status","config","collectTelemetry","path","import_path","fs","path","os","filePath","import_promises","import_path","import_os","path","fs","import_fs","import_path","import_os","import_path","import_promises","sessions","path","fs","filePath","path","os","fs","cache","https","pkg","currentVersion","import_fs","import_path","import_os","path","os","fs","import_child_process","import_fs","import_path","import_os","spawnDetached","isUploadRunning","currentVersion","args","import_fs","import_path","import_os","path","fs","lockData","createUploadLock","removeUploadLock","import_chalk","chalk","version","chalk","ora","import_chalk","import_chalk","progress","chalk","import_chalk","chalk","totalDuration","chalk","inquirer","import_chalk","import_chalk","import_inquirer","chalk","inquirer","import_chalk","currentVersion","chalk","import_chalk","config","getStatusLinePersonality","setStatusLinePersonality","isAuthenticated","import_fs","import_path","import_os","os","path","fs","getStatusLinePersonality","getScoreEmoji","homedir","path","fs","import_fs","import_path","ora","status","chalk","import_child_process","import_chalk","import_ora","inquirer","fs","path","import_inquirer","import_fs","import_path","chalk","open","ora","https","http","import_crypto","import_ora","import_chalk","chalk","import_chalk","status","inquirer","displayError","getTrackedProjects","discoverProjects","config","path","getToken","auth","readClaudeSessions","import_inquirer","import_path","os","path","Database","import_path","import_os","import_chalk","readline","showLogo","pkg","chalk","choice","showLogo","pkg","chalk","inquirer","import_inquirer","import_chalk","path","os","fs","import_child_process","import_fs","import_path","import_os","formatDuration","import_path","import_promises","import_os","path","os","fs","sessions","import_chalk","chalk","chalk","standupData","path","fs","formatDuration","sessions","import_chalk","import_path","import_promises","path","os","fs","inquirer","import_inquirer","import_promises","import_path","import_os","inquirer","import_inquirer","chalk","pkg","showLogo","showPrivacyNotice","inquirer","open","path","fs","import_inquirer","import_path","import_promises","import_open","import_chalk","displayEducationalHeader","inquirer","config","import_inquirer","config","getStatusLinePersonality","ora","inquirer","promptToContinue","import_inquirer","import_ora","status","displayEducationalHeader","config","getStatusLinePersonality","inquirer","setStatusLinePersonality","promptToContinue","import_inquirer","inquirer","import_inquirer","chalk","import_chalk","path","os","fs","status","import_promises","import_path","import_os","readline","import_inquirer","import_readline","path","import_fs","import_path","path","path","import_fs","import_path","fs","fs","files","htmlFiles","inquirer","installSubAgents","removeAllSubAgents","installSubAgentsInteractive","checkInstalledSubAgents","action","path","fs","os","tempDir","execSync","import_inquirer","import_fs","import_path","import_os","status","inquirer","generateLocalReportInteractive","import_inquirer","import_commander","import_chalk","config","chalk","import_inquirer","import_chalk","chalk","inquirer","import_chalk","import_inquirer","import_path","import_promises","chalk","inquirer","path","fs","import_fs","import_path","fs","content","path","fs","spawn","getStatusLinePersonality","import_commander","import_fs","import_path","import_os","import_child_process","import_os","import_path","path","os","fs","os","path","getStatusLinePersonality","format","output","import_commander","getStatusLinePersonality","setStatusLinePersonality","import_inquirer","status","import_chalk","chalk","cursorStats","import_open","inquirer","packageUpdateInfo","pkg","showLogo","showFirstTimeWelcome","showSetupMessage","standup","isAuthenticated","guidedCloudSetup","showStatusLineMenu","detectSetupState","showManualSyncMenu","readClaudeSessions","analyzeProject","cursorStats","open","checkInstalledSubAgents","installSubAgentsInteractive","generateLocalReportInteractive","showHooksManagementMenu","showPrivacyNotice","pkg","isSilent","guidedCloudSetup","config","showHelp"]}