shark-ai 0.3.1 β†’ 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/shark.js CHANGED
@@ -1165,7 +1165,8 @@ async function interactiveScanAgent(options = {}) {
1165
1165
  [TO BE ANALYZED]
1166
1166
  `;
1167
1167
  if (!fs5.existsSync(outputFile)) {
1168
- fs5.writeFileSync(outputFile, initialTemplate, { encoding: "utf-8" });
1168
+ const BOM = "\uFEFF";
1169
+ fs5.writeFileSync(outputFile, BOM + initialTemplate, { encoding: "utf-8" });
1169
1170
  tui.log.success(`${t("commands.scan.templateCreated")} ${outputFile}`);
1170
1171
  } else {
1171
1172
  tui.log.info(t("commands.scan.fileExists"));
@@ -1424,7 +1425,7 @@ async function runScanLoop(initialPrompt, targetPath) {
1424
1425
  let nextPrompt = initialPrompt;
1425
1426
  let keepGoing = true;
1426
1427
  let stepCount = 0;
1427
- const MAX_STEPS = 30;
1428
+ const MAX_STEPS = 60;
1428
1429
  while (keepGoing && stepCount < MAX_STEPS) {
1429
1430
  stepCount++;
1430
1431
  const spinner = tui.spinner();
@@ -1473,8 +1474,11 @@ ${result}
1473
1474
  }
1474
1475
  if (isTarget) {
1475
1476
  const finalPath = targetPath;
1477
+ const BOM = "\uFEFF";
1476
1478
  if (action.type === "create_file") {
1477
- fs5.writeFileSync(finalPath, action.content || "");
1479
+ const contentToWrite = action.content || "";
1480
+ const finalContent = contentToWrite.startsWith(BOM) ? contentToWrite : BOM + contentToWrite;
1481
+ fs5.writeFileSync(finalPath, finalContent, { encoding: "utf-8" });
1478
1482
  tui.log.success(t("commands.scan.generated").replace("{0}", finalPath));
1479
1483
  fileCreated = true;
1480
1484
  } else {
@@ -1482,7 +1486,8 @@ ${result}
1482
1486
  const currentContent = fs5.readFileSync(finalPath, "utf-8");
1483
1487
  if (action.target_content && currentContent.includes(action.target_content)) {
1484
1488
  const newContent = currentContent.replace(action.target_content, action.content || "");
1485
- fs5.writeFileSync(finalPath, newContent, { encoding: "utf-8" });
1489
+ const finalContent = newContent.startsWith(BOM) ? newContent : BOM + newContent;
1490
+ fs5.writeFileSync(finalPath, finalContent, { encoding: "utf-8" });
1486
1491
  tui.log.success(t("commands.scan.updated").replace("{0}", finalPath));
1487
1492
  fileCreated = true;
1488
1493
  } else {
@@ -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/commands/scan.ts","../../src/core/agents/scan-agent.ts","../../src/commands/dev.ts","../../src/core/agents/developer-agent.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\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 let creds = await tokenStorage.getCredentials(this.realm);\n\n if (!creds?.accessToken) {\n throw new AuthError(`Authentication required for realm '${this.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 (creds.expiresAt && creds.clientId && creds.clientKey) {\n if (now > creds.expiresAt - buffer) {\n try {\n if (this.debugMode) console.log(colors.dim('πŸ”„ Refreshing expired token...'));\n\n const newTokens = await authenticate(this.realm, creds.clientId, creds.clientKey);\n\n await tokenStorage.saveToken(\n this.realm,\n newTokens.access_token,\n creds.clientId,\n creds.clientKey,\n newTokens.expires_in\n );\n\n // Update local reference with new token\n creds.accessToken = newTokens.access_token;\n if (this.debugMode) console.log(colors.success('βœ… Token refreshed successfully.'));\n\n } catch (error) {\n console.warn(colors.warning(`⚠️ Failed to auto-refresh token: ${(error as Error).message}`));\n // Fallback to existing token (might still work for a few seconds or fail at API)\n }\n }\n }\n\n const headers = new Headers();\n headers.set('Authorization', `Bearer ${creds?.accessToken}`);\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 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(['create_file', 'modify_file', 'delete_file', 'talk_with_user', 'list_files', 'read_file', 'search_file', 'run_command', 'use_mcp_tool']),\n path: z.string().nullable().optional(), // Nullable for strict mode combatibility\n content: z.string().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\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\nfunction 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 } 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\n}\n\n/**\n * Interactive Specification Agent session.\n * Reads briefing, consults user, and generates tech-spec.md.\n */\nexport async function interactiveSpecificationAgent(options: SpecAgentOptions = {}): Promise<void> {\n FileLogger.init();\n tui.intro('πŸ—οΈ Specification Agent');\n\n // 1. Resolve Briefing File\n let briefingContent = '';\n let briefingPath = options.briefingPath;\n\n if (!briefingPath) {\n // Try to find a default briefing in current dir\n const files = fs.readdirSync(process.cwd());\n const defaultBriefing = files.find(f => f.endsWith('_briefing.md'));\n\n briefingPath = await tui.text({\n message: 'Path to Briefing file (Leave empty to skip)',\n initialValue: defaultBriefing || '',\n placeholder: 'e.g., todo-list_briefing.md',\n validate: (val) => {\n if (val && !fs.existsSync(val)) return 'File not found';\n }\n }) as string;\n }\n\n if (tui.isCancel(briefingPath)) return;\n\n if (briefingPath) {\n try {\n briefingContent = fs.readFileSync(briefingPath, 'utf-8');\n tui.log.info(`Loaded briefing: ${colors.bold(briefingPath)}`);\n } catch (e) {\n tui.log.error(`Failed to read briefing: ${e}`);\n return;\n }\n } else {\n tui.log.info('Skipping briefing file. Starting fresh or exploring existing project.');\n }\n\n // 2. Initial Prompt Construction\n const initialPrompt = briefingContent ? `\nTenho o seguinte Documento de Briefing de NegΓ³cio. \nPor favor, analise-o e inicie o processo de definiΓ§Γ£o da EspecificaΓ§Γ£o TΓ©cnica.\n\n---\n${briefingContent}\n---\n `.trim() : 'Gostaria de ajuda com uma especificaΓ§Γ£o tΓ©cnica ou explorar este projeto.';\n\n // 3. Start Conversation Loop\n await runSpecLoop(initialPrompt, options.agentId);\n}\n\n/**\n * Main Loop for Specification Agent\n */\nasync function runSpecLoop(initialMessage: string, overrideAgentId?: string) {\n let nextPrompt = initialMessage;\n let keepGoing = true;\n\n while (keepGoing) {\n const spinner = tui.spinner();\n spinner.start('πŸ—οΈ Specification Agent is thinking...');\n\n let responseText = '';\n let lastResponse: AgentResponse | null = null;\n\n try {\n // Call Agent\n lastResponse = await callSpecAgentApi(nextPrompt, (chunk) => {\n responseText += chunk;\n try {\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 }, overrideAgentId);\n\n spinner.stop('Response received');\n\n // Handle Response Actions\n if (lastResponse && lastResponse.actions) {\n // Reset next prompt, we will build it based on actions results\n let executionResults = \"\";\n let waitingForUser = false;\n\n for (const action of lastResponse.actions) {\n\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(`πŸ“‚ List files in: ${colors.bold(action.path || '.')}`);\n const result = handleListFiles(action.path || '.');\n executionResults += `[Action list_files(${action.path}) Result]:\\n${result}\\n\\n`;\n tui.log.info(colors.dim(`Files listed.`));\n }\n\n else if (action.type === 'read_file') {\n tui.log.info(`πŸ“– Read file: ${colors.bold(action.path || '')}`);\n const result = handleReadFile(action.path || '');\n executionResults += `[Action read_file(${action.path}) Result]:\\n${result}\\n\\n`;\n tui.log.info(colors.dim(`File read.`));\n }\n\n else if (action.type === 'search_file') {\n tui.log.info(`πŸ” Search file: ${colors.bold(action.path || '')}`);\n const result = handleSearchFile(action.path || '');\n executionResults += `[Action search_file(${action.path}) Result]:\\n${result}\\n\\n`;\n tui.log.info(colors.dim(`Files found.`));\n }\n\n else if (['create_file', 'modify_file', 'delete_file'].includes(action.type)) {\n tui.log.warning(`\\nπŸ€– Agent wants to ${action.type}: ${colors.bold(action.path || 'unknown')}`);\n\n // Preview\n if (action.content) {\n console.log(colors.dim('--- Content Preview ---'));\n console.log(action.content.substring(0, 300) + '...');\n console.log(colors.dim('-----------------------'));\n }\n\n const confirm = await tui.confirm({\n message: `Approve ${action.type}?`,\n active: 'Yes',\n inactive: 'No'\n });\n\n if (confirm) {\n if (action.path) {\n try {\n if (action.type === 'create_file') {\n fs.writeFileSync(action.path, action.content || '');\n tui.log.success(`βœ… Created: ${action.path}`);\n executionResults += `[Action create_file(${action.path})]: Success\\n\\n`;\n } else if (action.type === 'modify_file') {\n if (action.target_content) {\n const success = startSmartReplace(action.path, action.content || '', action.target_content, tui);\n executionResults += `[Action modify_file(${action.path})]: ${success ? 'Success' : 'Failed'}\\n\\n`;\n } else {\n fs.writeFileSync(action.path, action.content || '');\n tui.log.success(`βœ… Overwritten: ${action.path}`);\n executionResults += `[Action modify_file(${action.path})]: Success (Overwrite)\\n\\n`;\n }\n } else if (action.type === 'delete_file') {\n fs.unlinkSync(action.path);\n tui.log.success(`βœ… Deleted: ${action.path}`);\n executionResults += `[Action delete_file(${action.path})]: Success\\n\\n`;\n }\n } catch (e: any) {\n tui.log.error(`❌ Failed: ${e.message}`);\n executionResults += `[Action ${action.type}(${action.path})]: Error: ${e.message}\\n\\n`;\n }\n }\n } else {\n tui.log.error('❌ Action denied.');\n executionResults += `[Action ${action.type}]: User Denied\\n\\n`;\n }\n }\n }\n\n // Prepare next prompt\n if (executionResults) {\n // If actions produced output (like file list), send it back to agent automatically\n // But if the agent ALSO talked to user, we should give priority to user input??\n // Strategy: If agent asked something (talk_with_user), we MUST ask user.\n // The tool outputs are appended.\n\n if (waitingForUser) {\n const userReply = await tui.text({\n message: 'Your answer',\n placeholder: 'Type your answer...'\n });\n if (tui.isCancel(userReply)) {\n keepGoing = false;\n return;\n }\n nextPrompt = `${executionResults}\\n\\nUser Reply: ${userReply}`;\n tui.log.info(colors.dim('Auto-replying with tool results...'));\n } else {\n // Agent just did tools, let's auto-reply with results so it can continue\n nextPrompt = executionResults;\n FileLogger.log('SYSTEM', 'Auto-replying with Tool Results', { length: executionResults.length });\n tui.log.info(colors.dim('Auto-replying with tool results...'));\n }\n\n } else if (waitingForUser) {\n // Only talk, no tools\n const userReply = await tui.text({\n message: 'Your answer',\n placeholder: 'Type your answer...'\n });\n if (tui.isCancel(userReply)) {\n keepGoing = false;\n return;\n }\n nextPrompt = userReply as string;\n } else {\n // No actions? Weird.\n tui.log.warning('No actions taken.');\n keepGoing = false;\n }\n\n } else {\n tui.log.warning('No actions received from agent.');\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// --- Helper Functions in agent-tools.ts ---\n\n// --- API Wrapper ---\n\nasync function callSpecAgentApi(prompt: string, onChunk: (chunk: string) => void, agentId?: string): 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 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', {\n agentId: effectiveAgentId,\n conversationId,\n prompt: prompt.substring(0, 500) // Log summary of prompt\n });\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 // Prefer conversation_id from metadata (server response), fallback to sent ID\n const returnedId = metadata?.conversation_id;\n\n FileLogger.log('AGENT', 'Response Complete', {\n conversationId,\n returnedId,\n messageLength: msg?.length\n });\n\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\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';\n\n/**\n * Shared tools for Agent interaction (File System, etc.)\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): 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 return fs.readFileSync(fullPath, 'utf-8');\n } catch (e: any) {\n return `Error reading file: ${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 line endings?\n if (!currentFileContent.includes(targetContent)) {\n tui.log.error(`❌ Target content not found in ${filePath}. 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 updatedContent = currentFileContent.replace(targetContent, newContent);\n fs.writeFileSync(filePath, updatedContent);\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","\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 fs.writeFileSync(outputFile, 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 = 30; // 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 if (action.type === 'create_file') {\n fs.writeFileSync(finalPath, action.content || '');\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 fs.writeFileSync(finalPath, newContent, { 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 } from '../core/agents/developer-agent.js';\n\nexport const devCommand = new Command('dev')\n .description('Starts the Shark Developer Agent (Shark Dev)')\n .option('-t, --task <type>', 'Initial task description')\n .option('-c, --context <path>', 'Path to custom context file')\n .action(async (options) => {\n await interactiveDeveloperAgent(options);\n });\n","\nimport { STACKSPOT_AGENT_API_BASE } 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 handleRunCommand\n} from './agent-tools.js';\n\nconst AGENT_TYPE = 'developer_agent';\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\nexport async function interactiveDeveloperAgent(options: { task?: string, context?: string } = {}): Promise<void> {\n FileLogger.init();\n tui.intro('🦈 Shark Dev Agent');\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;\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 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 } else {\n tui.log.warning(`⚠️ No context file found. Agent will run without pre-loaded context.`);\n }\n\n // 2. Prepare Initial Prompt\n let nextPrompt = options.task || \"I'm ready to help. What's the task?\";\n if (contextContent) {\n nextPrompt += `\\n\\n--- PROJECT CONTEXT ---\\n${contextContent}\\n-----------------------`;\n }\n\n // 3. Main Loop\n let keepGoing = true;\n const spinner = tui.spinner();\n\n while (keepGoing) {\n try {\n spinner.start('Waiting for Agent...');\n\n // Call API\n let lastResponse: AgentResponse | null = null;\n await callDevAgentApi(nextPrompt, (chunk) => {\n // Optional: Stream text to TUI if needed\n if (!lastResponse) {\n // Maybe show thinking dots?\n }\n }).then(resp => {\n lastResponse = resp;\n });\n\n spinner.stop('Response received');\n\n if (lastResponse && (lastResponse as AgentResponse).actions) {\n const response = lastResponse as AgentResponse;\n let executionResults = \"\";\n let waitingForUser = false;\n\n for (const action of response.actions) {\n\n if (action.type === 'talk_with_user') {\n tui.log.info(colors.primary('πŸ€– Shark Dev:'));\n console.log(action.content);\n waitingForUser = true;\n }\n\n else if (action.type === 'list_files') {\n tui.log.info(`πŸ“‚ Scanning dir: ${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 (action.type === 'run_command') {\n const cmd = action.command || '';\n tui.log.info(`πŸ’» Executing: ${colors.dim(cmd)}`);\n // Execute Command\n // Warning: Prompt user for non-safe commands? \n // For now, let's assume Shark Dev is trusted or ask for everything.\n // Let's ask for confirmation for consistency.\n const confirm = await tui.confirm({\n message: `Execute command: ${cmd}?`,\n active: 'Yes',\n inactive: 'No'\n });\n\n if (confirm) {\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\n else if (['create_file', 'modify_file'].includes(action.type)) {\n const isCreate = action.type === 'create_file';\n const filePath = action.path || '';\n tui.log.warning(`\\nπŸ€– Agent wants to ${isCreate ? 'CREATE' : 'MODIFY'}: ${colors.bold(filePath)}`);\n\n // Preview content (maybe diff?)\n // For brevity, just log start\n if (action.content) {\n console.log(colors.dim('--- Content ---\\n') + action.content.substring(0, 200) + '...\\n' + colors.dim('---------------'));\n }\n\n const confirm = await tui.confirm({\n message: `Approve changes to ${filePath}?`,\n active: 'Yes',\n inactive: 'No'\n });\n\n if (confirm) {\n if (filePath) {\n const targetPath = path.resolve(projectRoot, filePath);\n const dir = path.dirname(targetPath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n\n if (isCreate) {\n fs.writeFileSync(targetPath, action.content || '');\n tui.log.success(`βœ… Created: ${filePath}`);\n executionResults += `[Action create_file(${filePath})]: Success\\n\\n`;\n } else {\n // Modify\n if (action.target_content) {\n const success = startSmartReplace(filePath, action.content || '', action.target_content, tui);\n executionResults += `[Action modify_file(${filePath})]: ${success ? 'Success' : 'Failed'}\\n\\n`;\n } else {\n // Fallback overwrite if no target_content provided (should be rare given schema)\n // But for Dev Agent, schema requires new_content (mapped to content) and target_content.\n // If target_content missing, we might fail or overwrite.\n // Let's safe fail.\n tui.log.error('❌ Missing target_content for modification.');\n executionResults += `[Action modify_file]: Failed. Missing target_content.\\n\\n`;\n }\n }\n }\n } else {\n tui.log.error('❌ Denied.');\n executionResults += `[Action ${action.type}]: User Denied.\\n\\n`;\n }\n }\n }\n\n // Prepare 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}\\n\\nUser Reply: ${userReply}`;\n } else {\n // Auto-continue\n nextPrompt = executionResults;\n tui.log.info(colors.dim('Sending tool results to agent...'));\n }\n } else if (waitingForUser) {\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 // Fallback: If no actions but we have a message/summary, assume it's a talk\n if (response.message) {\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)) {\n keepGoing = false;\n } else {\n nextPrompt = userReply as string;\n }\n } else {\n tui.log.warning('Agent took no actions.');\n keepGoing = false;\n }\n }\n\n } else {\n tui.log.warning('Invalid response from agent.');\n keepGoing = false;\n }\n\n } catch (e: any) {\n spinner.stop('Error');\n tui.log.error(e.message);\n FileLogger.log('DEV_AGENT', 'Main Loop Error', e);\n keepGoing = false;\n }\n }\n\n tui.outro('πŸ‘‹ Shark Dev Session Ended');\n}\n\nasync function callDevAgentApi(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. Run shark login.');\n\n const conversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n const payload = {\n user_prompt: prompt,\n streaming: true,\n use_conversation: true,\n conversation_id: conversationId,\n stackspot_knowledge: false // Dev Agent focuses on project context\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(AGENT_TYPE, parsed.conversation_id);\n }\n return parsed;\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 fs.writeFileSync(fullPath, action.content);\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":";;;;;;;;;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,QAAQ;AAGR,IAAM,eAAN,MAAM,cAAa;AAAA,EACtB,OAAe;AAAA,EACE;AAAA,EAET,cAAc;AAClB,SAAK,SAAS,KAAK,KAAK,GAAG,QAAQ,GAAG,UAAU,MAAM;AAAA,EAC1D;AAAA,EAEA,OAAc,cAA4B;AACtC,QAAI,CAAC,cAAa,UAAU;AACxB,oBAAa,WAAW,IAAI,cAAa;AAAA,IAC7C;AACA,WAAO,cAAa;AAAA,EACxB;AAAA,EAEO,OAAa;AAChB,YAAQ,GAAG,qBAAqB,CAAC,UAAU,KAAK,YAAY,OAAO,oBAAoB,CAAC;AACxF,YAAQ,GAAG,sBAAsB,CAAC,WAAW,KAAK,YAAY,QAAQ,qBAAqB,CAAC;AAAA,EAChG;AAAA,EAEQ,YAAY,OAAY,MAAoB;AAEhD,QAAI;AACA,YAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG;AAC/D,YAAM,UAAU,KAAK,KAAK,KAAK,QAAQ,SAAS,SAAS,MAAM;AAE/D,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAM,aAAa,iBAAiB,QAAQ,MAAM,QAAQ;AAE1D,YAAM,aAAa;AAAA,IAC5B,oBAAI,KAAK,GAAE,YAAY,CAAC,KAAK,IAAI;AAAA;AAAA,WAEzB,YAAY;AAAA;AAAA,EAErB,UAAU;AAAA;AAAA,UAEF,GAAG,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC;AAAA,QAC5C,QAAQ,OAAO;AAAA;AAIX,UAAI,CAAC,GAAG,WAAW,KAAK,MAAM,GAAG;AAC7B,WAAG,UAAU,KAAK,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,MACjD;AAEA,SAAG,cAAc,SAAS,YAAY,OAAO;AAE7C,cAAQ,MAAM,IAAI;AAClB,cAAQ,MAAM,OAAO,MAAM,oDAA6C,CAAC;AACzE,cAAQ,MAAM,OAAO,IAAI,kCAAkC,OAAO,EAAE,CAAC;AACrE,cAAQ,MAAM,OAAO,IAAI,+CAA+C,CAAC;AACzE,cAAQ,MAAM,OAAO,MAAM,aAAa,YAAY,EAAE,CAAC;AACvD,cAAQ,MAAM,IAAI;AAAA,IAEtB,SAAS,cAAc;AACnB,cAAQ,MAAM,2CAA2C,YAAY;AACrE,cAAQ,MAAM,mBAAmB,KAAK;AAAA,IAC1C,UAAE;AACE,cAAQ,KAAK,CAAC;AAAA,IAClB;AAAA,EACJ;AACJ;AAEO,IAAM,eAAe,aAAa,YAAY;;;AC9DrD,SAAS,WAAAA,gBAAe;;;ACNxB,SAAS,eAAe;;;ACAxB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACDjB,SAAS,SAAS;AAQX,IAAM,gBAAgB,EAAE,KAAK;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAIM,IAAM,oBAAoB,EAAE,KAAK;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAIM,IAAM,kBAAkB,EAAE,KAAK;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,CAAC;AAIM,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACnC,WAAW,EAAE,OAAO,EAAE,KAAK;AAAA,EAC3B,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,WAAW,cAAc,QAAQ,SAAS;AAAA,EAC1C,cAAc,kBAAkB,QAAQ,mBAAmB;AAAA,EAC3D,aAAa,gBAAgB,QAAQ,SAAS;AAAA,EAC9C,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EACjC,gBAAgB,EAAE,OAAO,EAAE,SAAS;AAAA,EACpC,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,EACzD,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAEzC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS;AAC7C,CAAC;;;ADlDM,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EACzB,OAAe;AAAA,EACE,WAAW;AAAA,EACX,cAAc;AAAA,EAEvB,cAAc;AAAA,EAAE;AAAA,EAExB,OAAc,cAA+B;AACzC,QAAI,CAAC,iBAAgB,UAAU;AAC3B,uBAAgB,WAAW,IAAI,iBAAgB;AAAA,IACnD;AACA,WAAO,iBAAgB;AAAA,EAC3B;AAAA,EAEQ,cAAsB;AAC1B,WAAOC,MAAK,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ;AAAA,EACjD;AAAA,EAEQ,iBAAyB;AAC7B,WAAOA,MAAK,KAAK,QAAQ,IAAI,GAAG,KAAK,WAAW;AAAA,EACpD;AAAA,EAEA,MAAa,KAAK,OAAqC;AAEnD,UAAM,SAAS,eAAe,UAAU,KAAK;AAC7C,QAAI,CAAC,OAAO,SAAS;AACjB,YAAM,IAAI,MAAM,2BAA2B,OAAO,MAAM,OAAO,EAAE;AAAA,IACrE;AAEA,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,UAAU,KAAK,eAAe;AACpC,UAAM,OAAO,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC;AAEhD,QAAI;AAEA,YAAMC,IAAG,UAAU,SAAS,MAAM,OAAO;AAGzC,YAAMA,IAAG,OAAO,SAAS,QAAQ;AAAA,IACrC,SAAS,OAAY;AACjB,YAAM,IAAI,MAAM,6CAA6C,MAAM,OAAO,EAAE;AAAA,IAChF;AAAA,EACJ;AAAA,EAEA,MAAa,OAAsC;AAC/C,UAAM,WAAW,KAAK,YAAY;AAElC,QAAI;AAEA,UAAI;AACA,cAAMA,IAAG,OAAO,QAAQ;AAAA,MAC5B,QAAQ;AACJ,eAAO;AAAA,MACX;AAEA,YAAM,UAAU,MAAMA,IAAG,SAAS,UAAU,OAAO;AACnD,YAAM,OAAO,KAAK,MAAM,OAAO;AAE/B,YAAM,SAAS,eAAe,UAAU,IAAI;AAC5C,UAAI,OAAO,SAAS;AAChB,eAAO,OAAO;AAAA,MAClB,OAAO;AACH,gBAAQ,KAAK,OAAO,QAAQ,mDAAyC,OAAO,MAAM,OAAO,EAAE,CAAC;AAC5F,eAAO;AAAA,MACX;AAAA,IAEJ,SAAS,OAAY;AACjB,cAAQ,KAAK,OAAO,QAAQ,gDAAsC,MAAM,OAAO,EAAE,CAAC;AAClF,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA,EAGA,MAAa,iBAAgD;AACzD,WAAO,MAAM,KAAK,KAAK;AAAA,EAC3B;AACJ;AAEO,IAAM,kBAAkB,gBAAgB,YAAY;;;AD/E3D,SAAS,kBAAkB;AAGpB,IAAM,aAAa,YAAY;AAClC,MAAI,MAAM,8BAA8B;AAGxC,QAAM,gBAAgB,MAAM,gBAAgB,KAAK;AACjD,MAAI,eAAe;AAEf,QAAI,IAAI,KAAK,OAAO,IAAI,0CAA0C,CAAC;AACnE,QAAI,IAAI,KAAK,cAAO,OAAO,QAAQ,4BAA4B,CAAC,EAAE;AAClE,QAAI,IAAI,QAAQ,eAAe,OAAO,MAAM,cAAc,WAAW,CAAC,EAAE;AACxE,QAAI,IAAI,QAAQ,eAAe,OAAO,UAAU,cAAc,YAAY,CAAC,EAAE;AAC7E,QAAI,IAAI,QAAQ,eAAe,OAAO,IAAI,IAAI,KAAK,cAAc,WAAW,EAAE,eAAe,CAAC,CAAC,EAAE;AACjG,QAAI,IAAI,KAAK,OAAO,IAAI,0CAA0C,CAAC;AAEnE,UAAM,SAAS,MAAM,IAAI,OAAO;AAAA,MAC5B,SAAS;AAAA,MACT,SAAS;AAAA,QACL,EAAE,OAAO,UAAU,OAAO,wBAAiB;AAAA,QAC3C,EAAE,OAAO,aAAa,OAAO,wCAA8B;AAAA,QAC3D,EAAE,OAAO,QAAQ,OAAO,cAAS;AAAA,MACrC;AAAA,IACJ,CAAC;AAED,QAAI,IAAI,SAAS,MAAM,KAAK,WAAW,QAAQ;AAC3C,UAAI,MAAM,0BAAmB;AAC7B;AAAA,IACJ;AAEA,QAAI,WAAW,UAAU;AACrB,UAAI,IAAI,QAAQ,oBAAoB,OAAO,QAAQ,cAAc,WAAW,CAAC,KAAK;AAElF,UAAI,MAAM,kDAAkD;AAC5D;AAAA,IACJ;AAAA,EAGJ;AAGA,QAAM,cAAc,MAAM,IAAI,KAAK;AAAA,IAC/B,SAAS;AAAA,IACT,aAAa;AAAA,IACb,UAAU,CAAC,UAAU;AACjB,UAAI,CAAC,MAAO,QAAO;AACnB,UAAI,MAAM,KAAK,EAAE,SAAS,EAAG,QAAO;AAAA,IACxC;AAAA,EACJ,CAAC;AAED,MAAI,IAAI,SAAS,WAAW,GAAG;AAC3B,QAAI,MAAM,2BAA2B;AACrC;AAAA,EACJ;AAGA,QAAM,mBAAmB,cAAc,QAAQ,IAAI,YAAU;AAAA,IACzD,OAAO;AAAA,IACP,OAAO,UAAU,YAAY,yBACzB,UAAU,WAAW,YACjB,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AAAA,EACzD,EAAE;AAEF,QAAM,YAAY,MAAM,IAAI,OAAO;AAAA,IAC/B,SAAS;AAAA,IACT,SAAS;AAAA,EACb,CAAC;AAED,MAAI,IAAI,SAAS,SAAS,GAAG;AACzB,QAAI,MAAM,2BAA2B;AACrC;AAAA,EACJ;AAGA,QAAM,UAAU,IAAI,QAAQ;AAC5B,UAAQ,MAAM,kCAAkC;AAEhD,MAAI;AACA,UAAM,WAAW;AAAA,MACb,WAAW,WAAW;AAAA,MACtB;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd,aAAa;AAAA,MACb,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,WAAW,CAAC;AAAA,MACZ,UAAU;AAAA,QACN,eAAe;AAAA,QACf,SAAS;AAAA,MACb;AAAA,IACJ;AAEA,UAAM,gBAAgB,KAAK,QAAQ;AACnC,YAAQ,KAAK,2BAA2B;AAExC,QAAI,IAAI,QAAQ,WAAW,OAAO,QAAQ,WAAqB,CAAC,4BAA4B;AAC5F,QAAI,IAAI,QAAQ,oBAAoB,OAAO,IAAI,SAAS,SAAS,CAAC,EAAE;AACpE,QAAI,MAAM,oEAAoE;AAAA,EAClF,SAAS,OAAY;AACjB,YAAQ,KAAK,0BAA0B,CAAC;AACxC,QAAI,IAAI,MAAM,MAAM,OAAO;AAC3B,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ;AAEO,IAAM,cAAc,IAAI,QAAQ,MAAM,EACxC,YAAY,gCAAgC,EAC5C,OAAO,UAAU;;;AG/Ff,IAAM,2BAA2B;;;ACTjC,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASnB,MAAM,oBACF,KACA,gBACA,SACA,YAA0B,CAAC,GACd;AACb,UAAM,EAAE,SAAS,YAAY,QAAQ,IAAI;AAEzC,eAAW,IAAI,OAAO,uBAAuB,GAAG,IAAI;AAAA,MAChD;AAAA,MACA,SAAS;AAAA,IACb,CAAC;AAED,QAAI;AACA,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAC9B,QAAQ;AAAA,QACR,SAAS;AAAA,UACL,GAAG;AAAA,UACH,gBAAgB;AAAA,QACpB;AAAA,QACA,MAAM,KAAK,UAAU,cAAc;AAAA,MACvC,CAAC;AAED,iBAAW,IAAI,OAAO,oBAAoB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAElF,YAAM,kBAA0C,CAAC;AACjD,eAAS,QAAQ,QAAQ,CAAC,OAAO,QAAQ;AAAE,wBAAgB,GAAG,IAAI;AAAA,MAAO,CAAC;AAC1E,iBAAW,IAAI,OAAO,oBAAoB,eAAe;AAEzD,UAAI,CAAC,SAAS,IAAI;AACd,cAAM,YAAY,MAAM,SAAS,KAAK;AACtC,mBAAW,IAAI,OAAO,uBAAuB,SAAS;AACtD,cAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,IAAI,SAAS,UAAU,MAAM,SAAS,EAAE;AAAA,MAClG;AAEA,UAAI,CAAC,SAAS,MAAM;AAChB,cAAM,IAAI,MAAM,uBAAuB;AAAA,MAC3C;AAEA,YAAM,SAAS,SAAS,KAAK,UAAU;AACvC,YAAM,UAAU,IAAI,YAAY;AAChC,UAAI,SAAS;AACb,UAAI,cAAc;AAClB,UAAI,WAAgB,CAAC;AAErB,aAAO,MAAM;AACT,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAE1C,YAAI,MAAM;AACN;AAAA,QACJ;AAGA,kBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAGhD,cAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,iBAAS,MAAM,IAAI,KAAK;AAExB,mBAAW,QAAQ,OAAO;AACtB,cAAI,KAAK,WAAW,OAAO,GAAG;AAC1B,kBAAM,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK;AAEhC,gBAAI,SAAS,UAAU;AACnB,yBAAW,IAAI,OAAO,0BAA0B,EAAE,aAAa,SAAS,CAAC;AAEzE,kBAAI,YAAY;AACZ,2BAAW,aAAa,QAAQ;AAAA,cACpC;AACA;AAAA,YACJ;AAEA,gBAAI;AACA,oBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,oBAAM,QAAQ,OAAO,WAAW,OAAO,WAAW;AAClD,6BAAe;AAGf,kBAAI,OAAO,iBAAiB;AACxB,yBAAS,kBAAkB,OAAO;AAAA,cACtC;AAEA,kBAAI,SAAS;AACT,wBAAQ,KAAK;AAAA,cACjB;AAAA,YACJ,SAAS,YAAY;AAEjB,6BAAe;AACf,kBAAI,SAAS;AACT,wBAAQ,IAAI;AAAA,cAChB;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAEA,iBAAW,IAAI,OAAO,0BAA0B,EAAE,aAAa,SAAS,CAAC;AAGzE,UAAI,YAAY;AACZ,mBAAW,aAAa,QAAQ;AAAA,MACpC;AAAA,IAEJ,SAAS,OAAO;AACZ,iBAAW,IAAI,OAAO,gBAAgB,KAAK;AAC3C,UAAI,SAAS;AACT,gBAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,MACrE,OAAO;AACH,cAAM;AAAA,MACV;AAAA,IACJ;AAAA,EACJ;AACJ;AAEO,IAAM,YAAY,IAAI,UAAU;;;ACnIvC,SAAS,KAAAC,UAAS;AAIX,IAAM,oBAAoBC,GAAE,OAAO;AAAA,EACtC,MAAMA,GAAE,KAAK,CAAC,eAAe,eAAe,eAAe,kBAAkB,cAAc,aAAa,eAAe,eAAe,cAAc,CAAC;AAAA,EACrJ,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA;AAAA,EACrC,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACxC,gBAAgBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC/C,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACxC,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC1C,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA;AAC9C,CAAC;AAKM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACvC,SAASA,GAAE,OAAO;AAAA,EAClB,aAAaA,GAAE,OAAO;AAAA,EACtB,UAAUA,GAAE,QAAQ;AACxB,CAAC;AAGM,IAAM,sBAAsBA,GAAE,OAAO;AAAA,EACxC,SAASA,GAAE,MAAM,iBAAiB;AAAA,EAClC,UAAUA,GAAE,MAAM,kBAAkB,EAAE,SAAS;AAAA,EAC/C,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA;AAAA,EAG7B,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,iBAAiBA,GAAE,OAAO,EAAE,SAAS;AACzC,CAAC;AAOM,SAAS,mBAAmB,aAAqC;AACpE,aAAW,IAAI,UAAU,0BAA0B,EAAE,SAAS,OAAO,YAAY,CAAC;AAElF,MAAI,YAAiB,CAAC;AACtB,MAAI;AAGJ,MAAI,OAAO,gBAAgB,UAAU;AACjC,eAAW,IAAI,UAAU,eAAe,EAAE,QAAQ,YAAY,OAAO,CAAC;AACtE,QAAI;AACA,kBAAY,iBAAiB,WAAW;AAAA,IAC5C,SAAS,GAAG;AACR,iBAAW,IAAI,UAAU,uBAAuB,EAAE,OAAQ,EAAY,QAAQ,CAAC;AAE/E,aAAO;AAAA,QACH,SAAS,CAAC;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,MAAM;AAAA,QACV,CAAC;AAAA,QACD,SAAS;AAAA,MACb;AAAA,IACJ;AAAA,EACJ,WAES,OAAO,gBAAgB,YAAY,gBAAgB,MAAM;AAC9D,UAAM,UAAU;AAChB,sBAAkB,QAAQ;AAE1B,eAAW,IAAI,UAAU,eAAe;AAAA,MACpC,YAAY,CAAC,CAAC,QAAQ;AAAA,MACtB,YAAY,CAAC,CAAC,QAAQ;AAAA,MACtB,aAAa,OAAO,QAAQ;AAAA,IAChC,CAAC;AAGD,UAAM,gBAAgB,QAAQ,WAAW,QAAQ;AACjD,QAAI,iBAAiB,OAAO,kBAAkB,UAAU;AACpD,UAAI;AAEA,cAAM,eAAe,iBAAiB,aAAa;AAEnD,YAAI,OAAO,iBAAiB,YAAY,iBAAiB,MAAM;AAC3D,sBAAY;AACZ,qBAAW,IAAI,UAAU,qBAAqB,EAAE,MAAM,OAAO,KAAK,SAAS,EAAE,CAAC;AAAA,QAClF,OAAO;AAEH,sBAAY;AACZ,qBAAW,IAAI,UAAU,0BAA0B;AAAA,QACvD;AAAA,MACJ,SAAS,GAAG;AAER,oBAAY;AACZ,mBAAW,IAAI,UAAU,4CAA4C,EAAE,OAAQ,EAAY,QAAQ,CAAC;AAAA,MACxG;AAAA,IACJ,OAAO;AACH,kBAAY;AAAA,IAChB;AAGA,QAAI,CAAC,UAAU,SAAS;AACpB,kBAAY;AAAA,IAChB;AAAA,EACJ;AAIA,MAAI,CAAC,UAAU,SAAS;AACpB,eAAW,IAAI,UAAU,yCAAyC;AAElE,WAAO;AAAA,MACH;AAAA,MACA,SAAS,CAAC;AAAA,QACN,MAAM;AAAA,QACN,SAAS,UAAU,WAAW,KAAK,UAAU,SAAS;AAAA,QACtD,MAAM;AAAA,MACV,CAAC;AAAA,MACD,SAAS,UAAU;AAAA,IACvB;AAAA,EACJ;AAIA,QAAM,SAAS;AAAA,IACX,SAAS,UAAU;AAAA,IACnB,UAAU,UAAU,YAAY,CAAC;AAAA,IACjC,SAAS,UAAU,WAAW;AAAA,IAC9B;AAAA,IACA,SAAS,UAAU,WAAW;AAAA;AAAA,EAClC;AAGA,aAAW,IAAI,UAAU,4BAA4B,EAAE,aAAa,OAAO,QAAQ,OAAO,CAAC;AAE3F,MAAI;AACA,WAAO,oBAAoB,MAAM,MAAM;AAAA,EAC3C,SAAS,GAAG;AACR,eAAW,IAAI,UAAU,4BAA4B,EAAE,OAAQ,EAAY,QAAQ,CAAC;AACpF,UAAM;AAAA,EACV;AACJ;AAEA,SAAS,iBAAiB,KAAkB;AACxC,MAAI;AACA,WAAO,KAAK,MAAM,GAAG;AAAA,EACzB,SAAS,GAAG;AAER,UAAM,YAAY,IAAI,QAAQ,GAAG;AACjC,QAAI,cAAc,GAAI,OAAM;AAE5B,QAAI,UAAU;AACd,QAAI,WAAW;AACf,QAAI,SAAS;AAEb,aAAS,IAAI,WAAW,IAAI,IAAI,QAAQ,KAAK;AACzC,YAAM,OAAO,IAAI,CAAC;AAElB,UAAI,QAAQ;AACR,iBAAS;AACT;AAAA,MACJ;AAEA,UAAI,SAAS,MAAM;AACf,iBAAS;AACT;AAAA,MACJ;AAEA,UAAI,SAAS,KAAK;AACd,mBAAW,CAAC;AACZ;AAAA,MACJ;AAEA,UAAI,CAAC,UAAU;AACX,YAAI,SAAS,IAAK;AAAA,iBACT,SAAS,KAAK;AACnB;AACA,cAAI,YAAY,GAAG;AAEf,kBAAM,gBAAgB,IAAI,UAAU,WAAW,IAAI,CAAC;AACpD,gBAAI;AACA,qBAAO,KAAK,MAAM,aAAa;AAAA,YACnC,SAAS,QAAQ;AAEb,oBAAM;AAAA,YACV;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AACA,UAAM;AAAA,EACV;AACJ;;;ACxLO,IAAM,sBAAN,MAAM,qBAAoB;AAAA,EAC7B,OAAe;AAAA,EAEP,cAAc;AAAA,EAAE;AAAA,EAExB,OAAc,cAAmC;AAC7C,QAAI,CAAC,qBAAoB,UAAU;AAC/B,2BAAoB,WAAW,IAAI,qBAAoB;AAAA,IAC3D;AACA,WAAO,qBAAoB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,mBAAmB,WAAmB,gBAAuC;AAC/E,UAAM,QAAQ,MAAM,gBAAgB,KAAK;AACzC,QAAI,CAAC,OAAO;AACR,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC7E;AAGA,QAAI,CAAC,MAAM,eAAe;AACtB,YAAM,gBAAgB,CAAC;AAAA,IAC3B;AAEA,UAAM,cAAc,SAAS,IAAI;AACjC,UAAM,gBAAgB,KAAK,KAAK;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBAAkB,WAAgD;AACpE,UAAM,QAAQ,MAAM,gBAAgB,KAAK;AACzC,QAAI,CAAC,SAAS,CAAC,MAAM,eAAe;AAChC,aAAO;AAAA,IACX;AAEA,WAAO,MAAM,cAAc,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,oBAAoB,WAAkC;AACxD,UAAM,QAAQ,MAAM,gBAAgB,KAAK;AACzC,QAAI,CAAC,SAAS,CAAC,MAAM,eAAe;AAChC;AAAA,IACJ;AAEA,WAAO,MAAM,cAAc,SAAS;AACpC,UAAM,gBAAgB,KAAK,KAAK;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,wBAAuC;AACzC,UAAM,QAAQ,MAAM,gBAAgB,KAAK;AACzC,QAAI,CAAC,OAAO;AACR;AAAA,IACJ;AAEA,UAAM,gBAAgB,CAAC;AACvB,UAAM,gBAAgB,KAAK,KAAK;AAAA,EACpC;AACJ;AAEO,IAAM,sBAAsB,oBAAoB,YAAY;;;AC5EnE,eAAsB,iBAAkC;AACpD,QAAM,gBAAgB,cAAc,YAAY;AAChD,QAAM,SAAS,cAAc,UAAU;AACvC,QAAM,QAAQ,OAAO;AAErB,MAAI,CAAC,OAAO;AACR,UAAM,IAAI;AAAA,MACN;AAAA,IAEJ;AAAA,EACJ;AAEA,SAAO;AACX;;;ACXA,IAAM,aAAa;AAEnB,SAAS,WAAW,YAA6B;AAC7C,MAAI,WAAY,QAAO;AACvB,QAAM,SAAS,cAAc,YAAY,EAAE,UAAU;AACrD,MAAI,OAAO,QAAQ,GAAI,QAAO,OAAO,OAAO;AAC5C,SAAO,QAAQ,IAAI,yBAAyB;AAChD;AAiBA,eAAsB,wBAClB,QACA,UAA0B,CAAC,GACL;AACtB,QAAM,EAAE,SAAS,SAAS,WAAW,IAAI;AAGzC,QAAM,QAAQ,MAAM,eAAe;AAGnC,QAAM,QAAQ,MAAM,aAAa,SAAS,KAAK;AAC/C,MAAI,CAAC,OAAO;AACR,UAAM,IAAI,MAAM,4CAA4C,KAAK,8BAA8B;AAAA,EACnG;AAGA,QAAM,yBAAyB,MAAM,oBAAoB,kBAAkB,UAAU;AAGrF,QAAM,iBAAiB;AAAA,IACnB,aAAa;AAAA,IACb,WAAW;AAAA,IACX,qBAAqB;AAAA;AAAA,IACrB,uBAAuB;AAAA,IACvB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,EACrB;AAGA,QAAM,mBAAmB,WAAW,QAAQ,OAAO;AACnD,QAAM,WAAW,GAAG,wBAAwB,aAAa,gBAAgB;AAGzE,QAAM,UAAU;AAAA,IACZ,iBAAiB,UAAU,KAAK;AAAA,IAChC,gBAAgB;AAAA,EACpB;AAGA,MAAI,cAAc;AAClB,MAAI,cAAmB,CAAC;AAExB,QAAM,UAAU;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACI,SAAS,CAAC,UAAU;AAChB,uBAAe;AACf,YAAI,SAAS;AACT,kBAAQ,KAAK;AAAA,QACjB;AAAA,MACJ;AAAA,MACA,YAAY,OAAO,YAAY;AAE3B,sBAAc;AAAA,UACV,SAAS,WAAW;AAAA,UACpB,iBAAiB;AAAA;AAAA,QACrB;AAAA,MACJ;AAAA,MACA,SAAS,CAAC,UAAU;AAChB,cAAM;AAAA,MACV;AAAA,IACJ;AAAA,EACJ;AAGA,QAAM,iBAAiB,mBAAmB,WAAW;AAGrD,MAAI,eAAe,iBAAiB;AAChC,UAAM,oBAAoB,mBAAmB,YAAY,eAAe,eAAe;AAAA,EAC3F;AAGA,MAAI,YAAY;AACZ,eAAW,cAAc;AAAA,EAC7B;AAEA,SAAO;AACX;AAOA,eAAsB,6BAA4C;AAC9D,MAAI,MAAM,kCAA2B;AAErC,QAAM,SAAS,MAAM,IAAI,KAAK;AAAA,IAC1B,SAAS;AAAA,IACT,aAAa;AAAA,IACb,UAAU,CAAC,UAAU;AACjB,UAAI,CAAC,SAAS,MAAM,SAAS,GAAI,QAAO;AAAA,IAC5C;AAAA,EACJ,CAAC;AAED,MAAI,IAAI,SAAS,MAAM,GAAG;AACtB,QAAI,MAAM,WAAW;AACrB;AAAA,EACJ;AAEA,QAAM,UAAU,IAAI,QAAQ;AAC5B,UAAQ,MAAM,2CAAoC;AAElD,MAAI,eAAe;AAEnB,MAAI;AACA,UAAM,wBAAwB,QAAkB;AAAA,MAC5C,SAAS,CAAC,UAAU;AAChB,wBAAgB;AAEhB,YAAI;AAEA,cAAI,aAAa,KAAK,EAAE,WAAW,GAAG,GAAG;AACrC,oBAAQ,QAAQ,OAAO,IAAI,8BAA8B,CAAC;AAAA,UAC9D,OAAO;AACH,oBAAQ,QAAQ,OAAO,IAAI,aAAa,CAAC;AAAA,UAC7C;AAAA,QACJ,SAAS,GAAG;AAAA,QAEZ;AAAA,MACJ;AAAA,MACA,YAAY,OAAO,aAAa;AAC5B,gBAAQ,KAAK,mBAAmB;AAGhC,YAAI,SAAS,SAAS;AAClB,cAAI,IAAI,KAAK,OAAO,OAAO,SAAS,OAAO,CAAC;AAAA,QAChD;AAGA,YAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,GAAG;AACjD,qBAAW,UAAU,SAAS,SAAS;AAGnC,gBAAI,OAAO,SAAS,kBAAkB;AAClC,kBAAI,IAAI,KAAK,OAAO,QAAQ,qBAAc,CAAC;AAC3C,sBAAQ,IAAI,OAAO,OAAO;AAAA,YAO9B,OAGK;AACD,kBAAI,IAAI,QAAQ;AAAA,2BAAuB,OAAO,IAAI,KAAK,OAAO,KAAK,OAAO,QAAQ,SAAS,CAAC,EAAE;AAG9F,kBAAI,OAAO,SAAS;AAChB,wBAAQ,IAAI,OAAO,IAAI,yBAAyB,CAAC;AACjD,wBAAQ,IAAI,OAAO,QAAQ,UAAU,GAAG,GAAG,KAAK,OAAO,QAAQ,SAAS,MAAM,QAAQ,GAAG;AACzF,wBAAQ,IAAI,OAAO,IAAI,yBAAyB,CAAC;AAAA,cACrD;AAEA,oBAAM,UAAU,MAAM,IAAI,QAAQ;AAAA,gBAC9B,SAAS,kBAAkB,OAAO,IAAI,KAAK,OAAO,IAAI;AAAA,gBACtD,QAAQ;AAAA,gBACR,UAAU;AAAA,cACd,CAAC;AAED,kBAAI,SAAS;AAGT,oBAAI,IAAI,QAAQ,2BAAsB,OAAO,IAAI,WAAW;AAAA,cAChE,OAAO;AACH,oBAAI,IAAI,MAAM,uBAAkB;AAAA,cACpC;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ;AAAA,MAEJ;AAAA,IACJ,CAAC;AAED,QAAI,MAAM,kBAAkB;AAAA,EAChC,SAAS,OAAY;AACjB,YAAQ,KAAK,gBAAW,CAAC;AACzB,QAAI,IAAI,MAAM,MAAM,OAAO;AAC3B,UAAM;AAAA,EACV;AACJ;;;AClNA,OAAOC,SAAQ;;;ACRf,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,OAAO,QAAQ;AAQR,SAAS,gBAAgB,SAAyB;AACrD,MAAI;AACA,UAAM,WAAWC,MAAK,QAAQ,QAAQ,IAAI,GAAG,OAAO;AACpD,QAAI,CAACC,IAAG,WAAW,QAAQ,EAAG,QAAO,oBAAoB,OAAO;AAEhE,UAAM,QAAQA,IAAG,YAAY,UAAU,EAAE,eAAe,KAAK,CAAC;AAC9D,WAAO,MAAM,IAAI,UAAQ;AACrB,aAAO,GAAG,KAAK,YAAY,IAAI,UAAU,QAAQ,IAAI,KAAK,IAAI;AAAA,IAClE,CAAC,EAAE,KAAK,IAAI;AAAA,EAChB,SAAS,GAAQ;AACb,WAAO,wBAAwB,EAAE,OAAO;AAAA,EAC5C;AACJ;AAEO,SAAS,eAAe,UAA0B;AACrD,MAAI;AACA,UAAM,WAAWD,MAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ;AACrD,QAAI,CAACC,IAAG,WAAW,QAAQ,EAAG,QAAO,eAAe,QAAQ;AAG5D,UAAM,QAAQA,IAAG,SAAS,QAAQ;AAClC,QAAI,MAAM,OAAO,MAAM,KAAM,QAAO,kCAAkC,MAAM,IAAI;AAEhF,WAAOA,IAAG,aAAa,UAAU,OAAO;AAAA,EAC5C,SAAS,GAAQ;AACb,WAAO,uBAAuB,EAAE,OAAO;AAAA,EAC3C;AACJ;AAEO,SAAS,iBAAiB,SAAyB;AACtD,MAAI;AAGA,UAAM,UAAU,GAAG,KAAK,SAAS,EAAE,KAAK,KAAK,CAAC;AAC9C,QAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,WAAO,QAAQ,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI;AAAA,EACzC,SAAS,GAAQ;AACb,WAAO,0BAA0B,EAAE,OAAO;AAAA,EAC9C;AACJ;AAEO,SAAS,kBAAkB,UAAkB,YAAoB,eAAuBC,MAAmB;AAC9G,MAAI,CAACD,IAAG,WAAW,QAAQ,GAAG;AAC1B,IAAAC,KAAI,IAAI,MAAM,2CAAsC,QAAQ,EAAE;AAC9D,WAAO;AAAA,EACX;AAEA,QAAM,qBAAqBD,IAAG,aAAa,UAAU,OAAO;AAI5D,MAAI,CAAC,mBAAmB,SAAS,aAAa,GAAG;AAC7C,IAAAC,KAAI,IAAI,MAAM,sCAAiC,QAAQ,yBAAyB;AAChF,YAAQ,IAAI,OAAO,IAAI,iCAAiC,CAAC;AACzD,YAAQ,IAAI,cAAc,UAAU,GAAG,GAAG,IAAI,KAAK;AACnD,WAAO;AAAA,EACX;AAGA,QAAM,cAAc,mBAAmB,MAAM,aAAa,EAAE,SAAS;AACrE,MAAI,cAAc,GAAG;AACjB,IAAAA,KAAI,IAAI,MAAM,kCAA6B,WAAW,mBAAmB,QAAQ,yBAAyB;AAC1G,WAAO;AAAA,EACX;AAGA,QAAM,iBAAiB,mBAAmB,QAAQ,eAAe,UAAU;AAC3E,EAAAD,IAAG,cAAc,UAAU,cAAc;AACzC,EAAAC,KAAI,IAAI,QAAQ,iCAA4B,QAAQ,EAAE;AACtD,SAAO;AACX;AAEA,eAAsB,iBAAiB,SAAkC;AACrE,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,eAAoB;AACnD,MAAI;AACA,QAAI,IAAI,KAAK,wBAAiB,OAAO,IAAI,OAAO,CAAC,EAAE;AAMnD,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC5B,YAAM,QAAQ,MAAM,SAAS;AAAA,QACzB,OAAO;AAAA,QACP,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,QAChC,KAAK,QAAQ,IAAI;AAAA,MACrB,CAAC;AAED,UAAI,SAAS;AACb,UAAI,SAAS;AAGb,YAAM,QAAQ,WAAW,MAAM;AAC3B,cAAM,KAAK;AACX,gBAAQ;AAAA;AAAA,EAA8D,MAAM;AAAA,EAAK,MAAM,EAAE;AAAA,MAC7F,GAAG,IAAI,KAAK,GAAI;AAEhB,YAAM,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC9B,cAAM,QAAQ,KAAK,SAAS;AAC5B,kBAAU;AAAA,MAEd,CAAC;AAED,YAAM,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC9B,kBAAU,KAAK,SAAS;AAAA,MAC5B,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,SAAS;AACxB,qBAAa,KAAK;AAClB,YAAI,SAAS,GAAG;AACZ,kBAAQ,OAAO,KAAK,KAAK,4CAA4C;AAAA,QACzE,OAAO;AACH,kBAAQ,iCAAiC,IAAI;AAAA;AAAA,EAAe,MAAM;AAAA;AAAA,EAAc,MAAM,EAAE;AAAA,QAC5F;AAAA,MACJ,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,QAAQ;AACvB,qBAAa,KAAK;AAClB,gBAAQ,4BAA4B,IAAI,OAAO,EAAE;AAAA,MACrD,CAAC;AAAA,IACL,CAAC;AAAA,EAEL,SAAS,GAAQ;AACb,WAAO,4BAA4B,EAAE,OAAO;AAAA,EAChD;AACJ;;;ADzHA,IAAMC,cAAa;AAEnB,SAASC,YAAW,YAA6B;AAC7C,MAAI,WAAY,QAAO;AACvB,QAAM,SAAS,cAAc,YAAY,EAAE,UAAU;AACrD,MAAI,OAAO,QAAQ,KAAM,QAAO,OAAO,OAAO;AAC9C,SAAO,QAAQ,IAAI,2BAA2B;AAClD;AAWA,eAAsB,8BAA8B,UAA4B,CAAC,GAAkB;AAC/F,aAAW,KAAK;AAChB,MAAI,MAAM,sCAA0B;AAGpC,MAAI,kBAAkB;AACtB,MAAI,eAAe,QAAQ;AAE3B,MAAI,CAAC,cAAc;AAEf,UAAM,QAAQC,IAAG,YAAY,QAAQ,IAAI,CAAC;AAC1C,UAAM,kBAAkB,MAAM,KAAK,OAAK,EAAE,SAAS,cAAc,CAAC;AAElE,mBAAe,MAAM,IAAI,KAAK;AAAA,MAC1B,SAAS;AAAA,MACT,cAAc,mBAAmB;AAAA,MACjC,aAAa;AAAA,MACb,UAAU,CAAC,QAAQ;AACf,YAAI,OAAO,CAACA,IAAG,WAAW,GAAG,EAAG,QAAO;AAAA,MAC3C;AAAA,IACJ,CAAC;AAAA,EACL;AAEA,MAAI,IAAI,SAAS,YAAY,EAAG;AAEhC,MAAI,cAAc;AACd,QAAI;AACA,wBAAkBA,IAAG,aAAa,cAAc,OAAO;AACvD,UAAI,IAAI,KAAK,oBAAoB,OAAO,KAAK,YAAY,CAAC,EAAE;AAAA,IAChE,SAAS,GAAG;AACR,UAAI,IAAI,MAAM,4BAA4B,CAAC,EAAE;AAC7C;AAAA,IACJ;AAAA,EACJ,OAAO;AACH,QAAI,IAAI,KAAK,uEAAuE;AAAA,EACxF;AAGA,QAAM,gBAAgB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAK1C,eAAe;AAAA;AAAA,MAEX,KAAK,IAAI;AAGX,QAAM,YAAY,eAAe,QAAQ,OAAO;AACpD;AAKA,eAAe,YAAY,gBAAwB,iBAA0B;AACzE,MAAI,aAAa;AACjB,MAAI,YAAY;AAEhB,SAAO,WAAW;AACd,UAAM,UAAU,IAAI,QAAQ;AAC5B,YAAQ,MAAM,qDAAyC;AAEvD,QAAI,eAAe;AACnB,QAAI,eAAqC;AAEzC,QAAI;AAEA,qBAAe,MAAM,iBAAiB,YAAY,CAAC,UAAU;AACzD,wBAAgB;AAChB,YAAI;AACA,cAAI,aAAa,KAAK,EAAE,WAAW,GAAG,GAAG;AACrC,oBAAQ,QAAQ,OAAO,IAAI,8BAA8B,CAAC;AAAA,UAC9D,OAAO;AACH,oBAAQ,QAAQ,OAAO,IAAI,aAAa,CAAC;AAAA,UAC7C;AAAA,QACJ,SAAS,GAAG;AAAA,QAAE;AAAA,MAClB,GAAG,eAAe;AAElB,cAAQ,KAAK,mBAAmB;AAGhC,UAAI,gBAAgB,aAAa,SAAS;AAEtC,YAAI,mBAAmB;AACvB,YAAI,iBAAiB;AAErB,mBAAW,UAAU,aAAa,SAAS;AAEvC,cAAI,OAAO,SAAS,kBAAkB;AAClC,gBAAI,IAAI,KAAK,OAAO,QAAQ,sBAAe,CAAC;AAC5C,oBAAQ,IAAI,OAAO,OAAO;AAC1B,6BAAiB;AAAA,UACrB,WAES,OAAO,SAAS,cAAc;AACnC,gBAAI,IAAI,KAAK,4BAAqB,OAAO,KAAK,OAAO,QAAQ,GAAG,CAAC,EAAE;AACnE,kBAAM,SAAS,gBAAgB,OAAO,QAAQ,GAAG;AACjD,gCAAoB,sBAAsB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AAC1E,gBAAI,IAAI,KAAK,OAAO,IAAI,eAAe,CAAC;AAAA,UAC5C,WAES,OAAO,SAAS,aAAa;AAClC,gBAAI,IAAI,KAAK,wBAAiB,OAAO,KAAK,OAAO,QAAQ,EAAE,CAAC,EAAE;AAC9D,kBAAM,SAAS,eAAe,OAAO,QAAQ,EAAE;AAC/C,gCAAoB,qBAAqB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AACzE,gBAAI,IAAI,KAAK,OAAO,IAAI,YAAY,CAAC;AAAA,UACzC,WAES,OAAO,SAAS,eAAe;AACpC,gBAAI,IAAI,KAAK,0BAAmB,OAAO,KAAK,OAAO,QAAQ,EAAE,CAAC,EAAE;AAChE,kBAAM,SAAS,iBAAiB,OAAO,QAAQ,EAAE;AACjD,gCAAoB,uBAAuB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AAC3E,gBAAI,IAAI,KAAK,OAAO,IAAI,cAAc,CAAC;AAAA,UAC3C,WAES,CAAC,eAAe,eAAe,aAAa,EAAE,SAAS,OAAO,IAAI,GAAG;AAC1E,gBAAI,IAAI,QAAQ;AAAA,2BAAuB,OAAO,IAAI,KAAK,OAAO,KAAK,OAAO,QAAQ,SAAS,CAAC,EAAE;AAG9F,gBAAI,OAAO,SAAS;AAChB,sBAAQ,IAAI,OAAO,IAAI,yBAAyB,CAAC;AACjD,sBAAQ,IAAI,OAAO,QAAQ,UAAU,GAAG,GAAG,IAAI,KAAK;AACpD,sBAAQ,IAAI,OAAO,IAAI,yBAAyB,CAAC;AAAA,YACrD;AAEA,kBAAM,UAAU,MAAM,IAAI,QAAQ;AAAA,cAC9B,SAAS,WAAW,OAAO,IAAI;AAAA,cAC/B,QAAQ;AAAA,cACR,UAAU;AAAA,YACd,CAAC;AAED,gBAAI,SAAS;AACT,kBAAI,OAAO,MAAM;AACb,oBAAI;AACA,sBAAI,OAAO,SAAS,eAAe;AAC/B,oBAAAA,IAAG,cAAc,OAAO,MAAM,OAAO,WAAW,EAAE;AAClD,wBAAI,IAAI,QAAQ,mBAAc,OAAO,IAAI,EAAE;AAC3C,wCAAoB,uBAAuB,OAAO,IAAI;AAAA;AAAA;AAAA,kBAC1D,WAAW,OAAO,SAAS,eAAe;AACtC,wBAAI,OAAO,gBAAgB;AACvB,4BAAM,UAAU,kBAAkB,OAAO,MAAM,OAAO,WAAW,IAAI,OAAO,gBAAgB,GAAG;AAC/F,0CAAoB,uBAAuB,OAAO,IAAI,OAAO,UAAU,YAAY,QAAQ;AAAA;AAAA;AAAA,oBAC/F,OAAO;AACH,sBAAAA,IAAG,cAAc,OAAO,MAAM,OAAO,WAAW,EAAE;AAClD,0BAAI,IAAI,QAAQ,uBAAkB,OAAO,IAAI,EAAE;AAC/C,0CAAoB,uBAAuB,OAAO,IAAI;AAAA;AAAA;AAAA,oBAC1D;AAAA,kBACJ,WAAW,OAAO,SAAS,eAAe;AACtC,oBAAAA,IAAG,WAAW,OAAO,IAAI;AACzB,wBAAI,IAAI,QAAQ,mBAAc,OAAO,IAAI,EAAE;AAC3C,wCAAoB,uBAAuB,OAAO,IAAI;AAAA;AAAA;AAAA,kBAC1D;AAAA,gBACJ,SAAS,GAAQ;AACb,sBAAI,IAAI,MAAM,kBAAa,EAAE,OAAO,EAAE;AACtC,sCAAoB,WAAW,OAAO,IAAI,IAAI,OAAO,IAAI,cAAc,EAAE,OAAO;AAAA;AAAA;AAAA,gBACpF;AAAA,cACJ;AAAA,YACJ,OAAO;AACH,kBAAI,IAAI,MAAM,uBAAkB;AAChC,kCAAoB,WAAW,OAAO,IAAI;AAAA;AAAA;AAAA,YAC9C;AAAA,UACJ;AAAA,QACJ;AAGA,YAAI,kBAAkB;AAMlB,cAAI,gBAAgB;AAChB,kBAAM,YAAY,MAAM,IAAI,KAAK;AAAA,cAC7B,SAAS;AAAA,cACT,aAAa;AAAA,YACjB,CAAC;AACD,gBAAI,IAAI,SAAS,SAAS,GAAG;AACzB,0BAAY;AACZ;AAAA,YACJ;AACA,yBAAa,GAAG,gBAAgB;AAAA;AAAA,cAAmB,SAAS;AAC5D,gBAAI,IAAI,KAAK,OAAO,IAAI,oCAAoC,CAAC;AAAA,UACjE,OAAO;AAEH,yBAAa;AACb,uBAAW,IAAI,UAAU,mCAAmC,EAAE,QAAQ,iBAAiB,OAAO,CAAC;AAC/F,gBAAI,IAAI,KAAK,OAAO,IAAI,oCAAoC,CAAC;AAAA,UACjE;AAAA,QAEJ,WAAW,gBAAgB;AAEvB,gBAAM,YAAY,MAAM,IAAI,KAAK;AAAA,YAC7B,SAAS;AAAA,YACT,aAAa;AAAA,UACjB,CAAC;AACD,cAAI,IAAI,SAAS,SAAS,GAAG;AACzB,wBAAY;AACZ;AAAA,UACJ;AACA,uBAAa;AAAA,QACjB,OAAO;AAEH,cAAI,IAAI,QAAQ,mBAAmB;AACnC,sBAAY;AAAA,QAChB;AAAA,MAEJ,OAAO;AACH,YAAI,IAAI,QAAQ,iCAAiC;AACjD,oBAAY;AAAA,MAChB;AAAA,IAEJ,SAAS,OAAY;AACjB,cAAQ,KAAK,OAAO;AACpB,UAAI,IAAI,MAAM,MAAM,OAAO;AAC3B,kBAAY;AAAA,IAChB;AAAA,EACJ;AACJ;AAMA,eAAe,iBAAiB,QAAgB,SAAkC,SAA0C;AACxH,QAAM,QAAQ,MAAM,eAAe;AACnC,QAAM,QAAQ,MAAM,aAAa,SAAS,KAAK;AAC/C,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,eAAe;AAE3C,QAAM,iBAAiB,MAAM,oBAAoB,kBAAkBF,WAAU;AAE7E,QAAM,UAAU;AAAA,IACZ,aAAa;AAAA,IACb,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,EACrB;AAEA,QAAM,mBAAmBC,YAAW,OAAO;AAC3C,QAAM,MAAM,GAAG,wBAAwB,aAAa,gBAAgB;AAEpE,MAAI,UAAU;AACd,MAAI,MAAW,CAAC;AAEhB,aAAW,IAAI,SAAS,qBAAqB;AAAA,IACzC,SAAS;AAAA,IACT;AAAA,IACA,QAAQ,OAAO,UAAU,GAAG,GAAG;AAAA;AAAA,EACnC,CAAC;AAED,QAAM,UAAU,oBAAoB,KAAK,SAAS,EAAE,iBAAiB,UAAU,KAAK,IAAI,gBAAgB,mBAAmB,GAAG;AAAA,IAC1H,SAAS,CAAC,MAAM;AAAE,iBAAW;AAAG,cAAQ,CAAC;AAAA,IAAG;AAAA,IAC5C,YAAY,CAAC,KAAK,aAAa;AAE3B,YAAM,aAAa,UAAU;AAE7B,iBAAW,IAAI,SAAS,qBAAqB;AAAA,QACzC;AAAA,QACA;AAAA,QACA,eAAe,KAAK;AAAA,MACxB,CAAC;AAED,YAAM;AAAA,QACF,SAAS,OAAO;AAAA,QAChB,iBAAiB,cAAc;AAAA,MACnC;AAAA,IACJ;AAAA,IACA,SAAS,CAAC,MAAM;AAAE,YAAM;AAAA,IAAG;AAAA,EAC/B,CAAC;AAED,QAAM,SAAS,mBAAmB,GAAG;AACrC,MAAI,OAAO,iBAAiB;AACxB,UAAM,oBAAoB,mBAAmBD,aAAY,OAAO,eAAe;AAAA,EACnF;AAEA,SAAO;AACX;;;AErTA,SAAS,WAAAG,gBAAe;;;ACUxB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAKjB,IAAMC,cAAa;AAEnB,SAASC,cAAqB;AAC1B,QAAM,SAAS,cAAc,YAAY,EAAE,UAAU;AACrD,MAAI,OAAO,QAAQ,KAAM,QAAO,OAAO,OAAO;AAC9C,SAAO,QAAQ,IAAI,2BAA2B;AAClD;AAMA,eAAsB,qBAAqB,UAA+C,CAAC,GAAkB;AACzG,aAAW,KAAK;AAChB,QAAM,SAAS,cAAc,YAAY,EAAE,UAAU;AACrD,QAAM,WAAW,OAAO,YAAY;AAEpC,MAAI,MAAM,EAAE,qBAAqB,CAAC;AAElC,QAAM,cAAc,QAAQ,IAAI;AAKhC,MAAI;AAEJ,MAAI,QAAQ,QAAQ;AAChB,iBAAaC,MAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ,MAAM;AAAA,EAC3D,OAAO;AACH,UAAM,YAAYA,MAAK,QAAQ,aAAa,UAAU;AACtD,QAAI,CAACC,IAAG,WAAW,SAAS,GAAG;AAG3B,YAAM,OAAOA,IAAG,WAAW,SAAS,IAAIA,IAAG,SAAS,SAAS,IAAI;AACjE,UAAI,QAAQ,KAAK,OAAO,GAAG;AACvB,YAAI,IAAI,QAAQ,iGAAiG;AACjH,cAAM,cAAcD,MAAK,QAAQ,aAAa,uBAAuB;AACrE,YAAI,CAACC,IAAG,WAAW,WAAW,EAAG,CAAAA,IAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAC9E,qBAAaD,MAAK,KAAK,aAAa,oBAAoB;AAAA,MAC5D,OAAO;AACH,QAAAC,IAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAC3C,qBAAaD,MAAK,KAAK,WAAW,oBAAoB;AAAA,MAC1D;AAAA,IACJ,OAAO;AACH,MAAAC,IAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAC3C,mBAAaD,MAAK,KAAK,WAAW,oBAAoB;AAAA,IAC1D;AAAA,EACJ;AAEA,MAAI,IAAI,KAAK,GAAG,EAAE,+BAA+B,CAAC,IAAI,OAAO,KAAK,WAAW,CAAC,EAAE;AAChF,MAAI,IAAI,KAAK,GAAG,EAAE,4BAA4B,CAAC,IAAI,OAAO,KAAK,UAAU,CAAC,EAAE;AAC5E,MAAI,IAAI,KAAK,GAAG,EAAE,wBAAwB,CAAC,IAAI,OAAO,KAAK,QAAQ,CAAC,EAAE;AAEtE,QAAM,qBAAqBA,MAAK,SAAS,aAAa,UAAU;AAGhE,QAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCxB,MAAI,CAACC,IAAG,WAAW,UAAU,GAAG;AAC5B,IAAAA,IAAG,cAAc,YAAY,iBAAiB,EAAE,UAAU,QAAQ,CAAC;AACnE,QAAI,IAAI,QAAQ,GAAG,EAAE,+BAA+B,CAAC,IAAI,UAAU,EAAE;AAAA,EACzE,OAAO;AACH,QAAI,IAAI,KAAK,EAAE,0BAA0B,CAAC;AAAA,EAC9C;AAGA,QAAM,cAAc;AAAA;AAAA;AAAA;AAAA,4BAII,kBAAkB;AAAA;AAAA;AAAA,kCAGZ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAsF3B,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eA+ElB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2E/B,KAAK;AAEH,QAAM,YAAY,aAAa,UAAU;AAC7C;AAIA,eAAe,YAAY,eAAuB,YAAoB;AAClE,MAAI,aAAa;AACjB,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,QAAM,YAAY;AAElB,SAAO,aAAa,YAAY,WAAW;AACvC;AACA,UAAM,UAAU,IAAI,QAAQ;AAC5B,UAAM,MAAM,EAAE,yBAAyB,EAAE,QAAQ,UAAU,UAAU,SAAS,CAAC;AAC/E,YAAQ,MAAM,GAAG;AAEjB,QAAI,eAAe;AACnB,QAAI,eAAqC;AAEzC,QAAI;AAEA,qBAAe,MAAM,iBAAiB,YAAY,CAAC,UAAU;AACzD,wBAAgB;AAAA,MAEpB,CAAC;AAED,cAAQ,KAAK,EAAE,4BAA4B,CAAC;AAG5C,UAAI,gBAAgB,aAAa,WAAW,aAAa,QAAQ,SAAS,GAAG;AACzE,YAAI,mBAAmB;AACvB,YAAI,cAAc;AAElB,mBAAW,UAAU,aAAa,SAAS;AACvC,cAAI,OAAO,SAAS,cAAc;AAC9B,gBAAI,IAAI,KAAK,EAAE,2BAA2B,EAAE,QAAQ,OAAO,OAAO,KAAK,OAAO,QAAQ,GAAG,CAAC,CAAC;AAC3F,kBAAM,SAAS,gBAAgB,OAAO,QAAQ,GAAG;AACjD,gCAAoB,sBAAsB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AAAA,UAC9E,WACS,OAAO,SAAS,aAAa;AAClC,gBAAI,IAAI,KAAK,EAAE,2BAA2B,EAAE,QAAQ,OAAO,OAAO,KAAK,OAAO,QAAQ,EAAE,CAAC,CAAC;AAC1F,kBAAM,SAAS,eAAe,OAAO,QAAQ,EAAE;AAE/C,gCAAoB,qBAAqB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AAAA,UAC7E,WACS,OAAO,SAAS,eAAe;AACpC,gBAAI,IAAI,KAAK,EAAE,yBAAyB,EAAE,QAAQ,OAAO,OAAO,KAAK,OAAO,QAAQ,EAAE,CAAC,CAAC;AACxF,kBAAM,SAAS,iBAAiB,OAAO,QAAQ,EAAE;AACjD,gCAAoB,uBAAuB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AAAA,UAC/E,WACS,OAAO,SAAS,iBAAiB,OAAO,SAAS,eAAe;AAOrE,kBAAM,qBAAqBD,MAAK,QAAQ,OAAO,QAAQ,EAAE;AACzD,kBAAM,qBAAqBA,MAAK,QAAQ,UAAU;AAClD,gBAAI,WAAW,uBAAuB;AAGtC,gBAAI,CAAC,YAAYA,MAAK,SAAS,OAAO,QAAQ,EAAE,MAAM,sBAAsB;AACxE,kBAAI,IAAI,QAAQ,EAAE,8BAA8B,EAAE,QAAQ,OAAO,OAAO,QAAQ,EAAE,EAAE,QAAQ,OAAOA,MAAK,SAAS,QAAQ,IAAI,GAAG,UAAU,CAAC,CAAC;AAC5I,yBAAW;AAEX,qBAAO,OAAO;AAAA,YAClB;AAEA,gBAAI,UAAU;AAEV,oBAAM,YAAY;AAClB,kBAAI,OAAO,SAAS,eAAe;AAC/B,gBAAAC,IAAG,cAAc,WAAW,OAAO,WAAW,EAAE;AAChD,oBAAI,IAAI,QAAQ,EAAE,yBAAyB,EAAE,QAAQ,OAAO,SAAS,CAAC;AACtE,8BAAc;AAAA,cAClB,OAAO;AAEH,oBAAIA,IAAG,WAAW,SAAS,GAAG;AAC1B,wBAAM,iBAAiBA,IAAG,aAAa,WAAW,OAAO;AAEzD,sBAAI,OAAO,kBAAkB,eAAe,SAAS,OAAO,cAAc,GAAG;AACzE,0BAAM,aAAa,eAAe,QAAQ,OAAO,gBAAgB,OAAO,WAAW,EAAE;AACrF,oBAAAA,IAAG,cAAc,WAAW,YAAY,EAAE,UAAU,QAAQ,CAAC;AAC7D,wBAAI,IAAI,QAAQ,EAAE,uBAAuB,EAAE,QAAQ,OAAO,SAAS,CAAC;AACpE,kCAAc;AAAA,kBAClB,OAAO;AAIH,wBAAI,IAAI,QAAQ,EAAE,qBAAqB,IAAI,OAAO,EAAE,+BAA+B,CAAC;AACpF,wCAAoB,WAAW,OAAO,IAAI;AAAA;AAE1C,kCAAc;AAAA,kBAClB;AAAA,gBACJ,OAAO;AAGH,sBAAI,IAAI,QAAQ,EAAE,qBAAqB,IAAI,OAAO,EAAE,wBAAwB,CAAC;AAAA,gBACjF;AAAA,cACJ;AACA,kCAAoB,WAAW,OAAO,IAAI;AAAA;AAAA,YAC9C,OAAO;AACH,kBAAI,IAAI,QAAQ,EAAE,qBAAqB,CAAC;AAGxC,kCAAoB,WAAW,OAAO,IAAI,MAAM,EAAE,uBAAuB,CAAC;AAAA;AAAA,YAC9E;AAAA,UACJ,WACS,OAAO,SAAS,kBAAkB;AACvC,gBAAI,IAAI,KAAK,OAAO,QAAQ,EAAE,yBAAyB,CAAC,CAAC;AACzD,oBAAQ,IAAI,OAAO,OAAO;AAG1B,kBAAM,QAAQ,MAAM,IAAI,KAAK,EAAE,SAAS,EAAE,0BAA0B,GAAG,aAAa,EAAE,gCAAgC,EAAE,CAAC;AACzH,gCAAoB,iBAAiB,KAAK;AAAA;AAAA,UAC9C;AAAA,QACJ;AAEA,YAAI,aAAa;AAEb,gBAAM,iBAAiBA,IAAG,aAAa,YAAY,OAAO;AAC1D,gBAAM,kBAA4B,CAAC;AACnC,gBAAM,QAAQ,eAAe,MAAM,IAAI;AACvC,cAAI,iBAAiB;AAErB,qBAAW,QAAQ,OAAO;AACtB,gBAAI,KAAK,WAAW,KAAK,GAAG;AACxB,+BAAiB,KAAK,UAAU,CAAC,EAAE,KAAK;AAAA,YAC5C;AACA,gBAAI,KAAK,SAAS,kBAAkB,GAAG;AACnC,kBAAI,kBAAkB,CAAC,gBAAgB,SAAS,cAAc,GAAG;AAC7D,gCAAgB,KAAK,cAAc;AAAA,cACvC;AAAA,YACJ;AAAA,UACJ;AAEA,gBAAM,aAAa,gBAAgB,SAAS,IACtC;AAAA;AAAA,mBAAwB,EAAE,+BAA+B,EAAE,QAAQ,OAAO,gBAAgB,KAAK,IAAI,CAAC,CAAC,KACrG;AAAA;AAAA,mBAAwB,EAAE,4BAA4B,CAAC;AAG7D,uBAAa,GAAG,gBAAgB;AAAA;AAAA,sCAA2C,UAAU;AACrF,qBAAW,IAAI,QAAQ,oCAAoC,EAAE,MAAM,WAAW,SAAS,gBAAgB,OAAO,CAAC;AAAA,QACnH,OAAO;AAEH,uBAAa;AACb,qBAAW,IAAI,QAAQ,8BAA8B,EAAE,QAAQ,iBAAiB,OAAO,CAAC;AAAA,QAC5F;AAAA,MAEJ,OAAO;AAEH,YAAI,IAAI,QAAQ,EAAE,yBAAyB,CAAC;AAC5C,oBAAY;AAAA,MAChB;AAAA,IAEJ,SAAS,OAAY;AACjB,cAAQ,KAAK,EAAE,cAAc,CAAC;AAC9B,UAAI,IAAI,MAAM,MAAM,OAAO;AAC3B,kBAAY;AAAA,IAChB;AAAA,EACJ;AACJ;AAGA,eAAe,iBAAiB,QAAgB,SAA0D;AACtG,QAAM,QAAQ,MAAM,eAAe;AACnC,QAAM,QAAQ,MAAM,aAAa,SAAS,KAAK;AAC/C,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,eAAe;AAK3C,MAAI,iBAAiB,MAAM,oBAAoB,kBAAkBH,WAAU;AAI3E,QAAM,UAAU;AAAA,IACZ,aAAa;AAAA,IACb,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,EACrB;AAEA,QAAM,MAAM,GAAG,wBAAwB,aAAaC,YAAW,CAAC;AAChE,MAAI,UAAU;AACd,MAAI,MAAW,CAAC;AAEhB,aAAW,IAAI,QAAQ,eAAe,EAAE,cAAc,OAAO,OAAO,CAAC;AAErE,QAAM,UAAU,oBAAoB,KAAK,SAAS,EAAE,iBAAiB,UAAU,KAAK,IAAI,gBAAgB,mBAAmB,GAAG;AAAA,IAC1H,SAAS,CAAC,MAAM;AAAE,iBAAW;AAAG,cAAQ,CAAC;AAAA,IAAG;AAAA,IAC5C,YAAY,CAAC,KAAK,aAAa;AAC3B,YAAM,aAAa,UAAU;AAC7B,YAAM;AAAA,QACF,SAAS,OAAO;AAAA,QAChB,iBAAiB,cAAc;AAAA,MACnC;AAAA,IACJ;AAAA,IACA,SAAS,CAAC,MAAM;AAAE,YAAM;AAAA,IAAG;AAAA,EAC/B,CAAC;AAED,QAAM,SAAS,mBAAmB,GAAG;AACrC,MAAI,OAAO,iBAAiB;AACxB,UAAM,oBAAoB,mBAAmBD,aAAY,OAAO,eAAe;AAAA,EACnF;AACA,SAAO;AACX;;;AD1jBO,IAAM,cAAc,IAAII,SAAQ,MAAM,EACxC,YAAY,wDAAwD,EACpE,OAAO,uBAAuB,sEAAsE,EACpG,OAAO,mBAAmB,wCAAwC,OAAO,EACzE,OAAO,OAAO,YAAY;AACvB,MAAI;AACA,UAAM,qBAAqB,OAAO;AAAA,EACtC,SAAS,OAAY;AACjB,YAAQ,MAAM,sBAAsB,MAAM,OAAO;AACjD,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ,CAAC;;;AEdL,SAAS,WAAAC,gBAAe;;;ACSxB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAUjB,IAAMC,cAAa;AAEnB,SAASC,YAAW,YAA6B;AAC7C,MAAI,WAAY,QAAO;AAGvB,QAAM,SAAS,cAAc,YAAY,EAAE,UAAU;AACrD,MAAI,OAAO,QAAQ,IAAK,QAAO,OAAO,OAAO;AAG7C,MAAI,QAAQ,IAAI,uBAAwB,QAAO,QAAQ,IAAI;AAG3D,SAAO;AACX;AAEA,eAAsB,0BAA0B,UAA+C,CAAC,GAAkB;AAC9G,aAAW,KAAK;AAChB,MAAI,MAAM,2BAAoB;AAE9B,QAAM,UAAUA,YAAW;AAE3B,MAAI,YAAY,yBAAyB;AACrC,QAAI,IAAI,MAAM,sDAAiD;AAC/D;AAAA,EACJ;AAGA,QAAM,cAAc,QAAQ,IAAI;AAChC,MAAI,iBAAiB;AACrB,QAAM,qBAAqBC,MAAK,QAAQ,aAAa,YAAY,oBAAoB;AACrF,QAAM,sBAAsB,QAAQ,UAAUA,MAAK,QAAQ,aAAa,QAAQ,OAAO,IAAI;AAE3F,MAAIC,IAAG,WAAW,mBAAmB,GAAG;AACpC,QAAI;AACA,uBAAiBA,IAAG,aAAa,qBAAqB,OAAO;AAC7D,UAAI,IAAI,KAAK,kCAA2B,OAAO,IAAID,MAAK,SAAS,aAAa,mBAAmB,CAAC,CAAC,EAAE;AAAA,IACzG,SAAS,GAAG;AACR,UAAI,IAAI,QAAQ,gCAAgC,CAAC,EAAE;AAAA,IACvD;AAAA,EACJ,OAAO;AACH,QAAI,IAAI,QAAQ,gFAAsE;AAAA,EAC1F;AAGA,MAAI,aAAa,QAAQ,QAAQ;AACjC,MAAI,gBAAgB;AAChB,kBAAc;AAAA;AAAA;AAAA,EAAgC,cAAc;AAAA;AAAA,EAChE;AAGA,MAAI,YAAY;AAChB,QAAM,UAAU,IAAI,QAAQ;AAE5B,SAAO,WAAW;AACd,QAAI;AACA,cAAQ,MAAM,sBAAsB;AAGpC,UAAI,eAAqC;AACzC,YAAM,gBAAgB,YAAY,CAAC,UAAU;AAEzC,YAAI,CAAC,cAAc;AAAA,QAEnB;AAAA,MACJ,CAAC,EAAE,KAAK,UAAQ;AACZ,uBAAe;AAAA,MACnB,CAAC;AAED,cAAQ,KAAK,mBAAmB;AAEhC,UAAI,gBAAiB,aAA+B,SAAS;AACzD,cAAM,WAAW;AACjB,YAAI,mBAAmB;AACvB,YAAI,iBAAiB;AAErB,mBAAW,UAAU,SAAS,SAAS;AAEnC,cAAI,OAAO,SAAS,kBAAkB;AAClC,gBAAI,IAAI,KAAK,OAAO,QAAQ,sBAAe,CAAC;AAC5C,oBAAQ,IAAI,OAAO,OAAO;AAC1B,6BAAiB;AAAA,UACrB,WAES,OAAO,SAAS,cAAc;AACnC,gBAAI,IAAI,KAAK,2BAAoB,OAAO,IAAI,OAAO,QAAQ,GAAG,CAAC,EAAE;AACjE,kBAAM,SAAS,gBAAgB,OAAO,QAAQ,GAAG;AACjD,gCAAoB,sBAAsB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AAAA,UAC9E,WAES,OAAO,SAAS,aAAa;AAClC,gBAAI,IAAI,KAAK,sBAAe,OAAO,IAAI,OAAO,QAAQ,EAAE,CAAC,EAAE;AAC3D,kBAAM,SAAS,eAAe,OAAO,QAAQ,EAAE;AAC/C,gCAAoB,qBAAqB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AAAA,UAC7E,WAES,OAAO,SAAS,eAAe;AACpC,gBAAI,IAAI,KAAK,wBAAiB,OAAO,IAAI,OAAO,QAAQ,EAAE,CAAC,EAAE;AAC7D,kBAAM,SAAS,iBAAiB,OAAO,QAAQ,EAAE;AACjD,gCAAoB,uBAAuB,OAAO,IAAI;AAAA,EAAe,MAAM;AAAA;AAAA;AAAA,UAC/E,WAES,OAAO,SAAS,eAAe;AACpC,kBAAM,MAAM,OAAO,WAAW;AAC9B,gBAAI,IAAI,KAAK,wBAAiB,OAAO,IAAI,GAAG,CAAC,EAAE;AAK/C,kBAAM,UAAU,MAAM,IAAI,QAAQ;AAAA,cAC9B,SAAS,oBAAoB,GAAG;AAAA,cAChC,QAAQ;AAAA,cACR,UAAU;AAAA,YACd,CAAC;AAED,gBAAI,SAAS;AACT,oBAAM,SAAS,MAAM,iBAAiB,GAAG;AACzC,kCAAoB,uBAAuB,GAAG;AAAA,EAAe,MAAM;AAAA;AAAA;AAAA,YACvE,OAAO;AACH,kCAAoB;AAAA;AAAA;AAAA,YACxB;AAAA,UACJ,WAES,CAAC,eAAe,aAAa,EAAE,SAAS,OAAO,IAAI,GAAG;AAC3D,kBAAM,WAAW,OAAO,SAAS;AACjC,kBAAM,WAAW,OAAO,QAAQ;AAChC,gBAAI,IAAI,QAAQ;AAAA,2BAAuB,WAAW,WAAW,QAAQ,KAAK,OAAO,KAAK,QAAQ,CAAC,EAAE;AAIjG,gBAAI,OAAO,SAAS;AAChB,sBAAQ,IAAI,OAAO,IAAI,mBAAmB,IAAI,OAAO,QAAQ,UAAU,GAAG,GAAG,IAAI,UAAU,OAAO,IAAI,iBAAiB,CAAC;AAAA,YAC5H;AAEA,kBAAM,UAAU,MAAM,IAAI,QAAQ;AAAA,cAC9B,SAAS,sBAAsB,QAAQ;AAAA,cACvC,QAAQ;AAAA,cACR,UAAU;AAAA,YACd,CAAC;AAED,gBAAI,SAAS;AACT,kBAAI,UAAU;AACV,sBAAM,aAAaA,MAAK,QAAQ,aAAa,QAAQ;AACrD,sBAAM,MAAMA,MAAK,QAAQ,UAAU;AACnC,oBAAI,CAACC,IAAG,WAAW,GAAG,EAAG,CAAAA,IAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAE9D,oBAAI,UAAU;AACV,kBAAAA,IAAG,cAAc,YAAY,OAAO,WAAW,EAAE;AACjD,sBAAI,IAAI,QAAQ,mBAAc,QAAQ,EAAE;AACxC,sCAAoB,uBAAuB,QAAQ;AAAA;AAAA;AAAA,gBACvD,OAAO;AAEH,sBAAI,OAAO,gBAAgB;AACvB,0BAAM,UAAU,kBAAkB,UAAU,OAAO,WAAW,IAAI,OAAO,gBAAgB,GAAG;AAC5F,wCAAoB,uBAAuB,QAAQ,OAAO,UAAU,YAAY,QAAQ;AAAA;AAAA;AAAA,kBAC5F,OAAO;AAKH,wBAAI,IAAI,MAAM,iDAA4C;AAC1D,wCAAoB;AAAA;AAAA;AAAA,kBACxB;AAAA,gBACJ;AAAA,cACJ;AAAA,YACJ,OAAO;AACH,kBAAI,IAAI,MAAM,gBAAW;AACzB,kCAAoB,WAAW,OAAO,IAAI;AAAA;AAAA;AAAA,YAC9C;AAAA,UACJ;AAAA,QACJ;AAGA,YAAI,kBAAkB;AAClB,cAAI,gBAAgB;AAChB,kBAAM,YAAY,MAAM,IAAI,KAAK,EAAE,SAAS,eAAe,CAAC;AAC5D,gBAAI,IAAI,SAAS,SAAS,GAAG;AAAE,0BAAY;AAAO;AAAA,YAAO;AACzD,yBAAa,GAAG,gBAAgB;AAAA;AAAA,cAAmB,SAAS;AAAA,UAChE,OAAO;AAEH,yBAAa;AACb,gBAAI,IAAI,KAAK,OAAO,IAAI,kCAAkC,CAAC;AAAA,UAC/D;AAAA,QACJ,WAAW,gBAAgB;AACvB,gBAAM,YAAY,MAAM,IAAI,KAAK,EAAE,SAAS,eAAe,CAAC;AAC5D,cAAI,IAAI,SAAS,SAAS,GAAG;AAAE,wBAAY;AAAO;AAAA,UAAO;AACzD,uBAAa;AAAA,QACjB,OAAO;AAEH,cAAI,SAAS,SAAS;AAClB,gBAAI,IAAI,KAAK,OAAO,QAAQ,sBAAe,CAAC;AAC5C,oBAAQ,IAAI,SAAS,OAAO;AAC5B,kBAAM,YAAY,MAAM,IAAI,KAAK,EAAE,SAAS,eAAe,CAAC;AAC5D,gBAAI,IAAI,SAAS,SAAS,GAAG;AACzB,0BAAY;AAAA,YAChB,OAAO;AACH,2BAAa;AAAA,YACjB;AAAA,UACJ,OAAO;AACH,gBAAI,IAAI,QAAQ,wBAAwB;AACxC,wBAAY;AAAA,UAChB;AAAA,QACJ;AAAA,MAEJ,OAAO;AACH,YAAI,IAAI,QAAQ,8BAA8B;AAC9C,oBAAY;AAAA,MAChB;AAAA,IAEJ,SAAS,GAAQ;AACb,cAAQ,KAAK,OAAO;AACpB,UAAI,IAAI,MAAM,EAAE,OAAO;AACvB,iBAAW,IAAI,aAAa,mBAAmB,CAAC;AAChD,kBAAY;AAAA,IAChB;AAAA,EACJ;AAEA,MAAI,MAAM,mCAA4B;AAC1C;AAEA,eAAe,gBAAgB,QAAgB,SAA0D;AACrG,QAAM,QAAQ,MAAM,eAAe;AACnC,QAAM,QAAQ,MAAM,aAAa,SAAS,KAAK;AAC/C,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,iCAAiC;AAE7D,QAAM,iBAAiB,MAAM,oBAAoB,kBAAkBH,WAAU;AAE7E,QAAM,UAAU;AAAA,IACZ,aAAa;AAAA,IACb,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,IACjB,qBAAqB;AAAA;AAAA,EACzB;AAEA,QAAM,MAAM,GAAG,wBAAwB,aAAaC,YAAW,CAAC;AAChE,MAAI,UAAU;AACd,MAAI,MAAW,CAAC;AAEhB,QAAM,UAAU,oBAAoB,KAAK,SAAS,EAAE,iBAAiB,UAAU,KAAK,IAAI,gBAAgB,mBAAmB,GAAG;AAAA,IAC1H,SAAS,CAAC,MAAM;AAAE,iBAAW;AAAG,cAAQ,CAAC;AAAA,IAAG;AAAA,IAC5C,YAAY,CAAC,KAAK,aAAa;AAC3B,YAAM,aAAa,UAAU;AAC7B,YAAM;AAAA,QACF,SAAS,OAAO;AAAA,QAChB,iBAAiB,cAAc;AAAA,MACnC;AAAA,IACJ;AAAA,IACA,SAAS,CAAC,MAAM;AAAE,YAAM;AAAA,IAAG;AAAA,EAC/B,CAAC;AAED,QAAM,SAAS,mBAAmB,GAAG;AACrC,MAAI,OAAO,iBAAiB;AACxB,UAAM,oBAAoB,mBAAmBD,aAAY,OAAO,eAAe;AAAA,EACnF;AACA,SAAO;AACX;;;ADjRO,IAAM,aAAa,IAAII,SAAQ,KAAK,EACtC,YAAY,8CAA8C,EAC1D,OAAO,qBAAqB,0BAA0B,EACtD,OAAO,wBAAwB,6BAA6B,EAC5D,OAAO,OAAO,YAAY;AACvB,QAAM,0BAA0B,OAAO;AAC3C,CAAC;;;AEVL,SAAS,WAAAC,gBAAe;;;ACQxB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,cAAc;AACvB,SAAS,4BAA4B;AAGrC,IAAMC,cAAa;AAEnB,SAASC,cAAqB;AAC1B,QAAM,SAAS,cAAc,YAAY,EAAE,UAAU;AACrD,MAAI,OAAO,QAAQ,GAAI,QAAO,OAAO,OAAO;AAC5C,SAAO,QAAQ,IAAI,yBAAyB;AAChD;AAQA,IAAM,uBAAN,MAA2B;AAAA,EACf,SAAwB;AAAA,EACxB,YAAyC;AAAA,EAEjD,MAAM,UAAU;AACZ,QAAI,KAAK,OAAQ;AAEjB,QAAI;AACA,WAAK,YAAY,IAAI,qBAAqB;AAAA,QACtC,SAAS;AAAA,QACT,MAAM,CAAC,MAAM,4BAA4B;AAAA,MAC7C,CAAC;AAED,WAAK,SAAS,IAAI,OAAO;AAAA,QACrB,MAAM;AAAA,QACN,SAAS;AAAA,MACb,GAAG;AAAA,QACC,cAAc,CAAC;AAAA,MACnB,CAAC;AAED,YAAM,KAAK,OAAO,QAAQ,KAAK,SAAS;AACxC,UAAI,IAAI,QAAQ,4CAAqC;AAAA,IACzD,SAAS,GAAQ;AACb,UAAI,IAAI,MAAM,oCAAoC,EAAE,OAAO,EAAE;AAC7D,YAAM;AAAA,IACV;AAAA,EACJ;AAAA,EAEA,MAAM,SAAS,MAAc,MAAW;AACpC,QAAI,CAAC,KAAK,OAAQ,OAAM,KAAK,QAAQ;AACrC,QAAI;AACA,YAAM,SAAS,MAAM,KAAK,OAAQ,SAAS;AAAA,QACvC;AAAA,QACA,WAAW;AAAA,MACf,CAAC;AACD,aAAO;AAAA,IACX,SAAS,GAAQ;AACb,aAAO,EAAE,SAAS,MAAM,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,cAAc,EAAE,OAAO,GAAG,CAAC,EAAE;AAAA,IACzF;AAAA,EACJ;AAAA,EAEA,MAAM,QAAQ;AACV,QAAI,KAAK,WAAW;AAChB,YAAM,KAAK,UAAU,MAAM;AAAA,IAC/B;AAAA,EACJ;AACJ;AAEA,IAAM,YAAY,IAAI,qBAAqB;AAE3C,eAAsB,WAAW,SAAyB;AACtD,QAAM,UAAUA,YAAW;AAE3B,MAAI,CAAC,SAAS;AACV,QAAI,IAAI,MAAM,8CAAyC;AACvD,QAAI,IAAI,KAAK,iDAAiD;AAC9D;AAAA,EACJ;AAGA,QAAM,UAAU,QAAQ;AAExB,MAAI,MAAM,0BAAmB;AAC7B,MAAI,IAAI,KAAK,kCAAkC;AAE/C,QAAM,QAAQ,MAAM,eAAe;AACnC,QAAM,QAAQ,MAAM,aAAa,SAAS,KAAK;AAE/C,MAAI,CAAC,OAAO;AACR,QAAI,IAAI,MAAM,6CAA6C;AAC3D;AAAA,EACJ;AAGA,MAAI,iBAAiB;AACrB,MAAI;AACA,UAAM,cAAcC,MAAK,KAAK,QAAQ,IAAI,GAAG,YAAY,oBAAoB;AAC7E,QAAIC,IAAG,WAAW,WAAW,GAAG;AAC5B,uBAAiBA,IAAG,aAAa,aAAa,OAAO;AACrD,UAAI,IAAI,KAAK,4DAAqD;AAAA,IACtE;AAAA,EACJ,SAAS,GAAG;AAAA,EAEZ;AAEA,MAAI,cAAc;AAAA,EAAyB,cAAc;AAAA;AAAA;AAEzD,MAAI,QAAQ,YAAY;AACpB,mBAAe,aAAa,QAAQ,UAAU;AAAA;AAAA,EAClD;AACA,MAAI,QAAQ,UAAU;AAClB,mBAAe,wBAAqB,QAAQ,QAAQ;AAAA;AAAA,EACxD,OAAO;AACH,mBAAe;AAAA,EACnB;AAGA,MAAI,cAAc;AAElB,SAAO,aAAa;AAChB,UAAM,UAAU,IAAI,QAAQ;AAC5B,YAAQ,MAAM,mCAA4B;AAE1C,QAAI,oBAAoB;AACxB,QAAI,gBAAsC;AAE1C,QAAI;AAEA,YAAM,yBAAyB,MAAM,oBAAoB,kBAAkBH,WAAU;AAErF,YAAM,UAAU;AAAA,QACZ,sDAAsDC,YAAW,CAAC;AAAA,QAClE;AAAA,UACI,aAAa;AAAA,UACb,WAAW;AAAA,UACX,kBAAkB;AAAA,UAClB,iBAAiB;AAAA,QACrB;AAAA,QACA;AAAA,UACI,iBAAiB,UAAU,KAAK;AAAA,QACpC;AAAA,QACA;AAAA,UACI,SAAS,CAAC,UAAU;AAChB,iCAAqB;AACrB,gBAAI,kBAAkB,SAAS,MAAM,kBAAkB,KAAK,EAAE,WAAW,GAAG,GAAG;AAC3E,sBAAQ,QAAQ,8BAA8B;AAAA,YAClD;AAAA,UACJ;AAAA,UACA,YAAY,CAAC,UAAU,aAAa;AAChC,gBAAI;AACA,kBAAI,UAAU,iBAAiB;AAC3B,oCAAoB,mBAAmBD,aAAY,SAAS,eAAe;AAAA,cAC/E;AACA,8BAAgB,mBAAmB,YAAY,iBAAiB;AAAA,YACpE,SAAS,GAAG;AACR,kBAAI,IAAI,MAAM,gBAAiB,EAAY,OAAO,EAAE;AACpD,8BAAgB,EAAE,SAAS,CAAC,GAAG,SAAS,0BAA0B,SAAS,SAAS;AAAA,YACxF;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAEA,cAAQ,KAAK,mBAAmB;AAAA,IAEpC,SAAS,OAAO;AACZ,cAAQ,KAAK,uBAAuB,CAAC;AACrC,UAAI,IAAI,MAAO,MAAgB,OAAO;AACtC,oBAAc;AACd;AAAA,IACJ;AAEA,QAAI,CAAC,cAAe;AAGpB,QAAI,cAAc,SAAS;AACvB,UAAI,IAAI,KAAK,OAAO,QAAQ,mBAAY,cAAc,OAAO,EAAE,CAAC;AAAA,IACpE;AAEA,QAAI,cAAc,QAAQ,WAAW,GAAG;AAEpC,YAAM,QAAQ,MAAM,IAAI,KAAK;AAAA,QACzB,SAAS;AAAA,QACT,aAAa;AAAA,MACjB,CAAC;AAED,UAAI,IAAI,SAAS,KAAK,GAAG;AACrB,sBAAc;AAAA,MAClB,OAAO;AACH,sBAAc;AAAA,MAClB;AACA;AAAA,IACJ;AAEA,eAAW,UAAU,cAAc,SAAS;AACxC,UAAI,IAAI,KAAK,OAAO,IAAI,cAAc,OAAO,IAAI,EAAE,CAAC;AAEpD,UAAI,SAAS;AAEb,UAAI;AACA,gBAAQ,OAAO,MAAM;AAAA,UACjB,KAAK;AACD,kBAAM,QAAQ,MAAM,IAAI,KAAK;AAAA,cACzB,SAAS,aAAM,OAAO,OAAO;AAAA,YACjC,CAAC;AACD,gBAAI,IAAI,SAAS,KAAK,EAAG,eAAc;AAAA,gBAClC,UAAS;AACd;AAAA,UAEJ,KAAK;AACD,gBAAI,OAAO,WAAW;AAClB,kBAAI,IAAI,KAAK,uBAAgB,OAAO,KAAK,OAAO,SAAS,CAAC,EAAE;AAC5D,kBAAI,OAAO,CAAC;AACZ,kBAAI;AACA,uBAAO,OAAO,OAAO,cAAc,WAC7B,KAAK,MAAM,OAAO,SAAS,IAC1B,OAAO,aAAa,CAAC;AAAA,cAChC,SAAS,GAAG;AACR,oBAAI,IAAI,QAAQ,+CAA+C;AAAA,cACnE;AACA,oBAAM,YAAY,MAAM,UAAU,SAAS,OAAO,WAAW,IAAI;AACjE,uBAAS,KAAK,UAAU,SAAS;AAEjC,kBAAI,IAAI,QAAQ,WAAW,OAAO,UAAU,GAAG,GAAG,CAAC,KAAK;AAAA,YAC5D;AACA;AAAA,UAEJ,KAAK;AACD,gBAAI,OAAO,QAAQ,OAAO,SAAS;AAC/B,oBAAM,WAAWE,MAAK,QAAQ,QAAQ,IAAI,GAAG,OAAO,IAAI;AACxD,cAAAC,IAAG,cAAc,UAAU,OAAO,OAAO;AACzC,kBAAI,IAAI,QAAQ,iBAAiB,OAAO,IAAI,EAAE;AAC9C,uBAAS;AAAA,YACb;AACA;AAAA,UAEJ,KAAK;AACD,qBAAS,eAAe,OAAO,QAAQ,EAAE;AACzC;AAAA,UAEJ,KAAK;AAED,kBAAM,UAAU,MAAM,IAAI,QAAQ,EAAE,SAAS,gBAAgB,OAAO,OAAO,IAAI,CAAC;AAChF,gBAAI,WAAW,OAAO,SAAS;AAC3B,uBAAS,MAAM,iBAAiB,OAAO,OAAO;AAAA,YAClD,OAAO;AACH,uBAAS;AAAA,YACb;AACA;AAAA,UAEJ;AACI,qBAAS,UAAU,OAAO,IAAI;AAAA,QACtC;AAAA,MACJ,SAAS,GAAQ;AACb,iBAAS,mBAAmB,OAAO,IAAI,KAAK,EAAE,OAAO;AACrD,YAAI,IAAI,MAAM,MAAM;AAAA,MACxB;AAGA,oBAAc,WAAW,OAAO,IAAI;AAAA,EAAc,MAAM;AAAA;AAAA;AAAA,IAC5D;AAAA,EACJ;AAEA,QAAM,UAAU,MAAM;AACtB,MAAI,MAAM,kCAA2B;AACzC;;;AD7QO,IAAM,YAAY,IAAIC,SAAQ,IAAI,EACpC,YAAY,mDAAmD,EAC/D,OAAO,eAAe,qBAAqB,EAC3C,OAAO,yBAAyB,8CAA8C,EAC9E,OAAO,OAAO,YAAY;AACvB,MAAI;AACA,UAAM,WAAW;AAAA,MACb,YAAY,QAAQ;AAAA,MACpB,UAAU,QAAQ;AAAA,IACtB,CAAC;AAAA,EACL,SAAS,OAAY;AACjB,YAAQ,MAAM,2BAA2B,MAAM,OAAO;AACtD,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ,CAAC;;;AhBbL,aAAa,KAAK;AAalB,IAAM,UAAU,IAAIC,SAAQ;AAE5B,QACK,KAAK,OAAO,EACZ,YAAY,qDAAqD,EACjE,QAAQ,OAAO;AAEpB,QAAQ,WAAW,YAAY;AAC/B,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,UAAU;AAC7B,QAAQ,WAAW,SAAS;AAI5B,QACK,QAAQ,IAAI,EACZ,YAAY,kDAAkD,EAC9D,OAAO,mBAAmB,mBAAmB,EAC7C,OAAO,OAAO,YAAY;AACvB,MAAI;AACA,UAAM,2BAA2B;AAAA,EACrC,SAAS,OAAY;AACjB,YAAQ,MAAM,UAAU,MAAM,OAAO;AACrC,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ,CAAC;AAIL,QACK,QAAQ,MAAM,EACd,YAAY,+CAA+C,EAC3D,OAAO,mBAAmB,mBAAmB,EAC7C,OAAO,qBAAqB,uBAAuB,EACnD,OAAO,OAAO,YAAY;AACvB,MAAI;AACA,UAAM,8BAA8B;AAAA,MAChC,SAAS,QAAQ;AAAA,MACjB,cAAc,QAAQ;AAAA,IAC1B,CAAC;AAAA,EACL,SAAS,OAAY;AACjB,YAAQ,MAAM,UAAU,MAAM,OAAO;AACrC,YAAQ,KAAK,CAAC;AAAA,EAClB;AACJ,CAAC;AAEL,QACK,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC,OAAO,cAAc,MAAM;AAGhC,QAAQ,GAAG,sBAAsB,CAAC,QAAQ;AACtC,UAAQ,MAAM,OAAO,MAAM,yBAAoB,GAAG,GAAG;AACrD,UAAQ,KAAK,CAAC;AAClB,CAAC;AAED,QAAQ,MAAM,QAAQ,IAAI;","names":["Command","fs","path","path","fs","z","z","fs","fs","path","path","fs","tui","AGENT_TYPE","getAgentId","fs","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","Command","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","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/commands/scan.ts","../../src/core/agents/scan-agent.ts","../../src/commands/dev.ts","../../src/core/agents/developer-agent.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\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 let creds = await tokenStorage.getCredentials(this.realm);\n\n if (!creds?.accessToken) {\n throw new AuthError(`Authentication required for realm '${this.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 (creds.expiresAt && creds.clientId && creds.clientKey) {\n if (now > creds.expiresAt - buffer) {\n try {\n if (this.debugMode) console.log(colors.dim('πŸ”„ Refreshing expired token...'));\n\n const newTokens = await authenticate(this.realm, creds.clientId, creds.clientKey);\n\n await tokenStorage.saveToken(\n this.realm,\n newTokens.access_token,\n creds.clientId,\n creds.clientKey,\n newTokens.expires_in\n );\n\n // Update local reference with new token\n creds.accessToken = newTokens.access_token;\n if (this.debugMode) console.log(colors.success('βœ… Token refreshed successfully.'));\n\n } catch (error) {\n console.warn(colors.warning(`⚠️ Failed to auto-refresh token: ${(error as Error).message}`));\n // Fallback to existing token (might still work for a few seconds or fail at API)\n }\n }\n }\n\n const headers = new Headers();\n headers.set('Authorization', `Bearer ${creds?.accessToken}`);\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 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(['create_file', 'modify_file', 'delete_file', 'talk_with_user', 'list_files', 'read_file', 'search_file', 'run_command', 'use_mcp_tool']),\n path: z.string().nullable().optional(), // Nullable for strict mode combatibility\n content: z.string().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\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\nfunction 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 } 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\n}\n\n/**\n * Interactive Specification Agent session.\n * Reads briefing, consults user, and generates tech-spec.md.\n */\nexport async function interactiveSpecificationAgent(options: SpecAgentOptions = {}): Promise<void> {\n FileLogger.init();\n tui.intro('πŸ—οΈ Specification Agent');\n\n // 1. Resolve Briefing File\n let briefingContent = '';\n let briefingPath = options.briefingPath;\n\n if (!briefingPath) {\n // Try to find a default briefing in current dir\n const files = fs.readdirSync(process.cwd());\n const defaultBriefing = files.find(f => f.endsWith('_briefing.md'));\n\n briefingPath = await tui.text({\n message: 'Path to Briefing file (Leave empty to skip)',\n initialValue: defaultBriefing || '',\n placeholder: 'e.g., todo-list_briefing.md',\n validate: (val) => {\n if (val && !fs.existsSync(val)) return 'File not found';\n }\n }) as string;\n }\n\n if (tui.isCancel(briefingPath)) return;\n\n if (briefingPath) {\n try {\n briefingContent = fs.readFileSync(briefingPath, 'utf-8');\n tui.log.info(`Loaded briefing: ${colors.bold(briefingPath)}`);\n } catch (e) {\n tui.log.error(`Failed to read briefing: ${e}`);\n return;\n }\n } else {\n tui.log.info('Skipping briefing file. Starting fresh or exploring existing project.');\n }\n\n // 2. Initial Prompt Construction\n const initialPrompt = briefingContent ? `\nTenho o seguinte Documento de Briefing de NegΓ³cio. \nPor favor, analise-o e inicie o processo de definiΓ§Γ£o da EspecificaΓ§Γ£o TΓ©cnica.\n\n---\n${briefingContent}\n---\n `.trim() : 'Gostaria de ajuda com uma especificaΓ§Γ£o tΓ©cnica ou explorar este projeto.';\n\n // 3. Start Conversation Loop\n await runSpecLoop(initialPrompt, options.agentId);\n}\n\n/**\n * Main Loop for Specification Agent\n */\nasync function runSpecLoop(initialMessage: string, overrideAgentId?: string) {\n let nextPrompt = initialMessage;\n let keepGoing = true;\n\n while (keepGoing) {\n const spinner = tui.spinner();\n spinner.start('πŸ—οΈ Specification Agent is thinking...');\n\n let responseText = '';\n let lastResponse: AgentResponse | null = null;\n\n try {\n // Call Agent\n lastResponse = await callSpecAgentApi(nextPrompt, (chunk) => {\n responseText += chunk;\n try {\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 }, overrideAgentId);\n\n spinner.stop('Response received');\n\n // Handle Response Actions\n if (lastResponse && lastResponse.actions) {\n // Reset next prompt, we will build it based on actions results\n let executionResults = \"\";\n let waitingForUser = false;\n\n for (const action of lastResponse.actions) {\n\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(`πŸ“‚ List files in: ${colors.bold(action.path || '.')}`);\n const result = handleListFiles(action.path || '.');\n executionResults += `[Action list_files(${action.path}) Result]:\\n${result}\\n\\n`;\n tui.log.info(colors.dim(`Files listed.`));\n }\n\n else if (action.type === 'read_file') {\n tui.log.info(`πŸ“– Read file: ${colors.bold(action.path || '')}`);\n const result = handleReadFile(action.path || '');\n executionResults += `[Action read_file(${action.path}) Result]:\\n${result}\\n\\n`;\n tui.log.info(colors.dim(`File read.`));\n }\n\n else if (action.type === 'search_file') {\n tui.log.info(`πŸ” Search file: ${colors.bold(action.path || '')}`);\n const result = handleSearchFile(action.path || '');\n executionResults += `[Action search_file(${action.path}) Result]:\\n${result}\\n\\n`;\n tui.log.info(colors.dim(`Files found.`));\n }\n\n else if (['create_file', 'modify_file', 'delete_file'].includes(action.type)) {\n tui.log.warning(`\\nπŸ€– Agent wants to ${action.type}: ${colors.bold(action.path || 'unknown')}`);\n\n // Preview\n if (action.content) {\n console.log(colors.dim('--- Content Preview ---'));\n console.log(action.content.substring(0, 300) + '...');\n console.log(colors.dim('-----------------------'));\n }\n\n const confirm = await tui.confirm({\n message: `Approve ${action.type}?`,\n active: 'Yes',\n inactive: 'No'\n });\n\n if (confirm) {\n if (action.path) {\n try {\n if (action.type === 'create_file') {\n fs.writeFileSync(action.path, action.content || '');\n tui.log.success(`βœ… Created: ${action.path}`);\n executionResults += `[Action create_file(${action.path})]: Success\\n\\n`;\n } else if (action.type === 'modify_file') {\n if (action.target_content) {\n const success = startSmartReplace(action.path, action.content || '', action.target_content, tui);\n executionResults += `[Action modify_file(${action.path})]: ${success ? 'Success' : 'Failed'}\\n\\n`;\n } else {\n fs.writeFileSync(action.path, action.content || '');\n tui.log.success(`βœ… Overwritten: ${action.path}`);\n executionResults += `[Action modify_file(${action.path})]: Success (Overwrite)\\n\\n`;\n }\n } else if (action.type === 'delete_file') {\n fs.unlinkSync(action.path);\n tui.log.success(`βœ… Deleted: ${action.path}`);\n executionResults += `[Action delete_file(${action.path})]: Success\\n\\n`;\n }\n } catch (e: any) {\n tui.log.error(`❌ Failed: ${e.message}`);\n executionResults += `[Action ${action.type}(${action.path})]: Error: ${e.message}\\n\\n`;\n }\n }\n } else {\n tui.log.error('❌ Action denied.');\n executionResults += `[Action ${action.type}]: User Denied\\n\\n`;\n }\n }\n }\n\n // Prepare next prompt\n if (executionResults) {\n // If actions produced output (like file list), send it back to agent automatically\n // But if the agent ALSO talked to user, we should give priority to user input??\n // Strategy: If agent asked something (talk_with_user), we MUST ask user.\n // The tool outputs are appended.\n\n if (waitingForUser) {\n const userReply = await tui.text({\n message: 'Your answer',\n placeholder: 'Type your answer...'\n });\n if (tui.isCancel(userReply)) {\n keepGoing = false;\n return;\n }\n nextPrompt = `${executionResults}\\n\\nUser Reply: ${userReply}`;\n tui.log.info(colors.dim('Auto-replying with tool results...'));\n } else {\n // Agent just did tools, let's auto-reply with results so it can continue\n nextPrompt = executionResults;\n FileLogger.log('SYSTEM', 'Auto-replying with Tool Results', { length: executionResults.length });\n tui.log.info(colors.dim('Auto-replying with tool results...'));\n }\n\n } else if (waitingForUser) {\n // Only talk, no tools\n const userReply = await tui.text({\n message: 'Your answer',\n placeholder: 'Type your answer...'\n });\n if (tui.isCancel(userReply)) {\n keepGoing = false;\n return;\n }\n nextPrompt = userReply as string;\n } else {\n // No actions? Weird.\n tui.log.warning('No actions taken.');\n keepGoing = false;\n }\n\n } else {\n tui.log.warning('No actions received from agent.');\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// --- Helper Functions in agent-tools.ts ---\n\n// --- API Wrapper ---\n\nasync function callSpecAgentApi(prompt: string, onChunk: (chunk: string) => void, agentId?: string): 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 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', {\n agentId: effectiveAgentId,\n conversationId,\n prompt: prompt.substring(0, 500) // Log summary of prompt\n });\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 // Prefer conversation_id from metadata (server response), fallback to sent ID\n const returnedId = metadata?.conversation_id;\n\n FileLogger.log('AGENT', 'Response Complete', {\n conversationId,\n returnedId,\n messageLength: msg?.length\n });\n\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\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';\n\n/**\n * Shared tools for Agent interaction (File System, etc.)\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): 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 return fs.readFileSync(fullPath, 'utf-8');\n } catch (e: any) {\n return `Error reading file: ${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 line endings?\n if (!currentFileContent.includes(targetContent)) {\n tui.log.error(`❌ Target content not found in ${filePath}. 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 updatedContent = currentFileContent.replace(targetContent, newContent);\n fs.writeFileSync(filePath, updatedContent);\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","\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 } from '../core/agents/developer-agent.js';\n\nexport const devCommand = new Command('dev')\n .description('Starts the Shark Developer Agent (Shark Dev)')\n .option('-t, --task <type>', 'Initial task description')\n .option('-c, --context <path>', 'Path to custom context file')\n .action(async (options) => {\n await interactiveDeveloperAgent(options);\n });\n","\nimport { STACKSPOT_AGENT_API_BASE } 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 handleRunCommand\n} from './agent-tools.js';\n\nconst AGENT_TYPE = 'developer_agent';\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\nexport async function interactiveDeveloperAgent(options: { task?: string, context?: string } = {}): Promise<void> {\n FileLogger.init();\n tui.intro('🦈 Shark Dev Agent');\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;\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 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 } else {\n tui.log.warning(`⚠️ No context file found. Agent will run without pre-loaded context.`);\n }\n\n // 2. Prepare Initial Prompt\n let nextPrompt = options.task || \"I'm ready to help. What's the task?\";\n if (contextContent) {\n nextPrompt += `\\n\\n--- PROJECT CONTEXT ---\\n${contextContent}\\n-----------------------`;\n }\n\n // 3. Main Loop\n let keepGoing = true;\n const spinner = tui.spinner();\n\n while (keepGoing) {\n try {\n spinner.start('Waiting for Agent...');\n\n // Call API\n let lastResponse: AgentResponse | null = null;\n await callDevAgentApi(nextPrompt, (chunk) => {\n // Optional: Stream text to TUI if needed\n if (!lastResponse) {\n // Maybe show thinking dots?\n }\n }).then(resp => {\n lastResponse = resp;\n });\n\n spinner.stop('Response received');\n\n if (lastResponse && (lastResponse as AgentResponse).actions) {\n const response = lastResponse as AgentResponse;\n let executionResults = \"\";\n let waitingForUser = false;\n\n for (const action of response.actions) {\n\n if (action.type === 'talk_with_user') {\n tui.log.info(colors.primary('πŸ€– Shark Dev:'));\n console.log(action.content);\n waitingForUser = true;\n }\n\n else if (action.type === 'list_files') {\n tui.log.info(`πŸ“‚ Scanning dir: ${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 (action.type === 'run_command') {\n const cmd = action.command || '';\n tui.log.info(`πŸ’» Executing: ${colors.dim(cmd)}`);\n // Execute Command\n // Warning: Prompt user for non-safe commands? \n // For now, let's assume Shark Dev is trusted or ask for everything.\n // Let's ask for confirmation for consistency.\n const confirm = await tui.confirm({\n message: `Execute command: ${cmd}?`,\n active: 'Yes',\n inactive: 'No'\n });\n\n if (confirm) {\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\n else if (['create_file', 'modify_file'].includes(action.type)) {\n const isCreate = action.type === 'create_file';\n const filePath = action.path || '';\n tui.log.warning(`\\nπŸ€– Agent wants to ${isCreate ? 'CREATE' : 'MODIFY'}: ${colors.bold(filePath)}`);\n\n // Preview content (maybe diff?)\n // For brevity, just log start\n if (action.content) {\n console.log(colors.dim('--- Content ---\\n') + action.content.substring(0, 200) + '...\\n' + colors.dim('---------------'));\n }\n\n const confirm = await tui.confirm({\n message: `Approve changes to ${filePath}?`,\n active: 'Yes',\n inactive: 'No'\n });\n\n if (confirm) {\n if (filePath) {\n const targetPath = path.resolve(projectRoot, filePath);\n const dir = path.dirname(targetPath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n\n if (isCreate) {\n fs.writeFileSync(targetPath, action.content || '');\n tui.log.success(`βœ… Created: ${filePath}`);\n executionResults += `[Action create_file(${filePath})]: Success\\n\\n`;\n } else {\n // Modify\n if (action.target_content) {\n const success = startSmartReplace(filePath, action.content || '', action.target_content, tui);\n executionResults += `[Action modify_file(${filePath})]: ${success ? 'Success' : 'Failed'}\\n\\n`;\n } else {\n // Fallback overwrite if no target_content provided (should be rare given schema)\n // But for Dev Agent, schema requires new_content (mapped to content) and target_content.\n // If target_content missing, we might fail or overwrite.\n // Let's safe fail.\n tui.log.error('❌ Missing target_content for modification.');\n executionResults += `[Action modify_file]: Failed. Missing target_content.\\n\\n`;\n }\n }\n }\n } else {\n tui.log.error('❌ Denied.');\n executionResults += `[Action ${action.type}]: User Denied.\\n\\n`;\n }\n }\n }\n\n // Prepare 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}\\n\\nUser Reply: ${userReply}`;\n } else {\n // Auto-continue\n nextPrompt = executionResults;\n tui.log.info(colors.dim('Sending tool results to agent...'));\n }\n } else if (waitingForUser) {\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 // Fallback: If no actions but we have a message/summary, assume it's a talk\n if (response.message) {\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)) {\n keepGoing = false;\n } else {\n nextPrompt = userReply as string;\n }\n } else {\n tui.log.warning('Agent took no actions.');\n keepGoing = false;\n }\n }\n\n } else {\n tui.log.warning('Invalid response from agent.');\n keepGoing = false;\n }\n\n } catch (e: any) {\n spinner.stop('Error');\n tui.log.error(e.message);\n FileLogger.log('DEV_AGENT', 'Main Loop Error', e);\n keepGoing = false;\n }\n }\n\n tui.outro('πŸ‘‹ Shark Dev Session Ended');\n}\n\nasync function callDevAgentApi(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. Run shark login.');\n\n const conversationId = await conversationManager.getConversationId(AGENT_TYPE);\n\n const payload = {\n user_prompt: prompt,\n streaming: true,\n use_conversation: true,\n conversation_id: conversationId,\n stackspot_knowledge: false // Dev Agent focuses on project context\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(AGENT_TYPE, parsed.conversation_id);\n }\n return parsed;\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 fs.writeFileSync(fullPath, action.content);\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","fs","path","path","fs","tui","AGENT_TYPE","getAgentId","fs","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","Command","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","Command","Command","fs","path","AGENT_TYPE","getAgentId","path","fs","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shark-ai",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Shark AI: AI-Native Collaborative Development Tool powered by StackSpot AI and BMAD Method",
5
5
  "main": "dist/index.js",
6
6
  "bin": {