@morphllm/morphsdk 0.2.22 → 0.2.24

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.
Files changed (72) hide show
  1. package/dist/{chunk-74ZHKB54.js → chunk-2DXRTGRH.js} +1 -1
  2. package/dist/{chunk-74ZHKB54.js.map → chunk-2DXRTGRH.js.map} +1 -1
  3. package/dist/{chunk-BILUTNBC.js → chunk-4A7UBGLS.js} +2 -2
  4. package/dist/{chunk-VJK4PH5V.js → chunk-AG3ICTC5.js} +5 -2
  5. package/dist/chunk-AG3ICTC5.js.map +1 -0
  6. package/dist/{chunk-5VQEQSJQ.js → chunk-DF2ZOO7R.js} +52 -3
  7. package/dist/chunk-DF2ZOO7R.js.map +1 -0
  8. package/dist/{chunk-FSVBNZMU.js → chunk-HNYSKGCP.js} +5 -5
  9. package/dist/chunk-HNYSKGCP.js.map +1 -0
  10. package/dist/{chunk-XQLKK2ZH.js → chunk-LFYQ6GKI.js} +5 -5
  11. package/dist/chunk-LFYQ6GKI.js.map +1 -0
  12. package/dist/{chunk-EAA7D24N.js → chunk-PRIYMEI6.js} +4 -4
  13. package/dist/{chunk-WXBUVKYL.js → chunk-WHZQDTM6.js} +2 -2
  14. package/dist/{chunk-YVGRWE7D.js → chunk-Y2IY7NYY.js} +2 -2
  15. package/dist/{chunk-JZGU5UC6.js → chunk-ZKIVLLZY.js} +5 -5
  16. package/dist/chunk-ZKIVLLZY.js.map +1 -0
  17. package/dist/{chunk-NSQGPBMU.js → chunk-ZPVYGJCS.js} +3 -3
  18. package/dist/client.cjs +55 -3
  19. package/dist/client.cjs.map +1 -1
  20. package/dist/client.js +4 -4
  21. package/dist/git/client.cjs +51 -2
  22. package/dist/git/client.cjs.map +1 -1
  23. package/dist/git/client.js +1 -1
  24. package/dist/git/index.cjs +51 -2
  25. package/dist/git/index.cjs.map +1 -1
  26. package/dist/git/index.js +2 -2
  27. package/dist/git/types.cjs.map +1 -1
  28. package/dist/index.cjs +55 -3
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.js +4 -4
  31. package/dist/tools/codebase_search/anthropic.cjs +4 -1
  32. package/dist/tools/codebase_search/anthropic.cjs.map +1 -1
  33. package/dist/tools/codebase_search/anthropic.js +2 -2
  34. package/dist/tools/codebase_search/core.cjs +4 -1
  35. package/dist/tools/codebase_search/core.cjs.map +1 -1
  36. package/dist/tools/codebase_search/core.js +1 -1
  37. package/dist/tools/codebase_search/index.cjs +4 -1
  38. package/dist/tools/codebase_search/index.cjs.map +1 -1
  39. package/dist/tools/codebase_search/index.js +4 -4
  40. package/dist/tools/codebase_search/openai.cjs +4 -1
  41. package/dist/tools/codebase_search/openai.cjs.map +1 -1
  42. package/dist/tools/codebase_search/openai.js +2 -2
  43. package/dist/tools/codebase_search/types.cjs.map +1 -1
  44. package/dist/tools/codebase_search/vercel.cjs +4 -1
  45. package/dist/tools/codebase_search/vercel.cjs.map +1 -1
  46. package/dist/tools/codebase_search/vercel.js +2 -2
  47. package/dist/tools/fastapply/index.js +3 -3
  48. package/dist/tools/index.js +3 -3
  49. package/dist/tools/warp_grep/agent/runner.js +2 -2
  50. package/dist/tools/warp_grep/anthropic.cjs +1 -1
  51. package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
  52. package/dist/tools/warp_grep/anthropic.js +4 -4
  53. package/dist/tools/warp_grep/index.cjs +3 -3
  54. package/dist/tools/warp_grep/index.cjs.map +1 -1
  55. package/dist/tools/warp_grep/index.js +8 -8
  56. package/dist/tools/warp_grep/openai.cjs +1 -1
  57. package/dist/tools/warp_grep/openai.cjs.map +1 -1
  58. package/dist/tools/warp_grep/openai.js +4 -4
  59. package/dist/tools/warp_grep/vercel.cjs +1 -1
  60. package/dist/tools/warp_grep/vercel.cjs.map +1 -1
  61. package/dist/tools/warp_grep/vercel.js +4 -4
  62. package/package.json +1 -1
  63. package/dist/chunk-5VQEQSJQ.js.map +0 -1
  64. package/dist/chunk-FSVBNZMU.js.map +0 -1
  65. package/dist/chunk-JZGU5UC6.js.map +0 -1
  66. package/dist/chunk-VJK4PH5V.js.map +0 -1
  67. package/dist/chunk-XQLKK2ZH.js.map +0 -1
  68. /package/dist/{chunk-BILUTNBC.js.map → chunk-4A7UBGLS.js.map} +0 -0
  69. /package/dist/{chunk-EAA7D24N.js.map → chunk-PRIYMEI6.js.map} +0 -0
  70. /package/dist/{chunk-WXBUVKYL.js.map → chunk-WHZQDTM6.js.map} +0 -0
  71. /package/dist/{chunk-YVGRWE7D.js.map → chunk-Y2IY7NYY.js.map} +0 -0
  72. /package/dist/{chunk-NSQGPBMU.js.map → chunk-ZPVYGJCS.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../tools/codebase_search/vercel.ts","../../../tools/utils/resilience.ts","../../../tools/codebase_search/core.ts","../../../tools/codebase_search/prompts.ts"],"sourcesContent":["/**\n * Vercel AI SDK adapter for codebase_search tool\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { executeCodebaseSearch } from './core.js';\nimport { CODEBASE_SEARCH_DESCRIPTION } from './prompts.js';\nimport type { CodebaseSearchConfig } from './types.js';\n\n/**\n * Create Vercel AI SDK codebase_search tool\n * \n * @param config - Configuration with repoId\n * @returns Vercel AI SDK tool definition (execution built-in)\n * \n * @example\n * ```ts\n * import { generateText } from 'ai';\n * import { anthropic } from '@ai-sdk/anthropic';\n * import { createCodebaseSearchTool } from 'morphsdk/tools/codebase-search/vercel';\n * \n * const tool = createCodebaseSearchTool({ repoId: 'my-project' });\n * \n * const result = await generateText({\n * model: anthropic('claude-3-5-sonnet-20241022'),\n * tools: { codebaseSearch: tool },\n * prompt: \"Find authentication code\",\n * maxSteps: 5\n * });\n * \n * // Vercel AI SDK automatically executes and handles results\n * console.log(result.text);\n * ```\n */\nexport function createCodebaseSearchTool(config: CodebaseSearchConfig) {\n const schema = z.object({\n query: z.string().describe('A complete question about what you want to understand. Ask as if talking to a colleague: \"How does X work?\", \"What happens when Y?\", \"Where is Z handled?\"'),\n target_directories: z.array(z.string()).describe('Prefix directory paths to limit search scope (single directory only, no glob patterns). Use [] to search entire repo.'),\n explanation: z.string().describe('One sentence explanation as to why this tool is being used, and how it contributes to the goal.'),\n limit: z.number().optional().describe('Max results to return (default: 10)'),\n });\n\n return tool({\n description: CODEBASE_SEARCH_DESCRIPTION,\n inputSchema: schema,\n execute: async (params) => {\n const { query, target_directories, explanation, limit } = params;\n const result = await executeCodebaseSearch(\n { query, target_directories, explanation, limit },\n config\n );\n\n if (!result.success) {\n return {\n error: result.error,\n results: [],\n };\n }\n\n // Format results for Vercel AI SDK\n return {\n found: result.results.length,\n searchTime: `${result.stats.searchTimeMs}ms`,\n results: result.results.map(r => ({\n file: r.filepath,\n symbol: r.symbolPath,\n lines: `${r.startLine}-${r.endLine}`,\n language: r.language,\n relevance: `${(r.rerankScore * 100).toFixed(1)}%`,\n code: r.content,\n })),\n };\n },\n });\n}\n\n/**\n * Get system prompt for Vercel AI SDK\n */\nexport function getSystemPrompt(): string {\n return CODEBASE_SEARCH_DESCRIPTION;\n}\n\n/**\n * Default export\n */\nexport default { createCodebaseSearchTool, getSystemPrompt };\n\n","/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nexport interface RetryConfig {\n maxRetries?: number; // Default: 3\n initialDelay?: number; // Default: 1000ms\n maxDelay?: number; // Default: 30000ms\n backoffMultiplier?: number; // Default: 2\n retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * 'https://api.example.com/data',\n * { method: 'POST', body: JSON.stringify(data) },\n * { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryConfig: RetryConfig = {}\n): Promise<Response> {\n const {\n maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n onRetry,\n } = retryConfig;\n\n let lastError: Error | null = null;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n \n // Retry on 429 (rate limit) or 503 (service unavailable)\n if (response.status === 429 || response.status === 503) {\n if (attempt < maxRetries) {\n // Check for Retry-After header\n const retryAfter = response.headers.get('Retry-After');\n const waitTime = retryAfter \n ? parseInt(retryAfter) * 1000 \n : Math.min(delay, maxDelay);\n \n const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n if (onRetry) {\n onRetry(attempt + 1, error);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n continue;\n }\n }\n\n return response;\n } catch (error) {\n lastError = error as Error;\n \n // Check if error is retryable\n const isRetryable = retryableErrors.some(errType => \n lastError?.message?.includes(errType)\n );\n\n if (!isRetryable || attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff\n const waitTime = Math.min(delay, maxDelay);\n if (onRetry) {\n onRetry(attempt + 1, lastError);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n }\n }\n\n throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage?: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout | number;\n \n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'MorphError';\n }\n}\n\n\n","/**\n * Core implementation for codebase search\n * Calls Morph rerank service for two-stage semantic search\n */\n\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport type { CodebaseSearchConfig, CodebaseSearchInput, CodebaseSearchResult } from './types.js';\n\n/**\n * CodebaseSearch client for programmatic semantic search\n */\nexport class CodebaseSearchClient {\n private config: { \n apiKey?: string; \n searchUrl?: string; \n debug?: boolean; \n timeout?: number; \n retryConfig?: any;\n };\n\n constructor(config: { apiKey?: string; debug?: boolean; timeout?: number; retryConfig?: any } = {}) {\n this.config = {\n apiKey: config.apiKey,\n searchUrl: process.env.MORPH_SEARCH_URL || 'http://embedrerank.morphllm.com:8081',\n debug: config.debug,\n timeout: config.timeout || 30000,\n retryConfig: config.retryConfig,\n };\n }\n\n /**\n * Execute a semantic code search\n * \n * @param input - Search parameters including query, repoId, and target directories\n * @param overrides - Optional config overrides for this operation\n * @returns Search results with ranked code matches\n */\n async search(\n input: { query: string; repoId: string; target_directories?: string[]; explanation?: string; limit?: number },\n overrides?: any\n ): Promise<CodebaseSearchResult> {\n return executeCodebaseSearch(\n {\n query: input.query,\n target_directories: input.target_directories,\n explanation: input.explanation,\n limit: input.limit,\n },\n { ...this.config, repoId: input.repoId, ...overrides }\n );\n }\n}\n\n/**\n * Execute semantic code search\n */\nexport async function executeCodebaseSearch(\n input: CodebaseSearchInput,\n config: CodebaseSearchConfig\n): Promise<CodebaseSearchResult> {\n const apiKey = config.apiKey || process.env.MORPH_API_KEY;\n if (!apiKey) {\n throw new Error('MORPH_API_KEY not found. Set environment variable or pass in config');\n }\n\n const searchUrl = config.searchUrl || process.env.MORPH_SEARCH_URL || 'http://embedrerank.morphllm.com:8081';\n const timeout = config.timeout || 30000;\n const debug = config.debug || false;\n\n if (debug) {\n console.log(`[CodebaseSearch] Query: \"${input.query.slice(0, 60)}...\" repo=${config.repoId}`);\n console.log(`[CodebaseSearch] URL: ${searchUrl}/v1/codebase_search`);\n }\n\n const startTime = Date.now();\n\n try {\n const fetchPromise = fetchWithRetry(\n `${searchUrl}/v1/codebase_search`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n query: input.query,\n repoId: config.repoId,\n targetDirectories: input.target_directories || [],\n limit: input.limit || 10,\n candidateLimit: 50,\n }),\n },\n config.retryConfig\n );\n\n const response = await withTimeout(fetchPromise, timeout, `Codebase search timed out after ${timeout}ms`);\n\n if (!response.ok) {\n const errorText = await response.text();\n if (debug) console.error(`[CodebaseSearch] Error: ${response.status} - ${errorText}`);\n return {\n success: false,\n results: [],\n stats: { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 },\n error: `Search failed (${response.status}): ${errorText}`,\n };\n }\n\n const data = await response.json();\n const elapsed = Date.now() - startTime;\n\n if (debug) {\n console.log(`[CodebaseSearch] ✅ ${data.results?.length || 0} results in ${elapsed}ms`);\n }\n\n return {\n success: true,\n results: data.results || [],\n stats: data.stats || { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: elapsed },\n };\n\n } catch (error) {\n if (debug) console.error(`[CodebaseSearch] Exception: ${error instanceof Error ? error.message : error}`);\n return {\n success: false,\n results: [],\n stats: { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 },\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n}\n\n","/**\n * Tool descriptions and system prompts for codebase search\n */\n\nexport const CODEBASE_SEARCH_DESCRIPTION = `Semantic search that finds code by meaning, not exact text.\n\nUse this to explore unfamiliar codebases or ask \"how/where/what\" questions:\n- \"How does X work?\" - Find implementation details\n- \"Where is Y handled?\" - Locate specific functionality\n- \"What happens when Z?\" - Understand flow\n\nThe tool uses two-stage retrieval (embedding similarity + reranking) to find the most semantically relevant code chunks.\n\nReturns code chunks with file paths, line ranges, and full content ranked by relevance.`;\n\nexport const CODEBASE_SEARCH_SYSTEM_PROMPT = `You have access to the codebase_search tool that performs semantic code search.\n\nWhen searching:\n- Use natural language queries describing what you're looking for\n- Be specific about functionality, not variable names\n- Use target_directories to narrow search if you know the area\n- Results are ranked by relevance (rerank score is most important)\n\nThe tool returns:\n- File paths with symbol names (e.g. \"src/auth.ts::AuthService@L1-L17\")\n- Line ranges for precise navigation\n- Full code content for each match\n- Dual relevance scores: embedding similarity + rerank score\n\nUse results to understand code or answer questions. The content is provided in full - avoid re-reading unless you need more context.`;\n\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../tools/codebase_search/vercel.ts","../../../tools/utils/resilience.ts","../../../tools/codebase_search/core.ts","../../../tools/codebase_search/prompts.ts"],"sourcesContent":["/**\n * Vercel AI SDK adapter for codebase_search tool\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { executeCodebaseSearch } from './core.js';\nimport { CODEBASE_SEARCH_DESCRIPTION } from './prompts.js';\nimport type { CodebaseSearchConfig } from './types.js';\n\n/**\n * Create Vercel AI SDK codebase_search tool\n * \n * @param config - Configuration with repoId\n * @returns Vercel AI SDK tool definition (execution built-in)\n * \n * @example\n * ```ts\n * import { generateText } from 'ai';\n * import { anthropic } from '@ai-sdk/anthropic';\n * import { createCodebaseSearchTool } from 'morphsdk/tools/codebase-search/vercel';\n * \n * const tool = createCodebaseSearchTool({ repoId: 'my-project' });\n * \n * const result = await generateText({\n * model: anthropic('claude-3-5-sonnet-20241022'),\n * tools: { codebaseSearch: tool },\n * prompt: \"Find authentication code\",\n * maxSteps: 5\n * });\n * \n * // Vercel AI SDK automatically executes and handles results\n * console.log(result.text);\n * ```\n */\nexport function createCodebaseSearchTool(config: CodebaseSearchConfig) {\n const schema = z.object({\n query: z.string().describe('A complete question about what you want to understand. Ask as if talking to a colleague: \"How does X work?\", \"What happens when Y?\", \"Where is Z handled?\"'),\n target_directories: z.array(z.string()).describe('Prefix directory paths to limit search scope (single directory only, no glob patterns). Use [] to search entire repo.'),\n explanation: z.string().describe('One sentence explanation as to why this tool is being used, and how it contributes to the goal.'),\n limit: z.number().optional().describe('Max results to return (default: 10)'),\n });\n\n return tool({\n description: CODEBASE_SEARCH_DESCRIPTION,\n inputSchema: schema,\n execute: async (params) => {\n const { query, target_directories, explanation, limit } = params;\n const result = await executeCodebaseSearch(\n { query, target_directories, explanation, limit },\n config\n );\n\n if (!result.success) {\n return {\n error: result.error,\n results: [],\n };\n }\n\n // Format results for Vercel AI SDK\n return {\n found: result.results.length,\n searchTime: `${result.stats.searchTimeMs}ms`,\n results: result.results.map(r => ({\n file: r.filepath,\n symbol: r.symbolPath,\n lines: `${r.startLine}-${r.endLine}`,\n language: r.language,\n relevance: `${(r.rerankScore * 100).toFixed(1)}%`,\n code: r.content,\n })),\n };\n },\n });\n}\n\n/**\n * Get system prompt for Vercel AI SDK\n */\nexport function getSystemPrompt(): string {\n return CODEBASE_SEARCH_DESCRIPTION;\n}\n\n/**\n * Default export\n */\nexport default { createCodebaseSearchTool, getSystemPrompt };\n\n","/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nexport interface RetryConfig {\n maxRetries?: number; // Default: 3\n initialDelay?: number; // Default: 1000ms\n maxDelay?: number; // Default: 30000ms\n backoffMultiplier?: number; // Default: 2\n retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * 'https://api.example.com/data',\n * { method: 'POST', body: JSON.stringify(data) },\n * { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryConfig: RetryConfig = {}\n): Promise<Response> {\n const {\n maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n onRetry,\n } = retryConfig;\n\n let lastError: Error | null = null;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n \n // Retry on 429 (rate limit) or 503 (service unavailable)\n if (response.status === 429 || response.status === 503) {\n if (attempt < maxRetries) {\n // Check for Retry-After header\n const retryAfter = response.headers.get('Retry-After');\n const waitTime = retryAfter \n ? parseInt(retryAfter) * 1000 \n : Math.min(delay, maxDelay);\n \n const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n if (onRetry) {\n onRetry(attempt + 1, error);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n continue;\n }\n }\n\n return response;\n } catch (error) {\n lastError = error as Error;\n \n // Check if error is retryable\n const isRetryable = retryableErrors.some(errType => \n lastError?.message?.includes(errType)\n );\n\n if (!isRetryable || attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff\n const waitTime = Math.min(delay, maxDelay);\n if (onRetry) {\n onRetry(attempt + 1, lastError);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n }\n }\n\n throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage?: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout | number;\n \n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'MorphError';\n }\n}\n\n\n","/**\n * Core implementation for codebase search\n * Calls Morph rerank service for two-stage semantic search\n */\n\nimport { fetchWithRetry, withTimeout } from '../utils/resilience.js';\nimport type { CodebaseSearchConfig, CodebaseSearchInput, CodebaseSearchResult } from './types.js';\n\n/**\n * CodebaseSearch client for programmatic semantic search\n */\nexport class CodebaseSearchClient {\n private config: { \n apiKey?: string; \n searchUrl?: string; \n debug?: boolean; \n timeout?: number; \n retryConfig?: any;\n };\n\n constructor(config: { apiKey?: string; debug?: boolean; timeout?: number; retryConfig?: any } = {}) {\n this.config = {\n apiKey: config.apiKey,\n searchUrl: process.env.MORPH_SEARCH_URL || 'http://embedrerank.morphllm.com:8081',\n debug: config.debug,\n timeout: config.timeout || 30000,\n retryConfig: config.retryConfig,\n };\n }\n\n /**\n * Execute a semantic code search\n * \n * @param input - Search parameters including query, repoId, and target directories\n * @param overrides - Optional config overrides for this operation\n * @returns Search results with ranked code matches\n */\n async search(\n input: { query: string; repoId: string; target_directories?: string[]; explanation?: string; limit?: number },\n overrides?: any\n ): Promise<CodebaseSearchResult> {\n return executeCodebaseSearch(\n {\n query: input.query,\n target_directories: input.target_directories,\n explanation: input.explanation,\n limit: input.limit,\n },\n { ...this.config, repoId: input.repoId, ...overrides }\n );\n }\n}\n\n/**\n * Execute semantic code search\n */\nexport async function executeCodebaseSearch(\n input: CodebaseSearchInput,\n config: CodebaseSearchConfig\n): Promise<CodebaseSearchResult> {\n const apiKey = config.apiKey || process.env.MORPH_API_KEY;\n if (!apiKey) {\n throw new Error('MORPH_API_KEY not found. Set environment variable or pass in config');\n }\n\n const searchUrl = config.searchUrl || process.env.MORPH_SEARCH_URL || 'http://embedrerank.morphllm.com:8081';\n const timeout = config.timeout || 30000;\n const debug = config.debug || false;\n\n if (debug) {\n const ref = config.commitHash ? `commit=${config.commitHash.slice(0, 8)}` : config.branch ? `branch=${config.branch}` : 'latest main';\n console.log(`[CodebaseSearch] Query: \"${input.query.slice(0, 60)}...\" repo=${config.repoId} (${ref})`);\n console.log(`[CodebaseSearch] URL: ${searchUrl}/v1/codebase_search`);\n }\n\n const startTime = Date.now();\n\n try {\n const fetchPromise = fetchWithRetry(\n `${searchUrl}/v1/codebase_search`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n query: input.query,\n repoId: config.repoId,\n branch: config.branch,\n commitHash: config.commitHash,\n targetDirectories: input.target_directories || [],\n limit: input.limit || 10,\n candidateLimit: 50,\n }),\n },\n config.retryConfig\n );\n\n const response = await withTimeout(fetchPromise, timeout, `Codebase search timed out after ${timeout}ms`);\n\n if (!response.ok) {\n const errorText = await response.text();\n if (debug) console.error(`[CodebaseSearch] Error: ${response.status} - ${errorText}`);\n return {\n success: false,\n results: [],\n stats: { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 },\n error: `Search failed (${response.status}): ${errorText}`,\n };\n }\n\n const data = await response.json();\n const elapsed = Date.now() - startTime;\n\n if (debug) {\n console.log(`[CodebaseSearch] ✅ ${data.results?.length || 0} results in ${elapsed}ms`);\n }\n\n return {\n success: true,\n results: data.results || [],\n stats: data.stats || { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: elapsed },\n };\n\n } catch (error) {\n if (debug) console.error(`[CodebaseSearch] Exception: ${error instanceof Error ? error.message : error}`);\n return {\n success: false,\n results: [],\n stats: { totalResults: 0, candidatesRetrieved: 0, searchTimeMs: 0 },\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n}\n\n","/**\n * Tool descriptions and system prompts for codebase search\n */\n\nexport const CODEBASE_SEARCH_DESCRIPTION = `Semantic search that finds code by meaning, not exact text.\n\nUse this to explore unfamiliar codebases or ask \"how/where/what\" questions:\n- \"How does X work?\" - Find implementation details\n- \"Where is Y handled?\" - Locate specific functionality\n- \"What happens when Z?\" - Understand flow\n\nThe tool uses two-stage retrieval (embedding similarity + reranking) to find the most semantically relevant code chunks.\n\nReturns code chunks with file paths, line ranges, and full content ranked by relevance.`;\n\nexport const CODEBASE_SEARCH_SYSTEM_PROMPT = `You have access to the codebase_search tool that performs semantic code search.\n\nWhen searching:\n- Use natural language queries describing what you're looking for\n- Be specific about functionality, not variable names\n- Use target_directories to narrow search if you know the area\n- Results are ranked by relevance (rerank score is most important)\n\nThe tool returns:\n- File paths with symbol names (e.g. \"src/auth.ts::AuthService@L1-L17\")\n- Line ranges for precise navigation\n- Full code content for each match\n- Dual relevance scores: embedding similarity + rerank score\n\nUse results to understand code or answer questions. The content is provided in full - avoid re-reading unless you need more context.`;\n\n"],"mappings":"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","names":[]}
@@ -2,9 +2,9 @@ import {
2
2
  createCodebaseSearchTool,
3
3
  getSystemPrompt,
4
4
  vercel_default
5
- } from "../../chunk-YVGRWE7D.js";
5
+ } from "../../chunk-Y2IY7NYY.js";
6
6
  import "../../chunk-YQMPVJ2L.js";
7
- import "../../chunk-VJK4PH5V.js";
7
+ import "../../chunk-AG3ICTC5.js";
8
8
  import "../../chunk-4VWJFZVS.js";
9
9
  import "../../chunk-PZ5AY32C.js";
10
10
  export {
@@ -1,13 +1,13 @@
1
1
  import "../../chunk-X2K57BH6.js";
2
+ import {
3
+ vercel_exports
4
+ } from "../../chunk-Y5RCNDLV.js";
2
5
  import {
3
6
  anthropic_exports
4
7
  } from "../../chunk-S3HTYGYF.js";
5
8
  import {
6
9
  openai_exports
7
10
  } from "../../chunk-OZMHDB6O.js";
8
- import {
9
- vercel_exports
10
- } from "../../chunk-Y5RCNDLV.js";
11
11
  import {
12
12
  EDIT_FILE_SYSTEM_PROMPT,
13
13
  EDIT_FILE_TOOL_DESCRIPTION
@@ -1,13 +1,13 @@
1
1
  import "../chunk-X2K57BH6.js";
2
+ import {
3
+ vercel_exports
4
+ } from "../chunk-Y5RCNDLV.js";
2
5
  import {
3
6
  anthropic_exports
4
7
  } from "../chunk-S3HTYGYF.js";
5
8
  import {
6
9
  openai_exports
7
10
  } from "../chunk-OZMHDB6O.js";
8
- import {
9
- vercel_exports
10
- } from "../chunk-Y5RCNDLV.js";
11
11
  import {
12
12
  EDIT_FILE_SYSTEM_PROMPT,
13
13
  EDIT_FILE_TOOL_DESCRIPTION
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  runWarpGrep
3
- } from "../../../chunk-EAA7D24N.js";
4
- import "../../../chunk-Z2FBMSNE.js";
3
+ } from "../../../chunk-PRIYMEI6.js";
5
4
  import "../../../chunk-HKZB23U7.js";
6
5
  import "../../../chunk-73RQWOQC.js";
7
6
  import "../../../chunk-EK7OQPWD.js";
7
+ import "../../../chunk-Z2FBMSNE.js";
8
8
  import "../../../chunk-AFEPUNAO.js";
9
9
  import "../../../chunk-TICMYDII.js";
10
10
  import "../../../chunk-NDZO5IPV.js";
@@ -937,7 +937,7 @@ var INPUT_SCHEMA = import_zod.z.object({
937
937
  function createMorphWarpGrepTool(config) {
938
938
  const tool = {
939
939
  name: "morph-warp-grep",
940
- description: "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
940
+ description: config.description ?? "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
941
941
  input_schema: {
942
942
  type: "object",
943
943
  properties: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../tools/warp_grep/anthropic.ts","../../../tools/warp_grep/agent/config.ts","../../../tools/warp_grep/agent/prompt.ts","../../../tools/warp_grep/agent/parser.ts","../../../tools/warp_grep/tools/read.ts","../../../tools/warp_grep/tools/analyse.ts","../../../tools/utils/resilience.ts","../../../tools/warp_grep/agent/formatter.ts","../../../tools/warp_grep/agent/grep_helpers.ts","../../../tools/warp_grep/tools/finish.ts","../../../tools/warp_grep/agent/runner.ts","../../../tools/warp_grep/providers/local.ts","../../../tools/warp_grep/utils/ripgrep.ts","../../../tools/warp_grep/utils/paths.ts","../../../tools/warp_grep/utils/files.ts"],"sourcesContent":["import type Anthropic from '@anthropic-ai/sdk';\nimport { z } from 'zod';\nimport { runWarpGrep } from './agent/runner.js';\nimport type { WarpGrepProvider } from './providers/types.js';\nimport { LocalRipgrepProvider } from './providers/local.js';\nimport { AGENT_CONFIG } from './agent/config.js';\n\nexport type WarpGrepConfig = {\n repoRoot: string;\n provider?: WarpGrepProvider;\n excludes?: string[];\n includes?: string[];\n debug?: boolean;\n apiKey?: string;\n};\n\nconst INPUT_SCHEMA = z.object({\n query: z.string().describe('Free-form repository question'),\n});\n\nexport function createMorphWarpGrepTool(config: WarpGrepConfig) {\n const tool: any = {\n name: 'morph-warp-grep',\n description: 'A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.',\n input_schema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Free-form repository question' },\n },\n required: ['query'],\n },\n };\n\n return Object.assign(tool, {\n execute: async (input: unknown) => {\n const parsed = INPUT_SCHEMA.parse(typeof input === 'string' ? JSON.parse(input) : input);\n const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);\n const result = await runWarpGrep({\n query: parsed.query,\n repoRoot: config.repoRoot,\n provider,\n excludes: config.excludes,\n includes: config.includes,\n debug: config.debug ?? false,\n apiKey: config.apiKey,\n });\n if (result.terminationReason !== 'completed' || !result.finish?.metadata) {\n return { success: false, error: 'Search did not complete', messages: result.messages };\n }\n const contexts = (result.finish.resolved || []).map((r: any) => ({\n file: r.path,\n content: r.content,\n }));\n return { success: true, contexts, summary: result.finish.payload };\n },\n });\n}\n\n\n","// Agent configuration defaults for morph-warp-grep\n// Hard-coded: SDK does not expose control over rounds or timeout.\nexport const AGENT_CONFIG = {\n // Give the model freedom; failsafe cap to prevent infinite loops\n MAX_ROUNDS: 10,\n TIMEOUT_MS: 30000,\n};\n\nexport const DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || '')\n .split(',')\n .map(s => s.trim())\n .filter(Boolean)\n .concat(['node_modules', '.git', 'dist', 'build', '.cache', 'venv', 'target']);\n\nexport const DEFAULT_MODEL = 'morph-warp-grep';\n\n\n","export const SYSTEM_PROMPT = `You are a code search agent. Your task is to find relevant code snippets based on a search query.\n\n<workflow>\nYou operate in exactly 3 rounds of tool exploration, followed by a final answer:\n\n1. In each round, you can make MULTIPLE tool calls (up to 8) to search in parallel. All tool results will be returned together after each round.\n2. After your third round of tool calls, your next turn MUST be a single call to the \\`finish\\` tool with all the context you have found.\n</workflow>\n\n<tool_calling>\nYou have tools at your disposal to solve the coding task. Follow these rules regarding tool calls:\n\n### 1. \\`analyse\\` - Explore Directories\nExplore directory structure in a tree-like format.\n**Syntax:** \\`analyse <path> [pattern]\\`\n- \\`<path>\\`: Directory path to analyze (defaults to \\`.\\`)\n- \\`[pattern]\\`: Optional regex pattern to filter names\n\nFor example:\n\\`\\`\\`\nanalyse src/api\nanalyse . \"test\"\n\\`\\`\\`\n\n### 2. \\`read\\` - Read File Contents\nRead entire files or specific line ranges.\n**Syntax:** \\`read <path>[:start-end]\\`\n- \\`<path>\\`: File path to read\n- \\`[:start-end]\\`: Optional 1-based, inclusive line range\n\nFor example:\n\\`\\`\\`\nread src/main.py\nread src/database/connection.py:10-50\n\\`\\`\\`\n\n### 3. \\`grep\\` - Search with Regex\nSearch for regex patterns across files using ripgrep.\n**Syntax:** \\`grep '<pattern>' <path>\\`\n- \\`'<pattern>'\\`: Regex pattern (always wrap in single quotes)\n- \\`<path>\\`: Directory or file to search (use \\`.\\` for the repo root)\n\nFor example:\n\\`\\`\\`\ngrep 'create_user' .\ngrep 'import.*requests' src/api\ngrep 'class\\\\\\\\s+AuthService' controllers/auth.py\n\\`\\`\\`\n\n### 4. \\`finish\\` - Submit Final Answer\nSubmit your findings when complete.\n**Syntax:** \\`finish <file1:range1,range2...> [file2:range3...]\\`\n- Provide file paths with colon-separated, comma-separated line ranges\n\nFor example:\n\\`\\`\\`\nfinish src/api/auth.py:25-50,75-80 src/models/user.py:10-15\n\\`\\`\\`\n</tool_calling>\n\n<strategy>\n- Use the \\`analyse\\`, \\`grep\\`, and \\`read\\` tools to gather information about the codebase.\n- Leverage the tools smartly to make full use of their potential\n- Make parallel tool calls within each round to investigate multiple paths or files efficiently\n- Be systematic and thorough within your 3-round limit\n</strategy>\n\n<output_format>\n- Only output tool calls themselves\n- Do not include explanatory text, reasoning, or commentary\n- Each tool call should be on its own line\n- After 3 rounds of exploration, call \\`finish\\` with all relevant code snippets you found\n</output_format>\n\nBegin your exploration now to find code relevant to the query.`;\n\nexport function getSystemPrompt(): string {\n\treturn SYSTEM_PROMPT;\n}\n\n\n","// Parses assistant lines into structured tool calls\nimport type { ToolCall } from './types.js';\n\nexport class LLMResponseParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'LLMResponseParseError';\n }\n}\n\ntype LineContext = { lineNumber: number; raw: string };\n\nexport class LLMResponseParser {\n private readonly finishSpecSplitRe = /,(?=[^,\\s]+:)/;\n\n parse(text: string): ToolCall[] {\n if (typeof text !== 'string') {\n throw new TypeError('Command text must be a string.');\n }\n const lines = text.split(/\\r?\\n/).map(l => l.trim());\n const commands: ToolCall[] = [];\n let finishAccumulator: Map<string, number[][]> | null = null;\n\n lines.forEach((line, idx) => {\n if (!line || line.startsWith('#')) return;\n const ctx: LineContext = { lineNumber: idx + 1, raw: line };\n const parts = this.splitLine(line, ctx);\n if (parts.length === 0) return;\n const cmd = parts[0];\n switch (cmd) {\n case 'analyse':\n this.handleAnalyse(parts, ctx, commands);\n break;\n case 'grep':\n this.handleGrep(parts, ctx, commands);\n break;\n case 'read':\n this.handleRead(parts, ctx, commands);\n break;\n case 'finish':\n finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);\n break;\n default:\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unsupported command '${cmd}'`);\n }\n });\n\n if (finishAccumulator) {\n const map = finishAccumulator as Map<string, number[][]>;\n const entries = [...map.entries()];\n const filesPayload = entries.map(([path, ranges]) => ({\n path,\n lines: [...ranges].sort((a, b) => a[0] - b[0]) as Array<[number, number]>,\n }));\n commands.push({ name: 'finish', arguments: { files: filesPayload } });\n }\n return commands;\n }\n\n private splitLine(line: string, ctx: LineContext): string[] {\n try {\n // Split by whitespace but keep quoted blocks as one\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n for (let i = 0; i < line.length; i++) {\n const ch = line[i];\n if (ch === \"'\" && line[i - 1] !== '\\\\') {\n inSingle = !inSingle;\n current += ch;\n } else if (!inSingle && /\\s/.test(ch)) {\n if (current) {\n parts.push(current);\n current = '';\n }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n } catch {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);\n }\n }\n\n private handleAnalyse(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // analyse <path> [pattern]\n if (parts.length < 2) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: analyse requires <path>`);\n }\n const path = parts[1];\n const pattern = parts[2]?.replace(/^\"|\"$/g, '') ?? null;\n commands.push({ name: 'analyse', arguments: { path, pattern } });\n }\n\n // no glob tool in MCP\n\n private handleGrep(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // grep '<pattern>' <path>\n if (parts.length < 3) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep requires '<pattern>' and <path>`);\n }\n const pat = parts[1];\n if (!pat.startsWith(\"'\") || !pat.endsWith(\"'\")) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep pattern must be single-quoted`);\n }\n commands.push({ name: 'grep', arguments: { pattern: pat.slice(1, -1), path: parts[2] } });\n }\n\n private handleRead(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // read <path>[:start-end]\n if (parts.length < 2) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: read requires <path> or <path>:<start-end>`);\n }\n const spec = parts[1];\n const rangeIdx = spec.indexOf(':');\n if (rangeIdx === -1) {\n commands.push({ name: 'read', arguments: { path: spec } });\n return;\n }\n const path = spec.slice(0, rangeIdx);\n const range = spec.slice(rangeIdx + 1);\n const [s, e] = range.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e)) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid read range '${range}'`);\n }\n commands.push({ name: 'read', arguments: { path, start: s, end: e } });\n }\n\n private handleFinish(parts: string[], ctx: LineContext, acc: Map<string, number[][]> | null) {\n // finish file1:1-10,20-30 file2:5-7\n const map = acc ?? new Map<string, number[][]>();\n const args = parts.slice(1);\n for (const token of args) {\n const [path, rangesText] = token.split(':', 2);\n if (!path || !rangesText) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid finish token '${token}'`);\n }\n const rangeSpecs = rangesText.split(',').filter(Boolean);\n for (const spec of rangeSpecs) {\n const [s, e] = spec.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid range '${spec}'`);\n }\n const arr = map.get(path) ?? [];\n arr.push([s, e]);\n map.set(path, arr);\n }\n }\n return map;\n }\n}\n\n\n","import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolRead(\n provider: WarpGrepProvider,\n args: { path: string; start?: number; end?: number }\n): Promise<string> {\n const res = await provider.read({ path: args.path, start: args.start, end: args.end });\n return res.lines.join('\\n');\n}\n\n\n","import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolAnalyse(\n provider: WarpGrepProvider,\n args: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }\n): Promise<string> {\n const list = await provider.analyse({\n path: args.path,\n pattern: args.pattern ?? null,\n maxResults: args.maxResults ?? 100,\n maxDepth: args.maxDepth ?? 2,\n });\n if (!list.length) return 'empty';\n return list\n .map((e) => `${' '.repeat(e.depth)}- ${e.type === 'dir' ? '[D]' : '[F]'} ${e.name}`)\n .join('\\n');\n}\n\n\n","/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nexport interface RetryConfig {\n maxRetries?: number; // Default: 3\n initialDelay?: number; // Default: 1000ms\n maxDelay?: number; // Default: 30000ms\n backoffMultiplier?: number; // Default: 2\n retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * 'https://api.example.com/data',\n * { method: 'POST', body: JSON.stringify(data) },\n * { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryConfig: RetryConfig = {}\n): Promise<Response> {\n const {\n maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n onRetry,\n } = retryConfig;\n\n let lastError: Error | null = null;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n \n // Retry on 429 (rate limit) or 503 (service unavailable)\n if (response.status === 429 || response.status === 503) {\n if (attempt < maxRetries) {\n // Check for Retry-After header\n const retryAfter = response.headers.get('Retry-After');\n const waitTime = retryAfter \n ? parseInt(retryAfter) * 1000 \n : Math.min(delay, maxDelay);\n \n const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n if (onRetry) {\n onRetry(attempt + 1, error);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n continue;\n }\n }\n\n return response;\n } catch (error) {\n lastError = error as Error;\n \n // Check if error is retryable\n const isRetryable = retryableErrors.some(errType => \n lastError?.message?.includes(errType)\n );\n\n if (!isRetryable || attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff\n const waitTime = Math.min(delay, maxDelay);\n if (onRetry) {\n onRetry(attempt + 1, lastError);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n }\n }\n\n throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage?: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout | number;\n \n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'MorphError';\n }\n}\n\n\n","export class ToolOutputFormatter {\n\tformat(\n\t\ttoolName: string,\n\t\targs: Record<string, unknown> | null | undefined,\n\t\toutput: string,\n\t\toptions: { isError?: boolean } = {}\n\t): string {\n\t\tconst name = (toolName ?? \"\").trim();\n\t\tif (!name) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst payload = (output as any)?.toString?.()?.trim?.() ?? \"\";\n\t\tconst isError = Boolean(options.isError);\n\t\tconst safeArgs = args ?? {};\n\n\t\tif (!payload && !isError) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tswitch (name) {\n\t\t\tcase \"read\":\n\t\t\t\treturn this.formatRead(safeArgs, payload, isError);\n\t\t\tcase \"analyse\":\n\t\t\t\treturn this.formatAnalyse(safeArgs, payload, isError);\n\t\t\tcase \"grep\":\n\t\t\t\treturn this.formatGrep(safeArgs, payload, isError);\n\t\t\tdefault:\n\t\t\t\treturn payload ? `<tool_output>\\n${payload}\\n</tool_output>` : \"\";\n\t\t}\n\t}\n\n\tprivate formatRead(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tif (isError) {\n\t\t\treturn payload;\n\t\t}\n\t\tconst path = this.asString(args.path) || \"...\";\n\t\treturn `<file path=\"${path}\">\\n${payload}\\n</file>`;\n\t}\n\n\tprivate formatAnalyse(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tconst path = this.asString(args.path) || \".\";\n\t\tif (isError) {\n\t\t\treturn `<analyse_results path=\"${path}\" status=\"error\">\\n${payload}\\n</analyse_results>`;\n\t\t}\n\t\treturn `<analyse_results path=\"${path}\">\\n${payload}\\n</analyse_results>`;\n\t}\n\n\tprivate formatGrep(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tconst pattern = this.asString(args.pattern);\n\t\tconst path = this.asString(args.path);\n\t\tconst attributes: string[] = [];\n\t\tif (pattern !== undefined) {\n\t\t\tattributes.push(`pattern=\"${pattern}\"`);\n\t\t}\n\t\tif (path !== undefined) {\n\t\t\tattributes.push(`path=\"${path}\"`);\n\t\t}\n\t\tif (isError) {\n\t\t\tattributes.push('status=\"error\"');\n\t\t}\n\t\tconst attrText = attributes.length ? ` ${attributes.join(\" \")}` : \"\";\n\t\treturn `<grep_output${attrText}>\\n${payload}\\n</grep_output>`;\n\t}\n\n\tprivate asString(value: unknown): string | undefined {\n\t\tif (value === null || value === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn String(value);\n\t}\n}\n\nconst sharedFormatter = new ToolOutputFormatter();\n\nexport function formatAgentToolOutput(\n\ttoolName: string,\n\targs: Record<string, unknown> | null | undefined,\n\toutput: string,\n\toptions: { isError?: boolean } = {}\n): string {\n\treturn sharedFormatter.format(toolName, args, output, options);\n}\n\n","export interface GrepMatch {\n\tpath: string;\n\tlineNumber: number;\n\tcontent: string;\n}\n\nexport class GrepState {\n\tprivate readonly seenLines = new Set<string>();\n\n\tisNew(path: string, lineNumber: number): boolean {\n\t\tconst key = this.makeKey(path, lineNumber);\n\t\treturn !this.seenLines.has(key);\n\t}\n\n\tadd(path: string, lineNumber: number): void {\n\t\tthis.seenLines.add(this.makeKey(path, lineNumber));\n\t}\n\n\tprivate makeKey(path: string, lineNumber: number): string {\n\t\treturn `${path}:${lineNumber}`;\n\t}\n}\n\nexport const MAX_GREP_OUTPUT_CHARS_PER_TURN = 60_000;\n\nfunction extractMatchFields(payload: string): GrepMatch | null {\n\tconst text = payload.replace(/\\r?\\n$/, \"\");\n\tif (!text || text.startsWith(\"[error]\")) {\n\t\treturn null;\n\t}\n\n\tconst firstSep = text.indexOf(\":\");\n\tif (firstSep === -1) {\n\t\treturn null;\n\t}\n\tlet filePath = text.slice(0, firstSep).trim();\n\tif (!filePath) {\n\t\treturn null;\n\t}\n\tif (filePath.startsWith(\"./\") || filePath.startsWith(\".\\\\\")) {\n\t\tfilePath = filePath.slice(2);\n\t}\n\n\tconst remainder = text.slice(firstSep + 1);\n\tconst secondSep = remainder.indexOf(\":\");\n\tif (secondSep === -1) {\n\t\treturn null;\n\t}\n\n\tconst linePart = remainder.slice(0, secondSep);\n\tconst lineNumber = Number.parseInt(linePart, 10);\n\tif (!Number.isInteger(lineNumber) || lineNumber <= 0) {\n\t\treturn null;\n\t}\n\n\tlet contentSegment = remainder.slice(secondSep + 1);\n\tconst columnSep = contentSegment.indexOf(\":\");\n\tif (columnSep !== -1 && /^\\d+$/.test(contentSegment.slice(0, columnSep))) {\n\t\tcontentSegment = contentSegment.slice(columnSep + 1);\n\t}\n\n\tconst content = contentSegment.trim();\n\tif (!content) {\n\t\treturn null;\n\t}\n\n\treturn { path: filePath, lineNumber, content };\n}\n\nexport function parseAndFilterGrepOutput(rawOutput: string, state: GrepState): GrepMatch[] {\n\tconst matches: GrepMatch[] = [];\n\tif (typeof rawOutput !== \"string\" || !rawOutput.trim()) {\n\t\treturn matches;\n\t}\n\n\tfor (const line of rawOutput.split(/\\r?\\n/)) {\n\t\tconst fields = extractMatchFields(line);\n\t\tif (!fields) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (state.isNew(fields.path, fields.lineNumber)) {\n\t\t\tmatches.push(fields);\n\t\t\tstate.add(fields.path, fields.lineNumber);\n\t\t}\n\t}\n\n\treturn matches;\n}\n\nfunction truncateOutput(payload: string, maxChars: number): string {\n\tif (payload.length <= maxChars) {\n\t\treturn payload;\n\t}\n\n\tconst note = \"... (output truncated)\";\n\tconst available = maxChars - note.length - 1;\n\tif (available <= 0) {\n\t\treturn note;\n\t}\n\n\tif (payload.length <= available) {\n\t\treturn `${payload.slice(0, available).replace(/\\n$/, \"\")}\\n${note}`;\n\t}\n\n\tconst core = payload.slice(0, Math.max(0, available - 1));\n\tconst trimmed = core.replace(/\\n$/, \"\").replace(/\\s+$/, \"\");\n\tconst snippet = trimmed ? `${trimmed}…` : \"…\";\n\treturn `${snippet}\\n${note}`;\n}\n\nexport function formatTurnGrepOutput(\n\tmatches: GrepMatch[],\n\tmaxChars: number = MAX_GREP_OUTPUT_CHARS_PER_TURN\n): string {\n\tif (!matches || matches.length === 0) {\n\t\treturn \"No new matches found.\";\n\t}\n\n\tconst matchesByFile = new Map<string, GrepMatch[]>();\n\tfor (const match of matches) {\n\t\tif (!matchesByFile.has(match.path)) {\n\t\t\tmatchesByFile.set(match.path, []);\n\t\t}\n\t\tmatchesByFile.get(match.path)!.push(match);\n\t}\n\n\tconst lines: string[] = [];\n\tconst sortedPaths = Array.from(matchesByFile.keys()).sort();\n\tsortedPaths.forEach((filePath, index) => {\n\t\tif (index > 0) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tlines.push(filePath);\n\t\tconst sortedMatches = matchesByFile\n\t\t\t.get(filePath)!\n\t\t\t.slice()\n\t\t\t.sort((a, b) => a.lineNumber - b.lineNumber);\n\t\tfor (const match of sortedMatches) {\n\t\t\tlines.push(`${match.lineNumber}:${match.content}`);\n\t\t}\n\t});\n\n\treturn truncateOutput(lines.join(\"\\n\"), maxChars);\n}\n\n\n","import type { FinishFileSpec } from '../agent/types.js';\nimport fs from 'fs/promises';\n\nexport function normalizeFinishFiles(files: FinishFileSpec[]): FinishFileSpec[] {\n return files.map((f) => {\n const merged = mergeRanges(f.lines);\n return { path: f.path, lines: merged };\n });\n}\n\nexport async function readFinishFiles(\n repoRoot: string,\n files: FinishFileSpec[],\n reader: (path: string, start: number, end: number) => Promise<string[]>\n): Promise<{ path: string; ranges: Array<[number, number]>; content: string }[]> {\n const out: { path: string; ranges: Array<[number, number]>; content: string }[] = [];\n for (const f of files) {\n const ranges = mergeRanges(f.lines);\n const chunks: string[] = [];\n for (const [s, e] of ranges) {\n const lines = await reader(f.path, s, e);\n chunks.push(lines.join('\\n'));\n }\n out.push({ path: f.path, ranges, content: chunks.join('\\n') });\n }\n return out;\n}\n\nfunction mergeRanges(ranges: Array<[number, number]>): Array<[number, number]> {\n if (!ranges.length) return [];\n const sorted = [...ranges].sort((a, b) => a[0] - b[0]);\n const merged: Array<[number, number]> = [];\n let [cs, ce] = sorted[0];\n for (let i = 1; i < sorted.length; i++) {\n const [s, e] = sorted[i];\n if (s <= ce + 1) {\n ce = Math.max(ce, e);\n } else {\n merged.push([cs, ce]);\n cs = s;\n ce = e;\n }\n }\n merged.push([cs, ce]);\n return merged;\n}\n\n\n","import { AGENT_CONFIG, DEFAULT_MODEL } from './config.js';\nimport { getSystemPrompt } from './prompt.js';\nimport type { AgentRunResult, ChatMessage, SessionConfig, ToolCall, AgentFinish } from './types.js';\nimport { LLMResponseParser, LLMResponseParseError } from './parser.js';\nimport type { WarpGrepProvider } from '../providers/types.js';\nimport { toolRead } from '../tools/read.js';\nimport { toolAnalyse } from '../tools/analyse.js';\nimport { fetchWithRetry, withTimeout } from '../../utils/resilience.js';\nimport { formatAgentToolOutput } from './formatter.js';\nimport { GrepState, parseAndFilterGrepOutput, formatTurnGrepOutput } from './grep_helpers.js';\nimport { readFinishFiles } from '../tools/finish.js';\nimport path from 'path';\nimport fs from 'fs/promises';\n\ntype EventName =\n | 'initial_state'\n | 'round_start'\n | 'round_end'\n | 'finish'\n | 'error';\n\nexport type EventCallback = (name: EventName, payload: Record<string, unknown>) => void;\n\nconst parser = new LLMResponseParser();\n\nasync function buildInitialState(repoRoot: string, query: string): Promise<string> {\n // Summarize top-level directories and file counts\n try {\n const entries = await fs.readdir(repoRoot, { withFileTypes: true });\n const dirs = entries.filter(e => e.isDirectory()).map(d => d.name).slice(0, 50);\n const files = entries.filter(e => e.isFile()).map(f => f.name).slice(0, 50);\n const parts = [\n `<repo_root>${repoRoot}</repo_root>`,\n `<top_dirs>${dirs.join(', ')}</top_dirs>`,\n `<top_files>${files.join(', ')}</top_files>`,\n ];\n return parts.join('\\n');\n } catch {\n return `<repo_root>${repoRoot}</repo_root>`;\n }\n}\n\nfunction formatAssistantToolBlock(name: string, args: Record<string, unknown>, payload: string, isError = false): string {\n const argStr = Object.entries(args)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n .join(' ');\n const prefix = isError ? 'error' : 'result';\n return `<${prefix} name=\"${name}\" ${argStr}>\\n${payload}\\n</${prefix}>`;\n}\n\nasync function callModel(messages: ChatMessage[], model: string, apiKey?: string): Promise<string> {\n const api = 'https://api.morphllm.com/v1/chat/completions';\n const fetchPromise = fetchWithRetry(\n api,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey || process.env.MORPH_API_KEY || ''}`,\n },\n body: JSON.stringify({\n model,\n temperature: 0.0,\n max_tokens: 1024,\n messages,\n }),\n },\n {}\n );\n const resp = await withTimeout(fetchPromise, AGENT_CONFIG.TIMEOUT_MS, 'morph-warp-grep request timed out');\n if (!resp.ok) {\n const t = await resp.text();\n throw new Error(`morph-warp-grep error ${resp.status}: ${t}`);\n }\n const data = await resp.json();\n const content = data?.choices?.[0]?.message?.content;\n if (!content || typeof content !== 'string') {\n throw new Error('Invalid response from model');\n }\n return content;\n}\n\nexport async function runWarpGrep(config: SessionConfig & { provider: WarpGrepProvider }): Promise<AgentRunResult> {\n const repoRoot = path.resolve(config.repoRoot || process.cwd());\n const messages: ChatMessage[] = [];\n\n // system\n const systemMessage = { role: 'system' as const, content: getSystemPrompt() };\n messages.push(systemMessage);\n // user query\n const queryContent = `<query>${config.query}</query>`;\n messages.push({ role: 'user', content: queryContent });\n // initial state\n const initialState = await buildInitialState(repoRoot, config.query);\n messages.push({ role: 'user', content: initialState });\n\n const maxRounds = AGENT_CONFIG.MAX_ROUNDS;\n const model = config.model || DEFAULT_MODEL;\n const provider = config.provider;\n const errors: Array<{ message: string }> = [];\n const grepState = new GrepState();\n\n let finishMeta: AgentFinish | undefined;\n let terminationReason: AgentRunResult['terminationReason'] = 'terminated';\n\n for (let round = 1; round <= maxRounds; round += 1) {\n // call model\n const assistantContent = await callModel(messages, model, config.apiKey).catch((e: unknown) => {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n return '';\n });\n if (!assistantContent) break;\n messages.push({ role: 'assistant', content: assistantContent });\n\n // parse tool calls\n let toolCalls: ToolCall[] = [];\n try {\n toolCalls = parser.parse(assistantContent);\n } catch (e) {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n terminationReason = 'terminated';\n break;\n }\n if (toolCalls.length === 0) {\n errors.push({ message: 'No tool calls produced by the model.' });\n terminationReason = 'terminated';\n break;\n }\n\n const finishCalls = toolCalls.filter(c => c.name === 'finish');\n const grepCalls = toolCalls.filter(c => c.name === 'grep');\n const analyseCalls = toolCalls.filter(c => c.name === 'analyse');\n const readCalls = toolCalls.filter(c => c.name === 'read');\n\n const formatted: string[] = [];\n\n // Execute non-grep tools in parallel\n const otherPromises: Array<Promise<string>> = [];\n for (const c of analyseCalls) {\n const args = (c.arguments ?? {}) as { path: string; pattern?: string | null };\n otherPromises.push(\n toolAnalyse(provider, args).then(\n p => formatAgentToolOutput('analyse', args, p, { isError: false }),\n err => formatAgentToolOutput('analyse', args, String(err), { isError: true })\n )\n );\n }\n for (const c of readCalls) {\n const args = (c.arguments ?? {}) as { path: string; start?: number; end?: number };\n otherPromises.push(\n toolRead(provider, args).then(\n p => formatAgentToolOutput('read', args, p, { isError: false }),\n err => formatAgentToolOutput('read', args, String(err), { isError: true })\n )\n );\n }\n const otherResults = await Promise.all(otherPromises);\n formatted.push(...otherResults);\n\n // Execute grep calls sequentially like MCP runner to keep outputs compact\n for (const c of grepCalls) {\n const args = (c.arguments ?? {}) as { pattern: string; path: string };\n try {\n const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });\n const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join('\\n') : '';\n const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);\n let formattedPayload = formatTurnGrepOutput(newMatches);\n if (formattedPayload === \"No new matches found.\") {\n formattedPayload = \"no new matches\";\n }\n formatted.push(formatAgentToolOutput('grep', args, formattedPayload, { isError: false }));\n } catch (err) {\n formatted.push(formatAgentToolOutput('grep', args, String(err), { isError: true }));\n }\n }\n\n if (formatted.length > 0) {\n messages.push({ role: 'user', content: formatted.join('\\n') });\n }\n\n if (finishCalls.length) {\n const fc = finishCalls[0];\n const files = ((fc.arguments as any)?.files ?? []) as AgentFinish['files'];\n finishMeta = { files };\n terminationReason = 'completed';\n break;\n }\n }\n\n if (terminationReason !== 'completed' || !finishMeta) {\n return { terminationReason, messages, errors };\n }\n\n // Build finish payload\n const parts: string[] = ['Relevant context found:'];\n for (const f of finishMeta.files) {\n const ranges = f.lines.map(([s, e]) => `${s}-${e}`).join(', ');\n parts.push(`- ${f.path}: ${ranges}`);\n }\n const payload = parts.join('\\n');\n\n // Resolve file contents for returned ranges\n const resolved = await readFinishFiles(\n repoRoot,\n finishMeta.files,\n async (p: string, s: number, e: number) => {\n const rr = await provider.read({ path: p, start: s, end: e });\n // rr.lines are \"line|content\" → strip the \"line|\" prefix\n return rr.lines.map(l => {\n const idx = l.indexOf('|');\n return idx >= 0 ? l.slice(idx + 1) : l;\n });\n }\n );\n\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta, resolved },\n };\n}\n\n\n","import fs from 'fs/promises';\nimport fssync from 'fs';\nimport path from 'path';\nimport { runRipgrep } from '../utils/ripgrep.js';\nimport { ensureWithinRepo, resolveUnderRepo, toRepoRelative, isSymlink, isTextualFile } from '../utils/paths.js';\nimport type { WarpGrepProvider, GrepResult, ReadResult, AnalyseEntry } from './types.js';\nimport { readAllLines } from '../utils/files.js';\nimport { DEFAULT_EXCLUDES } from '../agent/config.js';\n\nexport class LocalRipgrepProvider implements WarpGrepProvider {\n constructor(private readonly repoRoot: string, private readonly excludes: string[] = DEFAULT_EXCLUDES) {}\n\n async grep(params: { pattern: string; path: string }): Promise<GrepResult> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat) return { lines: [] };\n const targetArg = abs === path.resolve(this.repoRoot) ? '.' : toRepoRelative(this.repoRoot, abs);\n const args = [\n '--no-config',\n '--no-heading',\n '--with-filename',\n '--line-number',\n '--color=never',\n '--trim',\n '--max-columns=400',\n ...this.excludes.flatMap((e) => ['-g', `!${e}`]),\n params.pattern,\n targetArg || '.',\n ];\n const res = await runRipgrep(args, { cwd: this.repoRoot });\n if (res.exitCode === -1) {\n throw new Error(res.stderr || 'ripgrep (rg) execution failed.');\n }\n if (res.exitCode !== 0 && res.exitCode !== 1) {\n throw new Error(res.stderr || `ripgrep failed with code ${res.exitCode}`);\n }\n const lines = (res.stdout || '')\n .trim()\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0);\n return { lines };\n }\n\n async glob(params: { pattern: string; path: string }): Promise<{ files: string[] }> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const targetArg = abs === path.resolve(this.repoRoot) ? '.' : toRepoRelative(this.repoRoot, abs);\n const args = [\n '--no-config',\n '--files',\n '-g',\n params.pattern,\n ...this.excludes.flatMap((e) => ['-g', `!${e}`]),\n targetArg || '.',\n ];\n const res = await runRipgrep(args, { cwd: this.repoRoot });\n if (res.exitCode === -1) {\n throw new Error(res.stderr || 'ripgrep (rg) execution failed.');\n }\n const files = (res.stdout || '')\n .trim()\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0);\n return { files };\n }\n\n async read(params: { path: string; start?: number; end?: number }): Promise<ReadResult> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat || !stat.isFile()) {\n throw new Error(`Path is not a file: ${params.path}`);\n }\n if (isSymlink(abs)) {\n throw new Error(`Refusing to read symlink: ${params.path}`);\n }\n if (!isTextualFile(abs)) {\n throw new Error(`Non-text or too-large file: ${params.path}`);\n }\n const lines = await readAllLines(abs);\n const total = lines.length;\n const s = params.start ?? 1;\n const e = Math.min(params.end ?? total, total);\n if (s > total && total > 0) {\n throw new Error(`start ${s} exceeds file length (${total})`);\n }\n const out: string[] = [];\n for (let i = s; i <= e; i += 1) {\n const content = lines[i - 1] ?? '';\n out.push(`${i}|${content}`);\n }\n return { lines: out };\n }\n\n async analyse(params: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }): Promise<AnalyseEntry[]> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat || !stat.isDirectory()) {\n return [];\n }\n const maxResults = params.maxResults ?? 100;\n const maxDepth = params.maxDepth ?? 2;\n const regex = params.pattern ? new RegExp(params.pattern) : null;\n\n const results: AnalyseEntry[] = [];\n async function walk(dir: string, depth: number) {\n if (depth > maxDepth || results.length >= maxResults) return;\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n const rel = toRepoRelative(abs, full).replace(/^[.][/\\\\]?/, '');\n if (DEFAULT_EXCLUDES.some((ex) => rel.split(path.sep).includes(ex))) continue;\n if (regex && !regex.test(entry.name)) continue;\n if (results.length >= maxResults) break;\n results.push({\n name: entry.name,\n path: toRepoRelative(path.resolve(''), full), // relative display\n type: entry.isDirectory() ? 'dir' : 'file',\n depth,\n });\n if (entry.isDirectory()) {\n await walk(full, depth + 1);\n }\n }\n }\n await walk(abs, 0);\n return results;\n }\n}\n\n\n","import { spawn } from 'child_process';\n\nexport type ExecResult = { stdout: string; stderr: string; exitCode: number };\n\nexport function runRipgrep(args: string[], opts?: { cwd?: string; env?: NodeJS.ProcessEnv }): Promise<ExecResult> {\n return new Promise((resolve) => {\n const child = spawn('rg', args, {\n cwd: opts?.cwd,\n env: { ...process.env, ...(opts?.env || {}) },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (d) => (stdout += d.toString()));\n child.stderr.on('data', (d) => (stderr += d.toString()));\n child.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: typeof code === 'number' ? code : -1 });\n });\n child.on('error', () => {\n resolve({ stdout: '', stderr: 'Failed to spawn ripgrep (rg). Ensure it is installed.', exitCode: -1 });\n });\n });\n}\n\n\n","import fs from 'fs';\nimport path from 'path';\n\nexport function resolveUnderRepo(repoRoot: string, targetPath: string): string {\n const absRoot = path.resolve(repoRoot);\n const resolved = path.resolve(absRoot, targetPath);\n ensureWithinRepo(absRoot, resolved);\n return resolved;\n}\n\nexport function ensureWithinRepo(repoRoot: string, absTarget: string): void {\n const rel = path.relative(path.resolve(repoRoot), path.resolve(absTarget));\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw new Error(`Path outside repository root: ${absTarget}`);\n }\n}\n\nexport function toRepoRelative(repoRoot: string, absPath: string): string {\n return path.relative(path.resolve(repoRoot), path.resolve(absPath));\n}\n\nexport function isSymlink(p: string): boolean {\n try {\n const st = fs.lstatSync(p);\n return st.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nexport function isTextualFile(filePath: string, maxBytes = 2_000_000): boolean {\n try {\n const st = fs.statSync(filePath);\n if (!st.isFile()) return false;\n if (st.size > maxBytes) return false;\n const fd = fs.openSync(filePath, 'r');\n const buf = Buffer.alloc(512);\n const read = fs.readSync(fd, buf, 0, buf.length, 0);\n fs.closeSync(fd);\n for (let i = 0; i < read; i++) {\n const c = buf[i];\n if (c === 0) return false; // binary heuristic\n }\n return true;\n } catch {\n return false;\n }\n}\n\n\n","import fs from 'fs/promises';\n\nexport async function readAllLines(filePath: string): Promise<string[]> {\n const content = await fs.readFile(filePath, 'utf8');\n // Preserve newlines; split keeping consistency\n return content.split(/\\r?\\n/);\n}\n\n\n"],"mappings":"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","names":["path","path","path","fs","path","import_promises","import_path","import_path","path","fs","import_promises","fs","fs","path"]}
1
+ {"version":3,"sources":["../../../tools/warp_grep/anthropic.ts","../../../tools/warp_grep/agent/config.ts","../../../tools/warp_grep/agent/prompt.ts","../../../tools/warp_grep/agent/parser.ts","../../../tools/warp_grep/tools/read.ts","../../../tools/warp_grep/tools/analyse.ts","../../../tools/utils/resilience.ts","../../../tools/warp_grep/agent/formatter.ts","../../../tools/warp_grep/agent/grep_helpers.ts","../../../tools/warp_grep/tools/finish.ts","../../../tools/warp_grep/agent/runner.ts","../../../tools/warp_grep/providers/local.ts","../../../tools/warp_grep/utils/ripgrep.ts","../../../tools/warp_grep/utils/paths.ts","../../../tools/warp_grep/utils/files.ts"],"sourcesContent":["import type Anthropic from '@anthropic-ai/sdk';\nimport { z } from 'zod';\nimport { runWarpGrep } from './agent/runner.js';\nimport type { WarpGrepProvider } from './providers/types.js';\nimport { LocalRipgrepProvider } from './providers/local.js';\nimport { AGENT_CONFIG } from './agent/config.js';\n\nexport type WarpGrepConfig = {\n repoRoot: string;\n provider?: WarpGrepProvider;\n excludes?: string[];\n includes?: string[];\n debug?: boolean;\n apiKey?: string;\n description?: string;\n};\n\nconst INPUT_SCHEMA = z.object({\n query: z.string().describe('Free-form repository question'),\n});\n\nexport function createMorphWarpGrepTool(config: WarpGrepConfig) {\n const tool: any = {\n name: 'morph-warp-grep',\n description: config.description ?? 'A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.',\n input_schema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Free-form repository question' },\n },\n required: ['query'],\n },\n };\n\n return Object.assign(tool, {\n execute: async (input: unknown) => {\n const parsed = INPUT_SCHEMA.parse(typeof input === 'string' ? JSON.parse(input) : input);\n const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);\n const result = await runWarpGrep({\n query: parsed.query,\n repoRoot: config.repoRoot,\n provider,\n excludes: config.excludes,\n includes: config.includes,\n debug: config.debug ?? false,\n apiKey: config.apiKey,\n });\n if (result.terminationReason !== 'completed' || !result.finish?.metadata) {\n return { success: false, error: 'Search did not complete', messages: result.messages };\n }\n const contexts = (result.finish.resolved || []).map((r: any) => ({\n file: r.path,\n content: r.content,\n }));\n return { success: true, contexts, summary: result.finish.payload };\n },\n });\n}\n\n\n","// Agent configuration defaults for morph-warp-grep\n// Hard-coded: SDK does not expose control over rounds or timeout.\nexport const AGENT_CONFIG = {\n // Give the model freedom; failsafe cap to prevent infinite loops\n MAX_ROUNDS: 10,\n TIMEOUT_MS: 30000,\n};\n\nexport const DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || '')\n .split(',')\n .map(s => s.trim())\n .filter(Boolean)\n .concat(['node_modules', '.git', 'dist', 'build', '.cache', 'venv', 'target']);\n\nexport const DEFAULT_MODEL = 'morph-warp-grep';\n\n\n","export const SYSTEM_PROMPT = `You are a code search agent. Your task is to find relevant code snippets based on a search query.\n\n<workflow>\nYou operate in exactly 3 rounds of tool exploration, followed by a final answer:\n\n1. In each round, you can make MULTIPLE tool calls (up to 8) to search in parallel. All tool results will be returned together after each round.\n2. After your third round of tool calls, your next turn MUST be a single call to the \\`finish\\` tool with all the context you have found.\n</workflow>\n\n<tool_calling>\nYou have tools at your disposal to solve the coding task. Follow these rules regarding tool calls:\n\n### 1. \\`analyse\\` - Explore Directories\nExplore directory structure in a tree-like format.\n**Syntax:** \\`analyse <path> [pattern]\\`\n- \\`<path>\\`: Directory path to analyze (defaults to \\`.\\`)\n- \\`[pattern]\\`: Optional regex pattern to filter names\n\nFor example:\n\\`\\`\\`\nanalyse src/api\nanalyse . \"test\"\n\\`\\`\\`\n\n### 2. \\`read\\` - Read File Contents\nRead entire files or specific line ranges.\n**Syntax:** \\`read <path>[:start-end]\\`\n- \\`<path>\\`: File path to read\n- \\`[:start-end]\\`: Optional 1-based, inclusive line range\n\nFor example:\n\\`\\`\\`\nread src/main.py\nread src/database/connection.py:10-50\n\\`\\`\\`\n\n### 3. \\`grep\\` - Search with Regex\nSearch for regex patterns across files using ripgrep.\n**Syntax:** \\`grep '<pattern>' <path>\\`\n- \\`'<pattern>'\\`: Regex pattern (always wrap in single quotes)\n- \\`<path>\\`: Directory or file to search (use \\`.\\` for the repo root)\n\nFor example:\n\\`\\`\\`\ngrep 'create_user' .\ngrep 'import.*requests' src/api\ngrep 'class\\\\\\\\s+AuthService' controllers/auth.py\n\\`\\`\\`\n\n### 4. \\`finish\\` - Submit Final Answer\nSubmit your findings when complete.\n**Syntax:** \\`finish <file1:range1,range2...> [file2:range3...]\\`\n- Provide file paths with colon-separated, comma-separated line ranges\n\nFor example:\n\\`\\`\\`\nfinish src/api/auth.py:25-50,75-80 src/models/user.py:10-15\n\\`\\`\\`\n</tool_calling>\n\n<strategy>\n- Use the \\`analyse\\`, \\`grep\\`, and \\`read\\` tools to gather information about the codebase.\n- Leverage the tools smartly to make full use of their potential\n- Make parallel tool calls within each round to investigate multiple paths or files efficiently\n- Be systematic and thorough within your 3-round limit\n</strategy>\n\n<output_format>\n- Only output tool calls themselves\n- Do not include explanatory text, reasoning, or commentary\n- Each tool call should be on its own line\n- After 3 rounds of exploration, call \\`finish\\` with all relevant code snippets you found\n</output_format>\n\nBegin your exploration now to find code relevant to the query.`;\n\nexport function getSystemPrompt(): string {\n\treturn SYSTEM_PROMPT;\n}\n\n\n","// Parses assistant lines into structured tool calls\nimport type { ToolCall } from './types.js';\n\nexport class LLMResponseParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'LLMResponseParseError';\n }\n}\n\ntype LineContext = { lineNumber: number; raw: string };\n\nexport class LLMResponseParser {\n private readonly finishSpecSplitRe = /,(?=[^,\\s]+:)/;\n\n parse(text: string): ToolCall[] {\n if (typeof text !== 'string') {\n throw new TypeError('Command text must be a string.');\n }\n const lines = text.split(/\\r?\\n/).map(l => l.trim());\n const commands: ToolCall[] = [];\n let finishAccumulator: Map<string, number[][]> | null = null;\n\n lines.forEach((line, idx) => {\n if (!line || line.startsWith('#')) return;\n const ctx: LineContext = { lineNumber: idx + 1, raw: line };\n const parts = this.splitLine(line, ctx);\n if (parts.length === 0) return;\n const cmd = parts[0];\n switch (cmd) {\n case 'analyse':\n this.handleAnalyse(parts, ctx, commands);\n break;\n case 'grep':\n this.handleGrep(parts, ctx, commands);\n break;\n case 'read':\n this.handleRead(parts, ctx, commands);\n break;\n case 'finish':\n finishAccumulator = this.handleFinish(parts, ctx, finishAccumulator);\n break;\n default:\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unsupported command '${cmd}'`);\n }\n });\n\n if (finishAccumulator) {\n const map = finishAccumulator as Map<string, number[][]>;\n const entries = [...map.entries()];\n const filesPayload = entries.map(([path, ranges]) => ({\n path,\n lines: [...ranges].sort((a, b) => a[0] - b[0]) as Array<[number, number]>,\n }));\n commands.push({ name: 'finish', arguments: { files: filesPayload } });\n }\n return commands;\n }\n\n private splitLine(line: string, ctx: LineContext): string[] {\n try {\n // Split by whitespace but keep quoted blocks as one\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n for (let i = 0; i < line.length; i++) {\n const ch = line[i];\n if (ch === \"'\" && line[i - 1] !== '\\\\') {\n inSingle = !inSingle;\n current += ch;\n } else if (!inSingle && /\\s/.test(ch)) {\n if (current) {\n parts.push(current);\n current = '';\n }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n } catch {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);\n }\n }\n\n private handleAnalyse(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // analyse <path> [pattern]\n if (parts.length < 2) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: analyse requires <path>`);\n }\n const path = parts[1];\n const pattern = parts[2]?.replace(/^\"|\"$/g, '') ?? null;\n commands.push({ name: 'analyse', arguments: { path, pattern } });\n }\n\n // no glob tool in MCP\n\n private handleGrep(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // grep '<pattern>' <path>\n if (parts.length < 3) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep requires '<pattern>' and <path>`);\n }\n const pat = parts[1];\n if (!pat.startsWith(\"'\") || !pat.endsWith(\"'\")) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: grep pattern must be single-quoted`);\n }\n commands.push({ name: 'grep', arguments: { pattern: pat.slice(1, -1), path: parts[2] } });\n }\n\n private handleRead(parts: string[], ctx: LineContext, commands: ToolCall[]) {\n // read <path>[:start-end]\n if (parts.length < 2) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: read requires <path> or <path>:<start-end>`);\n }\n const spec = parts[1];\n const rangeIdx = spec.indexOf(':');\n if (rangeIdx === -1) {\n commands.push({ name: 'read', arguments: { path: spec } });\n return;\n }\n const path = spec.slice(0, rangeIdx);\n const range = spec.slice(rangeIdx + 1);\n const [s, e] = range.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e)) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid read range '${range}'`);\n }\n commands.push({ name: 'read', arguments: { path, start: s, end: e } });\n }\n\n private handleFinish(parts: string[], ctx: LineContext, acc: Map<string, number[][]> | null) {\n // finish file1:1-10,20-30 file2:5-7\n const map = acc ?? new Map<string, number[][]>();\n const args = parts.slice(1);\n for (const token of args) {\n const [path, rangesText] = token.split(':', 2);\n if (!path || !rangesText) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid finish token '${token}'`);\n }\n const rangeSpecs = rangesText.split(',').filter(Boolean);\n for (const spec of rangeSpecs) {\n const [s, e] = spec.split('-').map(v => parseInt(v, 10));\n if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {\n throw new LLMResponseParseError(`Line ${ctx.lineNumber}: invalid range '${spec}'`);\n }\n const arr = map.get(path) ?? [];\n arr.push([s, e]);\n map.set(path, arr);\n }\n }\n return map;\n }\n}\n\n\n","import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolRead(\n provider: WarpGrepProvider,\n args: { path: string; start?: number; end?: number }\n): Promise<string> {\n const res = await provider.read({ path: args.path, start: args.start, end: args.end });\n return res.lines.join('\\n');\n}\n\n\n","import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolAnalyse(\n provider: WarpGrepProvider,\n args: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }\n): Promise<string> {\n const list = await provider.analyse({\n path: args.path,\n pattern: args.pattern ?? null,\n maxResults: args.maxResults ?? 100,\n maxDepth: args.maxDepth ?? 2,\n });\n if (!list.length) return 'empty';\n return list\n .map((e) => `${' '.repeat(e.depth)}- ${e.type === 'dir' ? '[D]' : '[F]'} ${e.name}`)\n .join('\\n');\n}\n\n\n","/**\n * Resilience utilities for retry logic and timeout handling\n */\n\nexport interface RetryConfig {\n maxRetries?: number; // Default: 3\n initialDelay?: number; // Default: 1000ms\n maxDelay?: number; // Default: 30000ms\n backoffMultiplier?: number; // Default: 2\n retryableErrors?: string[]; // Default: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND']\n onRetry?: (attempt: number, error: Error) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<Omit<RetryConfig, 'onRetry'>> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffMultiplier: 2,\n retryableErrors: ['ECONNREFUSED', 'ETIMEDOUT', 'ENOTFOUND'],\n};\n\n/**\n * Retry a fetch request with exponential backoff\n * \n * @param url - Request URL\n * @param options - Fetch options\n * @param retryConfig - Retry configuration\n * @returns Response from fetch\n * \n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * 'https://api.example.com/data',\n * { method: 'POST', body: JSON.stringify(data) },\n * { maxRetries: 5, initialDelay: 500 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n retryConfig: RetryConfig = {}\n): Promise<Response> {\n const {\n maxRetries = DEFAULT_RETRY_CONFIG.maxRetries,\n initialDelay = DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay = DEFAULT_RETRY_CONFIG.maxDelay,\n backoffMultiplier = DEFAULT_RETRY_CONFIG.backoffMultiplier,\n retryableErrors = DEFAULT_RETRY_CONFIG.retryableErrors,\n onRetry,\n } = retryConfig;\n\n let lastError: Error | null = null;\n let delay = initialDelay;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n \n // Retry on 429 (rate limit) or 503 (service unavailable)\n if (response.status === 429 || response.status === 503) {\n if (attempt < maxRetries) {\n // Check for Retry-After header\n const retryAfter = response.headers.get('Retry-After');\n const waitTime = retryAfter \n ? parseInt(retryAfter) * 1000 \n : Math.min(delay, maxDelay);\n \n const error = new Error(`HTTP ${response.status}: Retrying after ${waitTime}ms`);\n if (onRetry) {\n onRetry(attempt + 1, error);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n continue;\n }\n }\n\n return response;\n } catch (error) {\n lastError = error as Error;\n \n // Check if error is retryable\n const isRetryable = retryableErrors.some(errType => \n lastError?.message?.includes(errType)\n );\n\n if (!isRetryable || attempt === maxRetries) {\n throw lastError;\n }\n\n // Exponential backoff\n const waitTime = Math.min(delay, maxDelay);\n if (onRetry) {\n onRetry(attempt + 1, lastError);\n }\n \n await sleep(waitTime);\n delay *= backoffMultiplier;\n }\n }\n\n throw lastError || new Error('Max retries exceeded');\n}\n\n/**\n * Add timeout to any promise\n * \n * @param promise - Promise to wrap with timeout\n * @param timeoutMs - Timeout in milliseconds\n * @param errorMessage - Optional custom error message\n * @returns Promise that rejects if timeout is reached\n * \n * @example\n * ```typescript\n * const result = await withTimeout(\n * fetchData(),\n * 5000,\n * 'Data fetch timed out'\n * );\n * ```\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage?: string\n): Promise<T> {\n let timeoutId: NodeJS.Timeout | number;\n \n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(errorMessage || `Operation timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n const result = await Promise.race([promise, timeoutPromise]);\n clearTimeout(timeoutId!);\n return result;\n } catch (error) {\n clearTimeout(timeoutId!);\n throw error;\n }\n}\n\n/**\n * Sleep for specified milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Unified error type for all tools\n */\nexport class MorphError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number,\n public retryable: boolean = false\n ) {\n super(message);\n this.name = 'MorphError';\n }\n}\n\n\n","export class ToolOutputFormatter {\n\tformat(\n\t\ttoolName: string,\n\t\targs: Record<string, unknown> | null | undefined,\n\t\toutput: string,\n\t\toptions: { isError?: boolean } = {}\n\t): string {\n\t\tconst name = (toolName ?? \"\").trim();\n\t\tif (!name) {\n\t\t\treturn \"\";\n\t\t}\n\t\tconst payload = (output as any)?.toString?.()?.trim?.() ?? \"\";\n\t\tconst isError = Boolean(options.isError);\n\t\tconst safeArgs = args ?? {};\n\n\t\tif (!payload && !isError) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tswitch (name) {\n\t\t\tcase \"read\":\n\t\t\t\treturn this.formatRead(safeArgs, payload, isError);\n\t\t\tcase \"analyse\":\n\t\t\t\treturn this.formatAnalyse(safeArgs, payload, isError);\n\t\t\tcase \"grep\":\n\t\t\t\treturn this.formatGrep(safeArgs, payload, isError);\n\t\t\tdefault:\n\t\t\t\treturn payload ? `<tool_output>\\n${payload}\\n</tool_output>` : \"\";\n\t\t}\n\t}\n\n\tprivate formatRead(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tif (isError) {\n\t\t\treturn payload;\n\t\t}\n\t\tconst path = this.asString(args.path) || \"...\";\n\t\treturn `<file path=\"${path}\">\\n${payload}\\n</file>`;\n\t}\n\n\tprivate formatAnalyse(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tconst path = this.asString(args.path) || \".\";\n\t\tif (isError) {\n\t\t\treturn `<analyse_results path=\"${path}\" status=\"error\">\\n${payload}\\n</analyse_results>`;\n\t\t}\n\t\treturn `<analyse_results path=\"${path}\">\\n${payload}\\n</analyse_results>`;\n\t}\n\n\tprivate formatGrep(args: Record<string, unknown>, payload: string, isError: boolean): string {\n\t\tconst pattern = this.asString(args.pattern);\n\t\tconst path = this.asString(args.path);\n\t\tconst attributes: string[] = [];\n\t\tif (pattern !== undefined) {\n\t\t\tattributes.push(`pattern=\"${pattern}\"`);\n\t\t}\n\t\tif (path !== undefined) {\n\t\t\tattributes.push(`path=\"${path}\"`);\n\t\t}\n\t\tif (isError) {\n\t\t\tattributes.push('status=\"error\"');\n\t\t}\n\t\tconst attrText = attributes.length ? ` ${attributes.join(\" \")}` : \"\";\n\t\treturn `<grep_output${attrText}>\\n${payload}\\n</grep_output>`;\n\t}\n\n\tprivate asString(value: unknown): string | undefined {\n\t\tif (value === null || value === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn String(value);\n\t}\n}\n\nconst sharedFormatter = new ToolOutputFormatter();\n\nexport function formatAgentToolOutput(\n\ttoolName: string,\n\targs: Record<string, unknown> | null | undefined,\n\toutput: string,\n\toptions: { isError?: boolean } = {}\n): string {\n\treturn sharedFormatter.format(toolName, args, output, options);\n}\n\n","export interface GrepMatch {\n\tpath: string;\n\tlineNumber: number;\n\tcontent: string;\n}\n\nexport class GrepState {\n\tprivate readonly seenLines = new Set<string>();\n\n\tisNew(path: string, lineNumber: number): boolean {\n\t\tconst key = this.makeKey(path, lineNumber);\n\t\treturn !this.seenLines.has(key);\n\t}\n\n\tadd(path: string, lineNumber: number): void {\n\t\tthis.seenLines.add(this.makeKey(path, lineNumber));\n\t}\n\n\tprivate makeKey(path: string, lineNumber: number): string {\n\t\treturn `${path}:${lineNumber}`;\n\t}\n}\n\nexport const MAX_GREP_OUTPUT_CHARS_PER_TURN = 60_000;\n\nfunction extractMatchFields(payload: string): GrepMatch | null {\n\tconst text = payload.replace(/\\r?\\n$/, \"\");\n\tif (!text || text.startsWith(\"[error]\")) {\n\t\treturn null;\n\t}\n\n\tconst firstSep = text.indexOf(\":\");\n\tif (firstSep === -1) {\n\t\treturn null;\n\t}\n\tlet filePath = text.slice(0, firstSep).trim();\n\tif (!filePath) {\n\t\treturn null;\n\t}\n\tif (filePath.startsWith(\"./\") || filePath.startsWith(\".\\\\\")) {\n\t\tfilePath = filePath.slice(2);\n\t}\n\n\tconst remainder = text.slice(firstSep + 1);\n\tconst secondSep = remainder.indexOf(\":\");\n\tif (secondSep === -1) {\n\t\treturn null;\n\t}\n\n\tconst linePart = remainder.slice(0, secondSep);\n\tconst lineNumber = Number.parseInt(linePart, 10);\n\tif (!Number.isInteger(lineNumber) || lineNumber <= 0) {\n\t\treturn null;\n\t}\n\n\tlet contentSegment = remainder.slice(secondSep + 1);\n\tconst columnSep = contentSegment.indexOf(\":\");\n\tif (columnSep !== -1 && /^\\d+$/.test(contentSegment.slice(0, columnSep))) {\n\t\tcontentSegment = contentSegment.slice(columnSep + 1);\n\t}\n\n\tconst content = contentSegment.trim();\n\tif (!content) {\n\t\treturn null;\n\t}\n\n\treturn { path: filePath, lineNumber, content };\n}\n\nexport function parseAndFilterGrepOutput(rawOutput: string, state: GrepState): GrepMatch[] {\n\tconst matches: GrepMatch[] = [];\n\tif (typeof rawOutput !== \"string\" || !rawOutput.trim()) {\n\t\treturn matches;\n\t}\n\n\tfor (const line of rawOutput.split(/\\r?\\n/)) {\n\t\tconst fields = extractMatchFields(line);\n\t\tif (!fields) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (state.isNew(fields.path, fields.lineNumber)) {\n\t\t\tmatches.push(fields);\n\t\t\tstate.add(fields.path, fields.lineNumber);\n\t\t}\n\t}\n\n\treturn matches;\n}\n\nfunction truncateOutput(payload: string, maxChars: number): string {\n\tif (payload.length <= maxChars) {\n\t\treturn payload;\n\t}\n\n\tconst note = \"... (output truncated)\";\n\tconst available = maxChars - note.length - 1;\n\tif (available <= 0) {\n\t\treturn note;\n\t}\n\n\tif (payload.length <= available) {\n\t\treturn `${payload.slice(0, available).replace(/\\n$/, \"\")}\\n${note}`;\n\t}\n\n\tconst core = payload.slice(0, Math.max(0, available - 1));\n\tconst trimmed = core.replace(/\\n$/, \"\").replace(/\\s+$/, \"\");\n\tconst snippet = trimmed ? `${trimmed}…` : \"…\";\n\treturn `${snippet}\\n${note}`;\n}\n\nexport function formatTurnGrepOutput(\n\tmatches: GrepMatch[],\n\tmaxChars: number = MAX_GREP_OUTPUT_CHARS_PER_TURN\n): string {\n\tif (!matches || matches.length === 0) {\n\t\treturn \"No new matches found.\";\n\t}\n\n\tconst matchesByFile = new Map<string, GrepMatch[]>();\n\tfor (const match of matches) {\n\t\tif (!matchesByFile.has(match.path)) {\n\t\t\tmatchesByFile.set(match.path, []);\n\t\t}\n\t\tmatchesByFile.get(match.path)!.push(match);\n\t}\n\n\tconst lines: string[] = [];\n\tconst sortedPaths = Array.from(matchesByFile.keys()).sort();\n\tsortedPaths.forEach((filePath, index) => {\n\t\tif (index > 0) {\n\t\t\tlines.push(\"\");\n\t\t}\n\t\tlines.push(filePath);\n\t\tconst sortedMatches = matchesByFile\n\t\t\t.get(filePath)!\n\t\t\t.slice()\n\t\t\t.sort((a, b) => a.lineNumber - b.lineNumber);\n\t\tfor (const match of sortedMatches) {\n\t\t\tlines.push(`${match.lineNumber}:${match.content}`);\n\t\t}\n\t});\n\n\treturn truncateOutput(lines.join(\"\\n\"), maxChars);\n}\n\n\n","import type { FinishFileSpec } from '../agent/types.js';\nimport fs from 'fs/promises';\n\nexport function normalizeFinishFiles(files: FinishFileSpec[]): FinishFileSpec[] {\n return files.map((f) => {\n const merged = mergeRanges(f.lines);\n return { path: f.path, lines: merged };\n });\n}\n\nexport async function readFinishFiles(\n repoRoot: string,\n files: FinishFileSpec[],\n reader: (path: string, start: number, end: number) => Promise<string[]>\n): Promise<{ path: string; ranges: Array<[number, number]>; content: string }[]> {\n const out: { path: string; ranges: Array<[number, number]>; content: string }[] = [];\n for (const f of files) {\n const ranges = mergeRanges(f.lines);\n const chunks: string[] = [];\n for (const [s, e] of ranges) {\n const lines = await reader(f.path, s, e);\n chunks.push(lines.join('\\n'));\n }\n out.push({ path: f.path, ranges, content: chunks.join('\\n') });\n }\n return out;\n}\n\nfunction mergeRanges(ranges: Array<[number, number]>): Array<[number, number]> {\n if (!ranges.length) return [];\n const sorted = [...ranges].sort((a, b) => a[0] - b[0]);\n const merged: Array<[number, number]> = [];\n let [cs, ce] = sorted[0];\n for (let i = 1; i < sorted.length; i++) {\n const [s, e] = sorted[i];\n if (s <= ce + 1) {\n ce = Math.max(ce, e);\n } else {\n merged.push([cs, ce]);\n cs = s;\n ce = e;\n }\n }\n merged.push([cs, ce]);\n return merged;\n}\n\n\n","import { AGENT_CONFIG, DEFAULT_MODEL } from './config.js';\nimport { getSystemPrompt } from './prompt.js';\nimport type { AgentRunResult, ChatMessage, SessionConfig, ToolCall, AgentFinish } from './types.js';\nimport { LLMResponseParser, LLMResponseParseError } from './parser.js';\nimport type { WarpGrepProvider } from '../providers/types.js';\nimport { toolRead } from '../tools/read.js';\nimport { toolAnalyse } from '../tools/analyse.js';\nimport { fetchWithRetry, withTimeout } from '../../utils/resilience.js';\nimport { formatAgentToolOutput } from './formatter.js';\nimport { GrepState, parseAndFilterGrepOutput, formatTurnGrepOutput } from './grep_helpers.js';\nimport { readFinishFiles } from '../tools/finish.js';\nimport path from 'path';\nimport fs from 'fs/promises';\n\ntype EventName =\n | 'initial_state'\n | 'round_start'\n | 'round_end'\n | 'finish'\n | 'error';\n\nexport type EventCallback = (name: EventName, payload: Record<string, unknown>) => void;\n\nconst parser = new LLMResponseParser();\n\nasync function buildInitialState(repoRoot: string, query: string): Promise<string> {\n // Summarize top-level directories and file counts\n try {\n const entries = await fs.readdir(repoRoot, { withFileTypes: true });\n const dirs = entries.filter(e => e.isDirectory()).map(d => d.name).slice(0, 50);\n const files = entries.filter(e => e.isFile()).map(f => f.name).slice(0, 50);\n const parts = [\n `<repo_root>${repoRoot}</repo_root>`,\n `<top_dirs>${dirs.join(', ')}</top_dirs>`,\n `<top_files>${files.join(', ')}</top_files>`,\n ];\n return parts.join('\\n');\n } catch {\n return `<repo_root>${repoRoot}</repo_root>`;\n }\n}\n\nfunction formatAssistantToolBlock(name: string, args: Record<string, unknown>, payload: string, isError = false): string {\n const argStr = Object.entries(args)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n .join(' ');\n const prefix = isError ? 'error' : 'result';\n return `<${prefix} name=\"${name}\" ${argStr}>\\n${payload}\\n</${prefix}>`;\n}\n\nasync function callModel(messages: ChatMessage[], model: string, apiKey?: string): Promise<string> {\n const api = 'https://api.morphllm.com/v1/chat/completions';\n const fetchPromise = fetchWithRetry(\n api,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey || process.env.MORPH_API_KEY || ''}`,\n },\n body: JSON.stringify({\n model,\n temperature: 0.0,\n max_tokens: 1024,\n messages,\n }),\n },\n {}\n );\n const resp = await withTimeout(fetchPromise, AGENT_CONFIG.TIMEOUT_MS, 'morph-warp-grep request timed out');\n if (!resp.ok) {\n const t = await resp.text();\n throw new Error(`morph-warp-grep error ${resp.status}: ${t}`);\n }\n const data = await resp.json();\n const content = data?.choices?.[0]?.message?.content;\n if (!content || typeof content !== 'string') {\n throw new Error('Invalid response from model');\n }\n return content;\n}\n\nexport async function runWarpGrep(config: SessionConfig & { provider: WarpGrepProvider }): Promise<AgentRunResult> {\n const repoRoot = path.resolve(config.repoRoot || process.cwd());\n const messages: ChatMessage[] = [];\n\n // system\n const systemMessage = { role: 'system' as const, content: getSystemPrompt() };\n messages.push(systemMessage);\n // user query\n const queryContent = `<query>${config.query}</query>`;\n messages.push({ role: 'user', content: queryContent });\n // initial state\n const initialState = await buildInitialState(repoRoot, config.query);\n messages.push({ role: 'user', content: initialState });\n\n const maxRounds = AGENT_CONFIG.MAX_ROUNDS;\n const model = config.model || DEFAULT_MODEL;\n const provider = config.provider;\n const errors: Array<{ message: string }> = [];\n const grepState = new GrepState();\n\n let finishMeta: AgentFinish | undefined;\n let terminationReason: AgentRunResult['terminationReason'] = 'terminated';\n\n for (let round = 1; round <= maxRounds; round += 1) {\n // call model\n const assistantContent = await callModel(messages, model, config.apiKey).catch((e: unknown) => {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n return '';\n });\n if (!assistantContent) break;\n messages.push({ role: 'assistant', content: assistantContent });\n\n // parse tool calls\n let toolCalls: ToolCall[] = [];\n try {\n toolCalls = parser.parse(assistantContent);\n } catch (e) {\n errors.push({ message: e instanceof Error ? e.message : String(e) });\n terminationReason = 'terminated';\n break;\n }\n if (toolCalls.length === 0) {\n errors.push({ message: 'No tool calls produced by the model.' });\n terminationReason = 'terminated';\n break;\n }\n\n const finishCalls = toolCalls.filter(c => c.name === 'finish');\n const grepCalls = toolCalls.filter(c => c.name === 'grep');\n const analyseCalls = toolCalls.filter(c => c.name === 'analyse');\n const readCalls = toolCalls.filter(c => c.name === 'read');\n\n const formatted: string[] = [];\n\n // Execute non-grep tools in parallel\n const otherPromises: Array<Promise<string>> = [];\n for (const c of analyseCalls) {\n const args = (c.arguments ?? {}) as { path: string; pattern?: string | null };\n otherPromises.push(\n toolAnalyse(provider, args).then(\n p => formatAgentToolOutput('analyse', args, p, { isError: false }),\n err => formatAgentToolOutput('analyse', args, String(err), { isError: true })\n )\n );\n }\n for (const c of readCalls) {\n const args = (c.arguments ?? {}) as { path: string; start?: number; end?: number };\n otherPromises.push(\n toolRead(provider, args).then(\n p => formatAgentToolOutput('read', args, p, { isError: false }),\n err => formatAgentToolOutput('read', args, String(err), { isError: true })\n )\n );\n }\n const otherResults = await Promise.all(otherPromises);\n formatted.push(...otherResults);\n\n // Execute grep calls sequentially like MCP runner to keep outputs compact\n for (const c of grepCalls) {\n const args = (c.arguments ?? {}) as { pattern: string; path: string };\n try {\n const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });\n const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join('\\n') : '';\n const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);\n let formattedPayload = formatTurnGrepOutput(newMatches);\n if (formattedPayload === \"No new matches found.\") {\n formattedPayload = \"no new matches\";\n }\n formatted.push(formatAgentToolOutput('grep', args, formattedPayload, { isError: false }));\n } catch (err) {\n formatted.push(formatAgentToolOutput('grep', args, String(err), { isError: true }));\n }\n }\n\n if (formatted.length > 0) {\n messages.push({ role: 'user', content: formatted.join('\\n') });\n }\n\n if (finishCalls.length) {\n const fc = finishCalls[0];\n const files = ((fc.arguments as any)?.files ?? []) as AgentFinish['files'];\n finishMeta = { files };\n terminationReason = 'completed';\n break;\n }\n }\n\n if (terminationReason !== 'completed' || !finishMeta) {\n return { terminationReason, messages, errors };\n }\n\n // Build finish payload\n const parts: string[] = ['Relevant context found:'];\n for (const f of finishMeta.files) {\n const ranges = f.lines.map(([s, e]) => `${s}-${e}`).join(', ');\n parts.push(`- ${f.path}: ${ranges}`);\n }\n const payload = parts.join('\\n');\n\n // Resolve file contents for returned ranges\n const resolved = await readFinishFiles(\n repoRoot,\n finishMeta.files,\n async (p: string, s: number, e: number) => {\n const rr = await provider.read({ path: p, start: s, end: e });\n // rr.lines are \"line|content\" → strip the \"line|\" prefix\n return rr.lines.map(l => {\n const idx = l.indexOf('|');\n return idx >= 0 ? l.slice(idx + 1) : l;\n });\n }\n );\n\n return {\n terminationReason: 'completed',\n messages,\n finish: { payload, metadata: finishMeta, resolved },\n };\n}\n\n\n","import fs from 'fs/promises';\nimport fssync from 'fs';\nimport path from 'path';\nimport { runRipgrep } from '../utils/ripgrep.js';\nimport { ensureWithinRepo, resolveUnderRepo, toRepoRelative, isSymlink, isTextualFile } from '../utils/paths.js';\nimport type { WarpGrepProvider, GrepResult, ReadResult, AnalyseEntry } from './types.js';\nimport { readAllLines } from '../utils/files.js';\nimport { DEFAULT_EXCLUDES } from '../agent/config.js';\n\nexport class LocalRipgrepProvider implements WarpGrepProvider {\n constructor(private readonly repoRoot: string, private readonly excludes: string[] = DEFAULT_EXCLUDES) {}\n\n async grep(params: { pattern: string; path: string }): Promise<GrepResult> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat) return { lines: [] };\n const targetArg = abs === path.resolve(this.repoRoot) ? '.' : toRepoRelative(this.repoRoot, abs);\n const args = [\n '--no-config',\n '--no-heading',\n '--with-filename',\n '--line-number',\n '--color=never',\n '--trim',\n '--max-columns=400',\n ...this.excludes.flatMap((e) => ['-g', `!${e}`]),\n params.pattern,\n targetArg || '.',\n ];\n const res = await runRipgrep(args, { cwd: this.repoRoot });\n if (res.exitCode === -1) {\n throw new Error(res.stderr || 'ripgrep (rg) execution failed.');\n }\n if (res.exitCode !== 0 && res.exitCode !== 1) {\n throw new Error(res.stderr || `ripgrep failed with code ${res.exitCode}`);\n }\n const lines = (res.stdout || '')\n .trim()\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0);\n return { lines };\n }\n\n async glob(params: { pattern: string; path: string }): Promise<{ files: string[] }> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const targetArg = abs === path.resolve(this.repoRoot) ? '.' : toRepoRelative(this.repoRoot, abs);\n const args = [\n '--no-config',\n '--files',\n '-g',\n params.pattern,\n ...this.excludes.flatMap((e) => ['-g', `!${e}`]),\n targetArg || '.',\n ];\n const res = await runRipgrep(args, { cwd: this.repoRoot });\n if (res.exitCode === -1) {\n throw new Error(res.stderr || 'ripgrep (rg) execution failed.');\n }\n const files = (res.stdout || '')\n .trim()\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0);\n return { files };\n }\n\n async read(params: { path: string; start?: number; end?: number }): Promise<ReadResult> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat || !stat.isFile()) {\n throw new Error(`Path is not a file: ${params.path}`);\n }\n if (isSymlink(abs)) {\n throw new Error(`Refusing to read symlink: ${params.path}`);\n }\n if (!isTextualFile(abs)) {\n throw new Error(`Non-text or too-large file: ${params.path}`);\n }\n const lines = await readAllLines(abs);\n const total = lines.length;\n const s = params.start ?? 1;\n const e = Math.min(params.end ?? total, total);\n if (s > total && total > 0) {\n throw new Error(`start ${s} exceeds file length (${total})`);\n }\n const out: string[] = [];\n for (let i = s; i <= e; i += 1) {\n const content = lines[i - 1] ?? '';\n out.push(`${i}|${content}`);\n }\n return { lines: out };\n }\n\n async analyse(params: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }): Promise<AnalyseEntry[]> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat || !stat.isDirectory()) {\n return [];\n }\n const maxResults = params.maxResults ?? 100;\n const maxDepth = params.maxDepth ?? 2;\n const regex = params.pattern ? new RegExp(params.pattern) : null;\n\n const results: AnalyseEntry[] = [];\n async function walk(dir: string, depth: number) {\n if (depth > maxDepth || results.length >= maxResults) return;\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n const rel = toRepoRelative(abs, full).replace(/^[.][/\\\\]?/, '');\n if (DEFAULT_EXCLUDES.some((ex) => rel.split(path.sep).includes(ex))) continue;\n if (regex && !regex.test(entry.name)) continue;\n if (results.length >= maxResults) break;\n results.push({\n name: entry.name,\n path: toRepoRelative(path.resolve(''), full), // relative display\n type: entry.isDirectory() ? 'dir' : 'file',\n depth,\n });\n if (entry.isDirectory()) {\n await walk(full, depth + 1);\n }\n }\n }\n await walk(abs, 0);\n return results;\n }\n}\n\n\n","import { spawn } from 'child_process';\n\nexport type ExecResult = { stdout: string; stderr: string; exitCode: number };\n\nexport function runRipgrep(args: string[], opts?: { cwd?: string; env?: NodeJS.ProcessEnv }): Promise<ExecResult> {\n return new Promise((resolve) => {\n const child = spawn('rg', args, {\n cwd: opts?.cwd,\n env: { ...process.env, ...(opts?.env || {}) },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (d) => (stdout += d.toString()));\n child.stderr.on('data', (d) => (stderr += d.toString()));\n child.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: typeof code === 'number' ? code : -1 });\n });\n child.on('error', () => {\n resolve({ stdout: '', stderr: 'Failed to spawn ripgrep (rg). Ensure it is installed.', exitCode: -1 });\n });\n });\n}\n\n\n","import fs from 'fs';\nimport path from 'path';\n\nexport function resolveUnderRepo(repoRoot: string, targetPath: string): string {\n const absRoot = path.resolve(repoRoot);\n const resolved = path.resolve(absRoot, targetPath);\n ensureWithinRepo(absRoot, resolved);\n return resolved;\n}\n\nexport function ensureWithinRepo(repoRoot: string, absTarget: string): void {\n const rel = path.relative(path.resolve(repoRoot), path.resolve(absTarget));\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw new Error(`Path outside repository root: ${absTarget}`);\n }\n}\n\nexport function toRepoRelative(repoRoot: string, absPath: string): string {\n return path.relative(path.resolve(repoRoot), path.resolve(absPath));\n}\n\nexport function isSymlink(p: string): boolean {\n try {\n const st = fs.lstatSync(p);\n return st.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nexport function isTextualFile(filePath: string, maxBytes = 2_000_000): boolean {\n try {\n const st = fs.statSync(filePath);\n if (!st.isFile()) return false;\n if (st.size > maxBytes) return false;\n const fd = fs.openSync(filePath, 'r');\n const buf = Buffer.alloc(512);\n const read = fs.readSync(fd, buf, 0, buf.length, 0);\n fs.closeSync(fd);\n for (let i = 0; i < read; i++) {\n const c = buf[i];\n if (c === 0) return false; // binary heuristic\n }\n return true;\n } catch {\n return false;\n }\n}\n\n\n","import fs from 'fs/promises';\n\nexport async function readAllLines(filePath: string): Promise<string[]> {\n const content = await fs.readFile(filePath, 'utf8');\n // Preserve newlines; split keeping consistency\n return content.split(/\\r?\\n/);\n}\n\n\n"],"mappings":"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","names":["path","path","path","fs","path","import_promises","import_path","import_path","path","fs","import_promises","fs","fs","path"]}
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  createMorphWarpGrepTool
3
- } from "../../chunk-JZGU5UC6.js";
4
- import "../../chunk-EAA7D24N.js";
5
- import "../../chunk-Z2FBMSNE.js";
6
- import "../../chunk-HKZB23U7.js";
3
+ } from "../../chunk-ZKIVLLZY.js";
7
4
  import "../../chunk-UYBIKZPM.js";
8
5
  import "../../chunk-G2RSY56Q.js";
9
6
  import "../../chunk-SMGZ6A64.js";
10
7
  import "../../chunk-RSLIOCOE.js";
8
+ import "../../chunk-PRIYMEI6.js";
9
+ import "../../chunk-HKZB23U7.js";
11
10
  import "../../chunk-73RQWOQC.js";
12
11
  import "../../chunk-EK7OQPWD.js";
12
+ import "../../chunk-Z2FBMSNE.js";
13
13
  import "../../chunk-AFEPUNAO.js";
14
14
  import "../../chunk-TICMYDII.js";
15
15
  import "../../chunk-NDZO5IPV.js";
@@ -1012,7 +1012,7 @@ function createMorphWarpGrepTool(config) {
1012
1012
  type: "function",
1013
1013
  function: {
1014
1014
  name: "morph-warp-grep",
1015
- description: "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1015
+ description: config.description ?? "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1016
1016
  parameters: {
1017
1017
  type: "object",
1018
1018
  properties: {
@@ -1055,7 +1055,7 @@ var INPUT_SCHEMA2 = import_zod2.z.object({
1055
1055
  function createMorphWarpGrepTool2(config) {
1056
1056
  const tool2 = {
1057
1057
  name: "morph-warp-grep",
1058
- description: "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1058
+ description: config.description ?? "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1059
1059
  input_schema: {
1060
1060
  type: "object",
1061
1061
  properties: {
@@ -1097,7 +1097,7 @@ function createMorphWarpGrepTool3(config) {
1097
1097
  query: import_zod3.z.string().describe("Free-form repository question")
1098
1098
  });
1099
1099
  return (0, import_ai.tool)({
1100
- description: "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1100
+ description: config.description ?? "A fast and accurate tool that can search for all relevant context in a codebase. You must use this tool to save time and avoid context pollution.",
1101
1101
  inputSchema: schema,
1102
1102
  execute: async (params) => {
1103
1103
  const provider = config.provider ?? new LocalRipgrepProvider(config.repoRoot, config.excludes);