shark-ai 0.4.11 → 0.4.13

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/error/crash-handler.ts","../../src/bin/shark.ts","../../src/commands/init.ts","../../src/core/workflow/workflow-manager.ts","../../src/core/workflow/shark-workflow.schema.ts","../../src/core/api/stackspot-client.ts","../../src/core/api/sse-client.ts","../../src/core/agents/agent-response-parser.ts","../../src/core/workflow/conversation-manager.ts","../../src/core/auth/get-active-realm.ts","../../src/core/agents/business-analyst-agent.ts","../../src/core/agents/specification-agent.ts","../../src/core/agents/agent-tools.ts","../../src/core/ast-editing/editors/code-editor-factory.ts","../../src/core/ast-editing/editors/typescript-editor.ts","../../src/commands/scan.ts","../../src/core/agents/scan-agent.ts","../../src/commands/dev.ts","../../src/core/agents/developer-agent.ts","../../src/core/workflow/task-manager.ts","../../src/commands/qa.ts","../../src/core/agents/qa-agent.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { colors } from '../../ui/colors.js';\n\nexport class CrashHandler {\n private static instance: CrashHandler;\n private readonly logDir: string;\n\n private constructor() {\n this.logDir = path.join(os.homedir(), '.shark', 'logs');\n }\n\n public static getInstance(): CrashHandler {\n if (!CrashHandler.instance) {\n CrashHandler.instance = new CrashHandler();\n }\n return CrashHandler.instance;\n }\n\n public init(): void {\n process.on('uncaughtException', (error) => this.handleError(error, 'Uncaught Exception'));\n process.on('unhandledRejection', (reason) => this.handleError(reason, 'Unhandled Rejection'));\n }\n\n private handleError(error: any, type: string): void {\n // Prevent infinite loops if logging fails\n try {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const logFile = path.join(this.logDir, `crash-${timestamp}.log`);\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n const stackTrace = error instanceof Error ? error.stack : 'No stack trace available';\n\n const logContent = `\n[${new Date().toISOString()}] ${type}\n--------------------------------------------------\nMessage: ${errorMessage}\nStack:\n${stackTrace}\n--------------------------------------------------\nSystem: ${os.platform()} ${os.release()} ${os.arch()}\nNode: ${process.version}\n`;\n\n // Ensure directory exists sync (we are crashing, async might not finish)\n if (!fs.existsSync(this.logDir)) {\n fs.mkdirSync(this.logDir, { recursive: true });\n }\n\n fs.writeFileSync(logFile, logContent, 'utf-8');\n\n console.error('\\n');\n console.error(colors.error('šŸ’„ Whoops! Shark CLI crashed unexpectedly.'));\n console.error(colors.dim(` Details have been saved to: ${logFile}`));\n console.error(colors.dim(' Please report this issue so we can fix it.'));\n console.error(colors.error(` Error: ${errorMessage}`));\n console.error('\\n');\n\n } catch (filesysError) {\n console.error('Fatal Error: Failed to write crash log.', filesysError);\n console.error('Original Error:', error);\n } finally {\n process.exit(1);\n }\n }\n}\n\nexport const crashHandler = CrashHandler.getInstance();\n","\nimport { crashHandler } from '../core/error/crash-handler.js';\n\n// Initialize Global Crash Handler\ncrashHandler.init();\n\nimport { Command } from 'commander';\nimport { loginCommand } from '../commands/login.js';\nimport { configCommand } from '../commands/config.js';\nimport { initCommand } from '../commands/init.js';\nimport { colors } from '../ui/colors.js';\nimport { interactiveBusinessAnalyst } from '../core/agents/business-analyst-agent.js';\nimport { interactiveSpecificationAgent } from '../core/agents/specification-agent.js';\nimport { scanCommand } from '../commands/scan.js';\nimport { devCommand } from '../commands/dev.js';\nimport { qaCommand } from '../commands/qa.js';\n\nconst program = new Command();\n\nprogram\n .name('shark')\n .description('Shark CLI: AI-Native Collaborative Development Tool')\n .version('0.0.1');\n\nprogram.addCommand(loginCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(scanCommand);\nprogram.addCommand(devCommand);\nprogram.addCommand(qaCommand);\n\n// Command: ba\n// Description: Starts the Business Analyst Agent interactive session\nprogram\n .command('ba')\n .description('Start Business Analyst Agent interactive session')\n .option('--id <agent_id>', 'Override Agent ID')\n .action(async (options) => {\n try {\n await interactiveBusinessAnalyst();\n } catch (error: any) {\n console.error('Error:', error.message);\n process.exit(1);\n }\n });\n\n// Command: spec\n// Description: Starts the Specification Agent session\nprogram\n .command('spec')\n .description('Start Specification Agent interactive session')\n .option('--id <agent_id>', 'Override Agent ID')\n .option('--briefing <path>', 'Path to briefing file')\n .action(async (options) => {\n try {\n await interactiveSpecificationAgent({\n agentId: options.id,\n briefingPath: options.briefing\n });\n } catch (error: any) {\n console.error('Error:', error.message);\n process.exit(1);\n }\n });\n\nprogram\n .command('config')\n .description('Manage global configuration')\n .action(configCommand.action);\n\n// Global Error Handler for the CLI\nprocess.on('unhandledRejection', (err) => {\n console.error(colors.error('āŒ Unhandled Error:'), err);\n process.exit(1);\n});\n\nprogram.parse(process.argv);\n","import { Command } from 'commander';\nimport { tui } from '../ui/tui.js';\nimport { workflowManager } from '../core/workflow/workflow-manager.js';\nimport { TechStackEnum } from '../core/workflow/shark-workflow.schema.js';\nimport { randomUUID } from 'crypto';\nimport { colors } from '../ui/colors.js';\n\nexport const initAction = async () => {\n tui.intro('Shark Project Initialization');\n\n // 1. Check if workflow already exists\n const existingState = await workflowManager.load();\n if (existingState) {\n // Smart Resume Context Card\n tui.log.info(colors.dim('----------------------------------------'));\n tui.log.info(`🦈 ${colors.primary('Welcome back to Shark CLI!')}`);\n tui.log.message(` Project: ${colors.white(existingState.projectName)}`);\n tui.log.message(` Stage: ${colors.secondary(existingState.currentStage)}`);\n tui.log.message(` Updated: ${colors.dim(new Date(existingState.lastUpdated).toLocaleString())}`);\n tui.log.info(colors.dim('----------------------------------------'));\n\n const action = await tui.select({\n message: 'An existing project was detected. What would you like to do?',\n options: [\n { value: 'resume', label: 'šŸš€ Resume Work' },\n { value: 'overwrite', label: 'āš ļø Overwrite (Start Fresh)' },\n { value: 'exit', label: 'āŒ Exit' }\n ]\n });\n\n if (tui.isCancel(action) || action === 'exit') {\n tui.outro('See you later! šŸ‘‹');\n return;\n }\n\n if (action === 'resume') {\n tui.log.success(`Resuming work on ${colors.primary(existingState.projectName)}...`);\n // Future: Route to specific agent based on stage\n tui.outro(`To continue, run: \"shark agent\" (Context loaded)`);\n return;\n }\n\n // If overwrite, we just proceed to step 2...\n }\n\n // 2. Prompt for Project Name\n const projectName = await tui.text({\n message: 'What is the name of your project?',\n placeholder: 'e.g. My Awesome App',\n validate: (value) => {\n if (!value) return 'Project name is required';\n if (value.trim().length < 2) return 'Project name must be at least 2 characters';\n }\n });\n\n if (tui.isCancel(projectName)) {\n tui.outro('Initialization cancelled.');\n return;\n }\n\n // 3. Prompt for Tech Stack\n const techStackOptions = TechStackEnum.options.map(stack => ({\n value: stack,\n label: stack === 'node-ts' ? 'Node.js (TypeScript)' :\n stack === 'nextjs' ? 'Next.js' :\n stack.charAt(0).toUpperCase() + stack.slice(1)\n }));\n\n const techStack = await tui.select({\n message: 'Select your technology stack:',\n options: techStackOptions\n });\n\n if (tui.isCancel(techStack)) {\n tui.outro('Initialization cancelled.');\n return;\n }\n\n // 4. Create and Save State\n const spinner = tui.spinner();\n spinner.start('Initializing project workflow...');\n\n try {\n const newState = {\n projectId: randomUUID(),\n projectName: projectName as string,\n techStack: techStack as any,\n currentStage: 'business_analysis' as const,\n stageStatus: 'pending' as const,\n lastUpdated: new Date().toISOString(),\n artifacts: [],\n metadata: {\n initializedBy: 'shark-cli',\n version: '0.0.1'\n }\n };\n\n await workflowManager.save(newState);\n spinner.stop('Project workflow created!');\n\n tui.log.success(`Project ${colors.primary(projectName as string)} initialized successfully.`);\n tui.log.message(`Your Project ID: ${colors.dim(newState.projectId)}`);\n tui.outro('Ready to start! Run \"shark agent\" to begin analyzing requirements.'); // Placeholder hint\n } catch (error: any) {\n spinner.stop('Initialization failed.', 1);\n tui.log.error(error.message);\n process.exit(1);\n }\n};\n\nexport const initCommand = new Command('init')\n .description('Initialize a new Shark project')\n .action(initAction);\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { WorkflowSchema, type WorkflowState } from './shark-workflow.schema.js';\nimport { colors } from '../../ui/colors.js';\n\nexport class WorkflowManager {\n private static instance: WorkflowManager;\n private readonly filename = 'shark-workflow.json';\n private readonly tmpFilename = '.shark-workflow.tmp';\n\n private constructor() { }\n\n public static getInstance(): WorkflowManager {\n if (!WorkflowManager.instance) {\n WorkflowManager.instance = new WorkflowManager();\n }\n return WorkflowManager.instance;\n }\n\n private getFilePath(): string {\n return path.join(process.cwd(), this.filename);\n }\n\n private getTmpFilePath(): string {\n return path.join(process.cwd(), this.tmpFilename);\n }\n\n public async save(state: WorkflowState): Promise<void> {\n // 1. Validate State\n const parsed = WorkflowSchema.safeParse(state);\n if (!parsed.success) {\n throw new Error(`Invalid workflow state: ${parsed.error.message}`);\n }\n\n const filePath = this.getFilePath();\n const tmpPath = this.getTmpFilePath();\n const data = JSON.stringify(parsed.data, null, 2);\n\n try {\n // 2. Write to TMP\n await fs.writeFile(tmpPath, data, 'utf-8');\n\n // 3. Rename TMP to Final (Atomic)\n await fs.rename(tmpPath, filePath);\n } catch (error: any) {\n throw new Error(`Failed to save workflow state atomically: ${error.message}`);\n }\n }\n\n public async load(): Promise<WorkflowState | null> {\n const filePath = this.getFilePath();\n\n try {\n // Check if file exists\n try {\n await fs.access(filePath);\n } catch {\n return null; // File doesn't exist, generic start\n }\n\n const content = await fs.readFile(filePath, 'utf-8');\n const json = JSON.parse(content);\n\n const parsed = WorkflowSchema.safeParse(json);\n if (parsed.success) {\n return parsed.data;\n } else {\n console.warn(colors.warning(`āš ļø Corrupted workflow file detected: ${parsed.error.message}`));\n return null;\n }\n\n } catch (error: any) {\n console.warn(colors.warning(`āš ļø Failed to load workflow state: ${error.message}`));\n return null;\n }\n }\n\n // Helper to get current state or default if none exists\n public async getOrInitState(): Promise<WorkflowState | null> {\n return await this.load();\n }\n}\n\nexport const workflowManager = WorkflowManager.getInstance();\n","import { z } from 'zod';\n\nexport enum ProjectParams {\n PROJECT_ID = 'projectId',\n PROJECT_NAME = 'projectName',\n TECH_STACK = 'techStack',\n}\n\nexport const TechStackEnum = z.enum([\n 'react',\n 'nextjs',\n 'angular',\n 'vue',\n 'node-ts',\n 'python',\n 'dotnet',\n 'java',\n 'unknown'\n]);\n\nexport type TechStack = z.infer<typeof TechStackEnum>;\n\nexport const WorkflowStageEnum = z.enum([\n 'business_analysis',\n 'specification',\n 'architecture',\n 'development',\n 'verification',\n 'deployment'\n]);\n\nexport type WorkflowStage = z.infer<typeof WorkflowStageEnum>;\n\nexport const StageStatusEnum = z.enum([\n 'pending',\n 'in_progress',\n 'completed',\n 'failed',\n 'skipped'\n]);\n\nexport type StageStatus = z.infer<typeof StageStatusEnum>;\n\nexport const WorkflowSchema = z.object({\n projectId: z.string().uuid(),\n projectName: z.string().min(1),\n techStack: TechStackEnum.default('unknown'),\n currentStage: WorkflowStageEnum.default('business_analysis'),\n stageStatus: StageStatusEnum.default('pending'),\n lastUpdated: z.string().datetime(), // ISO 8601\n conversationId: z.string().optional(),\n conversations: z.record(z.string(), z.string()).optional(), // agentType -> conversationId\n artifacts: z.array(z.string()).default([]),\n // Extensible metadata bag\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport type WorkflowState = z.infer<typeof WorkflowSchema>;\n","import { tokenStorage } from '../auth/token-storage.js';\nimport { authenticate } from '../auth/stackspot-auth.js';\nimport { colors } from '../../ui/colors.js';\n\nexport class AuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'AuthError';\n }\n}\n\ninterface RequestOptions extends RequestInit {\n params?: Record<string, string>;\n}\n\n// API Base URLs\nexport const STACKSPOT_API_BASE = 'https://api.stackspot.com';\nexport const STACKSPOT_AGENT_API_BASE = 'https://genai-inference-app.stackspot.com';\n\n// Shared Token Validation & Refresh Logic\nexport async function ensureValidToken(realm: string): Promise<string> {\n let creds = await tokenStorage.getCredentials(realm);\n\n if (!creds?.accessToken) {\n throw new AuthError(`Authentication required for realm '${realm}'.\\nPlease run 'shark login' to authenticate.`);\n }\n\n // Auto-Refresh Logic\n const now = Math.floor(Date.now() / 1000);\n const buffer = 300; // 5 minutes buffer\n\n // If we have credentials and expiry time, check if we need to refresh\n if (creds.expiresAt && creds.clientId && creds.clientKey) {\n if (now > creds.expiresAt - buffer) {\n try {\n // console.log(colors.dim('šŸ”„ Refreshing expired token...'));\n // We keep it silent or use a global logger if available\n\n const newTokens = await authenticate(realm, creds.clientId, creds.clientKey);\n\n await tokenStorage.saveToken(\n realm,\n newTokens.access_token,\n creds.clientId,\n creds.clientKey,\n newTokens.expires_in\n );\n\n return newTokens.access_token;\n\n } catch (error) {\n console.warn(colors.warning(`āš ļø Failed to auto-refresh token: ${(error as Error).message}`));\n // Fallback to existing token\n }\n }\n }\n\n return creds.accessToken;\n}\n\nexport class StackSpotClient {\n private readonly MAX_RETRIES = 3;\n private readonly RETRY_DELAYS = [1000, 2000, 4000]; // 1s, 2s, 4s\n private debugMode = false;\n\n constructor(private realm: string) { }\n\n public enableDebug(): void {\n this.debugMode = true;\n }\n\n private async getHeaders(): Promise<Headers> {\n const token = await ensureValidToken(this.realm);\n const headers = new Headers();\n headers.set('Authorization', `Bearer ${token}`);\n headers.set('Content-Type', 'application/json');\n return headers;\n }\n\n private shouldRetry(error: any, attempt: number): boolean {\n if (attempt >= this.MAX_RETRIES) return false;\n\n // Retry on network errors\n if (error.name === 'TypeError' || error.message?.includes('fetch')) return true;\n\n // Retry on 5xx server errors\n if (error.status && error.status >= 500) return true;\n\n return false;\n }\n\n private async sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private async request<T>(url: string, options: RequestOptions = {}): Promise<T> {\n let lastError: any;\n\n for (let attempt = 0; attempt <= this.MAX_RETRIES; attempt++) {\n try {\n if (this.debugMode && attempt > 0) {\n console.log(`[StackSpotClient] Retry attempt ${attempt}/${this.MAX_RETRIES} for ${url}`);\n }\n\n const headers = await this.getHeaders();\n\n // Merge custom headers\n if (options.headers) {\n new Headers(options.headers).forEach((value, key) => headers.set(key, value));\n }\n\n // Add Query Params\n let finalUrl = url;\n if (options.params) {\n const query = new URLSearchParams(options.params).toString();\n finalUrl += `?${query}`;\n }\n\n if (this.debugMode) {\n console.log(`[StackSpotClient] ${options.method || 'GET'} ${finalUrl}`);\n }\n\n const response = await fetch(finalUrl, {\n ...options,\n headers,\n });\n\n if (response.status === 401) {\n throw new AuthError(\"Session expired or invalid credentials. Please run 'shark login' again.\");\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n const error: any = new Error(`API Request failed: ${response.status} ${response.statusText} - ${errorText}`);\n error.status = response.status;\n throw error;\n }\n\n // Return null for 204 No Content\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n\n } catch (error: any) {\n lastError = error;\n\n // Don't retry auth errors\n if (error instanceof AuthError) {\n throw error;\n }\n\n if (this.shouldRetry(error, attempt)) {\n const delay = this.RETRY_DELAYS[attempt] || this.RETRY_DELAYS[this.RETRY_DELAYS.length - 1];\n if (this.debugMode) {\n console.log(`[StackSpotClient] Retrying in ${delay}ms...`);\n }\n await this.sleep(delay);\n continue;\n }\n\n // No more retries\n throw error;\n }\n }\n\n throw lastError;\n }\n\n async get<T>(url: string, options?: RequestOptions): Promise<T> {\n return this.request<T>(url, { ...options, method: 'GET' });\n }\n\n async post<T>(url: string, body: any, options?: RequestOptions): Promise<T> {\n return this.request<T>(url, {\n ...options,\n method: 'POST',\n body: JSON.stringify(body)\n });\n }\n\n async put<T>(url: string, body: any, options?: RequestOptions): Promise<T> {\n return this.request<T>(url, {\n ...options,\n method: 'PUT',\n body: JSON.stringify(body)\n });\n }\n\n async delete<T>(url: string, options?: RequestOptions): Promise<T> {\n return this.request<T>(url, { ...options, method: 'DELETE' });\n }\n}\n\nexport function createAuthenticatedClient(realm: string): StackSpotClient {\n return new StackSpotClient(realm);\n}\n","import { FileLogger } from '../debug/file-logger.js';\n\nexport interface SSECallbacks {\n onChunk?: (partialMessage: string) => void;\n onComplete?: (fullMessage: string, metadata?: any) => void;\n onError?: (error: Error) => void;\n}\n\nexport class SSEClient {\n /**\n * Streams agent response using Server-Sent Events.\n * \n * @param url - The SSE endpoint URL\n * @param requestPayload - The request payload to POST\n * @param headers - Request headers (including Authorization)\n * @param callbacks - Event callbacks for chunks, completion, and errors\n */\n async streamAgentResponse(\n url: string,\n requestPayload: unknown,\n headers: HeadersInit,\n callbacks: SSECallbacks = {}\n ): Promise<void> {\n const { onChunk, onComplete, onError } = callbacks;\n\n FileLogger.log('SSE', `Starting Request to ${url}`, {\n headers,\n payload: requestPayload\n });\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n ...headers,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestPayload),\n });\n\n FileLogger.log('SSE', `Response Status: ${response.status} ${response.statusText}`);\n\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => { responseHeaders[key] = value; });\n FileLogger.log('SSE', 'Response Headers', responseHeaders);\n\n if (!response.ok) {\n const errorText = await response.text();\n FileLogger.log('SSE', 'Response Error Body', errorText);\n throw new Error(`SSE request failed: ${response.status} ${response.statusText} - ${errorText}`);\n }\n\n if (!response.body) {\n throw new Error('Response body is null');\n }\n\n const contentType = response.headers.get('content-type') || '';\n const isJson = contentType.includes('application/json');\n\n if (isJson) {\n // Handle non-streaming JSON response properly\n const jsonBody = await response.json();\n FileLogger.log('SSE', 'Received Non-Streaming JSON Response', { length: JSON.stringify(jsonBody).length });\n\n // Try to extract message content depending on structure\n let content = '';\n if (typeof jsonBody === 'string') content = jsonBody;\n else if (jsonBody.message) content = jsonBody.message;\n else if (jsonBody.choices?.[0]?.message?.content) content = jsonBody.choices[0].message.content; // OpenAI style just in case\n else content = JSON.stringify(jsonBody); // Fallback to raw JSON\n\n // Trigger callbacks as if it streamed in one chunk\n if (onChunk) onChunk(content);\n if (onComplete) onComplete(content, jsonBody);\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let fullMessage = '';\n let metadata: any = {};\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n // Decode chunk\n buffer += decoder.decode(value, { stream: true });\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 if (line.startsWith('data:')) {\n const data = line.slice(5).trim(); // Remove 'data:' prefix\n\n if (data === '[DONE]') {\n FileLogger.log('SSE', 'Stream Complete [DONE]', { fullMessage, metadata });\n // End of stream\n if (onComplete) {\n onComplete(fullMessage, metadata);\n }\n return;\n }\n\n try {\n const parsed = JSON.parse(data);\n const chunk = parsed.message || parsed.content || data;\n fullMessage += chunk;\n\n // Capture latest metadata (e.g. conversation_id)\n if (parsed.conversation_id) {\n metadata.conversation_id = parsed.conversation_id;\n }\n\n if (onChunk) {\n onChunk(chunk);\n }\n } catch (parseError) {\n // Not JSON, treat as plain text\n fullMessage += data;\n if (onChunk) {\n onChunk(data);\n }\n }\n }\n }\n }\n\n FileLogger.log('SSE', 'Stream Ended Naturally', { fullMessage, metadata });\n\n // Stream ended without [DONE]\n if (onComplete) {\n onComplete(fullMessage, metadata);\n }\n\n } catch (error) {\n FileLogger.log('SSE', 'Stream Error', error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n } else {\n throw error;\n }\n }\n }\n}\n\nexport const sseClient = new SSEClient();\n","import { z } from 'zod';\nimport { FileLogger } from '../debug/file-logger.js';\n\n// Action Schema\nexport const AgentActionSchema = z.object({\n type: z.enum([\n 'create_file', 'modify_file', 'list_files', 'search_file', 'read_file', 'delete_file',\n 'list_structure', 'modify_ast', 'search_ast', 'run_command',\n 'talk_with_user',\n 'ast_list_structure',\n 'ast_get_method',\n 'ast_add_method', 'ast_modify_method', 'ast_remove_method',\n 'ast_add_class',\n 'ast_get_property', 'ast_add_property', 'ast_modify_property', 'ast_remove_property',\n 'ast_add_decorator',\n 'ast_add_interface', 'ast_add_type_alias',\n 'ast_add_function', 'ast_remove_function',\n 'ast_add_import', 'ast_remove_import', 'ast_organize_imports'\n ]),\n path: z.string().nullable().optional(), // Nullable for strict mode combatibility\n content: z.string().nullable().optional(),\n line_range: z.array(z.number()).nullable().optional(),\n target_content: z.string().nullable().optional(),\n command: z.string().nullable().optional(),\n tool_name: z.string().nullable().optional(),\n tool_args: z.string().nullable().optional(), // JSON string argument\n\n // AST-Grep fields\n pattern: z.string().nullable().optional(),\n fix: z.string().nullable().optional(),\n language: z.string().nullable().optional(),\n file_path: z.string().nullable().optional(), // Alias for path in ast-grep actions\n\n // New AST Tool Specific Fields\n class_name: z.string().nullable().optional(),\n method_name: z.string().nullable().optional(),\n method_code: z.string().nullable().optional(),\n property_name: z.string().nullable().optional(),\n property_code: z.string().nullable().optional(),\n extends_class: z.string().nullable().optional(),\n implements_interfaces: z.array(z.string()).nullable().optional(),\n decorator_code: z.string().nullable().optional(),\n interface_code: z.string().nullable().optional(),\n type_code: z.string().nullable().optional(),\n function_name: z.string().nullable().optional(),\n function_code: z.string().nullable().optional(),\n import_statement: z.string().nullable().optional(),\n module_path: z.string().nullable().optional(),\n new_body: z.string().nullable().optional(),\n\n // Preview confirmation\n confirmed: z.boolean().nullable().optional(),\n});\n\nexport type AgentAction = z.infer<typeof AgentActionSchema>;\n\n// Command Schema (for future use)\nexport const AgentCommandSchema = z.object({\n command: z.string(),\n description: z.string(),\n critical: z.boolean(),\n});\n\n// Full Structured Response Schema\nexport const AgentResponseSchema = z.object({\n actions: z.array(AgentActionSchema),\n commands: z.array(AgentCommandSchema).optional(),\n summary: z.string().optional(),\n\n // Legacy fields handling for smooth transition/fallback\n message: z.string().optional(),\n conversation_id: z.string().optional(),\n});\n\nexport type AgentResponse = z.infer<typeof AgentResponseSchema>;\n\n/**\n * Parses raw agent response expecting a JSON string that matches our schema.\n */\nexport function parseAgentResponse(rawResponse: unknown): AgentResponse {\n FileLogger.log('PARSER', 'Parsing Agent Response', { rawType: typeof rawResponse });\n\n let parsedObj: any = {};\n let conversation_id: string | undefined;\n\n // 1. Handle string input (accumulated SSE or raw JSON string)\n if (typeof rawResponse === 'string') {\n FileLogger.log('PARSER', 'Type String', { length: rawResponse.length });\n try {\n parsedObj = extractFirstJson(rawResponse);\n } catch (e) {\n FileLogger.log('PARSER', 'String Parse Failed', { error: (e as Error).message });\n // Fallback: treat as simple message if not valid JSON\n return {\n actions: [{\n type: 'talk_with_user',\n content: rawResponse,\n path: ''\n }],\n message: rawResponse\n };\n }\n }\n // 2. Handle object input (direct API response)\n else if (typeof rawResponse === 'object' && rawResponse !== null) {\n const anyResp = rawResponse as any;\n conversation_id = anyResp.conversation_id;\n\n FileLogger.log('PARSER', 'Type Object', {\n hasContent: !!anyResp.content,\n hasMessage: !!anyResp.message,\n messageType: typeof anyResp.message\n });\n\n // Sometimes content is nested in 'content' or 'message'\n const stringContent = anyResp.content || anyResp.message;\n if (stringContent && typeof stringContent === 'string') {\n try {\n // Try to parse it as JSON actions\n const parsedInside = extractFirstJson(stringContent);\n // Only use it if it looks like an object (not just a primitive)\n if (typeof parsedInside === 'object' && parsedInside !== null) {\n parsedObj = parsedInside;\n FileLogger.log('PARSER', 'Inner JSON Parsed', { keys: Object.keys(parsedObj) });\n } else {\n // It was a string literal or number, treat as text\n parsedObj = rawResponse;\n FileLogger.log('PARSER', 'Inner JSON was primitive');\n }\n } catch (e) {\n // Not JSON, continue with rawResponse\n parsedObj = rawResponse;\n FileLogger.log('PARSER', 'Inner JSON Parse Error - treating as raw', { error: (e as Error).message });\n }\n } else {\n parsedObj = rawResponse;\n }\n\n // If we didn't successfully parse inner JSON actions, use the raw object\n if (!parsedObj.actions) {\n parsedObj = rawResponse;\n }\n }\n\n // 3. Normalize Actions\n // Ensure 'actions' array exists\n if (!parsedObj.actions) {\n FileLogger.log('PARSER', 'No Actions Found - Constructing Default');\n // If it looks like the legacy format or direct message\n return {\n conversation_id,\n actions: [{\n type: 'talk_with_user',\n content: parsedObj.message || JSON.stringify(parsedObj),\n path: ''\n }],\n message: parsedObj.message\n };\n }\n\n // 4. Validate against Schema\n // We construct the final object to match our schema structure\n const result = {\n actions: parsedObj.actions,\n commands: parsedObj.commands || [],\n summary: parsedObj.summary || '',\n conversation_id,\n message: parsedObj.summary || 'Agent Action' // Backward compatibility\n };\n\n\n FileLogger.log('PARSER', 'Final Result Constructed', { actionCount: result.actions.length });\n\n try {\n return AgentResponseSchema.parse(result);\n } catch (e) {\n FileLogger.log('PARSER', 'Schema Validation Failed', { error: (e as Error).message });\n throw e;\n }\n}\n\nexport function extractFirstJson(str: string): any {\n try {\n return JSON.parse(str);\n } catch (e) {\n // If simple parse fails, try to find the first balanced object\n const firstOpen = str.indexOf('{');\n if (firstOpen === -1) throw e;\n\n let balance = 0;\n let inString = false;\n let escape = false;\n\n for (let i = firstOpen; i < str.length; i++) {\n const char = str[i];\n\n if (escape) {\n escape = false;\n continue;\n }\n\n if (char === '\\\\') {\n escape = true;\n continue;\n }\n\n if (char === '\"') {\n inString = !inString;\n continue;\n }\n\n if (!inString) {\n if (char === '{') balance++;\n else if (char === '}') {\n balance--;\n if (balance === 0) {\n // Found the end of the first object\n const potentialJson = str.substring(firstOpen, i + 1);\n try {\n return JSON.parse(potentialJson);\n } catch (innerE) {\n // If this chunk failed, maybe our brace counting was off (e.g. comments?), throw original\n throw e;\n }\n }\n }\n }\n }\n throw e;\n }\n}\n","import { workflowManager } from './workflow-manager.js';\n\n/**\n * Manages conversation IDs for agent interactions.\n * Stores conversation IDs in the workflow state to maintain context across sessions.\n */\nexport class ConversationManager {\n private static instance: ConversationManager;\n\n private constructor() { }\n\n public static getInstance(): ConversationManager {\n if (!ConversationManager.instance) {\n ConversationManager.instance = new ConversationManager();\n }\n return ConversationManager.instance;\n }\n\n /**\n * Saves a conversation ID for a specific agent type.\n * \n * @param agentType - The type of agent (e.g., 'business_analyst', 'architect')\n * @param conversationId - The conversation ID from the agent response\n */\n async saveConversationId(agentType: string, conversationId: string): Promise<void> {\n const state = await workflowManager.load();\n if (!state) {\n throw new Error('No workflow state found. Please run \"shark init\" first.');\n }\n\n // Initialize conversations object if it doesn't exist\n if (!state.conversations) {\n state.conversations = {};\n }\n\n state.conversations[agentType] = conversationId;\n await workflowManager.save(state);\n }\n\n /**\n * Retrieves the conversation ID for a specific agent type.\n * \n * @param agentType - The type of agent\n * @returns The conversation ID, or undefined if none exists\n */\n async getConversationId(agentType: string): Promise<string | undefined> {\n const state = await workflowManager.load();\n if (!state || !state.conversations) {\n return undefined;\n }\n\n return state.conversations[agentType];\n }\n\n /**\n * Clears the conversation ID for a specific agent type.\n * \n * @param agentType - The type of agent\n */\n async clearConversationId(agentType: string): Promise<void> {\n const state = await workflowManager.load();\n if (!state || !state.conversations) {\n return;\n }\n\n delete state.conversations[agentType];\n await workflowManager.save(state);\n }\n\n /**\n * Clears all conversation IDs.\n * Useful when transitioning to a new project or resetting state.\n */\n async clearAllConversations(): Promise<void> {\n const state = await workflowManager.load();\n if (!state) {\n return;\n }\n\n state.conversations = {};\n await workflowManager.save(state);\n }\n}\n\nexport const conversationManager = ConversationManager.getInstance();\n","import { ConfigManager } from '../config-manager.js';\n\n/**\n * Gets the currently active (logged-in) realm from config.\n * \n * @returns The active realm\n * @throws Error if no realm is active (user not logged in)\n */\nexport async function getActiveRealm(): Promise<string> {\n const configManager = ConfigManager.getInstance();\n const config = configManager.getConfig();\n const realm = config.activeRealm;\n\n if (!realm) {\n throw new Error(\n 'No active authentication found.\\n' +\n 'Please run \"shark login\" first to authenticate.'\n );\n }\n\n return realm;\n}\n","import { STACKSPOT_AGENT_API_BASE } from '../api/stackspot-client.js';\nimport { sseClient } from '../api/sse-client.js';\nimport { parseAgentResponse, AgentResponse } from './agent-response-parser.js';\nimport { conversationManager } from '../workflow/conversation-manager.js';\nimport { tokenStorage } from '../auth/token-storage.js';\nimport { getActiveRealm } from '../auth/get-active-realm.js';\nimport { tui } from '../../ui/tui.js';\nimport { colors } from '../../ui/colors.js';\nimport { ConfigManager } from '../config-manager.js';\n\nconst AGENT_TYPE = 'business_analyst';\n\nfunction getAgentId(overrideId?: string): string {\n if (overrideId) return overrideId;\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.ba) return config.agents.ba;\n return process.env.STACKSPOT_BA_AGENT_ID || '01KEJ95G304TNNAKGH5XNEEBVD';\n}\n\nexport interface BAAgentOptions {\n agentId?: string; // Allow overriding agent ID\n onChunk?: (chunk: string) => void;\n onComplete?: (response: AgentResponse) => void;\n}\n\n/**\n * Orchestrates interaction with the Business Analyst agent.\n * Integrates all communication components into a complete flow.\n * Automatically uses the active realm from config (no need to pass it).\n * \n * @param prompt - User's project description\n * @param options - Configuration options (callbacks, optional agentId override)\n * @returns Complete agent response\n */\nexport async function runBusinessAnalystAgent(\n prompt: string,\n options: BAAgentOptions = {}\n): Promise<AgentResponse> {\n const { agentId, onChunk, onComplete } = options;\n\n // 1. Get active realm from config (auto-detect)\n const realm = await getActiveRealm();\n\n // 1. Get auth token\n const token = await tokenStorage.getToken(realm);\n if (!token) {\n throw new Error(`No authentication token found for realm '${realm}'. Please run 'shark login'.`);\n }\n\n // 2. Load existing conversation ID (if any)\n const existingConversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n // 3. Build request payload (StackSpot agent format)\n const requestPayload = {\n user_prompt: prompt,\n streaming: true,\n stackspot_knowledge: false, // Use agent's configured KS instead\n return_ks_in_response: true,\n deep_search_ks: false,\n conversation_id: existingConversationId,\n };\n\n // 4. Construct agent URL - CORRECT FORMAT\n const effectiveAgentId = getAgentId(options.agentId);\n const agentUrl = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;\n\n // 5. Prepare headers\n const headers = {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n };\n\n // 6. Stream agent response\n let fullMessage = '';\n let rawResponse: any = {};\n\n await sseClient.streamAgentResponse(\n agentUrl,\n requestPayload,\n headers,\n {\n onChunk: (chunk) => {\n fullMessage += chunk;\n if (onChunk) {\n onChunk(chunk);\n }\n },\n onComplete: async (message) => {\n // Build complete response object\n rawResponse = {\n message: message || fullMessage,\n conversation_id: existingConversationId, // Will be updated if new one provided\n };\n },\n onError: (error) => {\n throw error;\n },\n }\n );\n\n // 7. Parse response\n const parsedResponse = parseAgentResponse(rawResponse);\n\n // 8. Save new conversation ID (if provided)\n if (parsedResponse.conversation_id) {\n await conversationManager.saveConversationId(AGENT_TYPE, parsedResponse.conversation_id);\n }\n\n // 9. Call completion callback\n if (onComplete) {\n onComplete(parsedResponse);\n }\n\n return parsedResponse;\n}\n\n/**\n * Interactive Business Analyst session with TUI.\n * Prompts user for input and displays streamed response.\n * Automatically uses the active realm from config.\n */\nexport async function interactiveBusinessAnalyst(): Promise<void> {\n tui.intro('šŸŽÆ Business Analyst Agent');\n\n const prompt = await tui.text({\n message: 'Describe your project idea',\n placeholder: 'E.g., I want to build a task management app for teams...',\n validate: (value) => {\n if (!value || value.length < 10) return 'Please provide a detailed description (at least 10 characters)';\n },\n });\n\n if (tui.isCancel(prompt)) {\n tui.outro('Cancelled');\n return;\n }\n\n const spinner = tui.spinner();\n spinner.start('šŸ’¬ Business Analyst is thinking...');\n\n let responseText = '';\n\n try {\n await runBusinessAnalystAgent(prompt as string, {\n onChunk: (chunk) => {\n responseText += chunk;\n // Update spinner with preview (try to parse JSON if possible, otherwise raw)\n try {\n // Start of JSON?\n if (responseText.trim().startsWith('{')) {\n spinner.message(colors.dim('Receiving structured data...'));\n } else {\n spinner.message(colors.dim('Thinking...'));\n }\n } catch (e) {\n // ignore\n }\n },\n onComplete: async (response) => {\n spinner.stop('Response received');\n\n // Show summary if exists\n if (response.summary) {\n tui.log.info(colors.italic(response.summary));\n }\n\n // Handle Actions\n if (response.actions && response.actions.length > 0) {\n for (const action of response.actions) {\n\n // CASE 1: TALK WITH USER (Conventional Message)\n if (action.type === 'talk_with_user') {\n tui.log.info(colors.success('šŸ¤– BA Agent:'));\n console.log(action.content); // Print formatted markdown\n\n // We don't verify \"talk\", we just show it.\n // The flow will wait for next user input naturally at loop start?\n // Wait! We need a loop here?\n // runBusinessAnalystAgent is a ONE-OFF request.\n // The LOOP needs to be in interactiveBusinessAnalyst.\n }\n\n // CASE 2: FILE OPERATIONS (Autonomous Actions)\n else {\n tui.log.warning(`\\nšŸ¤– Agent wants to ${action.type}: ${colors.bold(action.path || 'unknown')}`);\n\n // Show content preview\n if (action.content) {\n console.log(colors.dim('--- Content Preview ---'));\n console.log(action.content.substring(0, 300) + (action.content.length > 300 ? '...' : ''));\n console.log(colors.dim('-----------------------'));\n }\n\n const confirm = await tui.confirm({\n message: `Allow agent to ${action.type} '${action.path}'?`,\n active: 'Yes',\n inactive: 'No'\n });\n\n if (confirm) {\n // TODO: Add actual file system writing logic here\n // fs.writeFileSync(action.path!, action.content);\n tui.log.success(`āœ… Action executed: ${action.path} created.`);\n } else {\n tui.log.error('āŒ Action denied.');\n }\n }\n }\n }\n // Tokens property removed from schema, ignoring log.\n },\n });\n\n tui.outro('Session complete');\n } catch (error: any) {\n spinner.stop('āŒ Error', 1);\n tui.log.error(error.message);\n throw error;\n }\n}\n","\nimport { STACKSPOT_AGENT_API_BASE, ensureValidToken } from '../api/stackspot-client.js';\nimport { sseClient } from '../api/sse-client.js';\nimport { parseAgentResponse, AgentResponse } from './agent-response-parser.js';\nimport { conversationManager } from '../workflow/conversation-manager.js';\nimport { tokenStorage } from '../auth/token-storage.js';\nimport { getActiveRealm } from '../auth/get-active-realm.js';\nimport { tui } from '../../ui/tui.js';\nimport { colors } from '../../ui/colors.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { FileLogger } from '../debug/file-logger.js';\nimport { handleListFiles, handleReadFile, handleSearchFile, startSmartReplace } from './agent-tools.js';\nimport { ConfigManager } from '../config-manager.js';\n\nconst AGENT_TYPE = 'specification_agent';\n\nfunction getAgentId(overrideId?: string): string {\n if (overrideId) return overrideId;\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.spec) return config.agents.spec;\n return process.env.STACKSPOT_SPEC_AGENT_ID || '01KEPXTX37FTB4N672TZST4SGP';\n}\n\nexport interface SpecAgentOptions {\n agentId?: string;\n briefingPath?: string; // Path to the briefing file to read, explicit override\n initialContext?: string; // Handover context from Dev Agent or Orchestrator\n}\n\n/**\n * Interactive Specification Agent session.\n * Uses a Template-Based Incremental Workflow.\n */\nexport async function interactiveSpecificationAgent(options: SpecAgentOptions = {}): Promise<void> {\n FileLogger.init();\n tui.intro('šŸ—ļø Specification Agent (Template-Based)');\n\n const projectRoot = process.cwd();\n // User requested to store tech-spec.md in _sharkrc\n const sharkRcDir = path.resolve(projectRoot, '_sharkrc');\n if (!fs.existsSync(sharkRcDir)) fs.mkdirSync(sharkRcDir, { recursive: true });\n\n const outputFile = path.resolve(sharkRcDir, 'tech-spec.md');\n\n // 1. Ensure Template Exists (Inline Template)\n if (!fs.existsSync(outputFile)) {\n // Hardcoded template as requested, similar to scan-agent.ts\n let initialContent = `# Technical Specification: {{PROJECT_NAME}}\n\n## 1. Technology Stack\n[TO BE ANALYZED]\n- Language: [e.g. TypeScript]\n- Framework: [e.g. Node.js / React]\n- Database: [e.g. SQLite / PostgreSQL]\n- Key Libraries: [Top 5 dependencies]\n\n## 2. Architecture Overview\n[TO BE ANALYZED]\n[Brief description of architectural pattern]\n\n## 3. Data Model\n[TO BE ANALYZED]\n[Schema/ERD definitions]\n\n## 4. API / Interface Contracts\n[TO BE ANALYZED]\n[Main endpoints or CLI commands]\n\n## 5. Implementation Steps\n[TO BE FILLED - MUST BE CHECKBOXES]\n`;\n\n // Replace basic placeholders immediately\n const projectName = path.basename(projectRoot);\n initialContent = initialContent.replace(/{{PROJECT_NAME}}/g, projectName);\n\n const BOM = '\\uFEFF';\n fs.writeFileSync(outputFile, BOM + initialContent, { encoding: 'utf-8' });\n tui.log.success(`āœ… Created: ${colors.bold('_sharkrc/tech-spec.md')}`);\n } else {\n tui.log.info(`šŸ“„ Using existing ${colors.bold('_sharkrc/tech-spec.md')}`);\n }\n\n // 2. Load Inputs (Context, Briefing)\n let contextContent = '';\n const contextPath = path.resolve(projectRoot, '_sharkrc', 'project-context.md');\n if (fs.existsSync(contextPath)) {\n contextContent = fs.readFileSync(contextPath, 'utf-8');\n tui.log.info(`šŸ“˜ Context loaded.`);\n }\n\n let briefingContent = '';\n if (options.briefingPath && fs.existsSync(options.briefingPath)) {\n briefingContent = fs.readFileSync(options.briefingPath, 'utf-8');\n tui.log.info(`šŸ“„ Briefing loaded from: ${colors.dim(options.briefingPath)}`);\n } else {\n const standardBriefing = path.resolve(projectRoot, '_sharkrc', 'briefing.md');\n if (fs.existsSync(standardBriefing)) {\n briefingContent = fs.readFileSync(standardBriefing, 'utf-8');\n tui.log.info(`šŸ“„ Briefing loaded.`);\n }\n }\n\n // 3. Construct Super Prompt\n let initialPrompt = `\nVocĆŖ Ć© o **Shark Spec**, um Arquiteto de Software SĆŖnior e Tech Lead.\nSeu objetivo Ć© produzir uma especificação tĆ©cnica precisa e especĆ­fica para a tarefa no arquivo \\`_sharkrc/tech-spec.md\\`.\n\nāš ļø WORKFLOW OBRIGATƓRIO – SIGA ESSA SEQUÊNCIA ESTRITAMENTE. NƃO PULE ETAPAS.\n\n**FASE 1 – ENTENDA A TAREFA (COMECE AQUI):**\n- Use \\`talk_with_user\\` para perguntar ao usuĆ”rio qual tarefa especĆ­fica, funcionalidade ou bug ele precisa especificar.\n- NƃO explore o código ou leia arquivos ainda.\n- Confirme o escopo e os limites com o usuĆ”rio antes de prosseguir.\n\n**FASE 2 – INVESTIGUE (FOCADO APENAS NA TAREFA):**\n- Use \\`list_files\\` e \\`read_file\\` APENAS em arquivos diretamente relevantes para a tarefa confirmada.\n- NƃO leia o projeto de forma genĆ©rica.\n- REGRA DE LEITURA PRƉVIA: VocĆŖ NƃO PODE adicionar uma tarefa referenciando um arquivo que vocĆŖ nĆ£o leu nesta sessĆ£o (exceção: novos arquivos a serem criados).\n\n**FASE 3 – PREENCHA O TEMPLATE:**\n- Use \\`modify_file\\` em \\`_sharkrc/tech-spec.md\\` para substituir os placeholders com conteĆŗdo real e especĆ­fico da tarefa.\n- As SeƧƵes 1-4 (Stack, Arquitetura, Modelo de Dados, API) devem descrever o contexto da TAREFA, nĆ£o do projeto como um todo.\n- Passos de Implementação: APENAS checkboxes markdown: \\`- [ ] [Verbo de Ação] [O Que] em [Caminho Relativo]\\`. SEM listas numeradas, SEM subnĆ­veis.\n- Quando todos os placeholders acabarem e vocĆŖ estiver satisfeito, retorne: \\`SPEC_UPDATED: Complete\\`.\n\n**REGRAS CRƍTICAS:**\n- NUNCA preencha a Technology Stack ou Architecture com informaƧƵes genĆ©ricas do projeto. Essas seƧƵes devem refletir o que a tarefa irĆ” usar ou alterar.\n- Use \\`talk_with_user\\` sempre que os requisitos forem ambĆ­guos.\n- NƃO tente escrever todas as seƧƵes de uma vez. Trabalhe de forma incremental, uma seção por vez.\n- IMPORTANTE: Toda a sua comunicação e a especificação gerada DEVEM ser em PortuguĆŖs.\n`;\n\n if (briefingContent) {\n initialPrompt += `\nā„¹ļø Um documento de briefing foi encontrado. Ele define parcialmente a tarefa para a Fase 1.\nConfirme seu entendimento com o usuĆ”rio via \\`talk_with_user\\` antes de prosseguir para a Fase 2.\n\n--- BRIEFING ---\n${briefingContent}\n----------------\n`;\n } else {\n initialPrompt += `\nā„¹ļø Nenhum documento de briefing foi encontrado. Inicie a Fase 1 imediatamente: use \\`talk_with_user\\` para perguntar ao usuĆ”rio o que precisa ser especificado.\n`;\n }\n\n if (options.initialContext) {\n initialPrompt += `\\n--- CONTEXTO DE EXECUƇƃO ANTERIOR (HANDOVER/FEEDBACK) ---\\n${options.initialContext}\\n-----------------------------------------------------\\n`;\n }\n\n if (contextContent) {\n initialPrompt += `\nā„¹ļø O contexto do projeto estĆ” disponĆ­vel para referĆŖncia. Use-o na Fase 2 para se alinhar com os padrƵes de arquitetura existentes, mas NƃO o use para preencher as seƧƵes de forma genĆ©rica.\n\n--- PROJECT CONTEXT ---\n${contextContent}\n-----------------------\n`;\n }\n\n // 4. Start Loop\n await runSpecLoop(initialPrompt.trim(), outputFile, options.agentId);\n}\n\n/**\n * Main Loop for Specification Agent (Incremental)\n */\nasync function runSpecLoop(initialMessage: string, targetPath: string, overrideAgentId?: string) {\n let nextPrompt = initialMessage;\n let keepGoing = true;\n let stepCount = 0;\n const MAX_STEPS = 30;\n\n while (keepGoing && stepCount < MAX_STEPS) {\n stepCount++;\n const spinner = tui.spinner();\n spinner.start(`šŸ—ļø Spec Agent working (Step ${stepCount}/${MAX_STEPS})...`);\n\n // Check Pending Sections to guide the agent\n let pendingSections = [];\n if (fs.existsSync(targetPath)) {\n const content = fs.readFileSync(targetPath, 'utf-8');\n if (content.includes('[TO BE ANALYZED]')) pendingSections.push('Analysis Sections (Stack, Arch, Data, API)');\n if (content.includes('[TO BE FILLED')) pendingSections.push('Implementation Steps');\n }\n\n if (pendingSections.length === 0 && stepCount > 1) {\n // Check if user is done?\n }\n\n let responseText = '';\n let lastResponse: AgentResponse | null = null;\n\n try {\n lastResponse = await callSpecAgentApi(nextPrompt, (chunk) => {\n responseText += chunk;\n }, overrideAgentId);\n\n spinner.stop('Response received');\n\n if (lastResponse && lastResponse.actions) {\n let executionResults = \"\";\n let waitingForUser = false;\n let specUpdated = false;\n\n // Check for completion signal\n if (lastResponse.message && lastResponse.message.includes('SPEC_UPDATED:')) {\n const content = fs.existsSync(targetPath) ? fs.readFileSync(targetPath, 'utf-8') : '';\n if (content.includes('[TO BE')) {\n const pendingMatches = [...content.matchAll(/## ([^\\n]+)[\\s\\S]*?\\[TO BE/g)].map(m => m[1]);\n let missing = pendingMatches.length > 0 ? pendingMatches.join(', ') : 'algumas seƧƵes';\n \n tui.log.warning(`O agente tentou concluir prematuramente, mas hĆ” placeholders pendentes. ForƧando retorno...`);\n nextPrompt = `[System Error]: VocĆŖ tentou enviar 'SPEC_UPDATED: Complete', mas o arquivo AINDA possui placeholders '[TO BE...]'. \\nAs seguintes seƧƵes parecem incompletas: ${missing}.\\n\\nPor favor, retome a FASE 3 e continue editando o arquivo atĆ© que NENHUM placeholder reste. Lembre-se, use \\`modify_file\\` para cada uma dessas seƧƵes e foque na tarefa discutida.`;\n continue;\n } else {\n const updateSummary = lastResponse.message.split('SPEC_UPDATED:')[1].trim();\n tui.log.success(`āœ… Spec Finalized: ${updateSummary}`);\n return;\n }\n }\n\n for (const action of lastResponse.actions) {\n if (action.type === 'talk_with_user') {\n tui.log.info(colors.primary('šŸ¤– Architect:'));\n console.log(action.content);\n waitingForUser = true;\n }\n\n else if (action.type === 'list_files') {\n tui.log.info(`šŸ“‚ Scanning: ${colors.dim(action.path || '.')}`);\n const result = handleListFiles(action.path || '.');\n executionResults += `[Action list_files(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n\n else if (action.type === 'read_file') {\n tui.log.info(`šŸ“– Reading: ${colors.dim(action.path || '')}`);\n const result = handleReadFile(action.path || '');\n executionResults += `[Action read_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n\n else if (action.type === 'search_file') {\n tui.log.info(`šŸ” Searching: ${colors.dim(action.path || '')}`);\n const result = handleSearchFile(action.path || '');\n executionResults += `[Action search_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n\n else if (['create_file', 'modify_file'].includes(action.type)) {\n // Target Validation & Redirection\n let actionPath = path.resolve(action.path || '');\n const resolvedTargetPath = path.resolve(targetPath);\n let isTarget = actionPath === resolvedTargetPath;\n\n // Auto-redirect if agent tries to write to root tech-spec.md instead of _sharkrc\n if (!isTarget && path.basename(actionPath) === 'tech-spec.md') {\n tui.log.warning(`Redirecting ${action.type} from ${action.path} to ${path.relative(process.cwd(), targetPath)}`);\n action.path = targetPath;\n actionPath = resolvedTargetPath;\n isTarget = true;\n }\n\n if (!isTarget && action.type === 'create_file') {\n const confirm = await tui.confirm({ message: `Agent wants to create ${action.path}. Allow?` });\n if (!confirm) {\n executionResults += `[Action create_file]: User denied.\\n`;\n continue;\n }\n }\n\n try {\n if (action.type === 'create_file') {\n const BOM = '\\uFEFF';\n fs.writeFileSync(action.path!, BOM + (action.content || ''), 'utf-8');\n tui.log.success(`āœ… Created: ${action.path}`);\n executionResults += `[Action create_file]: Success.\\n`;\n } else if (action.type === 'modify_file') {\n if (action.target_content) {\n // Ensure we pass the possibly redirected path\n const success = startSmartReplace(action.path!, action.content || '', action.target_content, tui);\n if (success) {\n executionResults += `[Action modify_file]: Success.\\n`;\n specUpdated = true;\n } else {\n executionResults += `[Action modify_file]: Failed. Target content not found.\\n`;\n }\n } else {\n executionResults += `[Action modify_file]: Failed. 'target_content' is required.\\n`;\n }\n }\n } catch (e: any) {\n executionResults += `[Action ${action.type}]: Error: ${e.message}\\n`;\n }\n }\n }\n\n // Prepare Next Prompt\n if (waitingForUser) {\n const userReply = await tui.text({ message: 'Your answer', placeholder: 'Type your answer...' });\n if (tui.isCancel(userReply)) { keepGoing = false; return; }\n nextPrompt = `${executionResults}\\n\\nUser Reply: ${userReply}`;\n } else if (executionResults) {\n const content = fs.existsSync(targetPath) ? fs.readFileSync(targetPath, 'utf-8') : '';\n let systemMsg = \"Execução da ferramenta concluĆ­da.\";\n if (specUpdated) {\n if (content.includes('[TO BE')) {\n const pendingMatches = [...content.matchAll(/## ([^\\n]+)[\\s\\S]*?\\[TO BE/g)].map(m => m[1]);\n let missing = pendingMatches.length > 0 ? pendingMatches.join(', ') : 'vĆ”rias seƧƵes';\n systemMsg += `\\n[System]: Seção atualizada. Por favor, continue preenchendo os placeholders '[TO BE ...]' restantes nas seguintes seƧƵes: ${missing}.`;\n } else {\n systemMsg += \"\\n[System]: O arquivo parece completo! Se estiver satisfeito e possuir TODAS as implementaƧƵes descritas, retorne 'SPEC_UPDATED: Complete'.\";\n }\n }\n nextPrompt = `${executionResults}\\n\\n${systemMsg}`;\n } else {\n if (lastResponse.message) {\n tui.log.info(colors.primary('šŸ¤– Architect (Message only):'));\n console.log(lastResponse.message);\n const userReply = await tui.text({ message: 'Your answer:' });\n if (tui.isCancel(userReply)) { keepGoing = false; break; }\n nextPrompt = userReply as string;\n } else {\n keepGoing = false;\n }\n }\n\n } else {\n tui.log.warning('No actions received.');\n keepGoing = false;\n }\n\n } catch (error: any) {\n spinner.stop('Error');\n tui.log.error(error.message);\n keepGoing = false;\n }\n }\n}\n\n// --- API Wrapper Matches Scan/Dev Agent Pattern ---\nasync function callSpecAgentApi(prompt: string, onChunk: (chunk: string) => void, agentId?: string): Promise<AgentResponse> {\n const realm = await getActiveRealm();\n const token = await ensureValidToken(realm);\n const conversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n const payload = {\n user_prompt: prompt,\n streaming: true,\n stackspot_knowledge: false,\n return_ks_in_response: true,\n use_conversation: true,\n conversation_id: conversationId\n };\n\n const effectiveAgentId = getAgentId(agentId);\n const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;\n\n let fullMsg = '';\n let raw: any = {};\n\n FileLogger.log('AGENT', 'Calling Agent API', { agentId: effectiveAgentId, conversationId });\n\n await sseClient.streamAgentResponse(url, payload, { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, {\n onChunk: (c) => { fullMsg += c; onChunk(c); },\n onComplete: (msg, metadata) => {\n const returnedId = metadata?.conversation_id;\n raw = { message: msg || fullMsg, conversation_id: returnedId || conversationId };\n },\n onError: (e) => { throw e; }\n });\n\n const parsed = parseAgentResponse(raw);\n if (parsed.conversation_id) {\n await conversationManager.saveConversationId(AGENT_TYPE, parsed.conversation_id);\n }\n\n return parsed;\n}\n","\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport fg from 'fast-glob';\nimport { colors } from '../../ui/colors.js';\nimport { tui } from '../../ui/tui.js';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { fileURLToPath } from 'node:url';\nimport { CodeEditorFactory } from '../ast-editing/editors/code-editor-factory.js';\nimport { CodeStructure } from '../ast-editing/interfaces/structure.types.js';\n\nconst execAsync = promisify(exec);\n\n\n/**\n * Shared tools for Agent interaction (File System, etc.)\n */\n\n\nexport function detectLineEnding(content: string): string {\n const crlf = content.split('\\r\\n').length - 1;\n const lf = content.split('\\n').length - 1 - crlf;\n return crlf > lf ? '\\r\\n' : '\\n';\n}\n\nexport function handleListFiles(dirPath: string): string {\n try {\n const fullPath = path.resolve(process.cwd(), dirPath);\n if (!fs.existsSync(fullPath)) return `Error: Directory ${dirPath} does not exist.`;\n\n const items = fs.readdirSync(fullPath, { withFileTypes: true });\n return items.map(item => {\n return `${item.isDirectory() ? '[DIR]' : '[FILE]'} ${item.name}`;\n }).join('\\n');\n } catch (e: any) {\n return `Error listing files: ${e.message}`;\n }\n}\n\nexport function handleReadFile(filePath: string, showLineNumbers: boolean = true): string {\n try {\n const fullPath = path.resolve(process.cwd(), filePath);\n if (!fs.existsSync(fullPath)) return `Error: File ${filePath} does not exist.`;\n\n // Limit size?\n const stats = fs.statSync(fullPath);\n if (stats.size > 100 * 1024) return `Error: File too large to read (${stats.size} bytes). Limit is 100KB.`;\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n\n if (showLineNumbers) {\n const lines = content.split('\\n');\n return lines.map((line, idx) => `${idx + 1}: ${line}`).join('\\n');\n }\n\n return content;\n } catch (e: any) {\n return `Error reading file: ${e.message}`;\n }\n}\n\nexport function replaceLineRange(\n filePath: string,\n startLine: number, // 1-indexed\n endLine: number, // 1-indexed\n newContent: string,\n tui: any\n): boolean {\n try {\n if (!fs.existsSync(filePath)) {\n tui.log.error(`āŒ File not found for modification: ${filePath}`);\n return false;\n }\n\n const currentFileContent = fs.readFileSync(filePath, 'utf-8');\n const lineEnding = detectLineEnding(currentFileContent);\n const lines = currentFileContent.split(lineEnding);\n\n // Validation\n if (startLine < 1 || startLine > lines.length) {\n tui.log.error(`āŒ Invalid start line: ${startLine}. File has ${lines.length} lines.`);\n return false;\n }\n\n if (endLine < startLine || endLine > lines.length) {\n tui.log.error(`āŒ Invalid end line: ${endLine}. Must be >= startLine and <= file length.`);\n return false;\n }\n\n // Replace lines [startLine-1, endLine-1]\n // Note: lines array is 0-indexed\n const before = lines.slice(0, startLine - 1);\n const after = lines.slice(endLine);\n const newLines = newContent.split(lineEnding); // Use detected line ending for new content splitting if provided with one, usually agent provides \\n\n\n // If newContent comes from LLM, it likely has \\n. We should split by \\n and join by detected.\n // But wait, if newContent has \\n and we join by \\r\\n, it works if we split newContent by \\n.\n // If newContent already has \\r\\n, splitting by \\n leaves \\r.\n // Safe approach: Normalized split of new code.\n const normalizedNewLines = newContent.replace(/\\r\\n/g, '\\n').split('\\n');\n\n const result = [...before, ...normalizedNewLines, ...after].join(lineEnding);\n\n const BOM = '\\uFEFF';\n const finalContent = result.startsWith(BOM) ? result : BOM + result;\n fs.writeFileSync(filePath, finalContent, { encoding: 'utf-8' });\n\n tui.log.success(`āœ… Replaced lines ${startLine}-${endLine} in ${filePath}`);\n return true;\n\n } catch (e: any) {\n tui.log.error(`āŒ Error replacing line range: ${e.message}`);\n return false;\n }\n}\n\nimport { CodeReviewService } from '../services/code-review.service.js';\n\nexport async function generateFilePreview(\n filePath: string,\n startLine: number,\n endLine: number,\n newContent: string\n): Promise<string> {\n try {\n const fullPath = path.resolve(process.cwd(), filePath);\n if (!fs.existsSync(fullPath)) return `Error: File ${filePath} does not exist.`;\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const lines = content.split(/\\r\\n|\\r|\\n/);\n\n // 0-indexed adjustment\n const startIdx = startLine - 1;\n const endIdx = endLine - 1;\n\n if (startIdx < 0 || startIdx >= lines.length) return `Error: Start line ${startLine} is out of bounds (File has ${lines.length} lines).`;\n if (endIdx < startIdx || endIdx >= lines.length) return `Error: End line ${endLine} is invalid.`;\n\n const contextBefore = lines.slice(Math.max(0, startIdx - 3), startIdx).map((l, i) => `${Math.max(1, startLine - 3) + i} | ${l}`).join('\\n');\n const contentReplacing = lines.slice(startIdx, endIdx + 1).map((l, i) => `${startLine + i} | - ${l}`).join('\\n');\n const contextAfter = lines.slice(endIdx + 1, Math.min(lines.length, endIdx + 4)).map((l, i) => `${endLine + 1 + i} | ${l}`).join('\\n');\n\n const newLines = newContent.split('\\n').map(l => `+ ${l}`).join('\\n');\n\n // INTEGRATE CODE REVIEW AGENT\n let reviewFeedback = '';\n try {\n reviewFeedback = await CodeReviewService.reviewCode(filePath, newContent);\n } catch (err) {\n reviewFeedback = `āš ļø Code Review Service Unavailable: ${(err as any).message}`;\n }\n\n return `PREVIEW OF CHANGES to ${filePath}:\n--------------------------------------------------\nCONTEXT BEFORE:\n${contextBefore}\n\nCHANGES:\n${contentReplacing}\n${newLines}\n\nCONTEXT AFTER:\n${contextAfter}\n--------------------------------------------------\n${reviewFeedback}\n\nIMPORTANT: Please verify that the lines being replaced (marked with -) are exactly what you intend to remove.\nIf the context looks wrong, DO NOT CONFIRM. Re-read the file to check line numbers.\n`;\n } catch (e: any) {\n return `Error generating preview: ${e.message}`;\n }\n}\n\nexport function handleSearchFile(pattern: string): string {\n try {\n // Limit scope to current directory for safety?\n // Patterns are relative to process.cwd()\n const entries = fg.sync(pattern, { dot: true });\n if (entries.length === 0) return 'No files found matching pattern.';\n return entries.slice(0, 50).join('\\n');\n } catch (e: any) {\n return `Error searching files: ${e.message}`;\n }\n}\n\nexport function startSmartReplace(filePath: string, newContent: string, targetContent: string, tui: any): boolean {\n if (!fs.existsSync(filePath)) {\n tui.log.error(`āŒ File not found for modification: ${filePath}`);\n return false;\n }\n\n const currentFileContent = fs.readFileSync(filePath, 'utf-8');\n\n // 1. Validation: Does target exist?\n // Normalize string for comparison to avoid CRLF issues during check\n const normalizedTarget = targetContent.replace(/\\r\\n/g, '\\n');\n const normalizedContent = currentFileContent.replace(/\\r\\n/g, '\\n');\n\n if (!normalizedContent.includes(normalizedTarget)) {\n tui.log.error(`āŒ Target content not found in ${filePath} (checked with normalized line endings). Modification aborted.`);\n console.log(colors.dim('--- Target Content Expected ---'));\n console.log(targetContent.substring(0, 200) + '...');\n return false;\n }\n\n // 2. Validation: Is it unique?\n const occurrences = currentFileContent.split(targetContent).length - 1;\n if (occurrences > 1) {\n tui.log.error(`āŒ Ambiguous target: Found ${occurrences} occurrences in ${filePath}. Modification aborted.`);\n return false;\n }\n\n // 3. Apply Replacement\n const BOM = '\\uFEFF';\n const updatedContent = currentFileContent.replace(targetContent, newContent);\n const finalContent = updatedContent.startsWith(BOM) ? updatedContent : BOM + updatedContent;\n fs.writeFileSync(filePath, finalContent, { encoding: 'utf-8' });\n tui.log.success(`āœ… Smart Replace Applied: ${filePath}`);\n return true;\n}\n\nexport async function handleRunCommand(command: string): Promise<string> {\n const { spawn } = await import('node:child_process');\n try {\n tui.log.info(`šŸ’» Executing: ${colors.dim(command)}`);\n\n // Split command into cmd and args (naive split, use specific parser if needed for complex quotes)\n // For simplicity in Agent usage, we might act as a shell?\n // Let's use shell: true option for ease of piping/env usage.\n\n return new Promise((resolve) => {\n const child = spawn(command, {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: process.cwd()\n });\n\n let stdout = '';\n let stderr = '';\n\n // Timeout safety: 5 minutes\n const timer = setTimeout(() => {\n child.kill();\n resolve(`Error: Command timed out after 5 minutes.\\nOutput so far:\\n${stdout}\\n${stderr}`);\n }, 5 * 60 * 1000);\n\n child.stdout.on('data', (data) => {\n const chunk = data.toString();\n stdout += chunk;\n // Optional: Stream to TUI if verbose?\n });\n\n child.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n\n child.on('close', (code) => {\n clearTimeout(timer);\n if (code === 0) {\n resolve(stdout.trim() || 'Command executed successfully (no output).');\n } else {\n resolve(`Command failed with exit code ${code}.\\nSTDERR:\\n${stderr}\\nSTDOUT:\\n${stdout}`);\n }\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n resolve(`Error executing command: ${err.message}`);\n });\n });\n\n } catch (e: any) {\n return `Error launching command: ${e.message}`;\n }\n}\n\n\n/**\n * Resolves the ast-grep command to use.\n * Priorities:\n * 1. Package-local node_modules binary (for global installs)\n * 2. CWD node_modules binary (for local dev)\n * 3. Fallback to 'npx sg'\n */\nfunction resolveAstGrepCommand(): string {\n const isWin = process.platform === 'win32';\n const binName = isWin ? 'sg.cmd' : 'sg';\n\n // 1. Try to find binary relative to THIS file (package root)\n try {\n const currentFile = fileURLToPath(import.meta.url);\n // Go up until we find package root or hit root\n let dir = path.dirname(currentFile);\n\n // Simple heuristic: walk up up to 5 levels to find node_modules\n // When bundled, we might be in dist/ or dist/bin/\n for (let i = 0; i < 5; i++) {\n const candidate = path.join(dir, 'node_modules', '.bin', binName);\n if (fs.existsSync(candidate)) {\n return `\"${candidate}\"`;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch (e) {\n // Ignore errors resolving path\n }\n\n // 2. Try CWD (User's project)\n const cwdBin = path.resolve(process.cwd(), 'node_modules', '.bin', binName);\n if (fs.existsSync(cwdBin)) {\n return `\"${cwdBin}\"`;\n }\n\n // 3. Fallback\n return 'npx sg';\n}\n\n/**\n * Executes ast-grep search via local CLI.\n * Returns the raw output (JSON usually requested by consumer) or error message.\n */\nexport async function astGrepSearch(\n pattern: string,\n filePath: string,\n language: string,\n tui: any\n): Promise<string> {\n const { spawn } = await import('node:child_process');\n try {\n if (!fs.existsSync(filePath)) {\n return `āŒ File not found: ${filePath}`;\n }\n\n // Resolve sg command robustly\n const sgCmd = resolveAstGrepCommand();\n const cmd = `${sgCmd} run -p \"${pattern}\" -l ${language} --json ${filePath}`;\n\n tui.log.info(`šŸ” [AST-GREP] Searching: ${cmd}`);\n\n return new Promise((resolve) => {\n const child = spawn(cmd, {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: process.cwd(),\n env: { ...process.env, NO_COLOR: 'true' } // Avoid ANSI codes in JSON output\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (data) => stdout += data.toString());\n child.stderr.on('data', (data) => stderr += data.toString());\n\n child.on('close', (code) => {\n if (code === 0 && stdout) {\n resolve(stdout);\n } else if (code === 1 && !stderr) {\n // ast-grep finds simply nothing\n resolve(\"No structural matches found.\");\n } else {\n // Real error or no matches with empty stdout\n if (!stdout && !stderr) resolve(\"No structural matches found.\");\n else {\n tui.log.error(`āŒ ast-grep search error (code ${code}): ${stderr}`);\n resolve(`Error executing ast-grep search: ${stderr || stdout}`);\n }\n }\n });\n\n child.on('error', (err) => {\n resolve(`Error executing ast-grep search: ${err.message}`);\n });\n });\n\n } catch (e: any) {\n tui.log.error(`āŒ ast-grep search exception: ${e.message}`);\n return `Error executing ast-grep search: ${e.message}`;\n }\n}\n\n/**\n * Executes ast-grep rewrite via local CLI.\n * Returns boolean success/failure.\n */\nexport async function astGrepRewrite(\n pattern: string,\n fix: string,\n filePath: string,\n language: string,\n tui: any\n): Promise<boolean> {\n const { spawn } = await import('node:child_process');\n try {\n if (!fs.existsSync(filePath)) {\n tui.log.error(`āŒ File not found for AST modification: ${filePath}`);\n return false;\n }\n\n // Resolve sg command robustly\n const sgCmd = resolveAstGrepCommand();\n const cmd = `${sgCmd} run -p \"${pattern}\" -r \"${fix}\" -l ${language} ${filePath} --update-all`;\n\n tui.log.info(`āœļø [AST-GREP] Rewriting: pattern=\"${pattern}\" fix=\"${fix.substring(0, 50)}...\"`);\n\n return new Promise((resolve) => {\n const child = spawn(cmd, {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: process.cwd()\n });\n\n let stderr = '';\n child.stderr.on('data', (data) => stderr += data.toString());\n\n child.on('close', (code) => {\n if (code === 0) {\n tui.log.success(`āœ… AST Rewrite applied to ${filePath}`);\n resolve(true);\n } else {\n tui.log.error(`āŒ AST Rewrite failed (code ${code}): ${stderr}`);\n resolve(false);\n }\n });\n\n child.on('error', (err) => {\n tui.log.error(`āŒ AST Rewrite spawn error: ${err.message}`);\n resolve(false);\n });\n });\n\n } catch (e: any) {\n tui.log.error(`āŒ Unexpected error in astGrepRewrite: ${e.message}`);\n return false;\n }\n}\n\n// ═══════════════════════════════════════════════════════\n// AST TOOLS IMPLEMENTATION\n// ═══════════════════════════════════════════════════════\n\n/**\n * AST Tool: List file structure\n */\nexport async function astListStructure(filePath: string): Promise<string> {\n try {\n const editor = CodeEditorFactory.getEditor(filePath);\n\n if (!editor) {\n return `[AST Error] File type not supported: ${filePath}. Use read_file instead.`;\n }\n\n const structure: CodeStructure = await editor.listStructure(filePath);\n\n // Format for LLM consumption\n let output = `[AST Structure of ${filePath}]\\n\\n`;\n\n // Classes\n if (structure.classes.length > 0) {\n output += `CLASSES:\\n`;\n structure.classes.forEach(cls => {\n output += ` - ${cls.name}`;\n if (cls.extendsClass) output += ` extends ${cls.extendsClass}`;\n if (cls.implementsInterfaces.length > 0) {\n output += ` implements ${cls.implementsInterfaces.join(', ')}`;\n }\n output += `\\n`;\n\n if (cls.decorators.length > 0) {\n output += ` Decorators: ${cls.decorators.join(', ')}\\n`;\n }\n\n if (cls.properties.length > 0) {\n output += ` Properties:\\n`;\n cls.properties.forEach(prop => {\n output += ` - ${prop.visibility} ${prop.name}: ${prop.type}\\n`;\n });\n }\n\n if (cls.methods.length > 0) {\n output += ` Methods:\\n`;\n cls.methods.forEach(method => {\n const params = method.parameters.map(p => `${p.name}: ${p.type}`).join(', ');\n output += ` - ${method.visibility} ${method.name}(${params}): ${method.returnType}\\n`;\n });\n }\n output += `\\n`;\n });\n }\n\n // Interfaces\n if (structure.interfaces.length > 0) {\n output += `INTERFACES:\\n`;\n structure.interfaces.forEach(iface => {\n output += ` - ${iface.name}\\n`;\n iface.properties.forEach(prop => {\n output += ` ${prop.name}: ${prop.type}\\n`;\n });\n });\n output += `\\n`;\n }\n\n // Functions\n if (structure.functions.length > 0) {\n output += `FUNCTIONS:\\n`;\n structure.functions.forEach(fn => {\n const params = fn.parameters.map(p => `${p.name}: ${p.type}`).join(', ');\n output += ` - ${fn.name}(${params}): ${fn.returnType}\\n`;\n });\n output += `\\n`;\n }\n\n // Imports\n if (structure.imports.length > 0) {\n output += `IMPORTS:\\n`;\n structure.imports.forEach(imp => {\n output += ` - from \"${imp.modulePath}\": ${imp.namedImports.join(', ')}\\n`;\n });\n }\n\n return output;\n } catch (error: any) {\n return `[AST Error] ${error.message}`;\n }\n}\n\nexport async function astAddMethod(\n filePath: string,\n className: string,\n methodCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) {\n throw new Error(`No AST editor available for ${filePath}`);\n }\n return await editor.addMethod(filePath, className, methodCode);\n}\n\nexport async function astGetMethod(\n filePath: string,\n className: string,\n methodName: string\n): Promise<string> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) {\n throw new Error(`No AST editor available for ${filePath}`);\n }\n const methodContent = await editor.getMethod(filePath, className, methodName);\n if (!methodContent) {\n return `Method \"${methodName}\" not found in class \"${className}\"`;\n }\n return methodContent;\n}\n\nexport async function astAddClass(\n filePath: string,\n className: string,\n extendsClass?: string,\n implementsInterfaces?: string[]\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addClass(filePath, className, { extendsClass, implementsInterfaces });\n}\n\nexport async function astAddProperty(\n filePath: string,\n className: string,\n propertyCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addProperty(filePath, className, propertyCode);\n}\n\nexport async function astGetProperty(\n filePath: string,\n className: string,\n propertyName: string\n): Promise<string> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n const propContent = await editor.getProperty(filePath, className, propertyName);\n if (!propContent) {\n return `Property \"${propertyName}\" not found in class \"${className}\"`;\n }\n return propContent;\n}\n\nexport async function astModifyProperty(\n filePath: string,\n className: string,\n propertyName: string,\n propertyCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.modifyProperty(filePath, className, propertyName, propertyCode);\n}\n\nexport async function astRemoveProperty(\n filePath: string,\n className: string,\n propertyName: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.removeProperty(filePath, className, propertyName);\n}\n\nexport async function astModifyMethod(\n filePath: string,\n className: string,\n methodName: string,\n newBody: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.modifyMethod(filePath, className, methodName, newBody);\n}\n\nexport async function astRemoveMethod(\n filePath: string,\n className: string,\n methodName: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.removeMethod(filePath, className, methodName);\n}\n\nexport async function astAddDecorator(\n filePath: string,\n className: string,\n decoratorCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addDecorator(filePath, className, decoratorCode);\n}\n\nexport async function astAddInterface(\n filePath: string,\n interfaceCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addInterface(filePath, interfaceCode);\n}\n\nexport async function astAddTypeAlias(\n filePath: string,\n typeCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addTypeAlias(filePath, typeCode);\n}\n\nexport async function astAddFunction(\n filePath: string,\n functionCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addFunction(filePath, functionCode);\n}\n\nexport async function astRemoveFunction(\n filePath: string,\n functionName: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.removeFunction(filePath, functionName);\n}\n\nexport async function astAddImport(\n filePath: string,\n importStatement: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addImport(filePath, importStatement);\n}\n\nexport async function astRemoveImport(\n filePath: string,\n modulePath: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.removeImport(filePath, modulePath);\n}\n\nexport async function astOrganizeImports(\n filePath: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.organizeImports(filePath);\n}\n","import * as path from 'node:path';\nimport { CodeEditor } from '../interfaces/code-editor.interface.js';\nimport { TypeScriptEditor } from './typescript-editor.js';\n\nexport class CodeEditorFactory {\n private static tsEditor: TypeScriptEditor | null = null;\n\n /**\n * Returns appropriate editor for the file, or null if AST editing not supported\n */\n static getEditor(filePath: string): CodeEditor | null {\n const ext = path.extname(filePath).toLowerCase();\n\n // TypeScript/JavaScript\n if (['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {\n // Reuse singleton instance for performance (ts-morph Project is heavy)\n if (!this.tsEditor) {\n this.tsEditor = new TypeScriptEditor();\n }\n return this.tsEditor;\n }\n\n // HTML - TODO: Implement in Phase 2\n // if (ext === '.html') {\n // return new TreeSitterEditor('html');\n // }\n\n // For unsupported files, return null (will fallback to modify_file)\n return null;\n }\n\n /**\n * Clear cached editors (useful for testing)\n */\n static clearCache(): void {\n this.tsEditor = null;\n }\n}\n","import { Project, SourceFile, ClassDeclaration, SyntaxKind } from 'ts-morph';\nimport * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport { CodeEditor, ClassOptions } from '../interfaces/code-editor.interface.js';\nimport {\n CodeStructure,\n ClassInfo,\n MethodInfo,\n PropertyInfo\n} from '../interfaces/structure.types.js';\n\nexport class TypeScriptEditor implements CodeEditor {\n private project: Project;\n\n constructor() {\n this.project = new Project({\n skipAddingFilesFromTsConfig: true,\n compilerOptions: {\n target: 99, // ESNext\n module: 99, // ESNext\n },\n });\n }\n\n /**\n * Get or add source file to project\n */\n private getSourceFile(filePath: string): SourceFile {\n const absolutePath = path.resolve(filePath);\n\n // Check if already in project\n let sourceFile = this.project.getSourceFile(absolutePath);\n\n if (!sourceFile) {\n if (!fs.existsSync(absolutePath)) {\n throw new Error(`File not found: ${absolutePath}`);\n }\n sourceFile = this.project.addSourceFileAtPath(absolutePath);\n }\n\n return sourceFile;\n }\n\n /**\n * Get class declaration by name\n */\n private getClass(sourceFile: SourceFile, className: string): ClassDeclaration {\n const classDecl = sourceFile.getClass(className);\n if (!classDecl) {\n throw new Error(`Class \"${className}\" not found in ${sourceFile.getFilePath()}`);\n }\n return classDecl;\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: listStructure\n // ═══════════════════════════════════════════════════════\n\n async listStructure(filePath: string): Promise<CodeStructure> {\n const sourceFile = this.getSourceFile(filePath);\n\n // Extract classes\n const classes: ClassInfo[] = sourceFile.getClasses().map(cls => ({\n name: cls.getName() || '<anonymous>',\n methods: cls.getMethods().map(m => this.extractMethodInfo(m)),\n properties: cls.getProperties().map(p => this.extractPropertyInfo(p)),\n decorators: cls.getDecorators().map(d => d.getText()),\n extendsClass: cls.getExtends()?.getText(),\n implementsInterfaces: cls.getImplements().map(i => i.getText()),\n }));\n\n // Extract interfaces\n const interfaces = sourceFile.getInterfaces().map(iface => ({\n name: iface.getName(),\n properties: iface.getProperties().map(p => this.extractPropertyInfo(p)),\n extends: iface.getExtends().map(e => e.getText()),\n }));\n\n // Extract functions\n const functions = sourceFile.getFunctions().map(fn => ({\n name: fn.getName() || '<anonymous>',\n parameters: fn.getParameters().map(p => ({\n name: p.getName(),\n type: p.getType().getText(),\n isOptional: p.isOptional(),\n })),\n returnType: fn.getReturnType().getText(),\n isAsync: fn.isAsync(),\n isExported: fn.isExported(),\n }));\n\n // Extract imports\n const imports = sourceFile.getImportDeclarations().map(imp => ({\n modulePath: imp.getModuleSpecifierValue(),\n isDefault: !!imp.getDefaultImport(),\n namedImports: imp.getNamedImports().map(n => n.getName()),\n namespaceImport: imp.getNamespaceImport()?.getText(),\n }));\n\n // Extract exports\n const exports = sourceFile.getExportedDeclarations();\n const exportInfo = Array.from(exports.entries()).flatMap(([name, declarations]) =>\n declarations.map(decl => ({\n name,\n type: this.getDeclarationType(decl),\n isDefault: sourceFile.getDefaultExportSymbol()?.getName() === name,\n }))\n );\n\n return {\n classes,\n interfaces,\n functions,\n imports,\n exports: exportInfo,\n };\n }\n\n private extractMethodInfo(method: any): MethodInfo {\n return {\n name: method.getName(),\n parameters: method.getParameters().map((p: any) => ({\n name: p.getName(),\n type: p.getType().getText(),\n isOptional: p.isOptional(),\n })),\n returnType: method.getReturnType().getText(),\n isAsync: method.isAsync(),\n isStatic: method.isStatic(),\n visibility: this.getVisibility(method),\n decorators: method.getDecorators().map((d: any) => d.getText()),\n };\n }\n\n private extractPropertyInfo(property: any): PropertyInfo {\n return {\n name: property.getName(),\n type: property.getType()?.getText(),\n visibility: this.getVisibility(property),\n isReadonly: property.isReadonly(),\n initializer: property.getInitializer()?.getText(),\n };\n }\n\n private getVisibility(node: any): 'public' | 'private' | 'protected' {\n if (node.hasModifier?.(SyntaxKind.PrivateKeyword)) return 'private';\n if (node.hasModifier?.(SyntaxKind.ProtectedKeyword)) return 'protected';\n return 'public';\n }\n\n private getDeclarationType(decl: any): 'class' | 'function' | 'interface' | 'type' | 'const' {\n if (decl.getKind() === SyntaxKind.ClassDeclaration) return 'class';\n if (decl.getKind() === SyntaxKind.FunctionDeclaration) return 'function';\n if (decl.getKind() === SyntaxKind.InterfaceDeclaration) return 'interface';\n if (decl.getKind() === SyntaxKind.TypeAliasDeclaration) return 'type';\n return 'const';\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: Class Operations\n // ═══════════════════════════════════════════════════════\n\n async addClass(\n filePath: string,\n className: string,\n options?: ClassOptions\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n sourceFile.addClass({\n name: className,\n extends: options?.extendsClass,\n implements: options?.implementsInterfaces,\n isExported: true,\n });\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add class \"${className}\":`, error);\n return false;\n }\n }\n\n async addProperty(\n filePath: string,\n className: string,\n propertyCode: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n // Using insertText directly to support full property definitions\n const closeBrace = classDecl.getEnd() - 1;\n classDecl.insertText(closeBrace, `\\n ${propertyCode}`);\n\n // Reformat\n classDecl.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add property to \"${className}\":`, error);\n return false;\n }\n }\n\n async getProperty(\n filePath: string,\n className: string,\n propertyName: string\n ): Promise<string | undefined> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const property = classDecl.getProperty(propertyName);\n if (!property) {\n return undefined;\n }\n\n return property.getText();\n } catch (error) {\n console.error(`Failed to get property \"${propertyName}\":`, error);\n return undefined;\n }\n }\n\n async modifyProperty(\n filePath: string,\n className: string,\n propertyName: string,\n newCode: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const property = classDecl.getProperty(propertyName);\n if (!property) {\n throw new Error(`Property \"${propertyName}\" not found in class \"${className}\"`);\n }\n\n // Replace the entire property text\n property.replaceWithText(newCode);\n\n // Reformat\n classDecl.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to modify property \"${propertyName}\":`, error);\n return false;\n }\n }\n\n async removeProperty(\n filePath: string,\n className: string,\n propertyName: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const property = classDecl.getProperty(propertyName);\n if (!property) {\n throw new Error(`Property \"${propertyName}\" not found in class \"${className}\"`);\n }\n\n property.remove();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to remove property \"${propertyName}\":`, error);\n return false;\n }\n }\n\n async addMethod(\n filePath: string,\n className: string,\n methodCode: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n // Method code is likely \"methodName(...) { ... }\"\n // We can insert this as text.\n const closeBrace = classDecl.getEnd() - 1;\n classDecl.insertText(closeBrace, `\\n ${methodCode}\\n`);\n\n classDecl.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add method to \"${className}\":`, error);\n return false;\n }\n }\n\n async modifyMethod(\n filePath: string,\n className: string,\n methodName: string,\n newBody: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const method = classDecl.getMethod(methodName);\n if (!method) {\n throw new Error(`Method \"${methodName}\" not found in class \"${className}\"`);\n }\n\n method.setBodyText(newBody);\n\n // Optional: reformat\n method.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to modify method \"${methodName}\":`, error);\n return false;\n }\n }\n\n async removeMethod(\n filePath: string,\n className: string,\n methodName: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const method = classDecl.getMethod(methodName);\n if (!method) {\n throw new Error(`Method \"${methodName}\" not found in class \"${className}\"`);\n }\n\n method.remove();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to remove method \"${methodName}\":`, error);\n return false;\n }\n }\n\n async addDecorator(\n filePath: string,\n className: string,\n decoratorCode: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n // Robust text-based insertion\n const start = classDecl.getStart();\n // Prefix the class with the decorator\n sourceFile.insertText(start, `${decoratorCode}\\n`);\n sourceFile.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add decorator to \"${className}\":`, error);\n return false;\n }\n }\n\n async getMethod(\n filePath: string,\n className: string,\n methodName: string\n ): Promise<string | undefined> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const method = classDecl.getMethod(methodName);\n if (!method) {\n return undefined;\n }\n\n return method.getText();\n } catch (error) {\n console.error(`Failed to get method \"${methodName}\":`, error);\n return undefined;\n }\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: Interface/Type Operations\n // ═══════════════════════════════════════════════════════\n\n async addInterface(filePath: string, interfaceCode: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n // Add at the end of file\n sourceFile.insertText(sourceFile.getEnd(), `\\n\\n${interfaceCode}`);\n sourceFile.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add interface:`, error);\n return false;\n }\n }\n\n async addTypeAlias(filePath: string, typeCode: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n sourceFile.insertText(sourceFile.getEnd(), `\\n\\n${typeCode}`);\n sourceFile.formatText();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add type alias:`, error);\n return false;\n }\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: Function Operations\n // ═══════════════════════════════════════════════════════\n\n async addFunction(filePath: string, functionCode: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n sourceFile.insertText(sourceFile.getEnd(), `\\n\\n${functionCode}`);\n sourceFile.formatText();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add function:`, error);\n return false;\n }\n }\n\n async removeFunction(filePath: string, functionName: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n const func = sourceFile.getFunction(functionName);\n if (!func) {\n throw new Error(`Function \"${functionName}\" not found`);\n }\n\n func.remove();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to remove function \"${functionName}\":`, error);\n return false;\n }\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: Import/Export Operations\n // ═══════════════════════════════════════════════════════\n\n async addImport(filePath: string, importStatement: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n const lastImport = sourceFile.getImportDeclarations().pop();\n const pos = lastImport ? lastImport.getEnd() : 0;\n\n sourceFile.insertText(pos, `\\n${importStatement}`);\n\n // Organize to clean up\n this.organizeImports(filePath);\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add import:`, error);\n return false;\n }\n }\n\n async removeImport(filePath: string, modulePath: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n const importDecls = sourceFile.getImportDeclarations()\n .filter(imp => imp.getModuleSpecifierValue() === modulePath);\n\n if (importDecls.length === 0) {\n throw new Error(`Import from \"${modulePath}\" not found`);\n }\n\n importDecls.forEach(d => d.remove());\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to remove import from \"${modulePath}\":`, error);\n return false;\n }\n }\n\n async organizeImports(filePath: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n sourceFile.organizeImports();\n\n // Fallback manual just in case:\n const imports = sourceFile.getImportDeclarations();\n const importStructure = imports.map(i => i.getStructure());\n\n // Sort by module specifier\n importStructure.sort((a, b) => {\n return a.moduleSpecifier.localeCompare(b.moduleSpecifier);\n });\n\n // Remove all\n imports.forEach(i => i.remove());\n\n // Re-add\n sourceFile.addImportDeclarations(importStructure);\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to organize imports:`, error);\n return false;\n }\n }\n}\n","\nimport { Command } from 'commander';\nimport { interactiveScanAgent } from '../core/agents/scan-agent.js';\n\nexport const scanCommand = new Command('scan')\n .description('Analyze the project and generate context documentation')\n .option('-o, --output <path>', 'Output file path (default: _bmad/project-context/project-context.md)')\n .option('--depth <level>', 'Scan depth (quick, deep, exhaustive)', 'quick')\n .action(async (options) => {\n try {\n await interactiveScanAgent(options);\n } catch (error: any) {\n console.error('Error during scan:', error.message);\n process.exit(1);\n }\n });\n","\nimport { STACKSPOT_AGENT_API_BASE } from '../api/stackspot-client.js';\nimport { sseClient } from '../api/sse-client.js';\nimport { parseAgentResponse, AgentResponse } from './agent-response-parser.js';\nimport { conversationManager } from '../workflow/conversation-manager.js';\nimport { tokenStorage } from '../auth/token-storage.js';\nimport { getActiveRealm } from '../auth/get-active-realm.js';\nimport { tui } from '../../ui/tui.js';\nimport { colors } from '../../ui/colors.js';\nimport { FileLogger } from '../debug/file-logger.js';\nimport { handleListFiles, handleReadFile, handleSearchFile } from './agent-tools.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { ConfigManager } from '../config-manager.js';\nimport { t } from '../i18n/index.js';\n\nconst AGENT_TYPE = 'scan_agent';\n\nfunction getAgentId(): string {\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.scan) return config.agents.scan;\n return process.env.STACKSPOT_SCAN_AGENT_ID || '01KEQ9AHWB550J2244YBH3QATN';\n}\n\n/**\n * Scan Agent implementation.\n * It autonomously explores the project and generates project-context.md\n */\nexport async function interactiveScanAgent(options: { output?: string, depth?: string } = {}): Promise<void> {\n FileLogger.init();\n const config = ConfigManager.getInstance().getConfig();\n const language = config.language || 'English';\n\n tui.intro(t('commands.scan.intro'));\n\n const projectRoot = process.cwd();\n // Use options.output if provided, otherwise default to _sharkrc/project-context.md\n // If output option is provided, resolve it.\n // If not, use _sharkrc directory (create if needed).\n\n let outputFile: string;\n\n if (options.output) {\n outputFile = path.resolve(process.cwd(), options.output);\n } else {\n const outputDir = path.resolve(projectRoot, '_sharkrc');\n if (!fs.existsSync(outputDir)) {\n // Check if _sharkrc exists as a file (common config file name), if so, error or warn?\n // User requested \"pasta _sharkrc\".\n const stat = fs.existsSync(outputDir) ? fs.statSync(outputDir) : null;\n if (stat && stat.isFile()) {\n tui.log.warning(`Warning: '_sharkrc' exists as a file. Using '_bmad/project-context' instead to avoid overwrite.`);\n const fallbackDir = path.resolve(projectRoot, '_bmad/project-context');\n if (!fs.existsSync(fallbackDir)) fs.mkdirSync(fallbackDir, { recursive: true });\n outputFile = path.join(fallbackDir, 'project-context.md');\n } else {\n fs.mkdirSync(outputDir, { recursive: true });\n outputFile = path.join(outputDir, 'project-context.md');\n }\n } else {\n fs.mkdirSync(outputDir, { recursive: true });\n outputFile = path.join(outputDir, 'project-context.md');\n }\n }\n\n tui.log.info(`${t('commands.scan.scanningProject')} ${colors.bold(projectRoot)}`);\n tui.log.info(`${t('commands.scan.outputTarget')} ${colors.bold(outputFile)}`);\n tui.log.info(`${t('commands.scan.language')} ${colors.bold(language)}`);\n\n const configFileRelative = path.relative(projectRoot, outputFile);\n\n // Create template file automatically before starting scan\n const initialTemplate = `# Project Context\n\n## Overview\n[TO BE ANALYZED]\n\n## Tech Stack\n[TO BE ANALYZED]\n\n## Architecture\n[TO BE ANALYZED]\n\n## Directory Structure\n[TO BE ANALYZED]\n\n## Key Components\n[TO BE ANALYZED]\n\n## API / Interfaces\n[TO BE ANALYZED]\n\n## Data Layer\n[TO BE ANALYZED]\n\n## Configuration & Environment\n[TO BE ANALYZED]\n\n## Build & Development\n[TO BE ANALYZED]\n\n## Key Patterns & Conventions\n[TO BE ANALYZED]\n`;\n\n // Create the template file immediately\n if (!fs.existsSync(outputFile)) {\n const BOM = '\\uFEFF';\n fs.writeFileSync(outputFile, BOM + initialTemplate, { encoding: 'utf-8' });\n tui.log.success(`${t('commands.scan.templateCreated')} ${outputFile}`);\n } else {\n tui.log.info(t('commands.scan.fileExists'));\n }\n\n // Construct the \"Super Prompt\"\n const superPrompt = `\nYou are the **Scan Agent**, an expert software architect and analyst.\nYour mission is to explore this project's codebase THOROUGHLY and generate a COMPREHENSIVE context file that will be used by other AI agents (specifically a Developer Agent) to understand how to work on this project.\n\n**IMPORTANT**: The file \\`${configFileRelative}\\` has already been created with a template structure. Your job is to FILL IN each section by analyzing the project.\n\n**LANGUAGE INSTRUCTION**:\nYou MUST write the content in **${language}**.\n\n**CRITICAL STRATEGY - INCREMENTAL UPDATES**:\nDO NOT try to rewrite the entire file at once! Instead:\n\n1. **Explore** the project using \\`list_files\\`, \\`read_file\\`, \\`search_file\\`\n2. **Update** specific sections incrementally using \\`modify_file\\`\n3. **Benefit**: Build a MUCH MORE DETAILED document without context size limitations\n\n**WORKFLOW - FILL EACH SECTION:**\n\n**Step 1 - Analyze Tech Stack:**\n- \\`list_files\\` root directory to see project structure\n- \\`read_file\\` package.json (or pom.xml, go.mod, requirements.txt, etc.)\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Tech Stack\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Detailed tech stack with versions, dependencies, and their purposes\n\n**Step 2 - Analyze Directory Structure:**\n- \\`list_files\\` on ALL key directories (src, tests, config, docs, etc.)\n- Map the complete directory tree\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Directory Structure\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Visual directory tree with purpose of each folder\n\n**Step 3 - Analyze Architecture:**\n- \\`read_file\\` entry points (main.ts, index.js, app.py, etc.)\n- \\`read_file\\` 5-10 source files to understand code patterns and organization\n- Identify architectural pattern (Clean Arch, MVC, Microservices, etc.)\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Architecture\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Comprehensive architectural description with patterns and module organization\n\n**Step 4 - Document Components:**\n- Identify ALL major modules/components by reading source files\n- For each component: location, purpose, key files\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Key Components\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Detailed list of components with their purposes\n\n**Step 5 - Document APIs (if applicable):**\n- Search for route definitions, controllers, API endpoints\n- Document base URL, main endpoints, request/response patterns\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## API / Interfaces\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: API documentation (or \"Not applicable\" if no API)\n\n**Step 6 - Document Data Layer (if applicable):**\n- Search for database configs, ORM setup, model definitions\n- Document database type, ORM tool, key entities/tables\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Data Layer\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Data layer details (or \"Not applicable\" if no database)\n\n**Step 7 - Configuration & Environment:**\n- Read config files (.env.example, config/, etc.)\n- Identify environment variables and their purposes\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Configuration & Environment\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: List of env vars and config files\n\n**Step 8 - Build & Development:**\n- Read package.json scripts, Makefile, build configs\n- Document dev, build, test, lint commands\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Build & Development\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Commands for development workflow\n\n**Step 9 - Patterns & Conventions:**\n- Based on files read, document naming conventions, code organization\n- Note error handling, logging strategies\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Key Patterns & Conventions\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Observed patterns and conventions\n\n**Step 10 - Overview (LAST):**\n- Synthesize all findings into a comprehensive overview\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Overview\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Detailed project description with purpose and main functionality\n\n**HOW TO USE modify_file:**\n\\`\\`\\`json\n{\n \"actions\": [{\n \"type\": \"modify_file\",\n \"path\": \"${configFileRelative}\",\n \"target_content\": \"## Tech Stack\\\\n[TO BE ANALYZED]\",\n \"content\": \"## Tech Stack\\\\n- **Language**: TypeScript 5.3\\\\n- **Runtime**: Node.js 20.x\\\\n...\"\n }]\n}\n\\`\\`\\`\n\n\\`\\`\\`markdown\n# Project Context\n\n## Overview\n[TO BE ANALYZED]\n\n## Tech Stack\n[TO BE ANALYZED]\n\n## Architecture\n[TO BE ANALYZED]\n\n## Directory Structure\n[TO BE ANALYZED]\n\n## Key Components\n[TO BE ANALYZED]\n\n## API / Interfaces\n[TO BE ANALYZED]\n\n## Data Layer\n[TO BE ANALYZED]\n\n## Configuration & Environment\n[TO BE ANALYZED]\n\n## Build & Development\n[TO BE ANALYZED]\n\n## Key Patterns & Conventions\n[TO BE ANALYZED]\n\\`\\`\\`\n\n**Step 2 - Explore and Update Incrementally:**\nAfter creating the template, perform these analyses and UPDATE each section:\n\n**2.1 - Analyze Tech Stack:**\n- \\`list_files\\` root directory\n- \\`read_file\\` package.json (or equivalent manifest)\n- \\`modify_file\\` to replace \"## Tech Stack\\\\n[TO BE ANALYZED]\" with detailed findings\n\n**2.2 - Analyze Directory Structure:**\n- \\`list_files\\` on key directories (src, tests, config, etc.)\n- \\`modify_file\\` to replace \"## Directory Structure\\\\n[TO BE ANALYZED]\" with complete structure\n\n**2.3 - Analyze Architecture:**\n- \\`read_file\\` entry points (main.ts, index.js, etc.)\n- \\`read_file\\` 5-10 source files to understand patterns\n- \\`modify_file\\` to replace \"## Architecture\\\\n[TO BE ANALYZED]\" with architectural insights\n\n**2.4 - Document Components:**\n- Identify major modules/components\n- \\`modify_file\\` to replace \"## Key Components\\\\n[TO BE ANALYZED]\" with component details\n\n**2.5 - Document APIs (if applicable):**\n- Search for route definitions, controllers, API endpoints\n- \\`modify_file\\` to replace \"## API / Interfaces\\\\n[TO BE ANALYZED]\"\n\n**2.6 - Document Data Layer (if applicable):**\n- Search for database configs, ORM, models\n- \\`modify_file\\` to replace \"## Data Layer\\\\n[TO BE ANALYZED]\"\n\n**2.7 - Final Touches:**\n- Update remaining sections (Config, Build, Patterns)\n- Ensure Overview is comprehensive\n\n**HOW TO USE modify_file:**\n\\`\\`\\`json\n{\n \"actions\": [{\n \"type\": \"modify_file\",\n \"path\": \"${configFileRelative}\",\n \"target_content\": \"## Tech Stack\\\\n[TO BE ANALYZED]\",\n \"content\": \"## Tech Stack\\\\n- **Language**: TypeScript 5.3\\\\n- **Runtime**: Node.js 20.x\\\\n- **Framework**: Express 4.18\\\\n...\"\n }]\n}\n\\`\\`\\`\n\n**SECTION TEMPLATES (For your updates):**\n\n**Tech Stack:**\n\\`\\`\\`markdown\n## Tech Stack\n- **Language**: [name + version]\n- **Runtime**: [name + version]\n- **Framework**: [name + version]\n- **Build Tool**: [name]\n- **Testing**: [framework]\n- **Key Dependencies**:\n - [dep-name]: [purpose]\n - [dep-name]: [purpose]\n\\`\\`\\`\n\n**Architecture:**\n\\`\\`\\`markdown\n## Architecture\n[Comprehensive description]\n- **Pattern**: [Clean Arch, MVC, etc.]\n- **Module Organization**: [how modules are structured]\n- **Layer Separation**: [controllers, services, repos]\n- **Configuration**: [how config is managed]\n\\`\\`\\`\n\n**Directory Structure:**\n\\`\\`\\`markdown\n## Directory Structure\n\\\\\\`\\\\\\`\\\\\\`\n/src\n /core - [Purpose]\n /commands - [Purpose]\n /ui - [Purpose]\n/tests - [Purpose]\n/docs - [Purpose]\n\\\\\\`\\\\\\`\\\\\\`\n\\`\\`\\`\n\n**Key Components:**\n\\`\\`\\`markdown\n## Key Components\n\n### [Component Name 1]\n- **Location**: \\\\\\`path/to/component\\\\\\`\n- **Purpose**: [What it does]\n- **Key Files**: [Important files]\n\n### [Component Name 2]\n- **Location**: \\\\\\`path/to/component\\\\\\`\n- **Purpose**: [What it does]\n- **Key Files**: [Important files]\n\\`\\`\\`\n\n**DEPTH REQUIREMENT**:\n- Read MULTIPLE files (5-10 minimum) to understand patterns\n- Identify ALL major modules/components\n- Document API routes, database schemas if applicable\n- Note design patterns and architectural decisions\n- List important dependencies with their purposes\n\n**RULES**:\n- Create template FIRST (step 1)\n- Update sections INCREMENTALLY (steps 2-7)\n- Do NOT wait to write everything at the end\n- Use \\`modify_file\\` to replace \"[TO BE ANALYZED]\" sections\n- Be DETAILED and COMPREHENSIVE\n- Take your time - you have up to 30 steps\n- Verify facts with \\`read_file\\` or \\`search_file\\` before documenting\n`.trim();\n\n await runScanLoop(superPrompt, outputFile);\n}\n\n// ... (rest of the file)\n\nasync function runScanLoop(initialPrompt: string, targetPath: string) {\n let nextPrompt = initialPrompt;\n let keepGoing = true;\n let stepCount = 0;\n const MAX_STEPS = 60; // Safety limit - increased for deeper analysis\n\n while (keepGoing && stepCount < MAX_STEPS) {\n stepCount++;\n const spinner = tui.spinner();\n const msg = t('commands.scan.analyzing').replace('{step}', stepCount.toString());\n spinner.start(msg);\n\n let responseText = '';\n let lastResponse: AgentResponse | null = null;\n\n try {\n // Call Agent\n lastResponse = await callScanAgentApi(nextPrompt, (chunk) => {\n responseText += chunk;\n // Optional: Update spinner message based on chunk if needed\n });\n\n spinner.stop(t('commands.scan.stepComplete'));\n\n // Handle Response Actions\n if (lastResponse && lastResponse.actions && lastResponse.actions.length > 0) {\n let executionResults = \"\";\n let fileCreated = false;\n\n for (const action of lastResponse.actions) {\n if (action.type === 'list_files') {\n tui.log.info(t('commands.scan.scanningDir').replace('{0}', colors.bold(action.path || '.')));\n const result = handleListFiles(action.path || '.');\n executionResults += `[Action list_files(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'read_file') {\n tui.log.info(t('commands.scan.readingFile').replace('{0}', colors.bold(action.path || '')));\n const result = handleReadFile(action.path || '');\n // Truncate if too long for context window? Agent Tools already limits size.\n executionResults += `[Action read_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'search_file') {\n tui.log.info(t('commands.scan.searching').replace('{0}', colors.bold(action.path || '')));\n const result = handleSearchFile(action.path || '');\n executionResults += `[Action search_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'create_file' || action.type === 'modify_file') {\n // Check if this is our target file\n // The agent might try to create other files, but we mainly care about the context file.\n // We will allow it to create the target file automatically without prompt if it matches.\n\n // For safety, let's just confirm. Or since this is \"Scan\", maybe we auto-accept?\n // Let's auto-accept if it is the target file, confirm otherwise.\n const resolvedActionPath = path.resolve(action.path || '');\n const resolvedTargetPath = path.resolve(targetPath);\n let isTarget = resolvedActionPath === resolvedTargetPath;\n\n // Fallback: If agent uses wrong directory but correct filename \"project-context.md\", allow it and force correct path.\n if (!isTarget && path.basename(action.path || '') === 'project-context.md') {\n tui.log.warning(t('commands.scan.targetRedirect').replace('{0}', action.path || '').replace('{1}', path.relative(process.cwd(), targetPath)));\n isTarget = true;\n // Update action path for logging consistency (optional, but good for clarity)\n action.path = targetPath;\n }\n\n if (isTarget) {\n // Enforce writing to the correct targetPath regardless of what agent said\n const finalPath = targetPath;\n const BOM = '\\uFEFF';\n\n if (action.type === 'create_file') {\n const contentToWrite = action.content || '';\n const finalContent = contentToWrite.startsWith(BOM) ? contentToWrite : BOM + contentToWrite;\n fs.writeFileSync(finalPath, finalContent, { encoding: 'utf-8' });\n tui.log.success(t('commands.scan.generated').replace('{0}', finalPath));\n fileCreated = true;\n } else {\n // Modify Logic: Read, Replace, Write\n if (fs.existsSync(finalPath)) {\n const currentContent = fs.readFileSync(finalPath, 'utf-8');\n // action.target_content is needed for replacement\n if (action.target_content && currentContent.includes(action.target_content)) {\n const newContent = currentContent.replace(action.target_content, action.content || '');\n const finalContent = newContent.startsWith(BOM) ? newContent : BOM + newContent;\n fs.writeFileSync(finalPath, finalContent, { encoding: 'utf-8' });\n tui.log.success(t('commands.scan.updated').replace('{0}', finalPath));\n fileCreated = true;\n } else {\n // Fallback: If no target_content or target not found, what to do?\n // For Scan Agent incremental strategy, this is a failure in the prompt following.\n // We log a warning.\n tui.log.warning(t('commands.scan.error') + ': ' + t('commands.scan.contentNotFound'));\n executionResults += `[Action ${action.type}]: Failed. Target content not found in file.\\n`;\n // Continue loop to give agent a chance to fix?\n fileCreated = false;\n }\n } else {\n // File doesn't exist, treat as create?\n // But it should exist as template.\n tui.log.warning(t('commands.scan.error') + ': ' + t('commands.scan.notFound'));\n }\n }\n executionResults += `[Action ${action.type}]: Success. Task Completed.\\n`;\n } else {\n tui.log.warning(t('commands.scan.error')); // Using generic error for unexpected file write attempt\n // Skip for now to avoid side effects during scan, or ask user?\n // Let's just log it.\n executionResults += `[Action ${action.type}]: ${t('commands.scan.skipped')}\\n`;\n }\n }\n else if (action.type === 'talk_with_user') {\n tui.log.info(colors.primary(t('commands.scan.agentAsks')));\n console.log(action.content);\n // We don't really want to chat during auto-scan, but if it asks, we should probably answer or stop.\n // For now, let's stop and ask user.\n const reply = await tui.text({ message: t('commands.scan.agentInput'), placeholder: t('commands.scan.replyPlaceholder') });\n executionResults += `[User Reply]: ${reply}\\n`;\n }\n }\n\n if (fileCreated) {\n // Check for pending sections to guide the agent\n const currentContent = fs.readFileSync(targetPath, 'utf-8');\n const pendingSections: string[] = [];\n const lines = currentContent.split('\\n');\n let currentSection = '';\n\n for (const line of lines) {\n if (line.startsWith('## ')) {\n currentSection = line.substring(3).trim();\n }\n if (line.includes('[TO BE ANALYZED]')) {\n if (currentSection && !pendingSections.includes(currentSection)) {\n pendingSections.push(currentSection);\n }\n }\n }\n\n const pendingMsg = pendingSections.length > 0\n ? `\\n\\n[System Helper]: ${t('commands.scan.pendingSections').replace('{0}', pendingSections.join(', '))}`\n : `\\n\\n[System Helper]: ${t('commands.scan.allPopulated')}`;\n\n // Feed success back to agent so it can move to next section\n nextPrompt = `${executionResults}\\n\\n[System]: File updated successfully.${pendingMsg} Please continue with the next step of the analysis and focus on the pending sections.`;\n FileLogger.log('SCAN', 'Section updated, continuing loop', { step: stepCount, pending: pendingSections.length });\n } else {\n // Feed results back (could be failure or just tool output)\n nextPrompt = executionResults;\n FileLogger.log('SCAN', 'Auto-replying with results', { length: executionResults.length });\n }\n\n } else {\n // No actions? Agent considers job done.\n tui.log.success(t('commands.scan.completed'));\n keepGoing = false;\n }\n\n } catch (error: any) {\n spinner.stop(t('common.error'));\n tui.log.error(error.message);\n keepGoing = false;\n }\n }\n}\n\n\nasync function callScanAgentApi(prompt: string, onChunk: (chunk: string) => void): Promise<AgentResponse> {\n const realm = await getActiveRealm();\n const token = await tokenStorage.getToken(realm);\n if (!token) throw new Error('Not logged in');\n\n // Generate a temporary conversation ID for this scan session\n // We might not need to persist it long-term, but we need one for the session.\n // Or we rely on the one returned.\n let conversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n // If no conversation exists, that's fine, API will create one.\n\n const payload = {\n user_prompt: prompt,\n streaming: true,\n stackspot_knowledge: false,\n return_ks_in_response: true,\n use_conversation: true,\n conversation_id: conversationId\n };\n\n const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId()}/chat`;\n let fullMsg = '';\n let raw: any = {};\n\n FileLogger.log('SCAN', 'Calling API', { promptLength: prompt.length });\n\n await sseClient.streamAgentResponse(url, payload, { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, {\n onChunk: (c) => { fullMsg += c; onChunk(c); },\n onComplete: (msg, metadata) => {\n const returnedId = metadata?.conversation_id;\n raw = {\n message: msg || fullMsg,\n conversation_id: returnedId || conversationId\n };\n },\n onError: (e) => { throw e; }\n });\n\n const parsed = parseAgentResponse(raw);\n if (parsed.conversation_id) {\n await conversationManager.saveConversationId(AGENT_TYPE, parsed.conversation_id);\n }\n return parsed;\n}\n","\nimport { Command } from 'commander';\nimport { interactiveDeveloperAgent, DevelopmentResult } from '../core/agents/developer-agent.js';\nimport { TaskManager } from '../core/workflow/task-manager.js';\nimport { tui } from '../ui/tui.js';\nimport { colors } from '../ui/colors.js';\nimport { interactiveSpecificationAgent, SpecAgentOptions } from '../core/agents/specification-agent.js'; // We might need a programmatic way to call this too\n\n// We need a programmatic interface to Spec Agent for \"Pivot\". \n// For now, let's assume we can re-enter the interactive Spec Agent or we just let User edit file manually if they want major changes.\n// Or better: We instantiate Spec Agent with a specific 'instruction' to update spec.\n// Let's implement the loop first.\n\nexport const devCommand = new Command('dev')\n .description('Starts the Shark Developer Agent (Shark Dev Orchestration V2)')\n .option('-t, --task <type>', 'Initial task description (Quick Mode)')\n .option('-c, --context <path>', 'Path to custom context file')\n .action(async (options) => {\n const taskManager = new TaskManager(process.cwd());\n\n // 1. Check State\n let state = taskManager.analyzeSpecState();\n\n if (state.status === 'MISSING') {\n tui.log.warning('šŸ“‹ No tech-spec.md found.');\n const confirm = await tui.confirm({ message: 'Create a new Specification (Tech Spec)?' });\n if (confirm) {\n // Handover to Spec Agent\n await interactiveSpecificationAgent({\n briefingPath: options.task ? undefined : undefined // If task provided, maybe write a temp briefing? For now standard flow.\n });\n // Re-analyze after spec agent returns\n state = taskManager.analyzeSpecState();\n if (state.status === 'MISSING') {\n tui.log.error('āŒ Spec creation aborted or failed.');\n return;\n }\n } else {\n return;\n }\n }\n\n // 2. Orchestration Loop\n let keepOrchestrating = true;\n let burnMode = false; // \"Auto\" mode\n let contextHistory = \"\";\n\n tui.intro('🦈 Shark Orchestrator V2');\n\n while (keepOrchestrating) {\n state = taskManager.analyzeSpecState();\n\n if (state.status === 'COMPLETED') {\n tui.log.success('šŸŽ‰ All tasks in tech-spec.md are COMPLETED!');\n // Ask if they want to add more?\n const choice = await tui.select({\n message: 'What next?',\n options: [\n { value: 'exit', label: 'Exit' },\n { value: 'new_spec', label: 'New Specification (Reset)' }\n ]\n });\n if (choice === 'new_spec') {\n await interactiveSpecificationAgent();\n contextHistory = \"\"; // Reset history for new spec\n continue; // Loop again\n } else {\n keepOrchestrating = false;\n break;\n }\n }\n\n const currentTask = state.nextTask;\n if (!currentTask) {\n tui.log.error('Something went wrong. Status is not completed but no next task found.');\n break;\n }\n\n tui.log.info(`\\nšŸ‘‰ **NEXT TASK**: ${colors.bold(currentTask.description)}`);\n\n // Confirm Execution (unless Burn Mode)\n if (!burnMode) {\n const action = await tui.select({\n message: 'Orchestration Checkpoint:',\n options: [\n { value: 'execute', label: 'šŸš€ Execute Task (Start)' },\n { value: 'burn', label: 'šŸ”„ Burn Mode (Auto-Execute Remaining)' },\n { value: 'pivot', label: 'šŸ”§ Pivot/Correct (Edit Spec)' },\n { value: 'skip', label: 'ā­ļø Skip Task (Mark Done without Executing)' },\n { value: 'stop', label: 'šŸ›‘ Stop Session' }\n ]\n });\n\n if (action === 'stop') {\n keepOrchestrating = false;\n break;\n } else if (action === 'burn') {\n burnMode = true;\n } else if (action === 'skip') {\n taskManager.markTaskAsDone(currentTask.id);\n tui.log.info('Task skipped.');\n continue;\n } else if (action === 'pivot') {\n tui.log.info('Transferring control to Specification Agent...');\n // Ideally we pass context of \"Why we are pivoting\"\n await interactiveSpecificationAgent({\n initialContext: `User requested pivot after tasks:\\n${contextHistory}`\n });\n // State will be refreshed at start of loop\n continue;\n }\n }\n\n // Exceute Agent\n // Mark as IN_PROGRESS\n taskManager.markTaskInProgress(currentTask.id);\n\n tui.log.info(`⚔ Starting Micro-Context for Task: \"${currentTask.description}\"`);\n\n const result: DevelopmentResult = await interactiveDeveloperAgent({\n taskId: currentTask.id,\n taskInstruction: currentTask.description,\n history: contextHistory,\n context: options.context\n });\n\n if (result.success) {\n tui.log.success(`āœ… Task Completed: ${currentTask.description}`);\n taskManager.markTaskAsDone(currentTask.id);\n\n // Update History for next task\n contextHistory += `\\n[Task \"${currentTask.description}\" completed]: ${result.summary}`;\n } else {\n tui.log.error(`āŒ Task Failed: ${result.summary}`);\n burnMode = false; // Stop burn mode on failure\n\n const recovery = await tui.select({\n message: 'Task Failed. Recovery Action:',\n options: [\n { value: 'retry', label: 'Retry (Run Agent Again)' },\n { value: 'pivot', label: 'Pivot (Adjust Spec/Instructions)' },\n { value: 'ignore', label: 'Ignore (Mark Done anyway)' },\n { value: 'stop', label: 'Stop' }\n ]\n });\n\n if (recovery === 'stop') break;\n if (recovery === 'ignore') taskManager.markTaskAsDone(currentTask.id);\n if (recovery === 'pivot') {\n await interactiveSpecificationAgent({\n initialContext: `Task \"${currentTask.description}\" FAILED.\\nError: ${result.summary}\\nHistory:\\n${contextHistory}`\n });\n }\n // retry falls through to loop start (which re-fetches task)\n }\n }\n\n tui.outro('🦈 Orchestration Finished.');\n });\n","\nimport { STACKSPOT_AGENT_API_BASE, ensureValidToken } from '../api/stackspot-client.js';\nimport { sseClient } from '../api/sse-client.js';\nimport { parseAgentResponse, AgentResponse, AgentAction } from './agent-response-parser.js';\nimport { conversationManager } from '../workflow/conversation-manager.js';\nimport { tokenStorage } from '../auth/token-storage.js';\nimport { getActiveRealm } from '../auth/get-active-realm.js';\nimport { tui } from '../../ui/tui.js';\nimport { colors } from '../../ui/colors.js';\nimport { ConfigManager } from '../config-manager.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { FileLogger } from '../debug/file-logger.js';\nimport {\n handleListFiles,\n handleReadFile,\n handleSearchFile,\n startSmartReplace,\n replaceLineRange,\n handleRunCommand,\n astGrepSearch,\n astGrepRewrite,\n generateFilePreview,\n astListStructure,\n astAddMethod,\n astGetMethod,\n astAddClass,\n astGetProperty,\n astAddProperty,\n astRemoveProperty,\n astModifyMethod,\n astRemoveMethod,\n astAddDecorator,\n astAddInterface,\n astAddTypeAlias,\n astAddFunction,\n astRemoveFunction,\n astAddImport,\n astRemoveImport,\n astOrganizeImports,\n astModifyProperty\n} from './agent-tools.js';\nimport { t } from '../i18n/index.js';\n\nconst AGENT_TYPE = 'developer_agent';\n\n// Validation Functions\nasync function validateTypeScript(filePath: string): Promise<{ valid: boolean, error?: string }> {\n try {\n const result = await handleRunCommand(`npx tsc --noEmit --skipLibCheck ${filePath}`);\n if (result.trim() === '' || !result.includes('error TS')) {\n return { valid: true };\n }\n return { valid: false, error: result };\n } catch (e: any) {\n return { valid: false, error: e.message || 'TypeScript validation failed' };\n }\n}\n\nfunction validateHtmlTagBalance(filePath: string): { valid: boolean, error?: string } {\n const content = fs.readFileSync(filePath, 'utf-8');\n const stack: string[] = [];\n const tagRegex = /<\\/?(\\w+)(?:\\s[^>]*)?\\s*\\/?>/g;\n const selfClosingTags = ['br', 'hr', 'img', 'input', 'meta', 'link', 'area', 'base', 'col', 'embed', 'param', 'source', 'track', 'wbr'];\n\n let match;\n while ((match = tagRegex.exec(content)) !== null) {\n const fullTag = match[0];\n const tagName = match[1].toLowerCase();\n\n if (fullTag.startsWith('</')) {\n const expected = stack.pop();\n if (expected !== tagName) {\n return {\n valid: false,\n error: `Tag mismatch: expected </${expected}> but found </${tagName}> at position ${match.index}`\n };\n }\n } else if (!fullTag.endsWith('/>') && !selfClosingTags.includes(tagName)) {\n stack.push(tagName);\n }\n }\n\n if (stack.length > 0) {\n return { valid: false, error: `Unclosed tags: <${stack.join('>, <')}>` };\n }\n\n return { valid: true };\n}\n\n// Helper to get effective Agent ID\nfunction getAgentId(overrideId?: string): string {\n if (overrideId) return overrideId;\n\n // Check Config\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.dev) return config.agents.dev;\n\n // Check Env\n if (process.env.STACKSPOT_DEV_AGENT_ID) return process.env.STACKSPOT_DEV_AGENT_ID;\n\n // Default\n return '01KEQCGJ65YENRA4QBXVN1YFFX';\n}\n\ninterface SpecState {\n status: 'MISSING' | 'PENDING' | 'COMPLETED';\n nextTask?: string;\n specContent?: string;\n}\n\nfunction analyzeSpecState(projectRoot: string): SpecState {\n const specPath = path.resolve(projectRoot, 'tech-spec.md');\n if (!fs.existsSync(specPath)) {\n return { status: 'MISSING' };\n }\n\n const content = fs.readFileSync(specPath, 'utf-8');\n // Regex for unchecked task: - [ ] Task description\n // Capture the line content - simple regex, can be improved for nested lists if needed\n const match = content.match(/- \\[ \\] (.*)/);\n\n if (match) {\n return { status: 'PENDING', nextTask: match[1].trim(), specContent: content };\n }\n\n return { status: 'COMPLETED', specContent: content };\n}\n\nfunction buildSystemPrompt(state: SpecState, contextContent: string, additionalInstructions: string = ''): string {\n let basePrompt = ``;\n\n if (contextContent) {\n basePrompt += `\\n\\n--- PROJECT CONTEXT ---\\n${contextContent}\\n-----------------------\\n`;\n }\n\n if (state.status === 'MISSING') {\n basePrompt += `\\n\\n🚨 CRITICAL: NO 'tech-spec.md' FOUND.\\n\nYour FIRST priority is to analyze the user request and CREATE a 'tech-spec.md' file.\n\nāš ļø WORKFLOW:\n1. **Understand**: Clarify the goal with the user if needed.\n2. **Explore**: Use 'list_files'/'read_file' to find RELEVANT files for this specific task.\n3. **Specify**: Create 'tech-spec.md' referencing REAL file paths you found.\n\nDO NOT create a spec based on guesses. Verify file existence before writing the plan.\n\nStructure for 'tech-spec.md':\n\\`\\`\\`markdown\n# Technical Spec: [Title]\n\n## Goal\n[Brief description]\n\n## Implementation Plan\n- [ ] Step 1: [Description]\n- [ ] Step 2: [Description]\n...\n\\`\\`\\`\nUser Request: \"${additionalInstructions}\"\n`;\n } else if (state.status === 'PENDING') {\n basePrompt += `\\n\\n🟢 EXECUTION MODE\\n\nUse 'tech-spec.md' as your source of truth.\n\\nšŸ‘‰ **CURRENT TASK**: \"${state.nextTask}\"\n\\n\nFocus ONLY on this task. Do not jump ahead.\n1. Implement the necessary changes.\n2. Verify (compile/test).\n3. **MANDATORY**: Use 'modify_file' to mark this task as '[x]' in 'tech-spec.md' when done.\n`;\n } else {\n basePrompt += `\\n\\n✨ ALL TASKS COMPLETED according to 'tech-spec.md'.\\n\nAsk the user if they want to add more tasks or finish the session.\n`;\n }\n\n return basePrompt;\n}\n\n\nexport interface DevelopmentResult {\n success: boolean;\n summary: string;\n}\n\nexport async function interactiveDeveloperAgent(options: {\n taskId?: string,\n taskInstruction?: string,\n context?: string,\n history?: string\n} = {}): Promise<DevelopmentResult> {\n FileLogger.init();\n // tui.intro('🦈 Shark Dev Agent (Scoped)'); // Reduced verbosity for orchestration loop\n\n const agentId = getAgentId();\n\n if (agentId === 'PENDING_CONFIGURATION') {\n tui.log.error('āŒ STACKSPOT_DEV_AGENT_ID not configured in .env');\n return { success: false, summary: \"Missing configuration.\" };\n }\n\n // 1. Load Context\n const projectRoot = process.cwd();\n let contextContent = '';\n const defaultContextPath = path.resolve(projectRoot, '_sharkrc', 'project-context.md');\n // If orchestrator passes the summary of previous tasks, we append it to context\n const specificContextPath = options.context ? path.resolve(projectRoot, options.context) : defaultContextPath;\n\n if (fs.existsSync(specificContextPath)) {\n try {\n contextContent = fs.readFileSync(specificContextPath, 'utf-8');\n // tui.log.info(`šŸ“˜ Context loaded from: ${colors.dim(path.relative(projectRoot, specificContextPath))}`);\n } catch (e) {\n tui.log.warning(`Failed to read context file: ${e}`);\n }\n }\n\n // 2. Build Scoped Prompt\n // Note: We are NOT calling analyzeSpecState here anymore. The Orchestrator tells us WHAT to do.\n const currentTask = options.taskInstruction || \"Analyze the project and fix pending issues.\";\n\n let basePrompt = ``;\n if (contextContent) {\n basePrompt += `\\n\\n--- PROJECT CONTEXT ---\\n${contextContent}\\n-----------------------\\n`;\n }\n\n // Inject History from previous turns (Orchestrator Responsibility)\n if (options.history) {\n basePrompt += `\\n\\n--- PREVIOUS EXECUTION SUMMARY ---\\n${options.history}\\n----------------------------------\\n`;\n }\n\n basePrompt += `\\n\\n🟢 EXECUTION MODE\\n\nYou are a highly skilled Developer Agent.\nšŸ‘‰ **CURRENT TASK**: \"${currentTask}\"\n\nYour goal is to COMPLETE this specific task and then STOP.\n1. Implement the necessary changes.\n2. Verify (compile/test).\n3. **MANDATORY**: When you are confident the task is done, output a final message starting with \"TASK_COMPLETED:\" followed by a brief technical summary of what you did.\n`;\n\n let nextPrompt = basePrompt;\n\n // 3. Main Loop\n let keepGoing = true;\n const spinner = tui.spinner();\n let finalSummary = \"\";\n let isTaskCompleted = false;\n\n // Force NEW Conversation ID for Statelessness\n // We update the conversation manager to a random ID or based on TaskID\n // To ensure we don't pollute the global 'developer_agent' state if we want true statelessness.\n // Ideally, we pass a specific conversation ID Key.\n const conversationKey = options.taskId ? `dev_agent_${options.taskId}` : `dev_agent_${Date.now()}`;\n // Resetting for safety if repeated calls\n // await conversationManager.saveConversationId(conversationKey, \"\"); \n\n // Auto-Approval State\n let autoApprovals = {\n files: false,\n commands: false\n };\n\n while (keepGoing) {\n try {\n spinner.start('🦈 Shark Dev working...');\n\n // Call API\n const lastResponse = await callDevAgentApi(nextPrompt, (chunk) => {\n // Optional: Stream text\n }, conversationKey);\n\n spinner.stop('Response received');\n\n if (lastResponse) {\n const response = lastResponse;\n const actions = response.actions || []; // Should be array by schema, but safe fallback\n\n // Check Global Message first (e.g. Completion or Failure)\n if (response.message && response.message.includes('TASK_COMPLETED:')) {\n isTaskCompleted = true;\n finalSummary = response.message.split('TASK_COMPLETED:')[1].trim();\n // We continue to process actions if any, but stop loop after\n keepGoing = false;\n }\n\n // Check for explicit task failure signal from agent\n if (response.message && response.message.includes('TASK_FAILED:')) {\n const failureReason = response.message.split('TASK_FAILED:')[1].trim();\n tui.log.error(`āŒ Agent reported task failure: ${failureReason}`);\n return { success: false, summary: failureReason };\n }\n\n // If we have just a message and NO actions (or empty actions), treat as talk\n if (actions.length === 0 && response.message && !isTaskCompleted) {\n tui.log.info(colors.primary('šŸ¤– Shark Dev:'));\n console.log(response.message);\n const userReply = await tui.text({ message: 'Your answer:' });\n if (tui.isCancel(userReply)) { keepGoing = false; break; }\n nextPrompt = userReply as string;\n }\n\n let executionResults = \"\";\n let waitingForUser = false;\n\n for (const action of actions) {\n\n // ... (Existing Tool Handling Logic - reusing almost 1:1, just cleaner logging) ...\n // [Optimization: I will minimize the copy-paste here by keeping the core logic but ensuring it writes to executionResults]\n\n if (action.type === 'talk_with_user') {\n tui.log.info(colors.primary('šŸ¤– Shark Dev:'));\n console.log(action.content);\n // If agent talks, we might need input. \n // In stateless mode, if it asks a question, we might bubble it up?\n // For now, let's keep the TUI interaction valid.\n if (!isTaskCompleted) waitingForUser = true;\n }\n\n // ... (Include all tool handlers from original code: list_files, read_file, run_command, modify_file, ast_*, etc.) ...\n // To avoid a massive edit block that might break, I will assume the original tool handlers logic is robust.\n // I will reinject strictly the necessary parts. \n // [Developer Note: For the sake of this edit, I have to replicate the tool logic to ensure the function works. \n // I'll condense the logging.]\n\n else if (action.type === 'list_files') {\n tui.log.info(`šŸ“‚ Scanning: ${colors.dim(action.path || '.')}`);\n const result = handleListFiles(action.path || '.');\n executionResults += `[Action list_files(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'read_file') {\n tui.log.info(`šŸ“– Reading: ${colors.dim(action.path || '')}`);\n const result = handleReadFile(action.path || '');\n executionResults += `[Action read_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'search_file') {\n const result = handleSearchFile(action.path || '');\n executionResults += `[Action search_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'run_command') {\n const cmd = action.command || '';\n tui.log.info(`šŸ’» Executing: ${colors.dim(cmd)}`);\n // Auto-approval logic reuse\n let approved = autoApprovals.commands;\n if (!approved) {\n const choice = await tui.select({\n message: `Execute: ${cmd}?`,\n options: [{ value: 'yes', label: 'Yes' }, { value: 'always', label: 'Yes (Auto-Approve Session)' }, { value: 'no', label: 'No' }]\n });\n if (choice === 'always') { autoApprovals.commands = true; approved = true; }\n else if (choice === 'yes') approved = true;\n }\n if (approved) {\n const result = await handleRunCommand(cmd);\n executionResults += `[Action run_command(${cmd}) Result]:\\n${result}\\n\\n`;\n } else {\n executionResults += `[Action run_command]: User blocked execution.\\n\\n`;\n }\n }\n else if (['create_file', 'modify_file'].includes(action.type)) {\n const filePath = action.path || '';\n tui.log.warning(`šŸ“ ${action.type === 'create_file' ? 'CREATE' : 'MODIFY'}: ${colors.bold(filePath)}`);\n\n let approved = autoApprovals.files;\n if (!approved) {\n const choice = await tui.select({\n message: `Approve changes to ${filePath}?`,\n options: [{ value: 'yes', label: 'Yes' }, { value: 'always', label: 'Yes (Auto-Approve Session)' }, { value: 'no', label: 'No' }]\n });\n if (choice === 'always') { autoApprovals.files = true; approved = true; }\n else if (choice === 'yes') approved = true;\n }\n\n if (approved) {\n // ... (Perform Write) ...\n if (action.type === 'create_file') {\n // Simple Create Logic\n const dir = path.dirname(path.resolve(projectRoot, filePath));\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.resolve(projectRoot, filePath), action.content || '', 'utf-8');\n executionResults += `[Action create_file]: Success\\n\\n`;\n } else {\n // Modify Logic\n let success = false;\n if (action.line_range) success = replaceLineRange(filePath, action.line_range[0], action.line_range[1], action.content || '', tui);\n else if (action.target_content) success = startSmartReplace(filePath, action.content || '', action.target_content, tui);\n\n executionResults += success ? `[Action modify_file]: Success\\n\\n` : `[Action modify_file]: Failed\\n\\n`;\n }\n // Validation hooks can be re-added here similar to original\n const val = await validateTypeScript(path.resolve(projectRoot, filePath));\n if (!val.valid) executionResults += `[Validation Failed]: ${val.error}\\n\\n`;\n } else {\n executionResults += `[Action ${action.type}]: User Denied.\\n\\n`;\n }\n }\n // ... (AST Actions would follow similar pattern) ...\n else if (action.type.startsWith('ast_')) {\n try {\n // AST Tools Mapping (Async)\n let result = '';\n if (action.type === 'ast_list_structure') {\n result = await astListStructure(action.path || '');\n }\n else if (action.type === 'ast_get_method') {\n result = await astGetMethod(action.path || '', action.class_name || '', action.method_name || '');\n }\n else if (action.type === 'ast_add_method') {\n const success = await astAddMethod(action.path || '', action.class_name || '', action.method_code || '');\n result = success ? 'Method added successfully.' : 'Failed to add method.';\n }\n else if (action.type === 'ast_modify_method') {\n const success = await astModifyMethod(action.path || '', action.class_name || '', action.method_name || '', action.new_body || '');\n result = success ? 'Method modified successfully.' : 'Failed to modify method.';\n }\n else if (action.type === 'ast_remove_method') {\n const success = await astRemoveMethod(action.path || '', action.class_name || '', action.method_name || '');\n result = success ? 'Method removed successfully.' : 'Failed to remove method.';\n }\n else if (action.type === 'ast_add_class') {\n const success = await astAddClass(action.path || '', action.class_name || '', action.extends_class || undefined, action.implements_interfaces || undefined);\n result = success ? 'Class added successfully.' : 'Failed to add class.';\n }\n else if (action.type === 'ast_get_property') {\n tui.log.info(`šŸ” Reading property ${colors.gray(action.property_name || '')} in ${colors.gray(action.class_name || '')}`);\n const propContent = await astGetProperty(action.path || '', action.class_name || '', action.property_name || '');\n result = `[AST Get Property] Content:\\n${propContent}`;\n }\n else if (action.type === 'ast_add_property') {\n const success = await astAddProperty(action.path || '', action.class_name || '', action.property_code || '');\n result = success ? 'Property added successfully.' : 'Failed to add property.';\n }\n else if (action.type === 'ast_modify_property') {\n tui.log.info(`āœļø Modifying property ${colors.gray(action.property_name || '')} in ${colors.gray(action.class_name || '')}`);\n // Note: property_code here is the NEW full property definition\n const success = await astModifyProperty(action.path || '', action.class_name || '', action.property_name || '', action.property_code || '');\n result = success ? 'Property modified successfully.' : 'Failed to modify property.';\n }\n else if (action.type === 'ast_remove_property') {\n const success = await astRemoveProperty(action.path || '', action.class_name || '', action.property_name || '');\n result = success ? 'Property removed successfully.' : 'Failed to remove property.';\n }\n else if (action.type === 'ast_add_decorator') {\n // Tool only supports class decorators for now\n const success = await astAddDecorator(action.path || '', action.class_name || '', action.decorator_code || '');\n result = success ? 'Decorator added successfully.' : 'Failed to add decorator.';\n }\n else if (action.type === 'ast_add_interface') {\n const success = await astAddInterface(action.path || '', action.interface_code || '');\n result = success ? 'Interface added successfully.' : 'Failed to add interface.';\n }\n else if (action.type === 'ast_add_type_alias') {\n const success = await astAddTypeAlias(action.path || '', action.type_code || '');\n result = success ? 'Type alias added successfully.' : 'Failed to add type alias.';\n }\n else if (action.type === 'ast_add_function') {\n const success = await astAddFunction(action.path || '', action.function_code || '');\n result = success ? 'Function added successfully.' : 'Failed to add function.';\n }\n else if (action.type === 'ast_remove_function') {\n const success = await astRemoveFunction(action.path || '', action.function_name || '');\n result = success ? 'Function removed successfully.' : 'Failed to remove function.';\n }\n else if (action.type === 'ast_add_import') {\n const success = await astAddImport(action.path || '', action.import_statement || '');\n result = success ? 'Import added successfully.' : 'Failed to add import.';\n }\n else if (action.type === 'ast_remove_import') {\n const success = await astRemoveImport(action.path || '', action.module_path || '');\n result = success ? 'Import removed successfully.' : 'Failed to remove import.';\n }\n else if (action.type === 'ast_organize_imports') {\n const success = await astOrganizeImports(action.path || '');\n result = success ? 'Imports organized successfully.' : 'Failed to organize imports.';\n }\n else {\n result = `Unknown AST action: ${action.type}`;\n }\n\n executionResults += `[Action ${action.type} Result]:\\n${result}\\n\\n`;\n tui.log.info(`⚔ AST Action ${colors.dim(action.type)}: ${result}`);\n\n } catch (e: any) {\n executionResults += `[Action ${action.type} Failed]: ${e.message}\\n\\n`;\n tui.log.error(`āŒ AST Action Error: ${e.message}`);\n }\n }\n else if (action.type === 'search_ast') {\n const result = await astGrepSearch(action.pattern || '', action.path || '', action.language || 'typescript', tui);\n executionResults += `[Action search_ast Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'modify_ast') {\n const success = await astGrepRewrite(action.pattern || '', action.fix || '', action.path || '', action.language || 'typescript', tui);\n executionResults += success ? `[Action modify_ast]: Success\\n\\n` : `[Action modify_ast]: Failed\\n\\n`;\n }\n } // End Action Loop\n\n // Determine Next Prompt\n if (executionResults) {\n if (waitingForUser) {\n const userReply = await tui.text({ message: 'Your answer:' });\n if (tui.isCancel(userReply)) { keepGoing = false; break; }\n nextPrompt = `${executionResults}\\nUser Reply: ${userReply}`;\n } else {\n nextPrompt = `${executionResults}\\n[System]: Continue execution. If finished, output \"TASK_COMPLETED: summary\".`;\n tui.log.info(colors.dim('Processing results...'));\n }\n } else if (!keepGoing) {\n // Task completed or stopped\n } else if (waitingForUser) {\n // handled above in message fallback\n } else {\n if (!isTaskCompleted && actions.length > 0) nextPrompt = \"Please continue.\";\n }\n\n } else {\n tui.log.warning('No response received from agent.');\n }\n\n } catch (e: any) {\n tui.log.error(e.message);\n keepGoing = false;\n return { success: false, summary: `Error: ${e.message}` };\n }\n }\n\n tui.log.success('āœ… Task Scope Completed');\n return { success: true, summary: finalSummary || \"Task completed without summary.\" };\n}\n\n// Helper to support key-based conversation\nasync function callDevAgentApi(prompt: string, onChunk: (chunk: string) => void, conversationKey: string = AGENT_TYPE): Promise<AgentResponse> {\n const realm = await getActiveRealm();\n const token = await ensureValidToken(realm);\n\n // Get specific conversation ID for this TASK\n const conversationId = await conversationManager.getConversationId(conversationKey);\n\n const payload = {\n user_prompt: prompt,\n streaming: true,\n use_conversation: true,\n conversation_id: conversationId,\n stackspot_knowledge: false\n };\n\n const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId()}/chat`;\n let fullMsg = '';\n let raw: any = {};\n\n await sseClient.streamAgentResponse(url, payload, { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, {\n onChunk: (c) => { fullMsg += c; onChunk(c); },\n onComplete: (msg, metadata) => {\n const returnedId = metadata?.conversation_id;\n raw = {\n message: msg || fullMsg,\n conversation_id: returnedId || conversationId\n };\n },\n onError: (e) => { throw e; }\n });\n\n const parsed = parseAgentResponse(raw);\n if (parsed.conversation_id) {\n await conversationManager.saveConversationId(conversationKey, parsed.conversation_id);\n }\n return parsed;\n}\n\n","\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface SpecTask {\n id: string; // generated based on index (e.g., \"task-1\")\n description: string;\n status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED';\n line_number: number; // 0-based line index in the file\n}\n\nexport interface SpecState {\n status: 'MISSING' | 'PENDING' | 'COMPLETED';\n nextTask?: SpecTask;\n allTasks: SpecTask[];\n}\n\nexport class TaskManager {\n private projectRoot: string;\n private specPath: string;\n\n constructor(projectRoot: string = process.cwd()) {\n this.projectRoot = projectRoot;\n this.specPath = path.resolve(this.projectRoot, 'tech-spec.md');\n }\n\n /**\n * Reads the tech-spec.md file and analyzes its current state.\n */\n public analyzeSpecState(): SpecState {\n if (!fs.existsSync(this.specPath)) {\n return { status: 'MISSING', allTasks: [] };\n }\n\n const content = fs.readFileSync(this.specPath, 'utf-8');\n const lines = content.split('\\n');\n const tasks: SpecTask[] = [];\n\n let taskIndex = 1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n const pendingMatch = trimmed.match(/^- \\[ \\] (.*)/);\n const completedMatch = trimmed.match(/^- \\[x\\] (.*)/i);\n const progressMatch = trimmed.match(/^- \\[\\/\\] (.*)/);\n\n let currentTask: SpecTask | null = null;\n let status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | null = null;\n let description = '';\n\n if (pendingMatch) {\n description = pendingMatch[1].trim();\n status = 'PENDING';\n } else if (completedMatch) {\n description = completedMatch[1].trim();\n status = 'COMPLETED';\n } else if (progressMatch) {\n description = progressMatch[1].trim();\n status = 'IN_PROGRESS';\n }\n\n if (status && description) {\n // Look ahead for sub-bullets or details\n let j = i + 1;\n while (j < lines.length) {\n const nextLine = lines[j];\n const nextTrimmed = nextLine.trim();\n // Stop if next line is empty, a new task, or a new section\n if (!nextTrimmed || nextTrimmed.match(/^- \\[[ x\\/]\\]/) || nextTrimmed.startsWith('#')) {\n break;\n }\n description += '\\n' + nextTrimmed;\n j++;\n }\n\n currentTask = {\n id: `task-${taskIndex++}`,\n description: description,\n status: status,\n line_number: i\n };\n tasks.push(currentTask);\n }\n }\n\n // Determine next actionable task\n // Priority: IN_PROGRESS -> First PENDING\n let nextTask = tasks.find(t => t.status === 'IN_PROGRESS');\n if (!nextTask) {\n nextTask = tasks.find(t => t.status === 'PENDING');\n }\n\n const status = (!nextTask && tasks.length > 0 && tasks.every(t => t.status === 'COMPLETED'))\n ? 'COMPLETED'\n : 'PENDING';\n\n return {\n status: tasks.length === 0 ? 'MISSING' : status, // Empty file is effectively \"pending creation\" but we treat as missing content logic elsewhere\n nextTask,\n allTasks: tasks\n };\n }\n\n /**\n * Marks a specific task as COMPLETED in the file.\n * Uses line-based replacement to be safe.\n */\n public markTaskAsDone(taskId: string): boolean {\n const state = this.analyzeSpecState();\n const task = state.allTasks.find(t => t.id === taskId);\n\n if (!task) {\n console.error(`Task ${taskId} not found.`);\n return false;\n }\n\n const content = fs.readFileSync(this.specPath, 'utf-8');\n const lines = content.split('\\n');\n\n // Verify line content hasn't drifted (sanity check)\n const targetLine = lines[task.line_number];\n if (!targetLine.includes(task.description)) {\n console.error(`Concurrency Error: Task line content mistmatch. Expected \"${task.description}\" at line ${task.line_number}.`);\n // Fallback: search for the task description again\n // This is simple recovery, in a real DB we'd use IDs.\n return false;\n }\n\n // Replace [ ], [/] with [x]\n const newLine = targetLine\n .replace('- [ ]', '- [x]')\n .replace('- [/]', '- [x]');\n\n lines[task.line_number] = newLine;\n\n fs.writeFileSync(this.specPath, lines.join('\\n'), 'utf-8');\n return true;\n }\n\n /**\n * Marks a task as IN_PROGRESS.\n */\n public markTaskInProgress(taskId: string): boolean {\n const state = this.analyzeSpecState();\n const task = state.allTasks.find(t => t.id === taskId);\n\n if (!task) return false;\n\n const content = fs.readFileSync(this.specPath, 'utf-8');\n const lines = content.split('\\n');\n\n let targetLine = lines[task.line_number];\n\n // Replace [ ] with [/]\n targetLine = targetLine.replace('- [ ]', '- [/]');\n\n lines[task.line_number] = targetLine;\n fs.writeFileSync(this.specPath, lines.join('\\n'), 'utf-8');\n return true;\n }\n\n /**\n * Completely updates the spec file content (used by Spec Agent).\n */\n public updateSpecContent(newContent: string): void {\n fs.writeFileSync(this.specPath, newContent, 'utf-8');\n }\n\n public getSpecPath(): string {\n return this.specPath;\n }\n}\n","import { Command } from 'commander';\nimport { runQAAgent } from '../core/agents/qa-agent.js';\n\nexport const qaCommand = new Command('qa')\n .description('Start the Shark QA Agent to test web applications')\n .option('--url <url>', 'Initial URL to test')\n .option('--scenario <scenario>', 'Scenario description or test case to execute')\n .action(async (options) => {\n try {\n await runQAAgent({\n initialUrl: options.url,\n scenario: options.scenario\n });\n } catch (error: any) {\n console.error('Failed to run QA Agent:', error.message);\n process.exit(1);\n }\n });\n","import { tui } from '../../ui/tui';\nimport { colors } from '../../ui/colors';\nimport { getActiveRealm } from '../auth/get-active-realm';\nimport { tokenStorage } from '../auth/token-storage';\nimport { sseClient } from '../api/sse-client';\nimport { parseAgentResponse, AgentAction, AgentResponse } from './agent-response-parser';\nimport { conversationManager } from '../workflow/conversation-manager';\nimport { handleReadFile, handleListFiles, handleSearchFile, handleRunCommand } from './agent-tools';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { ConfigManager } from '../config-manager';\n\nconst AGENT_TYPE = 'qa_agent';\n\nfunction getAgentId(): string {\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.qa) return config.agents.qa;\n return process.env.STACKSPOT_QA_AGENT_ID || '01KEQFJZ3Q3JER11NH22HEZX9X';\n}\n\ninterface QAAgentOptions {\n initialUrl?: string;\n scenario?: string;\n}\n\n// MCP Client Wrapper\nclass ChromeDevToolsClient {\n private client: Client | null = null;\n private transport: StdioClientTransport | null = null;\n\n async connect() {\n if (this.client) return;\n\n try {\n this.transport = new StdioClientTransport({\n command: 'npx',\n args: ['-y', 'chrome-devtools-mcp@latest']\n });\n\n this.client = new Client({\n name: \"shark-qa-client\",\n version: \"1.0.0\"\n }, {\n capabilities: {}\n });\n\n await this.client.connect(this.transport);\n tui.log.success('šŸ”Œ Connected to Chrome DevTools MCP');\n } catch (e: any) {\n tui.log.error(`Failed to connect to Chrome MCP: ${e.message}`);\n throw e;\n }\n }\n\n async callTool(name: string, args: any) {\n if (!this.client) await this.connect();\n try {\n const result = await this.client!.callTool({\n name,\n arguments: args\n });\n return result;\n } catch (e: any) {\n return { isError: true, content: [{ type: 'text', text: `MCP Error: ${e.message}` }] };\n }\n }\n\n async close() {\n if (this.transport) {\n await this.transport.close();\n }\n }\n}\n\nconst mcpClient = new ChromeDevToolsClient();\n\nexport async function runQAAgent(options: QAAgentOptions) {\n const agentId = getAgentId();\n\n if (!agentId) {\n tui.log.error('āŒ STACKSPOT_QA_AGENT_ID not configured.');\n tui.log.info('Please run: set STACKSPOT_QA_AGENT_ID=<your-id>');\n return;\n }\n\n // Connect to MCP at start\n await mcpClient.connect();\n\n tui.intro('🦈 Shark QA Agent');\n tui.log.info('Connecting to Chrome DevTools...');\n\n const realm = await getActiveRealm();\n const token = await tokenStorage.getToken(realm);\n\n if (!token) {\n tui.log.error('Authentication required. Run \"shark login\".');\n return;\n }\n\n // 1. Prepare Initial Context\n let projectContext = \"\";\n try {\n const contextPath = path.join(process.cwd(), '_sharkrc', 'project-context.md');\n if (fs.existsSync(contextPath)) {\n projectContext = fs.readFileSync(contextPath, 'utf-8');\n tui.log.info(`šŸ“˜ Context loaded from: _sharkrc/project-context.md`);\n }\n } catch (e) {\n // Ignore if no context\n }\n\n let userMessage = `CONTEXTO DO PROJETO:\\n${projectContext}\\n\\n`;\n\n if (options.initialUrl) {\n userMessage += `URL ALVO: ${options.initialUrl}\\n`;\n }\n if (options.scenario) {\n userMessage += `CENƁRIO DE TESTE: ${options.scenario}\\n`;\n } else {\n userMessage += `Por favor, aguarde instruƧƵes do usuĆ”rio.`;\n }\n\n // 2. Interaction Loop\n let keepRunning = true;\n\n while (keepRunning) {\n const spinner = tui.spinner();\n spinner.start('šŸ¤– Shark QA is thinking...');\n\n let agentResponseText = \"\";\n let agentResponse: AgentResponse | null = null;\n\n try {\n // API Interaction (Manual Call until AgentManager is unified)\n const existingConversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n await sseClient.streamAgentResponse(\n `https://genai-inference-app.stackspot.com/v1/agent/${getAgentId()}/chat`,\n {\n user_prompt: userMessage,\n streaming: true,\n use_conversation: true,\n conversation_id: existingConversationId\n },\n {\n 'Authorization': `Bearer ${token}`\n },\n {\n onChunk: (chunk) => {\n agentResponseText += chunk;\n if (agentResponseText.length > 10 && agentResponseText.trim().startsWith('{')) {\n spinner.message('Receiving structured plan...');\n }\n },\n onComplete: (fullText, metadata) => {\n try {\n if (metadata?.conversation_id) {\n conversationManager.saveConversationId(AGENT_TYPE, metadata.conversation_id);\n }\n agentResponse = parseAgentResponse(fullText || agentResponseText);\n } catch (e) {\n tui.log.error(`Parse Error: ${(e as Error).message}`);\n agentResponse = { actions: [], summary: \"Error parsing response\", message: fullText };\n }\n }\n }\n );\n\n spinner.stop('Response Received');\n\n } catch (error) {\n spinner.stop('Communication Error', 1);\n tui.log.error((error as Error).message);\n keepRunning = false;\n break;\n }\n\n if (!agentResponse) continue;\n\n // 3. Handle Actions\n if (agentResponse.summary) {\n tui.log.info(colors.primary(`šŸ“‹ Plan: ${agentResponse.summary}`));\n }\n\n if (agentResponse.actions.length === 0) {\n // No actions usually means it's waiting for user or finished\n const reply = await tui.text({\n message: \"šŸ¤– Shark QA:\",\n placeholder: \"Your reply...\"\n });\n\n if (tui.isCancel(reply)) {\n keepRunning = false;\n } else {\n userMessage = reply as string;\n }\n continue;\n }\n\n for (const action of agentResponse.actions) {\n tui.log.info(colors.dim(`Executing: ${action.type}`));\n\n let result = \"\";\n\n try {\n switch (action.type) {\n case 'talk_with_user':\n const reply = await tui.text({\n message: `šŸ¤– ${action.content}`,\n });\n if (tui.isCancel(reply)) keepRunning = false;\n else result = reply as string;\n break;\n\n case 'use_mcp_tool':\n if (action.tool_name) {\n tui.log.info(`šŸ”§ MCP Tool: ${colors.bold(action.tool_name)}`);\n let args = {};\n try {\n args = typeof action.tool_args === 'string'\n ? JSON.parse(action.tool_args)\n : (action.tool_args || {});\n } catch (e) {\n tui.log.warning('Failed to parse tool_args, using empty object');\n }\n const mcpResult = await mcpClient.callTool(action.tool_name, args);\n result = JSON.stringify(mcpResult);\n // Brief preview\n tui.log.success(`Result: ${result.substring(0, 100)}...`);\n }\n break;\n\n case 'create_file':\n if (action.path && action.content) {\n const fullPath = path.resolve(process.cwd(), action.path);\n const BOM = '\\uFEFF';\n const contentToWrite = action.content;\n const finalContent = contentToWrite.startsWith(BOM) ? contentToWrite : BOM + contentToWrite;\n fs.writeFileSync(fullPath, finalContent, { encoding: 'utf-8' });\n tui.log.success(`File created: ${action.path}`);\n result = \"File created successfully.\";\n }\n break;\n\n case 'read_file':\n result = handleReadFile(action.path || '');\n break;\n\n case 'run_command':\n // Safety check?\n const confirm = await tui.confirm({ message: `Run command: ${action.command}?` });\n if (confirm && action.command) {\n result = await handleRunCommand(action.command);\n } else {\n result = \"Command execution denied by user.\";\n }\n break;\n\n default:\n result = `Action ${action.type} not fully implemented in local client.`;\n }\n } catch (e: any) {\n result = `Error executing ${action.type}: ${e.message}`;\n tui.log.error(result);\n }\n\n // Feed result back to agent\n userMessage = `[Action ${action.type} Result]:\\n${result}\\n\\n`;\n }\n }\n\n await mcpClient.close();\n tui.outro('🦈 Shark QA Session Ended');\n}\n"],"mappings":"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","names":["Command","fs","path","path","fs","z","z","fs","path","fs","path","path","path","fs","path","fs","tui","tui","fs","resolve","path","AGENT_TYPE","getAgentId","path","fs","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","Command","Command","fs","path","AGENT_TYPE","getAgentId","getAgentId","path","fs","AGENT_TYPE","fs","path","status","t","Command","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","Command","Command"]}
1
+ {"version":3,"sources":["../../src/core/error/crash-handler.ts","../../src/bin/shark.ts","../../src/commands/init.ts","../../src/core/workflow/workflow-manager.ts","../../src/core/workflow/shark-workflow.schema.ts","../../src/core/api/stackspot-client.ts","../../src/core/api/sse-client.ts","../../src/core/agents/agent-response-parser.ts","../../src/core/workflow/conversation-manager.ts","../../src/core/auth/get-active-realm.ts","../../src/core/agents/business-analyst-agent.ts","../../src/core/agents/specification-agent.ts","../../src/core/agents/agent-tools.ts","../../src/core/ast-editing/editors/code-editor-factory.ts","../../src/core/ast-editing/editors/typescript-editor.ts","../../src/commands/scan.ts","../../src/core/agents/scan-agent.ts","../../src/commands/dev.ts","../../src/core/agents/developer-agent.ts","../../src/core/workflow/task-manager.ts","../../src/commands/qa.ts","../../src/core/agents/qa-agent.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { colors } from '../../ui/colors.js';\n\nexport class CrashHandler {\n private static instance: CrashHandler;\n private readonly logDir: string;\n\n private constructor() {\n this.logDir = path.join(os.homedir(), '.shark', 'logs');\n }\n\n public static getInstance(): CrashHandler {\n if (!CrashHandler.instance) {\n CrashHandler.instance = new CrashHandler();\n }\n return CrashHandler.instance;\n }\n\n public init(): void {\n process.on('uncaughtException', (error) => this.handleError(error, 'Uncaught Exception'));\n process.on('unhandledRejection', (reason) => this.handleError(reason, 'Unhandled Rejection'));\n }\n\n private handleError(error: any, type: string): void {\n // Prevent infinite loops if logging fails\n try {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const logFile = path.join(this.logDir, `crash-${timestamp}.log`);\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n const stackTrace = error instanceof Error ? error.stack : 'No stack trace available';\n\n const logContent = `\n[${new Date().toISOString()}] ${type}\n--------------------------------------------------\nMessage: ${errorMessage}\nStack:\n${stackTrace}\n--------------------------------------------------\nSystem: ${os.platform()} ${os.release()} ${os.arch()}\nNode: ${process.version}\n`;\n\n // Ensure directory exists sync (we are crashing, async might not finish)\n if (!fs.existsSync(this.logDir)) {\n fs.mkdirSync(this.logDir, { recursive: true });\n }\n\n fs.writeFileSync(logFile, logContent, 'utf-8');\n\n console.error('\\n');\n console.error(colors.error('šŸ’„ Whoops! Shark CLI crashed unexpectedly.'));\n console.error(colors.dim(` Details have been saved to: ${logFile}`));\n console.error(colors.dim(' Please report this issue so we can fix it.'));\n console.error(colors.error(` Error: ${errorMessage}`));\n console.error('\\n');\n\n } catch (filesysError) {\n console.error('Fatal Error: Failed to write crash log.', filesysError);\n console.error('Original Error:', error);\n } finally {\n process.exit(1);\n }\n }\n}\n\nexport const crashHandler = CrashHandler.getInstance();\n","\nimport { crashHandler } from '../core/error/crash-handler.js';\n\n// Initialize Global Crash Handler\ncrashHandler.init();\n\nimport { Command } from 'commander';\nimport { loginCommand } from '../commands/login.js';\nimport { configCommand } from '../commands/config.js';\nimport { initCommand } from '../commands/init.js';\nimport { colors } from '../ui/colors.js';\nimport { interactiveBusinessAnalyst } from '../core/agents/business-analyst-agent.js';\nimport { interactiveSpecificationAgent } from '../core/agents/specification-agent.js';\nimport { scanCommand } from '../commands/scan.js';\nimport { devCommand } from '../commands/dev.js';\nimport { qaCommand } from '../commands/qa.js';\n\nconst program = new Command();\n\nprogram\n .name('shark')\n .description('Shark CLI: AI-Native Collaborative Development Tool')\n .version('0.0.1');\n\nprogram.addCommand(loginCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(scanCommand);\nprogram.addCommand(devCommand);\nprogram.addCommand(qaCommand);\n\n// Command: ba\n// Description: Starts the Business Analyst Agent interactive session\nprogram\n .command('ba')\n .description('Start Business Analyst Agent interactive session')\n .option('--id <agent_id>', 'Override Agent ID')\n .action(async (options) => {\n try {\n await interactiveBusinessAnalyst();\n } catch (error: any) {\n console.error('Error:', error.message);\n process.exit(1);\n }\n });\n\n// Command: spec\n// Description: Starts the Specification Agent session\nprogram\n .command('spec')\n .description('Start Specification Agent interactive session')\n .option('--id <agent_id>', 'Override Agent ID')\n .option('--briefing <path>', 'Path to briefing file')\n .action(async (options) => {\n try {\n await interactiveSpecificationAgent({\n agentId: options.id,\n briefingPath: options.briefing\n });\n } catch (error: any) {\n console.error('Error:', error.message);\n process.exit(1);\n }\n });\n\nprogram\n .command('config')\n .description('Manage global configuration')\n .action(configCommand.action);\n\n// Global Error Handler for the CLI\nprocess.on('unhandledRejection', (err) => {\n console.error(colors.error('āŒ Unhandled Error:'), err);\n process.exit(1);\n});\n\nprogram.parse(process.argv);\n","import { Command } from 'commander';\nimport { tui } from '../ui/tui.js';\nimport { workflowManager } from '../core/workflow/workflow-manager.js';\nimport { TechStackEnum } from '../core/workflow/shark-workflow.schema.js';\nimport { randomUUID } from 'crypto';\nimport { colors } from '../ui/colors.js';\n\nexport const initAction = async () => {\n tui.intro('Shark Project Initialization');\n\n // 1. Check if workflow already exists\n const existingState = await workflowManager.load();\n if (existingState) {\n // Smart Resume Context Card\n tui.log.info(colors.dim('----------------------------------------'));\n tui.log.info(`🦈 ${colors.primary('Welcome back to Shark CLI!')}`);\n tui.log.message(` Project: ${colors.white(existingState.projectName)}`);\n tui.log.message(` Stage: ${colors.secondary(existingState.currentStage)}`);\n tui.log.message(` Updated: ${colors.dim(new Date(existingState.lastUpdated).toLocaleString())}`);\n tui.log.info(colors.dim('----------------------------------------'));\n\n const action = await tui.select({\n message: 'An existing project was detected. What would you like to do?',\n options: [\n { value: 'resume', label: 'šŸš€ Resume Work' },\n { value: 'overwrite', label: 'āš ļø Overwrite (Start Fresh)' },\n { value: 'exit', label: 'āŒ Exit' }\n ]\n });\n\n if (tui.isCancel(action) || action === 'exit') {\n tui.outro('See you later! šŸ‘‹');\n return;\n }\n\n if (action === 'resume') {\n tui.log.success(`Resuming work on ${colors.primary(existingState.projectName)}...`);\n // Future: Route to specific agent based on stage\n tui.outro(`To continue, run: \"shark agent\" (Context loaded)`);\n return;\n }\n\n // If overwrite, we just proceed to step 2...\n }\n\n // 2. Prompt for Project Name\n const projectName = await tui.text({\n message: 'What is the name of your project?',\n placeholder: 'e.g. My Awesome App',\n validate: (value) => {\n if (!value) return 'Project name is required';\n if (value.trim().length < 2) return 'Project name must be at least 2 characters';\n }\n });\n\n if (tui.isCancel(projectName)) {\n tui.outro('Initialization cancelled.');\n return;\n }\n\n // 3. Prompt for Tech Stack\n const techStackOptions = TechStackEnum.options.map(stack => ({\n value: stack,\n label: stack === 'node-ts' ? 'Node.js (TypeScript)' :\n stack === 'nextjs' ? 'Next.js' :\n stack.charAt(0).toUpperCase() + stack.slice(1)\n }));\n\n const techStack = await tui.select({\n message: 'Select your technology stack:',\n options: techStackOptions\n });\n\n if (tui.isCancel(techStack)) {\n tui.outro('Initialization cancelled.');\n return;\n }\n\n // 4. Create and Save State\n const spinner = tui.spinner();\n spinner.start('Initializing project workflow...');\n\n try {\n const newState = {\n projectId: randomUUID(),\n projectName: projectName as string,\n techStack: techStack as any,\n currentStage: 'business_analysis' as const,\n stageStatus: 'pending' as const,\n lastUpdated: new Date().toISOString(),\n artifacts: [],\n metadata: {\n initializedBy: 'shark-cli',\n version: '0.0.1'\n }\n };\n\n await workflowManager.save(newState);\n spinner.stop('Project workflow created!');\n\n tui.log.success(`Project ${colors.primary(projectName as string)} initialized successfully.`);\n tui.log.message(`Your Project ID: ${colors.dim(newState.projectId)}`);\n tui.outro('Ready to start! Run \"shark agent\" to begin analyzing requirements.'); // Placeholder hint\n } catch (error: any) {\n spinner.stop('Initialization failed.', 1);\n tui.log.error(error.message);\n process.exit(1);\n }\n};\n\nexport const initCommand = new Command('init')\n .description('Initialize a new Shark project')\n .action(initAction);\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { WorkflowSchema, type WorkflowState } from './shark-workflow.schema.js';\nimport { colors } from '../../ui/colors.js';\n\nexport class WorkflowManager {\n private static instance: WorkflowManager;\n private readonly filename = 'shark-workflow.json';\n private readonly tmpFilename = '.shark-workflow.tmp';\n\n private constructor() { }\n\n public static getInstance(): WorkflowManager {\n if (!WorkflowManager.instance) {\n WorkflowManager.instance = new WorkflowManager();\n }\n return WorkflowManager.instance;\n }\n\n private getFilePath(): string {\n return path.join(process.cwd(), this.filename);\n }\n\n private getTmpFilePath(): string {\n return path.join(process.cwd(), this.tmpFilename);\n }\n\n public async save(state: WorkflowState): Promise<void> {\n // 1. Validate State\n const parsed = WorkflowSchema.safeParse(state);\n if (!parsed.success) {\n throw new Error(`Invalid workflow state: ${parsed.error.message}`);\n }\n\n const filePath = this.getFilePath();\n const tmpPath = this.getTmpFilePath();\n const data = JSON.stringify(parsed.data, null, 2);\n\n try {\n // 2. Write to TMP\n await fs.writeFile(tmpPath, data, 'utf-8');\n\n // 3. Rename TMP to Final (Atomic)\n await fs.rename(tmpPath, filePath);\n } catch (error: any) {\n throw new Error(`Failed to save workflow state atomically: ${error.message}`);\n }\n }\n\n public async load(): Promise<WorkflowState | null> {\n const filePath = this.getFilePath();\n\n try {\n // Check if file exists\n try {\n await fs.access(filePath);\n } catch {\n return null; // File doesn't exist, generic start\n }\n\n const content = await fs.readFile(filePath, 'utf-8');\n const json = JSON.parse(content);\n\n const parsed = WorkflowSchema.safeParse(json);\n if (parsed.success) {\n return parsed.data;\n } else {\n console.warn(colors.warning(`āš ļø Corrupted workflow file detected: ${parsed.error.message}`));\n return null;\n }\n\n } catch (error: any) {\n console.warn(colors.warning(`āš ļø Failed to load workflow state: ${error.message}`));\n return null;\n }\n }\n\n // Helper to get current state or default if none exists\n public async getOrInitState(): Promise<WorkflowState | null> {\n return await this.load();\n }\n}\n\nexport const workflowManager = WorkflowManager.getInstance();\n","import { z } from 'zod';\n\nexport enum ProjectParams {\n PROJECT_ID = 'projectId',\n PROJECT_NAME = 'projectName',\n TECH_STACK = 'techStack',\n}\n\nexport const TechStackEnum = z.enum([\n 'react',\n 'nextjs',\n 'angular',\n 'vue',\n 'node-ts',\n 'python',\n 'dotnet',\n 'java',\n 'unknown'\n]);\n\nexport type TechStack = z.infer<typeof TechStackEnum>;\n\nexport const WorkflowStageEnum = z.enum([\n 'business_analysis',\n 'specification',\n 'architecture',\n 'development',\n 'verification',\n 'deployment'\n]);\n\nexport type WorkflowStage = z.infer<typeof WorkflowStageEnum>;\n\nexport const StageStatusEnum = z.enum([\n 'pending',\n 'in_progress',\n 'completed',\n 'failed',\n 'skipped'\n]);\n\nexport type StageStatus = z.infer<typeof StageStatusEnum>;\n\nexport const WorkflowSchema = z.object({\n projectId: z.string().uuid(),\n projectName: z.string().min(1),\n techStack: TechStackEnum.default('unknown'),\n currentStage: WorkflowStageEnum.default('business_analysis'),\n stageStatus: StageStatusEnum.default('pending'),\n lastUpdated: z.string().datetime(), // ISO 8601\n conversationId: z.string().optional(),\n conversations: z.record(z.string(), z.string()).optional(), // agentType -> conversationId\n artifacts: z.array(z.string()).default([]),\n // Extensible metadata bag\n metadata: z.record(z.unknown()).optional(),\n});\n\nexport type WorkflowState = z.infer<typeof WorkflowSchema>;\n","import { tokenStorage } from '../auth/token-storage.js';\nimport { authenticate } from '../auth/stackspot-auth.js';\nimport { colors } from '../../ui/colors.js';\n\nexport class AuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'AuthError';\n }\n}\n\ninterface RequestOptions extends RequestInit {\n params?: Record<string, string>;\n}\n\n// API Base URLs\nexport const STACKSPOT_API_BASE = 'https://api.stackspot.com';\nexport const STACKSPOT_AGENT_API_BASE = 'https://genai-inference-app.stackspot.com';\n\n// Shared Token Validation & Refresh Logic\nexport async function ensureValidToken(realm: string): Promise<string> {\n let creds = await tokenStorage.getCredentials(realm);\n\n if (!creds?.accessToken) {\n throw new AuthError(`Authentication required for realm '${realm}'.\\nPlease run 'shark login' to authenticate.`);\n }\n\n // Auto-Refresh Logic\n const now = Math.floor(Date.now() / 1000);\n const buffer = 300; // 5 minutes buffer\n\n // If we have credentials and expiry time, check if we need to refresh\n if (creds.expiresAt && creds.clientId && creds.clientKey) {\n if (now > creds.expiresAt - buffer) {\n try {\n // console.log(colors.dim('šŸ”„ Refreshing expired token...'));\n // We keep it silent or use a global logger if available\n\n const newTokens = await authenticate(realm, creds.clientId, creds.clientKey);\n\n await tokenStorage.saveToken(\n realm,\n newTokens.access_token,\n creds.clientId,\n creds.clientKey,\n newTokens.expires_in\n );\n\n return newTokens.access_token;\n\n } catch (error) {\n console.warn(colors.warning(`āš ļø Failed to auto-refresh token: ${(error as Error).message}`));\n // Fallback to existing token\n }\n }\n }\n\n return creds.accessToken;\n}\n\nexport class StackSpotClient {\n private readonly MAX_RETRIES = 3;\n private readonly RETRY_DELAYS = [1000, 2000, 4000]; // 1s, 2s, 4s\n private debugMode = false;\n\n constructor(private realm: string) { }\n\n public enableDebug(): void {\n this.debugMode = true;\n }\n\n private async getHeaders(): Promise<Headers> {\n const token = await ensureValidToken(this.realm);\n const headers = new Headers();\n headers.set('Authorization', `Bearer ${token}`);\n headers.set('Content-Type', 'application/json');\n return headers;\n }\n\n private shouldRetry(error: any, attempt: number): boolean {\n if (attempt >= this.MAX_RETRIES) return false;\n\n // Retry on network errors\n if (error.name === 'TypeError' || error.message?.includes('fetch')) return true;\n\n // Retry on 5xx server errors\n if (error.status && error.status >= 500) return true;\n\n return false;\n }\n\n private async sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private async request<T>(url: string, options: RequestOptions = {}): Promise<T> {\n let lastError: any;\n\n for (let attempt = 0; attempt <= this.MAX_RETRIES; attempt++) {\n try {\n if (this.debugMode && attempt > 0) {\n console.log(`[StackSpotClient] Retry attempt ${attempt}/${this.MAX_RETRIES} for ${url}`);\n }\n\n const headers = await this.getHeaders();\n\n // Merge custom headers\n if (options.headers) {\n new Headers(options.headers).forEach((value, key) => headers.set(key, value));\n }\n\n // Add Query Params\n let finalUrl = url;\n if (options.params) {\n const query = new URLSearchParams(options.params).toString();\n finalUrl += `?${query}`;\n }\n\n if (this.debugMode) {\n console.log(`[StackSpotClient] ${options.method || 'GET'} ${finalUrl}`);\n }\n\n const response = await fetch(finalUrl, {\n ...options,\n headers,\n });\n\n if (response.status === 401) {\n throw new AuthError(\"Session expired or invalid credentials. Please run 'shark login' again.\");\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n const error: any = new Error(`API Request failed: ${response.status} ${response.statusText} - ${errorText}`);\n error.status = response.status;\n throw error;\n }\n\n // Return null for 204 No Content\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n\n } catch (error: any) {\n lastError = error;\n\n // Don't retry auth errors\n if (error instanceof AuthError) {\n throw error;\n }\n\n if (this.shouldRetry(error, attempt)) {\n const delay = this.RETRY_DELAYS[attempt] || this.RETRY_DELAYS[this.RETRY_DELAYS.length - 1];\n if (this.debugMode) {\n console.log(`[StackSpotClient] Retrying in ${delay}ms...`);\n }\n await this.sleep(delay);\n continue;\n }\n\n // No more retries\n throw error;\n }\n }\n\n throw lastError;\n }\n\n async get<T>(url: string, options?: RequestOptions): Promise<T> {\n return this.request<T>(url, { ...options, method: 'GET' });\n }\n\n async post<T>(url: string, body: any, options?: RequestOptions): Promise<T> {\n return this.request<T>(url, {\n ...options,\n method: 'POST',\n body: JSON.stringify(body)\n });\n }\n\n async put<T>(url: string, body: any, options?: RequestOptions): Promise<T> {\n return this.request<T>(url, {\n ...options,\n method: 'PUT',\n body: JSON.stringify(body)\n });\n }\n\n async delete<T>(url: string, options?: RequestOptions): Promise<T> {\n return this.request<T>(url, { ...options, method: 'DELETE' });\n }\n}\n\nexport function createAuthenticatedClient(realm: string): StackSpotClient {\n return new StackSpotClient(realm);\n}\n","import { FileLogger } from '../debug/file-logger.js';\n\nexport interface SSECallbacks {\n onChunk?: (partialMessage: string) => void;\n onComplete?: (fullMessage: string, metadata?: any) => void;\n onError?: (error: Error) => void;\n}\n\nexport class SSEClient {\n /**\n * Streams agent response using Server-Sent Events.\n * \n * @param url - The SSE endpoint URL\n * @param requestPayload - The request payload to POST\n * @param headers - Request headers (including Authorization)\n * @param callbacks - Event callbacks for chunks, completion, and errors\n */\n async streamAgentResponse(\n url: string,\n requestPayload: unknown,\n headers: HeadersInit,\n callbacks: SSECallbacks = {}\n ): Promise<void> {\n const { onChunk, onComplete, onError } = callbacks;\n\n FileLogger.log('SSE', `Starting Request to ${url}`, {\n headers,\n payload: requestPayload\n });\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n ...headers,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestPayload),\n });\n\n FileLogger.log('SSE', `Response Status: ${response.status} ${response.statusText}`);\n\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => { responseHeaders[key] = value; });\n FileLogger.log('SSE', 'Response Headers', responseHeaders);\n\n if (!response.ok) {\n const errorText = await response.text();\n FileLogger.log('SSE', 'Response Error Body', errorText);\n throw new Error(`SSE request failed: ${response.status} ${response.statusText} - ${errorText}`);\n }\n\n if (!response.body) {\n throw new Error('Response body is null');\n }\n\n const contentType = response.headers.get('content-type') || '';\n const isJson = contentType.includes('application/json');\n\n if (isJson) {\n // Handle non-streaming JSON response properly\n const jsonBody = await response.json();\n FileLogger.log('SSE', 'Received Non-Streaming JSON Response', { length: JSON.stringify(jsonBody).length });\n\n // Try to extract message content depending on structure\n let content = '';\n if (typeof jsonBody === 'string') content = jsonBody;\n else if (jsonBody.message) content = jsonBody.message;\n else if (jsonBody.choices?.[0]?.message?.content) content = jsonBody.choices[0].message.content; // OpenAI style just in case\n else content = JSON.stringify(jsonBody); // Fallback to raw JSON\n\n // Trigger callbacks as if it streamed in one chunk\n if (onChunk) onChunk(content);\n if (onComplete) onComplete(content, jsonBody);\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let fullMessage = '';\n let metadata: any = {};\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n // Decode chunk\n buffer += decoder.decode(value, { stream: true });\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 if (line.startsWith('data:')) {\n const data = line.slice(5).trim(); // Remove 'data:' prefix\n\n if (data === '[DONE]') {\n FileLogger.log('SSE', 'Stream Complete [DONE]', { fullMessage, metadata });\n // End of stream\n if (onComplete) {\n onComplete(fullMessage, metadata);\n }\n return;\n }\n\n try {\n const parsed = JSON.parse(data);\n const chunk = parsed.message || parsed.content || data;\n fullMessage += chunk;\n\n // Capture latest metadata (e.g. conversation_id)\n if (parsed.conversation_id) {\n metadata.conversation_id = parsed.conversation_id;\n }\n\n if (onChunk) {\n onChunk(chunk);\n }\n } catch (parseError) {\n // Not JSON, treat as plain text\n fullMessage += data;\n if (onChunk) {\n onChunk(data);\n }\n }\n }\n }\n }\n\n FileLogger.log('SSE', 'Stream Ended Naturally', { fullMessage, metadata });\n\n // Stream ended without [DONE]\n if (onComplete) {\n onComplete(fullMessage, metadata);\n }\n\n } catch (error) {\n FileLogger.log('SSE', 'Stream Error', error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n } else {\n throw error;\n }\n }\n }\n}\n\nexport const sseClient = new SSEClient();\n","import { z } from 'zod';\nimport { FileLogger } from '../debug/file-logger.js';\n\n// Action Schema\nexport const AgentActionSchema = z.object({\n type: z.enum([\n 'create_file', 'modify_file', 'list_files', 'search_file', 'read_file', 'delete_file',\n 'list_structure', 'modify_ast', 'search_ast', 'run_command',\n 'talk_with_user',\n 'ast_list_structure',\n 'ast_get_method',\n 'ast_add_method', 'ast_modify_method', 'ast_remove_method',\n 'ast_add_class',\n 'ast_get_property', 'ast_add_property', 'ast_modify_property', 'ast_remove_property',\n 'ast_add_decorator',\n 'ast_add_interface', 'ast_add_type_alias',\n 'ast_add_function', 'ast_remove_function',\n 'ast_add_import', 'ast_remove_import', 'ast_organize_imports'\n ]),\n path: z.string().nullable().optional(), // Nullable for strict mode combatibility\n content: z.string().nullable().optional(),\n line_range: z.array(z.number()).nullable().optional(),\n target_content: z.string().nullable().optional(),\n command: z.string().nullable().optional(),\n tool_name: z.string().nullable().optional(),\n tool_args: z.string().nullable().optional(), // JSON string argument\n\n // AST-Grep fields\n pattern: z.string().nullable().optional(),\n fix: z.string().nullable().optional(),\n language: z.string().nullable().optional(),\n file_path: z.string().nullable().optional(), // Alias for path in ast-grep actions\n\n // New AST Tool Specific Fields\n class_name: z.string().nullable().optional(),\n method_name: z.string().nullable().optional(),\n method_code: z.string().nullable().optional(),\n property_name: z.string().nullable().optional(),\n property_code: z.string().nullable().optional(),\n extends_class: z.string().nullable().optional(),\n implements_interfaces: z.array(z.string()).nullable().optional(),\n decorator_code: z.string().nullable().optional(),\n interface_code: z.string().nullable().optional(),\n type_code: z.string().nullable().optional(),\n function_name: z.string().nullable().optional(),\n function_code: z.string().nullable().optional(),\n import_statement: z.string().nullable().optional(),\n module_path: z.string().nullable().optional(),\n new_body: z.string().nullable().optional(),\n\n // Preview confirmation\n confirmed: z.boolean().nullable().optional(),\n});\n\nexport type AgentAction = z.infer<typeof AgentActionSchema>;\n\n// Command Schema (for future use)\nexport const AgentCommandSchema = z.object({\n command: z.string(),\n description: z.string(),\n critical: z.boolean(),\n});\n\n// Full Structured Response Schema\nexport const AgentResponseSchema = z.object({\n actions: z.array(AgentActionSchema),\n commands: z.array(AgentCommandSchema).optional(),\n summary: z.string().optional(),\n\n // Legacy fields handling for smooth transition/fallback\n message: z.string().optional(),\n conversation_id: z.string().optional(),\n});\n\nexport type AgentResponse = z.infer<typeof AgentResponseSchema>;\n\n/**\n * Parses raw agent response expecting a JSON string that matches our schema.\n */\nexport function parseAgentResponse(rawResponse: unknown): AgentResponse {\n FileLogger.log('PARSER', 'Parsing Agent Response', { rawType: typeof rawResponse });\n\n let parsedObj: any = {};\n let conversation_id: string | undefined;\n\n // 1. Handle string input (accumulated SSE or raw JSON string)\n if (typeof rawResponse === 'string') {\n FileLogger.log('PARSER', 'Type String', { length: rawResponse.length });\n try {\n parsedObj = extractFirstJson(rawResponse);\n } catch (e) {\n FileLogger.log('PARSER', 'String Parse Failed', { error: (e as Error).message });\n // Fallback: treat as simple message if not valid JSON\n return {\n actions: [{\n type: 'talk_with_user',\n content: rawResponse,\n path: ''\n }],\n message: rawResponse\n };\n }\n }\n // 2. Handle object input (direct API response)\n else if (typeof rawResponse === 'object' && rawResponse !== null) {\n const anyResp = rawResponse as any;\n conversation_id = anyResp.conversation_id;\n\n FileLogger.log('PARSER', 'Type Object', {\n hasContent: !!anyResp.content,\n hasMessage: !!anyResp.message,\n messageType: typeof anyResp.message\n });\n\n // Sometimes content is nested in 'content' or 'message'\n const stringContent = anyResp.content || anyResp.message;\n if (stringContent && typeof stringContent === 'string') {\n try {\n // Try to parse it as JSON actions\n const parsedInside = extractFirstJson(stringContent);\n // Only use it if it looks like an object (not just a primitive)\n if (typeof parsedInside === 'object' && parsedInside !== null) {\n parsedObj = parsedInside;\n FileLogger.log('PARSER', 'Inner JSON Parsed', { keys: Object.keys(parsedObj) });\n } else {\n // It was a string literal or number, treat as text\n parsedObj = rawResponse;\n FileLogger.log('PARSER', 'Inner JSON was primitive');\n }\n } catch (e) {\n // Not JSON, continue with rawResponse\n parsedObj = rawResponse;\n FileLogger.log('PARSER', 'Inner JSON Parse Error - treating as raw', { error: (e as Error).message });\n }\n } else {\n parsedObj = rawResponse;\n }\n\n // If we didn't successfully parse inner JSON actions, use the raw object\n if (!parsedObj.actions) {\n parsedObj = rawResponse;\n }\n }\n\n // 3. Normalize Actions\n // Ensure 'actions' array exists\n if (!parsedObj.actions) {\n FileLogger.log('PARSER', 'No Actions Found - Constructing Default');\n // If it looks like the legacy format or direct message\n return {\n conversation_id,\n actions: [{\n type: 'talk_with_user',\n content: parsedObj.message || JSON.stringify(parsedObj),\n path: ''\n }],\n message: parsedObj.message\n };\n }\n\n // 4. Validate against Schema\n // We construct the final object to match our schema structure\n const result = {\n actions: parsedObj.actions,\n commands: parsedObj.commands || [],\n summary: parsedObj.summary || '',\n conversation_id,\n message: parsedObj.summary || 'Agent Action' // Backward compatibility\n };\n\n\n FileLogger.log('PARSER', 'Final Result Constructed', { actionCount: result.actions.length });\n\n try {\n return AgentResponseSchema.parse(result);\n } catch (e) {\n FileLogger.log('PARSER', 'Schema Validation Failed', { error: (e as Error).message });\n throw e;\n }\n}\n\nexport function extractFirstJson(str: string): any {\n try {\n return JSON.parse(str);\n } catch (e) {\n // If simple parse fails, try to find the first balanced object\n const firstOpen = str.indexOf('{');\n if (firstOpen === -1) throw e;\n\n let balance = 0;\n let inString = false;\n let escape = false;\n\n for (let i = firstOpen; i < str.length; i++) {\n const char = str[i];\n\n if (escape) {\n escape = false;\n continue;\n }\n\n if (char === '\\\\') {\n escape = true;\n continue;\n }\n\n if (char === '\"') {\n inString = !inString;\n continue;\n }\n\n if (!inString) {\n if (char === '{') balance++;\n else if (char === '}') {\n balance--;\n if (balance === 0) {\n // Found the end of the first object\n const potentialJson = str.substring(firstOpen, i + 1);\n try {\n return JSON.parse(potentialJson);\n } catch (innerE) {\n // If this chunk failed, maybe our brace counting was off (e.g. comments?), throw original\n throw e;\n }\n }\n }\n }\n }\n throw e;\n }\n}\n","import { workflowManager } from './workflow-manager.js';\n\n/**\n * Manages conversation IDs for agent interactions.\n * Stores conversation IDs in the workflow state to maintain context across sessions.\n */\nexport class ConversationManager {\n private static instance: ConversationManager;\n\n private constructor() { }\n\n public static getInstance(): ConversationManager {\n if (!ConversationManager.instance) {\n ConversationManager.instance = new ConversationManager();\n }\n return ConversationManager.instance;\n }\n\n /**\n * Saves a conversation ID for a specific agent type.\n * \n * @param agentType - The type of agent (e.g., 'business_analyst', 'architect')\n * @param conversationId - The conversation ID from the agent response\n */\n async saveConversationId(agentType: string, conversationId: string): Promise<void> {\n const state = await workflowManager.load();\n if (!state) {\n throw new Error('No workflow state found. Please run \"shark init\" first.');\n }\n\n // Initialize conversations object if it doesn't exist\n if (!state.conversations) {\n state.conversations = {};\n }\n\n state.conversations[agentType] = conversationId;\n await workflowManager.save(state);\n }\n\n /**\n * Retrieves the conversation ID for a specific agent type.\n * \n * @param agentType - The type of agent\n * @returns The conversation ID, or undefined if none exists\n */\n async getConversationId(agentType: string): Promise<string | undefined> {\n const state = await workflowManager.load();\n if (!state || !state.conversations) {\n return undefined;\n }\n\n return state.conversations[agentType];\n }\n\n /**\n * Clears the conversation ID for a specific agent type.\n * \n * @param agentType - The type of agent\n */\n async clearConversationId(agentType: string): Promise<void> {\n const state = await workflowManager.load();\n if (!state || !state.conversations) {\n return;\n }\n\n delete state.conversations[agentType];\n await workflowManager.save(state);\n }\n\n /**\n * Clears all conversation IDs.\n * Useful when transitioning to a new project or resetting state.\n */\n async clearAllConversations(): Promise<void> {\n const state = await workflowManager.load();\n if (!state) {\n return;\n }\n\n state.conversations = {};\n await workflowManager.save(state);\n }\n}\n\nexport const conversationManager = ConversationManager.getInstance();\n","import { ConfigManager } from '../config-manager.js';\n\n/**\n * Gets the currently active (logged-in) realm from config.\n * \n * @returns The active realm\n * @throws Error if no realm is active (user not logged in)\n */\nexport async function getActiveRealm(): Promise<string> {\n const configManager = ConfigManager.getInstance();\n const config = configManager.getConfig();\n const realm = config.activeRealm;\n\n if (!realm) {\n throw new Error(\n 'No active authentication found.\\n' +\n 'Please run \"shark login\" first to authenticate.'\n );\n }\n\n return realm;\n}\n","import { STACKSPOT_AGENT_API_BASE } from '../api/stackspot-client.js';\nimport { sseClient } from '../api/sse-client.js';\nimport { parseAgentResponse, AgentResponse } from './agent-response-parser.js';\nimport { conversationManager } from '../workflow/conversation-manager.js';\nimport { tokenStorage } from '../auth/token-storage.js';\nimport { getActiveRealm } from '../auth/get-active-realm.js';\nimport { tui } from '../../ui/tui.js';\nimport { colors } from '../../ui/colors.js';\nimport { ConfigManager } from '../config-manager.js';\n\nconst AGENT_TYPE = 'business_analyst';\n\nfunction getAgentId(overrideId?: string): string {\n if (overrideId) return overrideId;\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.ba) return config.agents.ba;\n return process.env.STACKSPOT_BA_AGENT_ID || '01KEJ95G304TNNAKGH5XNEEBVD';\n}\n\nexport interface BAAgentOptions {\n agentId?: string; // Allow overriding agent ID\n onChunk?: (chunk: string) => void;\n onComplete?: (response: AgentResponse) => void;\n}\n\n/**\n * Orchestrates interaction with the Business Analyst agent.\n * Integrates all communication components into a complete flow.\n * Automatically uses the active realm from config (no need to pass it).\n * \n * @param prompt - User's project description\n * @param options - Configuration options (callbacks, optional agentId override)\n * @returns Complete agent response\n */\nexport async function runBusinessAnalystAgent(\n prompt: string,\n options: BAAgentOptions = {}\n): Promise<AgentResponse> {\n const { agentId, onChunk, onComplete } = options;\n\n // 1. Get active realm from config (auto-detect)\n const realm = await getActiveRealm();\n\n // 1. Get auth token\n const token = await tokenStorage.getToken(realm);\n if (!token) {\n throw new Error(`No authentication token found for realm '${realm}'. Please run 'shark login'.`);\n }\n\n // 2. Load existing conversation ID (if any)\n const existingConversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n // 3. Build request payload (StackSpot agent format)\n const requestPayload = {\n user_prompt: prompt,\n streaming: true,\n stackspot_knowledge: false, // Use agent's configured KS instead\n return_ks_in_response: true,\n deep_search_ks: false,\n conversation_id: existingConversationId,\n };\n\n // 4. Construct agent URL - CORRECT FORMAT\n const effectiveAgentId = getAgentId(options.agentId);\n const agentUrl = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;\n\n // 5. Prepare headers\n const headers = {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n };\n\n // 6. Stream agent response\n let fullMessage = '';\n let rawResponse: any = {};\n\n await sseClient.streamAgentResponse(\n agentUrl,\n requestPayload,\n headers,\n {\n onChunk: (chunk) => {\n fullMessage += chunk;\n if (onChunk) {\n onChunk(chunk);\n }\n },\n onComplete: async (message) => {\n // Build complete response object\n rawResponse = {\n message: message || fullMessage,\n conversation_id: existingConversationId, // Will be updated if new one provided\n };\n },\n onError: (error) => {\n throw error;\n },\n }\n );\n\n // 7. Parse response\n const parsedResponse = parseAgentResponse(rawResponse);\n\n // 8. Save new conversation ID (if provided)\n if (parsedResponse.conversation_id) {\n await conversationManager.saveConversationId(AGENT_TYPE, parsedResponse.conversation_id);\n }\n\n // 9. Call completion callback\n if (onComplete) {\n onComplete(parsedResponse);\n }\n\n return parsedResponse;\n}\n\n/**\n * Interactive Business Analyst session with TUI.\n * Prompts user for input and displays streamed response.\n * Automatically uses the active realm from config.\n */\nexport async function interactiveBusinessAnalyst(): Promise<void> {\n tui.intro('šŸŽÆ Business Analyst Agent');\n\n const prompt = await tui.text({\n message: 'Describe your project idea',\n placeholder: 'E.g., I want to build a task management app for teams...',\n validate: (value) => {\n if (!value || value.length < 10) return 'Please provide a detailed description (at least 10 characters)';\n },\n });\n\n if (tui.isCancel(prompt)) {\n tui.outro('Cancelled');\n return;\n }\n\n const spinner = tui.spinner();\n spinner.start('šŸ’¬ Business Analyst is thinking...');\n\n let responseText = '';\n\n try {\n await runBusinessAnalystAgent(prompt as string, {\n onChunk: (chunk) => {\n responseText += chunk;\n // Update spinner with preview (try to parse JSON if possible, otherwise raw)\n try {\n // Start of JSON?\n if (responseText.trim().startsWith('{')) {\n spinner.message(colors.dim('Receiving structured data...'));\n } else {\n spinner.message(colors.dim('Thinking...'));\n }\n } catch (e) {\n // ignore\n }\n },\n onComplete: async (response) => {\n spinner.stop('Response received');\n\n // Show summary if exists\n if (response.summary) {\n tui.log.info(colors.italic(response.summary));\n }\n\n // Handle Actions\n if (response.actions && response.actions.length > 0) {\n for (const action of response.actions) {\n\n // CASE 1: TALK WITH USER (Conventional Message)\n if (action.type === 'talk_with_user') {\n tui.log.info(colors.success('šŸ¤– BA Agent:'));\n console.log(action.content); // Print formatted markdown\n\n // We don't verify \"talk\", we just show it.\n // The flow will wait for next user input naturally at loop start?\n // Wait! We need a loop here?\n // runBusinessAnalystAgent is a ONE-OFF request.\n // The LOOP needs to be in interactiveBusinessAnalyst.\n }\n\n // CASE 2: FILE OPERATIONS (Autonomous Actions)\n else {\n tui.log.warning(`\\nšŸ¤– Agent wants to ${action.type}: ${colors.bold(action.path || 'unknown')}`);\n\n // Show content preview\n if (action.content) {\n console.log(colors.dim('--- Content Preview ---'));\n console.log(action.content.substring(0, 300) + (action.content.length > 300 ? '...' : ''));\n console.log(colors.dim('-----------------------'));\n }\n\n const confirm = await tui.confirm({\n message: `Allow agent to ${action.type} '${action.path}'?`,\n active: 'Yes',\n inactive: 'No'\n });\n\n if (confirm) {\n // TODO: Add actual file system writing logic here\n // fs.writeFileSync(action.path!, action.content);\n tui.log.success(`āœ… Action executed: ${action.path} created.`);\n } else {\n tui.log.error('āŒ Action denied.');\n }\n }\n }\n }\n // Tokens property removed from schema, ignoring log.\n },\n });\n\n tui.outro('Session complete');\n } catch (error: any) {\n spinner.stop('āŒ Error', 1);\n tui.log.error(error.message);\n throw error;\n }\n}\n","\nimport { STACKSPOT_AGENT_API_BASE, ensureValidToken } from '../api/stackspot-client.js';\nimport { sseClient } from '../api/sse-client.js';\nimport { parseAgentResponse, AgentResponse } from './agent-response-parser.js';\nimport { conversationManager } from '../workflow/conversation-manager.js';\nimport { tokenStorage } from '../auth/token-storage.js';\nimport { getActiveRealm } from '../auth/get-active-realm.js';\nimport { tui } from '../../ui/tui.js';\nimport { colors } from '../../ui/colors.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { FileLogger } from '../debug/file-logger.js';\nimport { handleListFiles, handleReadFile, handleSearchFile, startSmartReplace } from './agent-tools.js';\nimport { ConfigManager } from '../config-manager.js';\n\nconst AGENT_TYPE = 'specification_agent';\n\nfunction getAgentId(overrideId?: string): string {\n if (overrideId) return overrideId;\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.spec) return config.agents.spec;\n return process.env.STACKSPOT_SPEC_AGENT_ID || '01KEPXTX37FTB4N672TZST4SGP';\n}\n\nexport interface SpecAgentOptions {\n agentId?: string;\n briefingPath?: string; // Path to the briefing file to read, explicit override\n initialContext?: string; // Handover context from Dev Agent or Orchestrator\n}\n\n/**\n * Interactive Specification Agent session.\n * Uses a Template-Based Incremental Workflow.\n */\nexport async function interactiveSpecificationAgent(options: SpecAgentOptions = {}): Promise<void> {\n FileLogger.init();\n tui.intro('šŸ—ļø Specification Agent (Template-Based)');\n\n const projectRoot = process.cwd();\n // User requested to store tech-spec.md in _sharkrc\n const sharkRcDir = path.resolve(projectRoot, '_sharkrc');\n if (!fs.existsSync(sharkRcDir)) fs.mkdirSync(sharkRcDir, { recursive: true });\n\n const outputFile = path.resolve(sharkRcDir, 'tech-spec.md');\n\n // 1. Ensure Template Exists (Inline Template)\n if (!fs.existsSync(outputFile)) {\n // Hardcoded template as requested, similar to scan-agent.ts\n let initialContent = `# Technical Specification: {{PROJECT_NAME}}\n\n## 1. Technology Stack\n[TO BE ANALYZED]\n- Language: [e.g. TypeScript]\n- Framework: [e.g. Node.js / React]\n- Database: [e.g. SQLite / PostgreSQL]\n- Key Libraries: [Top 5 dependencies]\n\n## 2. Architecture Overview\n[TO BE ANALYZED]\n[Brief description of architectural pattern]\n\n## 3. Data Model\n[TO BE ANALYZED]\n[Schema/ERD definitions]\n\n## 4. API / Interface Contracts\n[TO BE ANALYZED]\n[Main endpoints or CLI commands]\n\n## 5. Implementation Steps\n[TO BE FILLED - MUST BE CHECKBOXES]\n`;\n\n // Replace basic placeholders immediately\n const projectName = path.basename(projectRoot);\n initialContent = initialContent.replace(/{{PROJECT_NAME}}/g, projectName);\n\n const BOM = '\\uFEFF';\n fs.writeFileSync(outputFile, BOM + initialContent, { encoding: 'utf-8' });\n tui.log.success(`āœ… Created: ${colors.bold('_sharkrc/tech-spec.md')}`);\n } else {\n tui.log.info(`šŸ“„ Using existing ${colors.bold('_sharkrc/tech-spec.md')}`);\n }\n\n // 2. Load Inputs (Context, Briefing)\n let contextContent = '';\n const contextPath = path.resolve(projectRoot, '_sharkrc', 'project-context.md');\n if (fs.existsSync(contextPath)) {\n contextContent = fs.readFileSync(contextPath, 'utf-8');\n tui.log.info(`šŸ“˜ Context loaded.`);\n }\n\n let briefingContent = '';\n if (options.briefingPath && fs.existsSync(options.briefingPath)) {\n briefingContent = fs.readFileSync(options.briefingPath, 'utf-8');\n tui.log.info(`šŸ“„ Briefing loaded from: ${colors.dim(options.briefingPath)}`);\n } else {\n const standardBriefing = path.resolve(projectRoot, '_sharkrc', 'briefing.md');\n if (fs.existsSync(standardBriefing)) {\n briefingContent = fs.readFileSync(standardBriefing, 'utf-8');\n tui.log.info(`šŸ“„ Briefing loaded.`);\n }\n }\n\n // 3. Construct Super Prompt\n let initialPrompt = `\nVocĆŖ Ć© o **Shark Spec**, um Arquiteto de Software SĆŖnior e Tech Lead.\nSeu objetivo Ć© produzir uma especificação tĆ©cnica precisa e especĆ­fica para a tarefa no arquivo \\`_sharkrc/tech-spec.md\\`.\n\nāš ļø WORKFLOW OBRIGATƓRIO – SIGA ESSA SEQUÊNCIA ESTRITAMENTE. NƃO PULE ETAPAS.\n\n**FASE 1 – ENTENDA A TAREFA (COMECE AQUI):**\n- Use \\`talk_with_user\\` para perguntar ao usuĆ”rio qual tarefa especĆ­fica, funcionalidade ou bug ele precisa especificar.\n- NƃO explore o código ou leia arquivos ainda.\n- Confirme o escopo e os limites com o usuĆ”rio antes de prosseguir.\n\n**FASE 2 – INVESTIGUE (FOCADO APENAS NA TAREFA):**\n- Use \\`list_files\\` e \\`read_file\\` APENAS em arquivos diretamente relevantes para a tarefa confirmada.\n- NƃO leia o projeto de forma genĆ©rica.\n- REGRA DE LEITURA PRƉVIA: VocĆŖ NƃO PODE adicionar uma tarefa referenciando um arquivo que vocĆŖ nĆ£o leu nesta sessĆ£o (exceção: novos arquivos a serem criados).\n\n**FASE 3 – PREENCHA O TEMPLATE:**\n- Use \\`modify_file\\` em \\`_sharkrc/tech-spec.md\\` para substituir os placeholders com conteĆŗdo real e especĆ­fico da tarefa.\n- As SeƧƵes 1-4 (Stack, Arquitetura, Modelo de Dados, API) devem descrever o contexto da TAREFA, nĆ£o do projeto como um todo.\n- Passos de Implementação: APENAS checkboxes markdown: \\`- [ ] [Verbo de Ação] [O Que] em [Caminho Relativo]\\`. SEM listas numeradas, SEM subnĆ­veis.\n- Quando todos os placeholders acabarem e vocĆŖ estiver satisfeito, retorne: \\`SPEC_UPDATED: Complete\\`.\n\n**REGRAS CRƍTICAS:**\n- NUNCA preencha a Technology Stack ou Architecture com informaƧƵes genĆ©ricas do projeto. Essas seƧƵes devem refletir o que a tarefa irĆ” usar ou alterar.\n- Use \\`talk_with_user\\` sempre que os requisitos forem ambĆ­guos.\n- NƃO tente escrever todas as seƧƵes de uma vez. Trabalhe de forma incremental, uma seção por vez.\n- IMPORTANTE: Toda a sua comunicação e a especificação gerada DEVEM ser em PortuguĆŖs.\n`;\n\n if (briefingContent) {\n initialPrompt += `\nā„¹ļø Um documento de briefing foi encontrado. Ele define parcialmente a tarefa para a Fase 1.\nConfirme seu entendimento com o usuĆ”rio via \\`talk_with_user\\` antes de prosseguir para a Fase 2.\n\n--- BRIEFING ---\n${briefingContent}\n----------------\n`;\n } else {\n initialPrompt += `\nā„¹ļø Nenhum documento de briefing foi encontrado. Inicie a Fase 1 imediatamente: use \\`talk_with_user\\` para perguntar ao usuĆ”rio o que precisa ser especificado.\n`;\n }\n\n if (options.initialContext) {\n initialPrompt += `\\n--- CONTEXTO DE EXECUƇƃO ANTERIOR (HANDOVER/FEEDBACK) ---\\n${options.initialContext}\\n-----------------------------------------------------\\n`;\n }\n\n if (contextContent) {\n initialPrompt += `\nā„¹ļø O contexto do projeto estĆ” disponĆ­vel para referĆŖncia. Use-o na Fase 2 para se alinhar com os padrƵes de arquitetura existentes, mas NƃO o use para preencher as seƧƵes de forma genĆ©rica.\n\n--- PROJECT CONTEXT ---\n${contextContent}\n-----------------------\n`;\n }\n\n // 4. Start Loop\n await runSpecLoop(initialPrompt.trim(), outputFile, options.agentId);\n}\n\n/**\n * Main Loop for Specification Agent (Incremental)\n */\nasync function runSpecLoop(initialMessage: string, targetPath: string, overrideAgentId?: string) {\n let nextPrompt = initialMessage;\n let keepGoing = true;\n let stepCount = 0;\n const MAX_STEPS = 30;\n\n while (keepGoing && stepCount < MAX_STEPS) {\n stepCount++;\n const spinner = tui.spinner();\n spinner.start(`šŸ—ļø Spec Agent working (Step ${stepCount}/${MAX_STEPS})...`);\n\n // Check Pending Sections to guide the agent\n let pendingSections = [];\n if (fs.existsSync(targetPath)) {\n const content = fs.readFileSync(targetPath, 'utf-8');\n if (content.includes('[TO BE ANALYZED]')) pendingSections.push('Analysis Sections (Stack, Arch, Data, API)');\n if (content.includes('[TO BE FILLED')) pendingSections.push('Implementation Steps');\n }\n\n if (pendingSections.length === 0 && stepCount > 1) {\n // Check if user is done?\n }\n\n let responseText = '';\n let lastResponse: AgentResponse | null = null;\n\n try {\n lastResponse = await callSpecAgentApi(nextPrompt, (chunk) => {\n responseText += chunk;\n }, overrideAgentId);\n\n spinner.stop('Response received');\n\n if (lastResponse && lastResponse.actions) {\n let executionResults = \"\";\n let waitingForUser = false;\n let specUpdated = false;\n\n // Check for completion signal\n if (lastResponse.message && lastResponse.message.includes('SPEC_UPDATED:')) {\n const content = fs.existsSync(targetPath) ? fs.readFileSync(targetPath, 'utf-8') : '';\n if (content.includes('[TO BE')) {\n const pendingMatches = [...content.matchAll(/## ([^\\n]+)[\\s\\S]*?\\[TO BE/g)].map(m => m[1]);\n let missing = pendingMatches.length > 0 ? pendingMatches.join(', ') : 'algumas seƧƵes';\n \n tui.log.warning(`O agente tentou concluir prematuramente, mas hĆ” placeholders pendentes. ForƧando retorno...`);\n nextPrompt = `[System Error]: A validação falhou e o bloqueio automĆ”tico foi acionado.\\nVocĆŖ tentou concluir a tarefa, mas o arquivo AINDA possui placeholders '[TO BE ANALYZED]' ou '[TO BE FILLED]'.\\nAs seguintes seƧƵes ainda contĆŖm estes placeholders: ${missing}.\\nVocĆŖ Ć© OBRIGADO a usar a action \\`modify_file\\` para preencher o conteĆŗdo de cada uma dessas seƧƵes. Use o placeholder exato no campo \\`target_content\\`. NƃO repita a conclusĆ£o da tarefa atĆ© corrigir todas as pendĆŖncias.`;\n continue;\n } else {\n const updateSummary = lastResponse.message.split('SPEC_UPDATED:')[1].trim();\n tui.log.success(`āœ… Spec Finalized: ${updateSummary}`);\n return;\n }\n }\n\n for (const action of lastResponse.actions) {\n if (action.type === 'talk_with_user') {\n tui.log.info(colors.primary('šŸ¤– Architect:'));\n console.log(action.content);\n waitingForUser = true;\n }\n\n else if (action.type === 'list_files') {\n tui.log.info(`šŸ“‚ Scanning: ${colors.dim(action.path || '.')}`);\n const result = handleListFiles(action.path || '.');\n executionResults += `[Action list_files(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n\n else if (action.type === 'read_file') {\n tui.log.info(`šŸ“– Reading: ${colors.dim(action.path || '')}`);\n const result = handleReadFile(action.path || '');\n executionResults += `[Action read_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n\n else if (action.type === 'search_file') {\n tui.log.info(`šŸ” Searching: ${colors.dim(action.path || '')}`);\n const result = handleSearchFile(action.path || '');\n executionResults += `[Action search_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n\n else if (['create_file', 'modify_file'].includes(action.type)) {\n // Target Validation & Redirection\n let actionPath = path.resolve(action.path || '');\n const resolvedTargetPath = path.resolve(targetPath);\n let isTarget = actionPath === resolvedTargetPath;\n\n // Auto-redirect if agent tries to write to root tech-spec.md instead of _sharkrc\n if (!isTarget && path.basename(actionPath) === 'tech-spec.md') {\n tui.log.warning(`Redirecting ${action.type} from ${action.path} to ${path.relative(process.cwd(), targetPath)}`);\n action.path = targetPath;\n actionPath = resolvedTargetPath;\n isTarget = true;\n }\n\n if (!isTarget && action.type === 'create_file') {\n const confirm = await tui.confirm({ message: `Agent wants to create ${action.path}. Allow?` });\n if (!confirm) {\n executionResults += `[Action create_file]: User denied.\\n`;\n continue;\n }\n }\n\n try {\n if (action.type === 'create_file') {\n const BOM = '\\uFEFF';\n fs.writeFileSync(action.path!, BOM + (action.content || ''), 'utf-8');\n tui.log.success(`āœ… Created: ${action.path}`);\n executionResults += `[Action create_file]: Success.\\n`;\n } else if (action.type === 'modify_file') {\n if (action.target_content) {\n // Ensure we pass the possibly redirected path\n const success = startSmartReplace(action.path!, action.content || '', action.target_content, tui);\n if (success) {\n executionResults += `[Action modify_file]: Success.\\n`;\n specUpdated = true;\n } else {\n executionResults += `[Action modify_file]: Failed. Target content not found.\\n`;\n }\n } else {\n executionResults += `[Action modify_file]: Failed. 'target_content' is required.\\n`;\n }\n }\n } catch (e: any) {\n executionResults += `[Action ${action.type}]: Error: ${e.message}\\n`;\n }\n }\n }\n\n // Prepare Next Prompt\n if (waitingForUser) {\n const userReply = await tui.text({ message: 'Your answer', placeholder: 'Type your answer...' });\n if (tui.isCancel(userReply)) { keepGoing = false; return; }\n nextPrompt = `${executionResults}\\n\\nUser Reply: ${userReply}`;\n } else if (executionResults) {\n const content = fs.existsSync(targetPath) ? fs.readFileSync(targetPath, 'utf-8') : '';\n let systemMsg = \"Execução da ferramenta concluĆ­da.\";\n if (specUpdated) {\n if (content.includes('[TO BE')) {\n const pendingMatches = [...content.matchAll(/## ([^\\n]+)[\\s\\S]*?\\[TO BE/g)].map(m => m[1]);\n let missing = pendingMatches.length > 0 ? pendingMatches.join(', ') : 'vĆ”rias seƧƵes';\n systemMsg += `\\n[System]: Seção atualizada com sucesso. A validação detectou que AINDA HƁ placeholders pendentes ('[TO BE...]') nas seguintes seƧƵes: ${missing}.\\nPor favor, envie uma nova action \\`modify_file\\` focada em uma destas seƧƵes obrigatoriamente. USE o respectivo placeholder no campo \\`target_content\\` para que o replace funcione.`;\n } else {\n systemMsg += \"\\n[System]: O arquivo parece completo! Se estiver satisfeito e possuir TODAS as implementaƧƵes descritas, retorne 'SPEC_UPDATED: Complete'.\";\n }\n }\n nextPrompt = `${executionResults}\\n\\n${systemMsg}`;\n } else {\n if (lastResponse.message) {\n tui.log.info(colors.primary('šŸ¤– Architect (Message only):'));\n console.log(lastResponse.message);\n const userReply = await tui.text({ message: 'Your answer:' });\n if (tui.isCancel(userReply)) { keepGoing = false; break; }\n nextPrompt = userReply as string;\n } else {\n keepGoing = false;\n }\n }\n\n } else {\n tui.log.warning('No actions received.');\n keepGoing = false;\n }\n\n } catch (error: any) {\n spinner.stop('Error');\n tui.log.error(error.message);\n keepGoing = false;\n }\n }\n}\n\n// --- API Wrapper Matches Scan/Dev Agent Pattern ---\nasync function callSpecAgentApi(prompt: string, onChunk: (chunk: string) => void, agentId?: string): Promise<AgentResponse> {\n const realm = await getActiveRealm();\n const token = await ensureValidToken(realm);\n const conversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n const payload = {\n user_prompt: prompt,\n streaming: true,\n stackspot_knowledge: false,\n return_ks_in_response: true,\n use_conversation: true,\n conversation_id: conversationId\n };\n\n const effectiveAgentId = getAgentId(agentId);\n const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;\n\n let fullMsg = '';\n let raw: any = {};\n\n FileLogger.log('AGENT', 'Calling Agent API', { agentId: effectiveAgentId, conversationId });\n\n await sseClient.streamAgentResponse(url, payload, { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, {\n onChunk: (c) => { fullMsg += c; onChunk(c); },\n onComplete: (msg, metadata) => {\n const returnedId = metadata?.conversation_id;\n raw = { message: msg || fullMsg, conversation_id: returnedId || conversationId };\n },\n onError: (e) => { throw e; }\n });\n\n const parsed = parseAgentResponse(raw);\n if (parsed.conversation_id) {\n await conversationManager.saveConversationId(AGENT_TYPE, parsed.conversation_id);\n }\n\n return parsed;\n}\n","\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport fg from 'fast-glob';\nimport { colors } from '../../ui/colors.js';\nimport { tui } from '../../ui/tui.js';\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { fileURLToPath } from 'node:url';\nimport { CodeEditorFactory } from '../ast-editing/editors/code-editor-factory.js';\nimport { CodeStructure } from '../ast-editing/interfaces/structure.types.js';\n\nconst execAsync = promisify(exec);\n\n\n/**\n * Shared tools for Agent interaction (File System, etc.)\n */\n\n\nexport function detectLineEnding(content: string): string {\n const crlf = content.split('\\r\\n').length - 1;\n const lf = content.split('\\n').length - 1 - crlf;\n return crlf > lf ? '\\r\\n' : '\\n';\n}\n\nexport function handleListFiles(dirPath: string): string {\n try {\n const fullPath = path.resolve(process.cwd(), dirPath);\n if (!fs.existsSync(fullPath)) return `Error: Directory ${dirPath} does not exist.`;\n\n const items = fs.readdirSync(fullPath, { withFileTypes: true });\n return items.map(item => {\n return `${item.isDirectory() ? '[DIR]' : '[FILE]'} ${item.name}`;\n }).join('\\n');\n } catch (e: any) {\n return `Error listing files: ${e.message}`;\n }\n}\n\nexport function handleReadFile(filePath: string, showLineNumbers: boolean = true): string {\n try {\n const fullPath = path.resolve(process.cwd(), filePath);\n if (!fs.existsSync(fullPath)) return `Error: File ${filePath} does not exist.`;\n\n // Limit size?\n const stats = fs.statSync(fullPath);\n if (stats.size > 100 * 1024) return `Error: File too large to read (${stats.size} bytes). Limit is 100KB.`;\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n\n if (showLineNumbers) {\n const lines = content.split('\\n');\n return lines.map((line, idx) => `${idx + 1}: ${line}`).join('\\n');\n }\n\n return content;\n } catch (e: any) {\n return `Error reading file: ${e.message}`;\n }\n}\n\nexport function replaceLineRange(\n filePath: string,\n startLine: number, // 1-indexed\n endLine: number, // 1-indexed\n newContent: string,\n tui: any\n): boolean {\n try {\n if (!fs.existsSync(filePath)) {\n tui.log.error(`āŒ File not found for modification: ${filePath}`);\n return false;\n }\n\n const currentFileContent = fs.readFileSync(filePath, 'utf-8');\n const lineEnding = detectLineEnding(currentFileContent);\n const lines = currentFileContent.split(lineEnding);\n\n // Validation\n if (startLine < 1 || startLine > lines.length) {\n tui.log.error(`āŒ Invalid start line: ${startLine}. File has ${lines.length} lines.`);\n return false;\n }\n\n if (endLine < startLine || endLine > lines.length) {\n tui.log.error(`āŒ Invalid end line: ${endLine}. Must be >= startLine and <= file length.`);\n return false;\n }\n\n // Replace lines [startLine-1, endLine-1]\n // Note: lines array is 0-indexed\n const before = lines.slice(0, startLine - 1);\n const after = lines.slice(endLine);\n const newLines = newContent.split(lineEnding); // Use detected line ending for new content splitting if provided with one, usually agent provides \\n\n\n // If newContent comes from LLM, it likely has \\n. We should split by \\n and join by detected.\n // But wait, if newContent has \\n and we join by \\r\\n, it works if we split newContent by \\n.\n // If newContent already has \\r\\n, splitting by \\n leaves \\r.\n // Safe approach: Normalized split of new code.\n const normalizedNewLines = newContent.replace(/\\r\\n/g, '\\n').split('\\n');\n\n const result = [...before, ...normalizedNewLines, ...after].join(lineEnding);\n\n const BOM = '\\uFEFF';\n const finalContent = result.startsWith(BOM) ? result : BOM + result;\n fs.writeFileSync(filePath, finalContent, { encoding: 'utf-8' });\n\n tui.log.success(`āœ… Replaced lines ${startLine}-${endLine} in ${filePath}`);\n return true;\n\n } catch (e: any) {\n tui.log.error(`āŒ Error replacing line range: ${e.message}`);\n return false;\n }\n}\n\nimport { CodeReviewService } from '../services/code-review.service.js';\n\nexport async function generateFilePreview(\n filePath: string,\n startLine: number,\n endLine: number,\n newContent: string\n): Promise<string> {\n try {\n const fullPath = path.resolve(process.cwd(), filePath);\n if (!fs.existsSync(fullPath)) return `Error: File ${filePath} does not exist.`;\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const lines = content.split(/\\r\\n|\\r|\\n/);\n\n // 0-indexed adjustment\n const startIdx = startLine - 1;\n const endIdx = endLine - 1;\n\n if (startIdx < 0 || startIdx >= lines.length) return `Error: Start line ${startLine} is out of bounds (File has ${lines.length} lines).`;\n if (endIdx < startIdx || endIdx >= lines.length) return `Error: End line ${endLine} is invalid.`;\n\n const contextBefore = lines.slice(Math.max(0, startIdx - 3), startIdx).map((l, i) => `${Math.max(1, startLine - 3) + i} | ${l}`).join('\\n');\n const contentReplacing = lines.slice(startIdx, endIdx + 1).map((l, i) => `${startLine + i} | - ${l}`).join('\\n');\n const contextAfter = lines.slice(endIdx + 1, Math.min(lines.length, endIdx + 4)).map((l, i) => `${endLine + 1 + i} | ${l}`).join('\\n');\n\n const newLines = newContent.split('\\n').map(l => `+ ${l}`).join('\\n');\n\n // INTEGRATE CODE REVIEW AGENT\n let reviewFeedback = '';\n try {\n reviewFeedback = await CodeReviewService.reviewCode(filePath, newContent);\n } catch (err) {\n reviewFeedback = `āš ļø Code Review Service Unavailable: ${(err as any).message}`;\n }\n\n return `PREVIEW OF CHANGES to ${filePath}:\n--------------------------------------------------\nCONTEXT BEFORE:\n${contextBefore}\n\nCHANGES:\n${contentReplacing}\n${newLines}\n\nCONTEXT AFTER:\n${contextAfter}\n--------------------------------------------------\n${reviewFeedback}\n\nIMPORTANT: Please verify that the lines being replaced (marked with -) are exactly what you intend to remove.\nIf the context looks wrong, DO NOT CONFIRM. Re-read the file to check line numbers.\n`;\n } catch (e: any) {\n return `Error generating preview: ${e.message}`;\n }\n}\n\nexport function handleSearchFile(pattern: string): string {\n try {\n // Limit scope to current directory for safety?\n // Patterns are relative to process.cwd()\n const entries = fg.sync(pattern, { dot: true });\n if (entries.length === 0) return 'No files found matching pattern.';\n return entries.slice(0, 50).join('\\n');\n } catch (e: any) {\n return `Error searching files: ${e.message}`;\n }\n}\n\nexport function startSmartReplace(filePath: string, newContent: string, targetContent: string, tui: any): boolean {\n if (!fs.existsSync(filePath)) {\n tui.log.error(`āŒ File not found for modification: ${filePath}`);\n return false;\n }\n\n const currentFileContent = fs.readFileSync(filePath, 'utf-8');\n\n // 1. Validation: Does target exist?\n // Normalize string for comparison to avoid CRLF issues during check\n const normalizedTarget = targetContent.replace(/\\r\\n/g, '\\n');\n const normalizedContent = currentFileContent.replace(/\\r\\n/g, '\\n');\n\n if (!normalizedContent.includes(normalizedTarget)) {\n tui.log.error(`āŒ Target content not found in ${filePath} (checked with normalized line endings). Modification aborted.`);\n console.log(colors.dim('--- Target Content Expected ---'));\n console.log(targetContent.substring(0, 200) + '...');\n return false;\n }\n\n // 2. Validation: Is it unique?\n const occurrences = currentFileContent.split(targetContent).length - 1;\n if (occurrences > 1) {\n tui.log.error(`āŒ Ambiguous target: Found ${occurrences} occurrences in ${filePath}. Modification aborted.`);\n return false;\n }\n\n // 3. Apply Replacement\n const BOM = '\\uFEFF';\n const updatedContent = currentFileContent.replace(targetContent, newContent);\n const finalContent = updatedContent.startsWith(BOM) ? updatedContent : BOM + updatedContent;\n fs.writeFileSync(filePath, finalContent, { encoding: 'utf-8' });\n tui.log.success(`āœ… Smart Replace Applied: ${filePath}`);\n return true;\n}\n\nexport async function handleRunCommand(command: string): Promise<string> {\n const { spawn } = await import('node:child_process');\n try {\n tui.log.info(`šŸ’» Executing: ${colors.dim(command)}`);\n\n // Split command into cmd and args (naive split, use specific parser if needed for complex quotes)\n // For simplicity in Agent usage, we might act as a shell?\n // Let's use shell: true option for ease of piping/env usage.\n\n return new Promise((resolve) => {\n const child = spawn(command, {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: process.cwd()\n });\n\n let stdout = '';\n let stderr = '';\n\n // Timeout safety: 5 minutes\n const timer = setTimeout(() => {\n child.kill();\n resolve(`Error: Command timed out after 5 minutes.\\nOutput so far:\\n${stdout}\\n${stderr}`);\n }, 5 * 60 * 1000);\n\n child.stdout.on('data', (data) => {\n const chunk = data.toString();\n stdout += chunk;\n // Optional: Stream to TUI if verbose?\n });\n\n child.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n\n child.on('close', (code) => {\n clearTimeout(timer);\n if (code === 0) {\n resolve(stdout.trim() || 'Command executed successfully (no output).');\n } else {\n resolve(`Command failed with exit code ${code}.\\nSTDERR:\\n${stderr}\\nSTDOUT:\\n${stdout}`);\n }\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n resolve(`Error executing command: ${err.message}`);\n });\n });\n\n } catch (e: any) {\n return `Error launching command: ${e.message}`;\n }\n}\n\n\n/**\n * Resolves the ast-grep command to use.\n * Priorities:\n * 1. Package-local node_modules binary (for global installs)\n * 2. CWD node_modules binary (for local dev)\n * 3. Fallback to 'npx sg'\n */\nfunction resolveAstGrepCommand(): string {\n const isWin = process.platform === 'win32';\n const binName = isWin ? 'sg.cmd' : 'sg';\n\n // 1. Try to find binary relative to THIS file (package root)\n try {\n const currentFile = fileURLToPath(import.meta.url);\n // Go up until we find package root or hit root\n let dir = path.dirname(currentFile);\n\n // Simple heuristic: walk up up to 5 levels to find node_modules\n // When bundled, we might be in dist/ or dist/bin/\n for (let i = 0; i < 5; i++) {\n const candidate = path.join(dir, 'node_modules', '.bin', binName);\n if (fs.existsSync(candidate)) {\n return `\"${candidate}\"`;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch (e) {\n // Ignore errors resolving path\n }\n\n // 2. Try CWD (User's project)\n const cwdBin = path.resolve(process.cwd(), 'node_modules', '.bin', binName);\n if (fs.existsSync(cwdBin)) {\n return `\"${cwdBin}\"`;\n }\n\n // 3. Fallback\n return 'npx sg';\n}\n\n/**\n * Executes ast-grep search via local CLI.\n * Returns the raw output (JSON usually requested by consumer) or error message.\n */\nexport async function astGrepSearch(\n pattern: string,\n filePath: string,\n language: string,\n tui: any\n): Promise<string> {\n const { spawn } = await import('node:child_process');\n try {\n if (!fs.existsSync(filePath)) {\n return `āŒ File not found: ${filePath}`;\n }\n\n // Resolve sg command robustly\n const sgCmd = resolveAstGrepCommand();\n const cmd = `${sgCmd} run -p \"${pattern}\" -l ${language} --json ${filePath}`;\n\n tui.log.info(`šŸ” [AST-GREP] Searching: ${cmd}`);\n\n return new Promise((resolve) => {\n const child = spawn(cmd, {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: process.cwd(),\n env: { ...process.env, NO_COLOR: 'true' } // Avoid ANSI codes in JSON output\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (data) => stdout += data.toString());\n child.stderr.on('data', (data) => stderr += data.toString());\n\n child.on('close', (code) => {\n if (code === 0 && stdout) {\n resolve(stdout);\n } else if (code === 1 && !stderr) {\n // ast-grep finds simply nothing\n resolve(\"No structural matches found.\");\n } else {\n // Real error or no matches with empty stdout\n if (!stdout && !stderr) resolve(\"No structural matches found.\");\n else {\n tui.log.error(`āŒ ast-grep search error (code ${code}): ${stderr}`);\n resolve(`Error executing ast-grep search: ${stderr || stdout}`);\n }\n }\n });\n\n child.on('error', (err) => {\n resolve(`Error executing ast-grep search: ${err.message}`);\n });\n });\n\n } catch (e: any) {\n tui.log.error(`āŒ ast-grep search exception: ${e.message}`);\n return `Error executing ast-grep search: ${e.message}`;\n }\n}\n\n/**\n * Executes ast-grep rewrite via local CLI.\n * Returns boolean success/failure.\n */\nexport async function astGrepRewrite(\n pattern: string,\n fix: string,\n filePath: string,\n language: string,\n tui: any\n): Promise<boolean> {\n const { spawn } = await import('node:child_process');\n try {\n if (!fs.existsSync(filePath)) {\n tui.log.error(`āŒ File not found for AST modification: ${filePath}`);\n return false;\n }\n\n // Resolve sg command robustly\n const sgCmd = resolveAstGrepCommand();\n const cmd = `${sgCmd} run -p \"${pattern}\" -r \"${fix}\" -l ${language} ${filePath} --update-all`;\n\n tui.log.info(`āœļø [AST-GREP] Rewriting: pattern=\"${pattern}\" fix=\"${fix.substring(0, 50)}...\"`);\n\n return new Promise((resolve) => {\n const child = spawn(cmd, {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: process.cwd()\n });\n\n let stderr = '';\n child.stderr.on('data', (data) => stderr += data.toString());\n\n child.on('close', (code) => {\n if (code === 0) {\n tui.log.success(`āœ… AST Rewrite applied to ${filePath}`);\n resolve(true);\n } else {\n tui.log.error(`āŒ AST Rewrite failed (code ${code}): ${stderr}`);\n resolve(false);\n }\n });\n\n child.on('error', (err) => {\n tui.log.error(`āŒ AST Rewrite spawn error: ${err.message}`);\n resolve(false);\n });\n });\n\n } catch (e: any) {\n tui.log.error(`āŒ Unexpected error in astGrepRewrite: ${e.message}`);\n return false;\n }\n}\n\n// ═══════════════════════════════════════════════════════\n// AST TOOLS IMPLEMENTATION\n// ═══════════════════════════════════════════════════════\n\n/**\n * AST Tool: List file structure\n */\nexport async function astListStructure(filePath: string): Promise<string> {\n try {\n const editor = CodeEditorFactory.getEditor(filePath);\n\n if (!editor) {\n return `[AST Error] File type not supported: ${filePath}. Use read_file instead.`;\n }\n\n const structure: CodeStructure = await editor.listStructure(filePath);\n\n // Format for LLM consumption\n let output = `[AST Structure of ${filePath}]\\n\\n`;\n\n // Classes\n if (structure.classes.length > 0) {\n output += `CLASSES:\\n`;\n structure.classes.forEach(cls => {\n output += ` - ${cls.name}`;\n if (cls.extendsClass) output += ` extends ${cls.extendsClass}`;\n if (cls.implementsInterfaces.length > 0) {\n output += ` implements ${cls.implementsInterfaces.join(', ')}`;\n }\n output += `\\n`;\n\n if (cls.decorators.length > 0) {\n output += ` Decorators: ${cls.decorators.join(', ')}\\n`;\n }\n\n if (cls.properties.length > 0) {\n output += ` Properties:\\n`;\n cls.properties.forEach(prop => {\n output += ` - ${prop.visibility} ${prop.name}: ${prop.type}\\n`;\n });\n }\n\n if (cls.methods.length > 0) {\n output += ` Methods:\\n`;\n cls.methods.forEach(method => {\n const params = method.parameters.map(p => `${p.name}: ${p.type}`).join(', ');\n output += ` - ${method.visibility} ${method.name}(${params}): ${method.returnType}\\n`;\n });\n }\n output += `\\n`;\n });\n }\n\n // Interfaces\n if (structure.interfaces.length > 0) {\n output += `INTERFACES:\\n`;\n structure.interfaces.forEach(iface => {\n output += ` - ${iface.name}\\n`;\n iface.properties.forEach(prop => {\n output += ` ${prop.name}: ${prop.type}\\n`;\n });\n });\n output += `\\n`;\n }\n\n // Functions\n if (structure.functions.length > 0) {\n output += `FUNCTIONS:\\n`;\n structure.functions.forEach(fn => {\n const params = fn.parameters.map(p => `${p.name}: ${p.type}`).join(', ');\n output += ` - ${fn.name}(${params}): ${fn.returnType}\\n`;\n });\n output += `\\n`;\n }\n\n // Imports\n if (structure.imports.length > 0) {\n output += `IMPORTS:\\n`;\n structure.imports.forEach(imp => {\n output += ` - from \"${imp.modulePath}\": ${imp.namedImports.join(', ')}\\n`;\n });\n }\n\n return output;\n } catch (error: any) {\n return `[AST Error] ${error.message}`;\n }\n}\n\nexport async function astAddMethod(\n filePath: string,\n className: string,\n methodCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) {\n throw new Error(`No AST editor available for ${filePath}`);\n }\n return await editor.addMethod(filePath, className, methodCode);\n}\n\nexport async function astGetMethod(\n filePath: string,\n className: string,\n methodName: string\n): Promise<string> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) {\n throw new Error(`No AST editor available for ${filePath}`);\n }\n const methodContent = await editor.getMethod(filePath, className, methodName);\n if (!methodContent) {\n return `Method \"${methodName}\" not found in class \"${className}\"`;\n }\n return methodContent;\n}\n\nexport async function astAddClass(\n filePath: string,\n className: string,\n extendsClass?: string,\n implementsInterfaces?: string[]\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addClass(filePath, className, { extendsClass, implementsInterfaces });\n}\n\nexport async function astAddProperty(\n filePath: string,\n className: string,\n propertyCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addProperty(filePath, className, propertyCode);\n}\n\nexport async function astGetProperty(\n filePath: string,\n className: string,\n propertyName: string\n): Promise<string> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n const propContent = await editor.getProperty(filePath, className, propertyName);\n if (!propContent) {\n return `Property \"${propertyName}\" not found in class \"${className}\"`;\n }\n return propContent;\n}\n\nexport async function astModifyProperty(\n filePath: string,\n className: string,\n propertyName: string,\n propertyCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.modifyProperty(filePath, className, propertyName, propertyCode);\n}\n\nexport async function astRemoveProperty(\n filePath: string,\n className: string,\n propertyName: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.removeProperty(filePath, className, propertyName);\n}\n\nexport async function astModifyMethod(\n filePath: string,\n className: string,\n methodName: string,\n newBody: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.modifyMethod(filePath, className, methodName, newBody);\n}\n\nexport async function astRemoveMethod(\n filePath: string,\n className: string,\n methodName: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.removeMethod(filePath, className, methodName);\n}\n\nexport async function astAddDecorator(\n filePath: string,\n className: string,\n decoratorCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addDecorator(filePath, className, decoratorCode);\n}\n\nexport async function astAddInterface(\n filePath: string,\n interfaceCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addInterface(filePath, interfaceCode);\n}\n\nexport async function astAddTypeAlias(\n filePath: string,\n typeCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addTypeAlias(filePath, typeCode);\n}\n\nexport async function astAddFunction(\n filePath: string,\n functionCode: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addFunction(filePath, functionCode);\n}\n\nexport async function astRemoveFunction(\n filePath: string,\n functionName: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.removeFunction(filePath, functionName);\n}\n\nexport async function astAddImport(\n filePath: string,\n importStatement: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.addImport(filePath, importStatement);\n}\n\nexport async function astRemoveImport(\n filePath: string,\n modulePath: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.removeImport(filePath, modulePath);\n}\n\nexport async function astOrganizeImports(\n filePath: string\n): Promise<boolean> {\n const editor = CodeEditorFactory.getEditor(filePath);\n if (!editor) throw new Error(`AST editing not supported for: ${filePath}`);\n\n return await editor.organizeImports(filePath);\n}\n","import * as path from 'node:path';\nimport { CodeEditor } from '../interfaces/code-editor.interface.js';\nimport { TypeScriptEditor } from './typescript-editor.js';\n\nexport class CodeEditorFactory {\n private static tsEditor: TypeScriptEditor | null = null;\n\n /**\n * Returns appropriate editor for the file, or null if AST editing not supported\n */\n static getEditor(filePath: string): CodeEditor | null {\n const ext = path.extname(filePath).toLowerCase();\n\n // TypeScript/JavaScript\n if (['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {\n // Reuse singleton instance for performance (ts-morph Project is heavy)\n if (!this.tsEditor) {\n this.tsEditor = new TypeScriptEditor();\n }\n return this.tsEditor;\n }\n\n // HTML - TODO: Implement in Phase 2\n // if (ext === '.html') {\n // return new TreeSitterEditor('html');\n // }\n\n // For unsupported files, return null (will fallback to modify_file)\n return null;\n }\n\n /**\n * Clear cached editors (useful for testing)\n */\n static clearCache(): void {\n this.tsEditor = null;\n }\n}\n","import { Project, SourceFile, ClassDeclaration, SyntaxKind } from 'ts-morph';\nimport * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport { CodeEditor, ClassOptions } from '../interfaces/code-editor.interface.js';\nimport {\n CodeStructure,\n ClassInfo,\n MethodInfo,\n PropertyInfo\n} from '../interfaces/structure.types.js';\n\nexport class TypeScriptEditor implements CodeEditor {\n private project: Project;\n\n constructor() {\n this.project = new Project({\n skipAddingFilesFromTsConfig: true,\n compilerOptions: {\n target: 99, // ESNext\n module: 99, // ESNext\n },\n });\n }\n\n /**\n * Get or add source file to project\n */\n private getSourceFile(filePath: string): SourceFile {\n const absolutePath = path.resolve(filePath);\n\n // Check if already in project\n let sourceFile = this.project.getSourceFile(absolutePath);\n\n if (!sourceFile) {\n if (!fs.existsSync(absolutePath)) {\n throw new Error(`File not found: ${absolutePath}`);\n }\n sourceFile = this.project.addSourceFileAtPath(absolutePath);\n }\n\n return sourceFile;\n }\n\n /**\n * Get class declaration by name\n */\n private getClass(sourceFile: SourceFile, className: string): ClassDeclaration {\n const classDecl = sourceFile.getClass(className);\n if (!classDecl) {\n throw new Error(`Class \"${className}\" not found in ${sourceFile.getFilePath()}`);\n }\n return classDecl;\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: listStructure\n // ═══════════════════════════════════════════════════════\n\n async listStructure(filePath: string): Promise<CodeStructure> {\n const sourceFile = this.getSourceFile(filePath);\n\n // Extract classes\n const classes: ClassInfo[] = sourceFile.getClasses().map(cls => ({\n name: cls.getName() || '<anonymous>',\n methods: cls.getMethods().map(m => this.extractMethodInfo(m)),\n properties: cls.getProperties().map(p => this.extractPropertyInfo(p)),\n decorators: cls.getDecorators().map(d => d.getText()),\n extendsClass: cls.getExtends()?.getText(),\n implementsInterfaces: cls.getImplements().map(i => i.getText()),\n }));\n\n // Extract interfaces\n const interfaces = sourceFile.getInterfaces().map(iface => ({\n name: iface.getName(),\n properties: iface.getProperties().map(p => this.extractPropertyInfo(p)),\n extends: iface.getExtends().map(e => e.getText()),\n }));\n\n // Extract functions\n const functions = sourceFile.getFunctions().map(fn => ({\n name: fn.getName() || '<anonymous>',\n parameters: fn.getParameters().map(p => ({\n name: p.getName(),\n type: p.getType().getText(),\n isOptional: p.isOptional(),\n })),\n returnType: fn.getReturnType().getText(),\n isAsync: fn.isAsync(),\n isExported: fn.isExported(),\n }));\n\n // Extract imports\n const imports = sourceFile.getImportDeclarations().map(imp => ({\n modulePath: imp.getModuleSpecifierValue(),\n isDefault: !!imp.getDefaultImport(),\n namedImports: imp.getNamedImports().map(n => n.getName()),\n namespaceImport: imp.getNamespaceImport()?.getText(),\n }));\n\n // Extract exports\n const exports = sourceFile.getExportedDeclarations();\n const exportInfo = Array.from(exports.entries()).flatMap(([name, declarations]) =>\n declarations.map(decl => ({\n name,\n type: this.getDeclarationType(decl),\n isDefault: sourceFile.getDefaultExportSymbol()?.getName() === name,\n }))\n );\n\n return {\n classes,\n interfaces,\n functions,\n imports,\n exports: exportInfo,\n };\n }\n\n private extractMethodInfo(method: any): MethodInfo {\n return {\n name: method.getName(),\n parameters: method.getParameters().map((p: any) => ({\n name: p.getName(),\n type: p.getType().getText(),\n isOptional: p.isOptional(),\n })),\n returnType: method.getReturnType().getText(),\n isAsync: method.isAsync(),\n isStatic: method.isStatic(),\n visibility: this.getVisibility(method),\n decorators: method.getDecorators().map((d: any) => d.getText()),\n };\n }\n\n private extractPropertyInfo(property: any): PropertyInfo {\n return {\n name: property.getName(),\n type: property.getType()?.getText(),\n visibility: this.getVisibility(property),\n isReadonly: property.isReadonly(),\n initializer: property.getInitializer()?.getText(),\n };\n }\n\n private getVisibility(node: any): 'public' | 'private' | 'protected' {\n if (node.hasModifier?.(SyntaxKind.PrivateKeyword)) return 'private';\n if (node.hasModifier?.(SyntaxKind.ProtectedKeyword)) return 'protected';\n return 'public';\n }\n\n private getDeclarationType(decl: any): 'class' | 'function' | 'interface' | 'type' | 'const' {\n if (decl.getKind() === SyntaxKind.ClassDeclaration) return 'class';\n if (decl.getKind() === SyntaxKind.FunctionDeclaration) return 'function';\n if (decl.getKind() === SyntaxKind.InterfaceDeclaration) return 'interface';\n if (decl.getKind() === SyntaxKind.TypeAliasDeclaration) return 'type';\n return 'const';\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: Class Operations\n // ═══════════════════════════════════════════════════════\n\n async addClass(\n filePath: string,\n className: string,\n options?: ClassOptions\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n sourceFile.addClass({\n name: className,\n extends: options?.extendsClass,\n implements: options?.implementsInterfaces,\n isExported: true,\n });\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add class \"${className}\":`, error);\n return false;\n }\n }\n\n async addProperty(\n filePath: string,\n className: string,\n propertyCode: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n // Using insertText directly to support full property definitions\n const closeBrace = classDecl.getEnd() - 1;\n classDecl.insertText(closeBrace, `\\n ${propertyCode}`);\n\n // Reformat\n classDecl.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add property to \"${className}\":`, error);\n return false;\n }\n }\n\n async getProperty(\n filePath: string,\n className: string,\n propertyName: string\n ): Promise<string | undefined> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const property = classDecl.getProperty(propertyName);\n if (!property) {\n return undefined;\n }\n\n return property.getText();\n } catch (error) {\n console.error(`Failed to get property \"${propertyName}\":`, error);\n return undefined;\n }\n }\n\n async modifyProperty(\n filePath: string,\n className: string,\n propertyName: string,\n newCode: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const property = classDecl.getProperty(propertyName);\n if (!property) {\n throw new Error(`Property \"${propertyName}\" not found in class \"${className}\"`);\n }\n\n // Replace the entire property text\n property.replaceWithText(newCode);\n\n // Reformat\n classDecl.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to modify property \"${propertyName}\":`, error);\n return false;\n }\n }\n\n async removeProperty(\n filePath: string,\n className: string,\n propertyName: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const property = classDecl.getProperty(propertyName);\n if (!property) {\n throw new Error(`Property \"${propertyName}\" not found in class \"${className}\"`);\n }\n\n property.remove();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to remove property \"${propertyName}\":`, error);\n return false;\n }\n }\n\n async addMethod(\n filePath: string,\n className: string,\n methodCode: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n // Method code is likely \"methodName(...) { ... }\"\n // We can insert this as text.\n const closeBrace = classDecl.getEnd() - 1;\n classDecl.insertText(closeBrace, `\\n ${methodCode}\\n`);\n\n classDecl.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add method to \"${className}\":`, error);\n return false;\n }\n }\n\n async modifyMethod(\n filePath: string,\n className: string,\n methodName: string,\n newBody: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const method = classDecl.getMethod(methodName);\n if (!method) {\n throw new Error(`Method \"${methodName}\" not found in class \"${className}\"`);\n }\n\n method.setBodyText(newBody);\n\n // Optional: reformat\n method.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to modify method \"${methodName}\":`, error);\n return false;\n }\n }\n\n async removeMethod(\n filePath: string,\n className: string,\n methodName: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const method = classDecl.getMethod(methodName);\n if (!method) {\n throw new Error(`Method \"${methodName}\" not found in class \"${className}\"`);\n }\n\n method.remove();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to remove method \"${methodName}\":`, error);\n return false;\n }\n }\n\n async addDecorator(\n filePath: string,\n className: string,\n decoratorCode: string\n ): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n // Robust text-based insertion\n const start = classDecl.getStart();\n // Prefix the class with the decorator\n sourceFile.insertText(start, `${decoratorCode}\\n`);\n sourceFile.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add decorator to \"${className}\":`, error);\n return false;\n }\n }\n\n async getMethod(\n filePath: string,\n className: string,\n methodName: string\n ): Promise<string | undefined> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n const classDecl = this.getClass(sourceFile, className);\n\n const method = classDecl.getMethod(methodName);\n if (!method) {\n return undefined;\n }\n\n return method.getText();\n } catch (error) {\n console.error(`Failed to get method \"${methodName}\":`, error);\n return undefined;\n }\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: Interface/Type Operations\n // ═══════════════════════════════════════════════════════\n\n async addInterface(filePath: string, interfaceCode: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n // Add at the end of file\n sourceFile.insertText(sourceFile.getEnd(), `\\n\\n${interfaceCode}`);\n sourceFile.formatText();\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add interface:`, error);\n return false;\n }\n }\n\n async addTypeAlias(filePath: string, typeCode: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n sourceFile.insertText(sourceFile.getEnd(), `\\n\\n${typeCode}`);\n sourceFile.formatText();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add type alias:`, error);\n return false;\n }\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: Function Operations\n // ═══════════════════════════════════════════════════════\n\n async addFunction(filePath: string, functionCode: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n sourceFile.insertText(sourceFile.getEnd(), `\\n\\n${functionCode}`);\n sourceFile.formatText();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add function:`, error);\n return false;\n }\n }\n\n async removeFunction(filePath: string, functionName: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n const func = sourceFile.getFunction(functionName);\n if (!func) {\n throw new Error(`Function \"${functionName}\" not found`);\n }\n\n func.remove();\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to remove function \"${functionName}\":`, error);\n return false;\n }\n }\n\n // ═══════════════════════════════════════════════════════\n // IMPLEMENTATION: Import/Export Operations\n // ═══════════════════════════════════════════════════════\n\n async addImport(filePath: string, importStatement: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n const lastImport = sourceFile.getImportDeclarations().pop();\n const pos = lastImport ? lastImport.getEnd() : 0;\n\n sourceFile.insertText(pos, `\\n${importStatement}`);\n\n // Organize to clean up\n this.organizeImports(filePath);\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to add import:`, error);\n return false;\n }\n }\n\n async removeImport(filePath: string, modulePath: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n const importDecls = sourceFile.getImportDeclarations()\n .filter(imp => imp.getModuleSpecifierValue() === modulePath);\n\n if (importDecls.length === 0) {\n throw new Error(`Import from \"${modulePath}\" not found`);\n }\n\n importDecls.forEach(d => d.remove());\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to remove import from \"${modulePath}\":`, error);\n return false;\n }\n }\n\n async organizeImports(filePath: string): Promise<boolean> {\n try {\n const sourceFile = this.getSourceFile(filePath);\n\n sourceFile.organizeImports();\n\n // Fallback manual just in case:\n const imports = sourceFile.getImportDeclarations();\n const importStructure = imports.map(i => i.getStructure());\n\n // Sort by module specifier\n importStructure.sort((a, b) => {\n return a.moduleSpecifier.localeCompare(b.moduleSpecifier);\n });\n\n // Remove all\n imports.forEach(i => i.remove());\n\n // Re-add\n sourceFile.addImportDeclarations(importStructure);\n\n await sourceFile.save();\n return true;\n } catch (error) {\n console.error(`Failed to organize imports:`, error);\n return false;\n }\n }\n}\n","\nimport { Command } from 'commander';\nimport { interactiveScanAgent } from '../core/agents/scan-agent.js';\n\nexport const scanCommand = new Command('scan')\n .description('Analyze the project and generate context documentation')\n .option('-o, --output <path>', 'Output file path (default: _bmad/project-context/project-context.md)')\n .option('--depth <level>', 'Scan depth (quick, deep, exhaustive)', 'quick')\n .action(async (options) => {\n try {\n await interactiveScanAgent(options);\n } catch (error: any) {\n console.error('Error during scan:', error.message);\n process.exit(1);\n }\n });\n","\nimport { STACKSPOT_AGENT_API_BASE } from '../api/stackspot-client.js';\nimport { sseClient } from '../api/sse-client.js';\nimport { parseAgentResponse, AgentResponse } from './agent-response-parser.js';\nimport { conversationManager } from '../workflow/conversation-manager.js';\nimport { tokenStorage } from '../auth/token-storage.js';\nimport { getActiveRealm } from '../auth/get-active-realm.js';\nimport { tui } from '../../ui/tui.js';\nimport { colors } from '../../ui/colors.js';\nimport { FileLogger } from '../debug/file-logger.js';\nimport { handleListFiles, handleReadFile, handleSearchFile } from './agent-tools.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { ConfigManager } from '../config-manager.js';\nimport { t } from '../i18n/index.js';\n\nconst AGENT_TYPE = 'scan_agent';\n\nfunction getAgentId(): string {\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.scan) return config.agents.scan;\n return process.env.STACKSPOT_SCAN_AGENT_ID || '01KEQ9AHWB550J2244YBH3QATN';\n}\n\n/**\n * Scan Agent implementation.\n * It autonomously explores the project and generates project-context.md\n */\nexport async function interactiveScanAgent(options: { output?: string, depth?: string } = {}): Promise<void> {\n FileLogger.init();\n const config = ConfigManager.getInstance().getConfig();\n const language = config.language || 'English';\n\n tui.intro(t('commands.scan.intro'));\n\n const projectRoot = process.cwd();\n // Use options.output if provided, otherwise default to _sharkrc/project-context.md\n // If output option is provided, resolve it.\n // If not, use _sharkrc directory (create if needed).\n\n let outputFile: string;\n\n if (options.output) {\n outputFile = path.resolve(process.cwd(), options.output);\n } else {\n const outputDir = path.resolve(projectRoot, '_sharkrc');\n if (!fs.existsSync(outputDir)) {\n // Check if _sharkrc exists as a file (common config file name), if so, error or warn?\n // User requested \"pasta _sharkrc\".\n const stat = fs.existsSync(outputDir) ? fs.statSync(outputDir) : null;\n if (stat && stat.isFile()) {\n tui.log.warning(`Warning: '_sharkrc' exists as a file. Using '_bmad/project-context' instead to avoid overwrite.`);\n const fallbackDir = path.resolve(projectRoot, '_bmad/project-context');\n if (!fs.existsSync(fallbackDir)) fs.mkdirSync(fallbackDir, { recursive: true });\n outputFile = path.join(fallbackDir, 'project-context.md');\n } else {\n fs.mkdirSync(outputDir, { recursive: true });\n outputFile = path.join(outputDir, 'project-context.md');\n }\n } else {\n fs.mkdirSync(outputDir, { recursive: true });\n outputFile = path.join(outputDir, 'project-context.md');\n }\n }\n\n tui.log.info(`${t('commands.scan.scanningProject')} ${colors.bold(projectRoot)}`);\n tui.log.info(`${t('commands.scan.outputTarget')} ${colors.bold(outputFile)}`);\n tui.log.info(`${t('commands.scan.language')} ${colors.bold(language)}`);\n\n const configFileRelative = path.relative(projectRoot, outputFile);\n\n // Create template file automatically before starting scan\n const initialTemplate = `# Project Context\n\n## Overview\n[TO BE ANALYZED]\n\n## Tech Stack\n[TO BE ANALYZED]\n\n## Architecture\n[TO BE ANALYZED]\n\n## Directory Structure\n[TO BE ANALYZED]\n\n## Key Components\n[TO BE ANALYZED]\n\n## API / Interfaces\n[TO BE ANALYZED]\n\n## Data Layer\n[TO BE ANALYZED]\n\n## Configuration & Environment\n[TO BE ANALYZED]\n\n## Build & Development\n[TO BE ANALYZED]\n\n## Key Patterns & Conventions\n[TO BE ANALYZED]\n`;\n\n // Create the template file immediately\n if (!fs.existsSync(outputFile)) {\n const BOM = '\\uFEFF';\n fs.writeFileSync(outputFile, BOM + initialTemplate, { encoding: 'utf-8' });\n tui.log.success(`${t('commands.scan.templateCreated')} ${outputFile}`);\n } else {\n tui.log.info(t('commands.scan.fileExists'));\n }\n\n // Construct the \"Super Prompt\"\n const superPrompt = `\nYou are the **Scan Agent**, an expert software architect and analyst.\nYour mission is to explore this project's codebase THOROUGHLY and generate a COMPREHENSIVE context file that will be used by other AI agents (specifically a Developer Agent) to understand how to work on this project.\n\n**IMPORTANT**: The file \\`${configFileRelative}\\` has already been created with a template structure. Your job is to FILL IN each section by analyzing the project.\n\n**LANGUAGE INSTRUCTION**:\nYou MUST write the content in **${language}**.\n\n**CRITICAL STRATEGY - INCREMENTAL UPDATES**:\nDO NOT try to rewrite the entire file at once! Instead:\n\n1. **Explore** the project using \\`list_files\\`, \\`read_file\\`, \\`search_file\\`\n2. **Update** specific sections incrementally using \\`modify_file\\`\n3. **Benefit**: Build a MUCH MORE DETAILED document without context size limitations\n\n**WORKFLOW - FILL EACH SECTION:**\n\n**Step 1 - Analyze Tech Stack:**\n- \\`list_files\\` root directory to see project structure\n- \\`read_file\\` package.json (or pom.xml, go.mod, requirements.txt, etc.)\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Tech Stack\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Detailed tech stack with versions, dependencies, and their purposes\n\n**Step 2 - Analyze Directory Structure:**\n- \\`list_files\\` on ALL key directories (src, tests, config, docs, etc.)\n- Map the complete directory tree\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Directory Structure\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Visual directory tree with purpose of each folder\n\n**Step 3 - Analyze Architecture:**\n- \\`read_file\\` entry points (main.ts, index.js, app.py, etc.)\n- \\`read_file\\` 5-10 source files to understand code patterns and organization\n- Identify architectural pattern (Clean Arch, MVC, Microservices, etc.)\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Architecture\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Comprehensive architectural description with patterns and module organization\n\n**Step 4 - Document Components:**\n- Identify ALL major modules/components by reading source files\n- For each component: location, purpose, key files\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Key Components\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Detailed list of components with their purposes\n\n**Step 5 - Document APIs (if applicable):**\n- Search for route definitions, controllers, API endpoints\n- Document base URL, main endpoints, request/response patterns\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## API / Interfaces\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: API documentation (or \"Not applicable\" if no API)\n\n**Step 6 - Document Data Layer (if applicable):**\n- Search for database configs, ORM setup, model definitions\n- Document database type, ORM tool, key entities/tables\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Data Layer\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Data layer details (or \"Not applicable\" if no database)\n\n**Step 7 - Configuration & Environment:**\n- Read config files (.env.example, config/, etc.)\n- Identify environment variables and their purposes\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Configuration & Environment\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: List of env vars and config files\n\n**Step 8 - Build & Development:**\n- Read package.json scripts, Makefile, build configs\n- Document dev, build, test, lint commands\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Build & Development\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Commands for development workflow\n\n**Step 9 - Patterns & Conventions:**\n- Based on files read, document naming conventions, code organization\n- Note error handling, logging strategies\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Key Patterns & Conventions\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Observed patterns and conventions\n\n**Step 10 - Overview (LAST):**\n- Synthesize all findings into a comprehensive overview\n- \\`modify_file\\` to replace:\n - \\`target_content\\`: \"## Overview\\\\n[TO BE ANALYZED]\"\n - \\`content\\`: Detailed project description with purpose and main functionality\n\n**HOW TO USE modify_file:**\n\\`\\`\\`json\n{\n \"actions\": [{\n \"type\": \"modify_file\",\n \"path\": \"${configFileRelative}\",\n \"target_content\": \"## Tech Stack\\\\n[TO BE ANALYZED]\",\n \"content\": \"## Tech Stack\\\\n- **Language**: TypeScript 5.3\\\\n- **Runtime**: Node.js 20.x\\\\n...\"\n }]\n}\n\\`\\`\\`\n\n\\`\\`\\`markdown\n# Project Context\n\n## Overview\n[TO BE ANALYZED]\n\n## Tech Stack\n[TO BE ANALYZED]\n\n## Architecture\n[TO BE ANALYZED]\n\n## Directory Structure\n[TO BE ANALYZED]\n\n## Key Components\n[TO BE ANALYZED]\n\n## API / Interfaces\n[TO BE ANALYZED]\n\n## Data Layer\n[TO BE ANALYZED]\n\n## Configuration & Environment\n[TO BE ANALYZED]\n\n## Build & Development\n[TO BE ANALYZED]\n\n## Key Patterns & Conventions\n[TO BE ANALYZED]\n\\`\\`\\`\n\n**Step 2 - Explore and Update Incrementally:**\nAfter creating the template, perform these analyses and UPDATE each section:\n\n**2.1 - Analyze Tech Stack:**\n- \\`list_files\\` root directory\n- \\`read_file\\` package.json (or equivalent manifest)\n- \\`modify_file\\` to replace \"## Tech Stack\\\\n[TO BE ANALYZED]\" with detailed findings\n\n**2.2 - Analyze Directory Structure:**\n- \\`list_files\\` on key directories (src, tests, config, etc.)\n- \\`modify_file\\` to replace \"## Directory Structure\\\\n[TO BE ANALYZED]\" with complete structure\n\n**2.3 - Analyze Architecture:**\n- \\`read_file\\` entry points (main.ts, index.js, etc.)\n- \\`read_file\\` 5-10 source files to understand patterns\n- \\`modify_file\\` to replace \"## Architecture\\\\n[TO BE ANALYZED]\" with architectural insights\n\n**2.4 - Document Components:**\n- Identify major modules/components\n- \\`modify_file\\` to replace \"## Key Components\\\\n[TO BE ANALYZED]\" with component details\n\n**2.5 - Document APIs (if applicable):**\n- Search for route definitions, controllers, API endpoints\n- \\`modify_file\\` to replace \"## API / Interfaces\\\\n[TO BE ANALYZED]\"\n\n**2.6 - Document Data Layer (if applicable):**\n- Search for database configs, ORM, models\n- \\`modify_file\\` to replace \"## Data Layer\\\\n[TO BE ANALYZED]\"\n\n**2.7 - Final Touches:**\n- Update remaining sections (Config, Build, Patterns)\n- Ensure Overview is comprehensive\n\n**HOW TO USE modify_file:**\n\\`\\`\\`json\n{\n \"actions\": [{\n \"type\": \"modify_file\",\n \"path\": \"${configFileRelative}\",\n \"target_content\": \"## Tech Stack\\\\n[TO BE ANALYZED]\",\n \"content\": \"## Tech Stack\\\\n- **Language**: TypeScript 5.3\\\\n- **Runtime**: Node.js 20.x\\\\n- **Framework**: Express 4.18\\\\n...\"\n }]\n}\n\\`\\`\\`\n\n**SECTION TEMPLATES (For your updates):**\n\n**Tech Stack:**\n\\`\\`\\`markdown\n## Tech Stack\n- **Language**: [name + version]\n- **Runtime**: [name + version]\n- **Framework**: [name + version]\n- **Build Tool**: [name]\n- **Testing**: [framework]\n- **Key Dependencies**:\n - [dep-name]: [purpose]\n - [dep-name]: [purpose]\n\\`\\`\\`\n\n**Architecture:**\n\\`\\`\\`markdown\n## Architecture\n[Comprehensive description]\n- **Pattern**: [Clean Arch, MVC, etc.]\n- **Module Organization**: [how modules are structured]\n- **Layer Separation**: [controllers, services, repos]\n- **Configuration**: [how config is managed]\n\\`\\`\\`\n\n**Directory Structure:**\n\\`\\`\\`markdown\n## Directory Structure\n\\\\\\`\\\\\\`\\\\\\`\n/src\n /core - [Purpose]\n /commands - [Purpose]\n /ui - [Purpose]\n/tests - [Purpose]\n/docs - [Purpose]\n\\\\\\`\\\\\\`\\\\\\`\n\\`\\`\\`\n\n**Key Components:**\n\\`\\`\\`markdown\n## Key Components\n\n### [Component Name 1]\n- **Location**: \\\\\\`path/to/component\\\\\\`\n- **Purpose**: [What it does]\n- **Key Files**: [Important files]\n\n### [Component Name 2]\n- **Location**: \\\\\\`path/to/component\\\\\\`\n- **Purpose**: [What it does]\n- **Key Files**: [Important files]\n\\`\\`\\`\n\n**DEPTH REQUIREMENT**:\n- Read MULTIPLE files (5-10 minimum) to understand patterns\n- Identify ALL major modules/components\n- Document API routes, database schemas if applicable\n- Note design patterns and architectural decisions\n- List important dependencies with their purposes\n\n**RULES**:\n- Create template FIRST (step 1)\n- Update sections INCREMENTALLY (steps 2-7)\n- Do NOT wait to write everything at the end\n- Use \\`modify_file\\` to replace \"[TO BE ANALYZED]\" sections\n- Be DETAILED and COMPREHENSIVE\n- Take your time - you have up to 30 steps\n- Verify facts with \\`read_file\\` or \\`search_file\\` before documenting\n`.trim();\n\n await runScanLoop(superPrompt, outputFile);\n}\n\n// ... (rest of the file)\n\nasync function runScanLoop(initialPrompt: string, targetPath: string) {\n let nextPrompt = initialPrompt;\n let keepGoing = true;\n let stepCount = 0;\n const MAX_STEPS = 60; // Safety limit - increased for deeper analysis\n\n while (keepGoing && stepCount < MAX_STEPS) {\n stepCount++;\n const spinner = tui.spinner();\n const msg = t('commands.scan.analyzing').replace('{step}', stepCount.toString());\n spinner.start(msg);\n\n let responseText = '';\n let lastResponse: AgentResponse | null = null;\n\n try {\n // Call Agent\n lastResponse = await callScanAgentApi(nextPrompt, (chunk) => {\n responseText += chunk;\n // Optional: Update spinner message based on chunk if needed\n });\n\n spinner.stop(t('commands.scan.stepComplete'));\n\n // Handle Response Actions\n if (lastResponse && lastResponse.actions && lastResponse.actions.length > 0) {\n let executionResults = \"\";\n let fileCreated = false;\n\n for (const action of lastResponse.actions) {\n if (action.type === 'list_files') {\n tui.log.info(t('commands.scan.scanningDir').replace('{0}', colors.bold(action.path || '.')));\n const result = handleListFiles(action.path || '.');\n executionResults += `[Action list_files(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'read_file') {\n tui.log.info(t('commands.scan.readingFile').replace('{0}', colors.bold(action.path || '')));\n const result = handleReadFile(action.path || '');\n // Truncate if too long for context window? Agent Tools already limits size.\n executionResults += `[Action read_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'search_file') {\n tui.log.info(t('commands.scan.searching').replace('{0}', colors.bold(action.path || '')));\n const result = handleSearchFile(action.path || '');\n executionResults += `[Action search_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'create_file' || action.type === 'modify_file') {\n // Check if this is our target file\n // The agent might try to create other files, but we mainly care about the context file.\n // We will allow it to create the target file automatically without prompt if it matches.\n\n // For safety, let's just confirm. Or since this is \"Scan\", maybe we auto-accept?\n // Let's auto-accept if it is the target file, confirm otherwise.\n const resolvedActionPath = path.resolve(action.path || '');\n const resolvedTargetPath = path.resolve(targetPath);\n let isTarget = resolvedActionPath === resolvedTargetPath;\n\n // Fallback: If agent uses wrong directory but correct filename \"project-context.md\", allow it and force correct path.\n if (!isTarget && path.basename(action.path || '') === 'project-context.md') {\n tui.log.warning(t('commands.scan.targetRedirect').replace('{0}', action.path || '').replace('{1}', path.relative(process.cwd(), targetPath)));\n isTarget = true;\n // Update action path for logging consistency (optional, but good for clarity)\n action.path = targetPath;\n }\n\n if (isTarget) {\n // Enforce writing to the correct targetPath regardless of what agent said\n const finalPath = targetPath;\n const BOM = '\\uFEFF';\n\n if (action.type === 'create_file') {\n const contentToWrite = action.content || '';\n const finalContent = contentToWrite.startsWith(BOM) ? contentToWrite : BOM + contentToWrite;\n fs.writeFileSync(finalPath, finalContent, { encoding: 'utf-8' });\n tui.log.success(t('commands.scan.generated').replace('{0}', finalPath));\n fileCreated = true;\n } else {\n // Modify Logic: Read, Replace, Write\n if (fs.existsSync(finalPath)) {\n const currentContent = fs.readFileSync(finalPath, 'utf-8');\n // action.target_content is needed for replacement\n if (action.target_content && currentContent.includes(action.target_content)) {\n const newContent = currentContent.replace(action.target_content, action.content || '');\n const finalContent = newContent.startsWith(BOM) ? newContent : BOM + newContent;\n fs.writeFileSync(finalPath, finalContent, { encoding: 'utf-8' });\n tui.log.success(t('commands.scan.updated').replace('{0}', finalPath));\n fileCreated = true;\n } else {\n // Fallback: If no target_content or target not found, what to do?\n // For Scan Agent incremental strategy, this is a failure in the prompt following.\n // We log a warning.\n tui.log.warning(t('commands.scan.error') + ': ' + t('commands.scan.contentNotFound'));\n executionResults += `[Action ${action.type}]: Failed. Target content not found in file.\\n`;\n // Continue loop to give agent a chance to fix?\n fileCreated = false;\n }\n } else {\n // File doesn't exist, treat as create?\n // But it should exist as template.\n tui.log.warning(t('commands.scan.error') + ': ' + t('commands.scan.notFound'));\n }\n }\n executionResults += `[Action ${action.type}]: Success. Task Completed.\\n`;\n } else {\n tui.log.warning(t('commands.scan.error')); // Using generic error for unexpected file write attempt\n // Skip for now to avoid side effects during scan, or ask user?\n // Let's just log it.\n executionResults += `[Action ${action.type}]: ${t('commands.scan.skipped')}\\n`;\n }\n }\n else if (action.type === 'talk_with_user') {\n tui.log.info(colors.primary(t('commands.scan.agentAsks')));\n console.log(action.content);\n // We don't really want to chat during auto-scan, but if it asks, we should probably answer or stop.\n // For now, let's stop and ask user.\n const reply = await tui.text({ message: t('commands.scan.agentInput'), placeholder: t('commands.scan.replyPlaceholder') });\n executionResults += `[User Reply]: ${reply}\\n`;\n }\n }\n\n if (fileCreated) {\n // Check for pending sections to guide the agent\n const currentContent = fs.readFileSync(targetPath, 'utf-8');\n const pendingSections: string[] = [];\n const lines = currentContent.split('\\n');\n let currentSection = '';\n\n for (const line of lines) {\n if (line.startsWith('## ')) {\n currentSection = line.substring(3).trim();\n }\n if (line.includes('[TO BE ANALYZED]')) {\n if (currentSection && !pendingSections.includes(currentSection)) {\n pendingSections.push(currentSection);\n }\n }\n }\n\n const pendingMsg = pendingSections.length > 0\n ? `\\n\\n[System Helper]: ${t('commands.scan.pendingSections').replace('{0}', pendingSections.join(', '))}`\n : `\\n\\n[System Helper]: ${t('commands.scan.allPopulated')}`;\n\n // Feed success back to agent so it can move to next section\n nextPrompt = `${executionResults}\\n\\n[System]: File updated successfully.${pendingMsg} Please continue with the next step of the analysis and focus on the pending sections.`;\n FileLogger.log('SCAN', 'Section updated, continuing loop', { step: stepCount, pending: pendingSections.length });\n } else {\n // Feed results back (could be failure or just tool output)\n nextPrompt = executionResults;\n FileLogger.log('SCAN', 'Auto-replying with results', { length: executionResults.length });\n }\n\n } else {\n // No actions? Agent considers job done.\n tui.log.success(t('commands.scan.completed'));\n keepGoing = false;\n }\n\n } catch (error: any) {\n spinner.stop(t('common.error'));\n tui.log.error(error.message);\n keepGoing = false;\n }\n }\n}\n\n\nasync function callScanAgentApi(prompt: string, onChunk: (chunk: string) => void): Promise<AgentResponse> {\n const realm = await getActiveRealm();\n const token = await tokenStorage.getToken(realm);\n if (!token) throw new Error('Not logged in');\n\n // Generate a temporary conversation ID for this scan session\n // We might not need to persist it long-term, but we need one for the session.\n // Or we rely on the one returned.\n let conversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n // If no conversation exists, that's fine, API will create one.\n\n const payload = {\n user_prompt: prompt,\n streaming: true,\n stackspot_knowledge: false,\n return_ks_in_response: true,\n use_conversation: true,\n conversation_id: conversationId\n };\n\n const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId()}/chat`;\n let fullMsg = '';\n let raw: any = {};\n\n FileLogger.log('SCAN', 'Calling API', { promptLength: prompt.length });\n\n await sseClient.streamAgentResponse(url, payload, { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, {\n onChunk: (c) => { fullMsg += c; onChunk(c); },\n onComplete: (msg, metadata) => {\n const returnedId = metadata?.conversation_id;\n raw = {\n message: msg || fullMsg,\n conversation_id: returnedId || conversationId\n };\n },\n onError: (e) => { throw e; }\n });\n\n const parsed = parseAgentResponse(raw);\n if (parsed.conversation_id) {\n await conversationManager.saveConversationId(AGENT_TYPE, parsed.conversation_id);\n }\n return parsed;\n}\n","\nimport { Command } from 'commander';\nimport { interactiveDeveloperAgent, DevelopmentResult } from '../core/agents/developer-agent.js';\nimport { TaskManager } from '../core/workflow/task-manager.js';\nimport { tui } from '../ui/tui.js';\nimport { colors } from '../ui/colors.js';\nimport { interactiveSpecificationAgent, SpecAgentOptions } from '../core/agents/specification-agent.js'; // We might need a programmatic way to call this too\n\n// We need a programmatic interface to Spec Agent for \"Pivot\". \n// For now, let's assume we can re-enter the interactive Spec Agent or we just let User edit file manually if they want major changes.\n// Or better: We instantiate Spec Agent with a specific 'instruction' to update spec.\n// Let's implement the loop first.\n\nexport const devCommand = new Command('dev')\n .description('Starts the Shark Developer Agent (Shark Dev Orchestration V2)')\n .option('-t, --task <type>', 'Initial task description (Quick Mode)')\n .option('-c, --context <path>', 'Path to custom context file')\n .action(async (options) => {\n const taskManager = new TaskManager(process.cwd());\n\n // 1. Check State\n let state = taskManager.analyzeSpecState();\n\n if (state.status === 'MISSING') {\n tui.log.warning('šŸ“‹ No tech-spec.md found.');\n const confirm = await tui.confirm({ message: 'Create a new Specification (Tech Spec)?' });\n if (confirm) {\n // Handover to Spec Agent\n await interactiveSpecificationAgent({\n briefingPath: options.task ? undefined : undefined // If task provided, maybe write a temp briefing? For now standard flow.\n });\n // Re-analyze after spec agent returns\n state = taskManager.analyzeSpecState();\n if (state.status === 'MISSING') {\n tui.log.error('āŒ Spec creation aborted or failed.');\n return;\n }\n } else {\n return;\n }\n }\n\n // 2. Orchestration Loop\n let keepOrchestrating = true;\n let burnMode = false; // \"Auto\" mode\n let contextHistory = \"\";\n\n tui.intro('🦈 Shark Orchestrator V2');\n\n while (keepOrchestrating) {\n state = taskManager.analyzeSpecState();\n\n if (state.status === 'COMPLETED') {\n tui.log.success('šŸŽ‰ All tasks in tech-spec.md are COMPLETED!');\n // Ask if they want to add more?\n const choice = await tui.select({\n message: 'What next?',\n options: [\n { value: 'exit', label: 'Exit' },\n { value: 'new_spec', label: 'New Specification (Reset)' }\n ]\n });\n if (choice === 'new_spec') {\n await interactiveSpecificationAgent();\n contextHistory = \"\"; // Reset history for new spec\n continue; // Loop again\n } else {\n keepOrchestrating = false;\n break;\n }\n }\n\n const currentTask = state.nextTask;\n if (!currentTask) {\n tui.log.error('Something went wrong. Status is not completed but no next task found.');\n break;\n }\n\n tui.log.info(`\\nšŸ‘‰ **NEXT TASK**: ${colors.bold(currentTask.description)}`);\n\n // Confirm Execution (unless Burn Mode)\n if (!burnMode) {\n const action = await tui.select({\n message: 'Orchestration Checkpoint:',\n options: [\n { value: 'execute', label: 'šŸš€ Execute Task (Start)' },\n { value: 'burn', label: 'šŸ”„ Burn Mode (Auto-Execute Remaining)' },\n { value: 'pivot', label: 'šŸ”§ Pivot/Correct (Edit Spec)' },\n { value: 'skip', label: 'ā­ļø Skip Task (Mark Done without Executing)' },\n { value: 'stop', label: 'šŸ›‘ Stop Session' }\n ]\n });\n\n if (action === 'stop') {\n keepOrchestrating = false;\n break;\n } else if (action === 'burn') {\n burnMode = true;\n } else if (action === 'skip') {\n taskManager.markTaskAsDone(currentTask.id);\n tui.log.info('Task skipped.');\n continue;\n } else if (action === 'pivot') {\n tui.log.info('Transferring control to Specification Agent...');\n // Ideally we pass context of \"Why we are pivoting\"\n await interactiveSpecificationAgent({\n initialContext: `User requested pivot after tasks:\\n${contextHistory}`\n });\n // State will be refreshed at start of loop\n continue;\n }\n }\n\n // Exceute Agent\n // Mark as IN_PROGRESS\n taskManager.markTaskInProgress(currentTask.id);\n\n tui.log.info(`⚔ Starting Micro-Context for Task: \"${currentTask.description}\"`);\n\n const result: DevelopmentResult = await interactiveDeveloperAgent({\n taskId: currentTask.id,\n taskInstruction: currentTask.description,\n history: contextHistory,\n context: options.context\n });\n\n if (result.success) {\n tui.log.success(`āœ… Task Completed: ${currentTask.description}`);\n taskManager.markTaskAsDone(currentTask.id);\n\n // Update History for next task\n contextHistory += `\\n[Task \"${currentTask.description}\" completed]: ${result.summary}`;\n } else {\n tui.log.error(`āŒ Task Failed: ${result.summary}`);\n burnMode = false; // Stop burn mode on failure\n\n const recovery = await tui.select({\n message: 'Task Failed. Recovery Action:',\n options: [\n { value: 'retry', label: 'Retry (Run Agent Again)' },\n { value: 'pivot', label: 'Pivot (Adjust Spec/Instructions)' },\n { value: 'ignore', label: 'Ignore (Mark Done anyway)' },\n { value: 'stop', label: 'Stop' }\n ]\n });\n\n if (recovery === 'stop') break;\n if (recovery === 'ignore') taskManager.markTaskAsDone(currentTask.id);\n if (recovery === 'pivot') {\n await interactiveSpecificationAgent({\n initialContext: `Task \"${currentTask.description}\" FAILED.\\nError: ${result.summary}\\nHistory:\\n${contextHistory}`\n });\n }\n // retry falls through to loop start (which re-fetches task)\n }\n }\n\n tui.outro('🦈 Orchestration Finished.');\n });\n","\nimport { STACKSPOT_AGENT_API_BASE, ensureValidToken } from '../api/stackspot-client.js';\nimport { sseClient } from '../api/sse-client.js';\nimport { parseAgentResponse, AgentResponse, AgentAction } from './agent-response-parser.js';\nimport { conversationManager } from '../workflow/conversation-manager.js';\nimport { tokenStorage } from '../auth/token-storage.js';\nimport { getActiveRealm } from '../auth/get-active-realm.js';\nimport { tui } from '../../ui/tui.js';\nimport { colors } from '../../ui/colors.js';\nimport { ConfigManager } from '../config-manager.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { FileLogger } from '../debug/file-logger.js';\nimport {\n handleListFiles,\n handleReadFile,\n handleSearchFile,\n startSmartReplace,\n replaceLineRange,\n handleRunCommand,\n astGrepSearch,\n astGrepRewrite,\n generateFilePreview,\n astListStructure,\n astAddMethod,\n astGetMethod,\n astAddClass,\n astGetProperty,\n astAddProperty,\n astRemoveProperty,\n astModifyMethod,\n astRemoveMethod,\n astAddDecorator,\n astAddInterface,\n astAddTypeAlias,\n astAddFunction,\n astRemoveFunction,\n astAddImport,\n astRemoveImport,\n astOrganizeImports,\n astModifyProperty\n} from './agent-tools.js';\nimport { t } from '../i18n/index.js';\n\nconst AGENT_TYPE = 'developer_agent';\n\n// Validation Functions\nasync function validateTypeScript(filePath: string): Promise<{ valid: boolean, error?: string }> {\n try {\n const result = await handleRunCommand(`npx tsc --noEmit --skipLibCheck ${filePath}`);\n if (result.trim() === '' || !result.includes('error TS')) {\n return { valid: true };\n }\n return { valid: false, error: result };\n } catch (e: any) {\n return { valid: false, error: e.message || 'TypeScript validation failed' };\n }\n}\n\nfunction validateHtmlTagBalance(filePath: string): { valid: boolean, error?: string } {\n const content = fs.readFileSync(filePath, 'utf-8');\n const stack: string[] = [];\n const tagRegex = /<\\/?(\\w+)(?:\\s[^>]*)?\\s*\\/?>/g;\n const selfClosingTags = ['br', 'hr', 'img', 'input', 'meta', 'link', 'area', 'base', 'col', 'embed', 'param', 'source', 'track', 'wbr'];\n\n let match;\n while ((match = tagRegex.exec(content)) !== null) {\n const fullTag = match[0];\n const tagName = match[1].toLowerCase();\n\n if (fullTag.startsWith('</')) {\n const expected = stack.pop();\n if (expected !== tagName) {\n return {\n valid: false,\n error: `Tag mismatch: expected </${expected}> but found </${tagName}> at position ${match.index}`\n };\n }\n } else if (!fullTag.endsWith('/>') && !selfClosingTags.includes(tagName)) {\n stack.push(tagName);\n }\n }\n\n if (stack.length > 0) {\n return { valid: false, error: `Unclosed tags: <${stack.join('>, <')}>` };\n }\n\n return { valid: true };\n}\n\n// Helper to get effective Agent ID\nfunction getAgentId(overrideId?: string): string {\n if (overrideId) return overrideId;\n\n // Check Config\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.dev) return config.agents.dev;\n\n // Check Env\n if (process.env.STACKSPOT_DEV_AGENT_ID) return process.env.STACKSPOT_DEV_AGENT_ID;\n\n // Default\n return '01KEQCGJ65YENRA4QBXVN1YFFX';\n}\n\ninterface SpecState {\n status: 'MISSING' | 'PENDING' | 'COMPLETED';\n nextTask?: string;\n specContent?: string;\n}\n\nfunction analyzeSpecState(projectRoot: string): SpecState {\n const specPath = path.resolve(projectRoot, '_sharkrc', 'tech-spec.md');\n if (!fs.existsSync(specPath)) {\n return { status: 'MISSING' };\n }\n\n const content = fs.readFileSync(specPath, 'utf-8');\n // Regex for unchecked task: - [ ] Task description\n // Capture the line content - simple regex, can be improved for nested lists if needed\n const match = content.match(/- \\[ \\] (.*)/);\n\n if (match) {\n return { status: 'PENDING', nextTask: match[1].trim(), specContent: content };\n }\n\n return { status: 'COMPLETED', specContent: content };\n}\n\nfunction buildSystemPrompt(state: SpecState, contextContent: string, additionalInstructions: string = ''): string {\n let basePrompt = ``;\n\n if (contextContent) {\n basePrompt += `\\n\\n--- PROJECT CONTEXT ---\\n${contextContent}\\n-----------------------\\n`;\n }\n\n if (state.status === 'MISSING') {\n basePrompt += `\\n\\n🚨 CRITICAL: NO 'tech-spec.md' FOUND.\\n\nYour FIRST priority is to analyze the user request and CREATE a 'tech-spec.md' file.\n\nāš ļø WORKFLOW:\n1. **Understand**: Clarify the goal with the user if needed.\n2. **Explore**: Use 'list_files'/'read_file' to find RELEVANT files for this specific task.\n3. **Specify**: Create 'tech-spec.md' referencing REAL file paths you found.\n\nDO NOT create a spec based on guesses. Verify file existence before writing the plan.\n\nStructure for 'tech-spec.md':\n\\`\\`\\`markdown\n# Technical Spec: [Title]\n\n## Goal\n[Brief description]\n\n## Implementation Plan\n- [ ] Step 1: [Description]\n- [ ] Step 2: [Description]\n...\n\\`\\`\\`\nUser Request: \"${additionalInstructions}\"\n`;\n } else if (state.status === 'PENDING') {\n basePrompt += `\\n\\n🟢 EXECUTION MODE\\n\nUse 'tech-spec.md' as your source of truth.\n\\nšŸ‘‰ **CURRENT TASK**: \"${state.nextTask}\"\n\\n\nFocus ONLY on this task. Do not jump ahead.\n1. Implement the necessary changes.\n2. Verify (compile/test).\n3. **MANDATORY**: Use 'modify_file' to mark this task as '[x]' in 'tech-spec.md' when done.\n`;\n } else {\n basePrompt += `\\n\\n✨ ALL TASKS COMPLETED according to 'tech-spec.md'.\\n\nAsk the user if they want to add more tasks or finish the session.\n`;\n }\n\n return basePrompt;\n}\n\n\nexport interface DevelopmentResult {\n success: boolean;\n summary: string;\n}\n\nexport async function interactiveDeveloperAgent(options: {\n taskId?: string,\n taskInstruction?: string,\n context?: string,\n history?: string\n} = {}): Promise<DevelopmentResult> {\n FileLogger.init();\n // tui.intro('🦈 Shark Dev Agent (Scoped)'); // Reduced verbosity for orchestration loop\n\n const agentId = getAgentId();\n\n if (agentId === 'PENDING_CONFIGURATION') {\n tui.log.error('āŒ STACKSPOT_DEV_AGENT_ID not configured in .env');\n return { success: false, summary: \"Missing configuration.\" };\n }\n\n // 1. Load Context\n const projectRoot = process.cwd();\n let contextContent = '';\n const defaultContextPath = path.resolve(projectRoot, '_sharkrc', 'project-context.md');\n // If orchestrator passes the summary of previous tasks, we append it to context\n const specificContextPath = options.context ? path.resolve(projectRoot, options.context) : defaultContextPath;\n\n if (fs.existsSync(specificContextPath)) {\n try {\n contextContent = fs.readFileSync(specificContextPath, 'utf-8');\n // tui.log.info(`šŸ“˜ Context loaded from: ${colors.dim(path.relative(projectRoot, specificContextPath))}`);\n } catch (e) {\n tui.log.warning(`Failed to read context file: ${e}`);\n }\n }\n\n // 2. Build Scoped Prompt\n // Note: We are NOT calling analyzeSpecState here anymore. The Orchestrator tells us WHAT to do.\n const currentTask = options.taskInstruction || \"Analyze the project and fix pending issues.\";\n\n let basePrompt = ``;\n if (contextContent) {\n basePrompt += `\\n\\n--- PROJECT CONTEXT ---\\n${contextContent}\\n-----------------------\\n`;\n }\n\n // Inject History from previous turns (Orchestrator Responsibility)\n if (options.history) {\n basePrompt += `\\n\\n--- PREVIOUS EXECUTION SUMMARY ---\\n${options.history}\\n----------------------------------\\n`;\n }\n\n basePrompt += `\\n\\n🟢 EXECUTION MODE\\n\nYou are a highly skilled Developer Agent.\nšŸ‘‰ **CURRENT TASK**: \"${currentTask}\"\n\nYour goal is to COMPLETE this specific task and then STOP.\n1. Implement the necessary changes.\n2. Verify (compile/test).\n3. **MANDATORY**: When you are confident the task is done, output a final message starting with \"TASK_COMPLETED:\" followed by a brief technical summary of what you did.\n`;\n\n let nextPrompt = basePrompt;\n\n // 3. Main Loop\n let keepGoing = true;\n const spinner = tui.spinner();\n let finalSummary = \"\";\n let isTaskCompleted = false;\n\n // Force NEW Conversation ID for Statelessness\n // We update the conversation manager to a random ID or based on TaskID\n // To ensure we don't pollute the global 'developer_agent' state if we want true statelessness.\n // Ideally, we pass a specific conversation ID Key.\n const conversationKey = options.taskId ? `dev_agent_${options.taskId}` : `dev_agent_${Date.now()}`;\n // Resetting for safety if repeated calls\n // await conversationManager.saveConversationId(conversationKey, \"\"); \n\n // Auto-Approval State\n let autoApprovals = {\n files: false,\n commands: false\n };\n\n while (keepGoing) {\n try {\n spinner.start('🦈 Shark Dev working...');\n\n // Call API\n const lastResponse = await callDevAgentApi(nextPrompt, (chunk) => {\n // Optional: Stream text\n }, conversationKey);\n\n spinner.stop('Response received');\n\n if (lastResponse) {\n const response = lastResponse;\n const actions = response.actions || []; // Should be array by schema, but safe fallback\n\n // Check Global Message first (e.g. Completion or Failure)\n if (response.message && response.message.includes('TASK_COMPLETED:')) {\n isTaskCompleted = true;\n finalSummary = response.message.split('TASK_COMPLETED:')[1].trim();\n // We continue to process actions if any, but stop loop after\n keepGoing = false;\n }\n\n // Check for explicit task failure signal from agent\n if (response.message && response.message.includes('TASK_FAILED:')) {\n const failureReason = response.message.split('TASK_FAILED:')[1].trim();\n tui.log.error(`āŒ Agent reported task failure: ${failureReason}`);\n return { success: false, summary: failureReason };\n }\n\n // If we have just a message and NO actions (or empty actions), treat as talk\n if (actions.length === 0 && response.message && !isTaskCompleted) {\n tui.log.info(colors.primary('šŸ¤– Shark Dev:'));\n console.log(response.message);\n const userReply = await tui.text({ message: 'Your answer:' });\n if (tui.isCancel(userReply)) { keepGoing = false; break; }\n nextPrompt = userReply as string;\n }\n\n let executionResults = \"\";\n let waitingForUser = false;\n\n for (const action of actions) {\n\n // ... (Existing Tool Handling Logic - reusing almost 1:1, just cleaner logging) ...\n // [Optimization: I will minimize the copy-paste here by keeping the core logic but ensuring it writes to executionResults]\n\n if (action.type === 'talk_with_user') {\n tui.log.info(colors.primary('šŸ¤– Shark Dev:'));\n console.log(action.content);\n // If agent talks, we might need input. \n // In stateless mode, if it asks a question, we might bubble it up?\n // For now, let's keep the TUI interaction valid.\n if (!isTaskCompleted) waitingForUser = true;\n }\n\n // ... (Include all tool handlers from original code: list_files, read_file, run_command, modify_file, ast_*, etc.) ...\n // To avoid a massive edit block that might break, I will assume the original tool handlers logic is robust.\n // I will reinject strictly the necessary parts. \n // [Developer Note: For the sake of this edit, I have to replicate the tool logic to ensure the function works. \n // I'll condense the logging.]\n\n else if (action.type === 'list_files') {\n tui.log.info(`šŸ“‚ Scanning: ${colors.dim(action.path || '.')}`);\n const result = handleListFiles(action.path || '.');\n executionResults += `[Action list_files(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'read_file') {\n tui.log.info(`šŸ“– Reading: ${colors.dim(action.path || '')}`);\n const result = handleReadFile(action.path || '');\n executionResults += `[Action read_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'search_file') {\n const result = handleSearchFile(action.path || '');\n executionResults += `[Action search_file(${action.path}) Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'run_command') {\n const cmd = action.command || '';\n tui.log.info(`šŸ’» Executing: ${colors.dim(cmd)}`);\n // Auto-approval logic reuse\n let approved = autoApprovals.commands;\n if (!approved) {\n const choice = await tui.select({\n message: `Execute: ${cmd}?`,\n options: [{ value: 'yes', label: 'Yes' }, { value: 'always', label: 'Yes (Auto-Approve Session)' }, { value: 'no', label: 'No' }]\n });\n if (choice === 'always') { autoApprovals.commands = true; approved = true; }\n else if (choice === 'yes') approved = true;\n }\n if (approved) {\n const result = await handleRunCommand(cmd);\n executionResults += `[Action run_command(${cmd}) Result]:\\n${result}\\n\\n`;\n } else {\n executionResults += `[Action run_command]: User blocked execution.\\n\\n`;\n }\n }\n else if (['create_file', 'modify_file'].includes(action.type)) {\n const filePath = action.path || '';\n tui.log.warning(`šŸ“ ${action.type === 'create_file' ? 'CREATE' : 'MODIFY'}: ${colors.bold(filePath)}`);\n\n let approved = autoApprovals.files;\n if (!approved) {\n const choice = await tui.select({\n message: `Approve changes to ${filePath}?`,\n options: [{ value: 'yes', label: 'Yes' }, { value: 'always', label: 'Yes (Auto-Approve Session)' }, { value: 'no', label: 'No' }]\n });\n if (choice === 'always') { autoApprovals.files = true; approved = true; }\n else if (choice === 'yes') approved = true;\n }\n\n if (approved) {\n // ... (Perform Write) ...\n if (action.type === 'create_file') {\n // Simple Create Logic\n const dir = path.dirname(path.resolve(projectRoot, filePath));\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(path.resolve(projectRoot, filePath), action.content || '', 'utf-8');\n executionResults += `[Action create_file]: Success\\n\\n`;\n } else {\n // Modify Logic\n let success = false;\n if (action.line_range) success = replaceLineRange(filePath, action.line_range[0], action.line_range[1], action.content || '', tui);\n else if (action.target_content) success = startSmartReplace(filePath, action.content || '', action.target_content, tui);\n\n executionResults += success ? `[Action modify_file]: Success\\n\\n` : `[Action modify_file]: Failed\\n\\n`;\n }\n // Validation hooks can be re-added here similar to original\n const val = await validateTypeScript(path.resolve(projectRoot, filePath));\n if (!val.valid) executionResults += `[Validation Failed]: ${val.error}\\n\\n`;\n } else {\n executionResults += `[Action ${action.type}]: User Denied.\\n\\n`;\n }\n }\n // ... (AST Actions would follow similar pattern) ...\n else if (action.type.startsWith('ast_')) {\n try {\n // AST Tools Mapping (Async)\n let result = '';\n if (action.type === 'ast_list_structure') {\n result = await astListStructure(action.path || '');\n }\n else if (action.type === 'ast_get_method') {\n result = await astGetMethod(action.path || '', action.class_name || '', action.method_name || '');\n }\n else if (action.type === 'ast_add_method') {\n const success = await astAddMethod(action.path || '', action.class_name || '', action.method_code || '');\n result = success ? 'Method added successfully.' : 'Failed to add method.';\n }\n else if (action.type === 'ast_modify_method') {\n const success = await astModifyMethod(action.path || '', action.class_name || '', action.method_name || '', action.new_body || '');\n result = success ? 'Method modified successfully.' : 'Failed to modify method.';\n }\n else if (action.type === 'ast_remove_method') {\n const success = await astRemoveMethod(action.path || '', action.class_name || '', action.method_name || '');\n result = success ? 'Method removed successfully.' : 'Failed to remove method.';\n }\n else if (action.type === 'ast_add_class') {\n const success = await astAddClass(action.path || '', action.class_name || '', action.extends_class || undefined, action.implements_interfaces || undefined);\n result = success ? 'Class added successfully.' : 'Failed to add class.';\n }\n else if (action.type === 'ast_get_property') {\n tui.log.info(`šŸ” Reading property ${colors.gray(action.property_name || '')} in ${colors.gray(action.class_name || '')}`);\n const propContent = await astGetProperty(action.path || '', action.class_name || '', action.property_name || '');\n result = `[AST Get Property] Content:\\n${propContent}`;\n }\n else if (action.type === 'ast_add_property') {\n const success = await astAddProperty(action.path || '', action.class_name || '', action.property_code || '');\n result = success ? 'Property added successfully.' : 'Failed to add property.';\n }\n else if (action.type === 'ast_modify_property') {\n tui.log.info(`āœļø Modifying property ${colors.gray(action.property_name || '')} in ${colors.gray(action.class_name || '')}`);\n // Note: property_code here is the NEW full property definition\n const success = await astModifyProperty(action.path || '', action.class_name || '', action.property_name || '', action.property_code || '');\n result = success ? 'Property modified successfully.' : 'Failed to modify property.';\n }\n else if (action.type === 'ast_remove_property') {\n const success = await astRemoveProperty(action.path || '', action.class_name || '', action.property_name || '');\n result = success ? 'Property removed successfully.' : 'Failed to remove property.';\n }\n else if (action.type === 'ast_add_decorator') {\n // Tool only supports class decorators for now\n const success = await astAddDecorator(action.path || '', action.class_name || '', action.decorator_code || '');\n result = success ? 'Decorator added successfully.' : 'Failed to add decorator.';\n }\n else if (action.type === 'ast_add_interface') {\n const success = await astAddInterface(action.path || '', action.interface_code || '');\n result = success ? 'Interface added successfully.' : 'Failed to add interface.';\n }\n else if (action.type === 'ast_add_type_alias') {\n const success = await astAddTypeAlias(action.path || '', action.type_code || '');\n result = success ? 'Type alias added successfully.' : 'Failed to add type alias.';\n }\n else if (action.type === 'ast_add_function') {\n const success = await astAddFunction(action.path || '', action.function_code || '');\n result = success ? 'Function added successfully.' : 'Failed to add function.';\n }\n else if (action.type === 'ast_remove_function') {\n const success = await astRemoveFunction(action.path || '', action.function_name || '');\n result = success ? 'Function removed successfully.' : 'Failed to remove function.';\n }\n else if (action.type === 'ast_add_import') {\n const success = await astAddImport(action.path || '', action.import_statement || '');\n result = success ? 'Import added successfully.' : 'Failed to add import.';\n }\n else if (action.type === 'ast_remove_import') {\n const success = await astRemoveImport(action.path || '', action.module_path || '');\n result = success ? 'Import removed successfully.' : 'Failed to remove import.';\n }\n else if (action.type === 'ast_organize_imports') {\n const success = await astOrganizeImports(action.path || '');\n result = success ? 'Imports organized successfully.' : 'Failed to organize imports.';\n }\n else {\n result = `Unknown AST action: ${action.type}`;\n }\n\n executionResults += `[Action ${action.type} Result]:\\n${result}\\n\\n`;\n tui.log.info(`⚔ AST Action ${colors.dim(action.type)}: ${result}`);\n\n } catch (e: any) {\n executionResults += `[Action ${action.type} Failed]: ${e.message}\\n\\n`;\n tui.log.error(`āŒ AST Action Error: ${e.message}`);\n }\n }\n else if (action.type === 'search_ast') {\n const result = await astGrepSearch(action.pattern || '', action.path || '', action.language || 'typescript', tui);\n executionResults += `[Action search_ast Result]:\\n${result}\\n\\n`;\n }\n else if (action.type === 'modify_ast') {\n const success = await astGrepRewrite(action.pattern || '', action.fix || '', action.path || '', action.language || 'typescript', tui);\n executionResults += success ? `[Action modify_ast]: Success\\n\\n` : `[Action modify_ast]: Failed\\n\\n`;\n }\n } // End Action Loop\n\n // Determine Next Prompt\n if (executionResults) {\n if (waitingForUser) {\n const userReply = await tui.text({ message: 'Your answer:' });\n if (tui.isCancel(userReply)) { keepGoing = false; break; }\n nextPrompt = `${executionResults}\\nUser Reply: ${userReply}`;\n } else {\n nextPrompt = `${executionResults}\\n[System]: Continue execution. If finished, output \"TASK_COMPLETED: summary\".`;\n tui.log.info(colors.dim('Processing results...'));\n }\n } else if (!keepGoing) {\n // Task completed or stopped\n } else if (waitingForUser) {\n // handled above in message fallback\n } else {\n if (!isTaskCompleted && actions.length > 0) nextPrompt = \"Please continue.\";\n }\n\n } else {\n tui.log.warning('No response received from agent.');\n }\n\n } catch (e: any) {\n tui.log.error(e.message);\n keepGoing = false;\n return { success: false, summary: `Error: ${e.message}` };\n }\n }\n\n tui.log.success('āœ… Task Scope Completed');\n return { success: true, summary: finalSummary || \"Task completed without summary.\" };\n}\n\n// Helper to support key-based conversation\nasync function callDevAgentApi(prompt: string, onChunk: (chunk: string) => void, conversationKey: string = AGENT_TYPE): Promise<AgentResponse> {\n const realm = await getActiveRealm();\n const token = await ensureValidToken(realm);\n\n // Get specific conversation ID for this TASK\n const conversationId = await conversationManager.getConversationId(conversationKey);\n\n const payload = {\n user_prompt: prompt,\n streaming: true,\n use_conversation: true,\n conversation_id: conversationId,\n stackspot_knowledge: false\n };\n\n const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId()}/chat`;\n let fullMsg = '';\n let raw: any = {};\n\n await sseClient.streamAgentResponse(url, payload, { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, {\n onChunk: (c) => { fullMsg += c; onChunk(c); },\n onComplete: (msg, metadata) => {\n const returnedId = metadata?.conversation_id;\n raw = {\n message: msg || fullMsg,\n conversation_id: returnedId || conversationId\n };\n },\n onError: (e) => { throw e; }\n });\n\n const parsed = parseAgentResponse(raw);\n if (parsed.conversation_id) {\n await conversationManager.saveConversationId(conversationKey, parsed.conversation_id);\n }\n return parsed;\n}\n\n","\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface SpecTask {\n id: string; // generated based on index (e.g., \"task-1\")\n description: string;\n status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED';\n line_number: number; // 0-based line index in the file\n}\n\nexport interface SpecState {\n status: 'MISSING' | 'PENDING' | 'COMPLETED';\n nextTask?: SpecTask;\n allTasks: SpecTask[];\n}\n\nexport class TaskManager {\n private projectRoot: string;\n private specPath: string;\n\n constructor(projectRoot: string = process.cwd()) {\n this.projectRoot = projectRoot;\n this.specPath = path.resolve(this.projectRoot, '_sharkrc', 'tech-spec.md');\n }\n\n /**\n * Reads the tech-spec.md file and analyzes its current state.\n */\n public analyzeSpecState(): SpecState {\n if (!fs.existsSync(this.specPath)) {\n return { status: 'MISSING', allTasks: [] };\n }\n\n const content = fs.readFileSync(this.specPath, 'utf-8');\n const lines = content.split('\\n');\n const tasks: SpecTask[] = [];\n\n let taskIndex = 1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n const pendingMatch = trimmed.match(/^- \\[ \\] (.*)/);\n const completedMatch = trimmed.match(/^- \\[x\\] (.*)/i);\n const progressMatch = trimmed.match(/^- \\[\\/\\] (.*)/);\n\n let currentTask: SpecTask | null = null;\n let status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | null = null;\n let description = '';\n\n if (pendingMatch) {\n description = pendingMatch[1].trim();\n status = 'PENDING';\n } else if (completedMatch) {\n description = completedMatch[1].trim();\n status = 'COMPLETED';\n } else if (progressMatch) {\n description = progressMatch[1].trim();\n status = 'IN_PROGRESS';\n }\n\n if (status && description) {\n // Look ahead for sub-bullets or details\n let j = i + 1;\n while (j < lines.length) {\n const nextLine = lines[j];\n const nextTrimmed = nextLine.trim();\n // Stop if next line is empty, a new task, or a new section\n if (!nextTrimmed || nextTrimmed.match(/^- \\[[ x\\/]\\]/) || nextTrimmed.startsWith('#')) {\n break;\n }\n description += '\\n' + nextTrimmed;\n j++;\n }\n\n currentTask = {\n id: `task-${taskIndex++}`,\n description: description,\n status: status,\n line_number: i\n };\n tasks.push(currentTask);\n }\n }\n\n // Determine next actionable task\n // Priority: IN_PROGRESS -> First PENDING\n let nextTask = tasks.find(t => t.status === 'IN_PROGRESS');\n if (!nextTask) {\n nextTask = tasks.find(t => t.status === 'PENDING');\n }\n\n const status = (!nextTask && tasks.length > 0 && tasks.every(t => t.status === 'COMPLETED'))\n ? 'COMPLETED'\n : 'PENDING';\n\n return {\n status: tasks.length === 0 ? 'MISSING' : status, // Empty file is effectively \"pending creation\" but we treat as missing content logic elsewhere\n nextTask,\n allTasks: tasks\n };\n }\n\n /**\n * Marks a specific task as COMPLETED in the file.\n * Uses line-based replacement to be safe.\n */\n public markTaskAsDone(taskId: string): boolean {\n const state = this.analyzeSpecState();\n const task = state.allTasks.find(t => t.id === taskId);\n\n if (!task) {\n console.error(`Task ${taskId} not found.`);\n return false;\n }\n\n const content = fs.readFileSync(this.specPath, 'utf-8');\n const lines = content.split('\\n');\n\n // Verify line content hasn't drifted (sanity check)\n const targetLine = lines[task.line_number];\n if (!targetLine.includes(task.description)) {\n console.error(`Concurrency Error: Task line content mistmatch. Expected \"${task.description}\" at line ${task.line_number}.`);\n // Fallback: search for the task description again\n // This is simple recovery, in a real DB we'd use IDs.\n return false;\n }\n\n // Replace [ ], [/] with [x]\n const newLine = targetLine\n .replace('- [ ]', '- [x]')\n .replace('- [/]', '- [x]');\n\n lines[task.line_number] = newLine;\n\n fs.writeFileSync(this.specPath, lines.join('\\n'), 'utf-8');\n return true;\n }\n\n /**\n * Marks a task as IN_PROGRESS.\n */\n public markTaskInProgress(taskId: string): boolean {\n const state = this.analyzeSpecState();\n const task = state.allTasks.find(t => t.id === taskId);\n\n if (!task) return false;\n\n const content = fs.readFileSync(this.specPath, 'utf-8');\n const lines = content.split('\\n');\n\n let targetLine = lines[task.line_number];\n\n // Replace [ ] with [/]\n targetLine = targetLine.replace('- [ ]', '- [/]');\n\n lines[task.line_number] = targetLine;\n fs.writeFileSync(this.specPath, lines.join('\\n'), 'utf-8');\n return true;\n }\n\n /**\n * Completely updates the spec file content (used by Spec Agent).\n */\n public updateSpecContent(newContent: string): void {\n fs.writeFileSync(this.specPath, newContent, 'utf-8');\n }\n\n public getSpecPath(): string {\n return this.specPath;\n }\n}\n","import { Command } from 'commander';\nimport { runQAAgent } from '../core/agents/qa-agent.js';\n\nexport const qaCommand = new Command('qa')\n .description('Start the Shark QA Agent to test web applications')\n .option('--url <url>', 'Initial URL to test')\n .option('--scenario <scenario>', 'Scenario description or test case to execute')\n .action(async (options) => {\n try {\n await runQAAgent({\n initialUrl: options.url,\n scenario: options.scenario\n });\n } catch (error: any) {\n console.error('Failed to run QA Agent:', error.message);\n process.exit(1);\n }\n });\n","import { tui } from '../../ui/tui';\nimport { colors } from '../../ui/colors';\nimport { getActiveRealm } from '../auth/get-active-realm';\nimport { tokenStorage } from '../auth/token-storage';\nimport { sseClient } from '../api/sse-client';\nimport { parseAgentResponse, AgentAction, AgentResponse } from './agent-response-parser';\nimport { conversationManager } from '../workflow/conversation-manager';\nimport { handleReadFile, handleListFiles, handleSearchFile, handleRunCommand } from './agent-tools';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { ConfigManager } from '../config-manager';\n\nconst AGENT_TYPE = 'qa_agent';\n\nfunction getAgentId(): string {\n const config = ConfigManager.getInstance().getConfig();\n if (config.agents?.qa) return config.agents.qa;\n return process.env.STACKSPOT_QA_AGENT_ID || '01KEQFJZ3Q3JER11NH22HEZX9X';\n}\n\ninterface QAAgentOptions {\n initialUrl?: string;\n scenario?: string;\n}\n\n// MCP Client Wrapper\nclass ChromeDevToolsClient {\n private client: Client | null = null;\n private transport: StdioClientTransport | null = null;\n\n async connect() {\n if (this.client) return;\n\n try {\n this.transport = new StdioClientTransport({\n command: 'npx',\n args: ['-y', 'chrome-devtools-mcp@latest']\n });\n\n this.client = new Client({\n name: \"shark-qa-client\",\n version: \"1.0.0\"\n }, {\n capabilities: {}\n });\n\n await this.client.connect(this.transport);\n tui.log.success('šŸ”Œ Connected to Chrome DevTools MCP');\n } catch (e: any) {\n tui.log.error(`Failed to connect to Chrome MCP: ${e.message}`);\n throw e;\n }\n }\n\n async callTool(name: string, args: any) {\n if (!this.client) await this.connect();\n try {\n const result = await this.client!.callTool({\n name,\n arguments: args\n });\n return result;\n } catch (e: any) {\n return { isError: true, content: [{ type: 'text', text: `MCP Error: ${e.message}` }] };\n }\n }\n\n async close() {\n if (this.transport) {\n await this.transport.close();\n }\n }\n}\n\nconst mcpClient = new ChromeDevToolsClient();\n\nexport async function runQAAgent(options: QAAgentOptions) {\n const agentId = getAgentId();\n\n if (!agentId) {\n tui.log.error('āŒ STACKSPOT_QA_AGENT_ID not configured.');\n tui.log.info('Please run: set STACKSPOT_QA_AGENT_ID=<your-id>');\n return;\n }\n\n // Connect to MCP at start\n await mcpClient.connect();\n\n tui.intro('🦈 Shark QA Agent');\n tui.log.info('Connecting to Chrome DevTools...');\n\n const realm = await getActiveRealm();\n const token = await tokenStorage.getToken(realm);\n\n if (!token) {\n tui.log.error('Authentication required. Run \"shark login\".');\n return;\n }\n\n // 1. Prepare Initial Context\n let projectContext = \"\";\n try {\n const contextPath = path.join(process.cwd(), '_sharkrc', 'project-context.md');\n if (fs.existsSync(contextPath)) {\n projectContext = fs.readFileSync(contextPath, 'utf-8');\n tui.log.info(`šŸ“˜ Context loaded from: _sharkrc/project-context.md`);\n }\n } catch (e) {\n // Ignore if no context\n }\n\n let userMessage = `CONTEXTO DO PROJETO:\\n${projectContext}\\n\\n`;\n\n if (options.initialUrl) {\n userMessage += `URL ALVO: ${options.initialUrl}\\n`;\n }\n if (options.scenario) {\n userMessage += `CENƁRIO DE TESTE: ${options.scenario}\\n`;\n } else {\n userMessage += `Por favor, aguarde instruƧƵes do usuĆ”rio.`;\n }\n\n // 2. Interaction Loop\n let keepRunning = true;\n\n while (keepRunning) {\n const spinner = tui.spinner();\n spinner.start('šŸ¤– Shark QA is thinking...');\n\n let agentResponseText = \"\";\n let agentResponse: AgentResponse | null = null;\n\n try {\n // API Interaction (Manual Call until AgentManager is unified)\n const existingConversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n await sseClient.streamAgentResponse(\n `https://genai-inference-app.stackspot.com/v1/agent/${getAgentId()}/chat`,\n {\n user_prompt: userMessage,\n streaming: true,\n use_conversation: true,\n conversation_id: existingConversationId\n },\n {\n 'Authorization': `Bearer ${token}`\n },\n {\n onChunk: (chunk) => {\n agentResponseText += chunk;\n if (agentResponseText.length > 10 && agentResponseText.trim().startsWith('{')) {\n spinner.message('Receiving structured plan...');\n }\n },\n onComplete: (fullText, metadata) => {\n try {\n if (metadata?.conversation_id) {\n conversationManager.saveConversationId(AGENT_TYPE, metadata.conversation_id);\n }\n agentResponse = parseAgentResponse(fullText || agentResponseText);\n } catch (e) {\n tui.log.error(`Parse Error: ${(e as Error).message}`);\n agentResponse = { actions: [], summary: \"Error parsing response\", message: fullText };\n }\n }\n }\n );\n\n spinner.stop('Response Received');\n\n } catch (error) {\n spinner.stop('Communication Error', 1);\n tui.log.error((error as Error).message);\n keepRunning = false;\n break;\n }\n\n if (!agentResponse) continue;\n\n // 3. Handle Actions\n if (agentResponse.summary) {\n tui.log.info(colors.primary(`šŸ“‹ Plan: ${agentResponse.summary}`));\n }\n\n if (agentResponse.actions.length === 0) {\n // No actions usually means it's waiting for user or finished\n const reply = await tui.text({\n message: \"šŸ¤– Shark QA:\",\n placeholder: \"Your reply...\"\n });\n\n if (tui.isCancel(reply)) {\n keepRunning = false;\n } else {\n userMessage = reply as string;\n }\n continue;\n }\n\n for (const action of agentResponse.actions) {\n tui.log.info(colors.dim(`Executing: ${action.type}`));\n\n let result = \"\";\n\n try {\n switch (action.type) {\n case 'talk_with_user':\n const reply = await tui.text({\n message: `šŸ¤– ${action.content}`,\n });\n if (tui.isCancel(reply)) keepRunning = false;\n else result = reply as string;\n break;\n\n case 'use_mcp_tool':\n if (action.tool_name) {\n tui.log.info(`šŸ”§ MCP Tool: ${colors.bold(action.tool_name)}`);\n let args = {};\n try {\n args = typeof action.tool_args === 'string'\n ? JSON.parse(action.tool_args)\n : (action.tool_args || {});\n } catch (e) {\n tui.log.warning('Failed to parse tool_args, using empty object');\n }\n const mcpResult = await mcpClient.callTool(action.tool_name, args);\n result = JSON.stringify(mcpResult);\n // Brief preview\n tui.log.success(`Result: ${result.substring(0, 100)}...`);\n }\n break;\n\n case 'create_file':\n if (action.path && action.content) {\n const fullPath = path.resolve(process.cwd(), action.path);\n const BOM = '\\uFEFF';\n const contentToWrite = action.content;\n const finalContent = contentToWrite.startsWith(BOM) ? contentToWrite : BOM + contentToWrite;\n fs.writeFileSync(fullPath, finalContent, { encoding: 'utf-8' });\n tui.log.success(`File created: ${action.path}`);\n result = \"File created successfully.\";\n }\n break;\n\n case 'read_file':\n result = handleReadFile(action.path || '');\n break;\n\n case 'run_command':\n // Safety check?\n const confirm = await tui.confirm({ message: `Run command: ${action.command}?` });\n if (confirm && action.command) {\n result = await handleRunCommand(action.command);\n } else {\n result = \"Command execution denied by user.\";\n }\n break;\n\n default:\n result = `Action ${action.type} not fully implemented in local client.`;\n }\n } catch (e: any) {\n result = `Error executing ${action.type}: ${e.message}`;\n tui.log.error(result);\n }\n\n // Feed result back to agent\n userMessage = `[Action ${action.type} Result]:\\n${result}\\n\\n`;\n }\n }\n\n await mcpClient.close();\n tui.outro('🦈 Shark QA Session Ended');\n}\n"],"mappings":"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","names":["Command","fs","path","path","fs","z","z","fs","path","fs","path","path","path","fs","path","fs","tui","tui","fs","resolve","path","AGENT_TYPE","getAgentId","path","fs","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","Command","Command","fs","path","AGENT_TYPE","getAgentId","getAgentId","path","fs","AGENT_TYPE","fs","path","status","t","Command","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","Command","Command"]}