From c4b99ddb23937279181c7a6000bfddf74dfc9594 Mon Sep 17 00:00:00 2001 From: abdulrehmann231 Date: Mon, 2 Mar 2026 17:27:32 +0500 Subject: [PATCH 1/7] fix: empty file while applying diff view --- ai/src/utils/prompt-builder.ts | 2 +- package-lock.json | 10 ++++ .../project/chat/components/chat-input.tsx | 3 +- .../components/generated-files-preview.tsx | 49 +++++++++++++++---- web/components/project/chat/index.tsx | 2 + web/components/project/chat/lib/file-utils.ts | 27 ++++++---- web/components/project/chat/lib/types.ts | 4 ++ web/components/project/chat/lib/utils.ts | 17 ++++--- .../project/hooks/lib/merge-resolver.ts | 5 +- .../project/hooks/useAIFileActions.ts | 21 +++++++- web/components/project/hooks/useCodeDiffer.ts | 12 ++++- .../layout/hooks/useChatPanelHandlers.ts | 8 +++ web/lib/utils.ts | 13 ++--- web/package.json | 5 +- 14 files changed, 136 insertions(+), 42 deletions(-) diff --git a/ai/src/utils/prompt-builder.ts b/ai/src/utils/prompt-builder.ts index f0f4201..fe16f0e 100644 --- a/ai/src/utils/prompt-builder.ts +++ b/ai/src/utils/prompt-builder.ts @@ -51,7 +51,7 @@ MANDATORY Rules for code changes: - Format using triple backticks with the appropriate language identifier - CRITICAL: Always specify the complete file path relative to the project root - For new files, add "(new file)" after the path -- Before any code block, include a line like "File: /path/to/file.ext" to indicate which file the code belongs to +- Before every code block, include a line that shows FULL Path to the file like "File: /path/to/file.ext" to indicate which file the code belongs to - Keep responses brief and to the point - Use aider diff format: \`<<<<<<< SEARCH\` / \`=======\` / \`>>>>>>> REPLACE\` blocks inside code blocks - If multiple search/replace blocks are for the same file, group them in the same code block diff --git a/package-lock.json b/package-lock.json index 2658efa..883ce6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7581,6 +7581,15 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "license": "MIT" }, + "node_modules/jsonrepair": { + "version": "3.13.2", + "resolved": "https://registry.npmjs.org/jsonrepair/-/jsonrepair-3.13.2.tgz", + "integrity": "sha512-Leuly0nbM4R+S5SVJk3VHfw1oxnlEK9KygdZvfUtEtTawNDyzB4qa1xWTmFt1aeoA7sXZkVTRuIixJ8bAvqVUg==", + "license": "ISC", + "bin": { + "jsonrepair": "bin/cli.js" + } + }, "node_modules/jszip": { "version": "3.10.1", "dev": true, @@ -12812,6 +12821,7 @@ "framer-motion": "^11.2.3", "geist": "^1.3.0", "hono": "^4.7.11", + "jsonrepair": "^3.13.2", "lucide-react": "^0.511.0", "minimatch": "^3.1.2", "monaco-editor": "^0.52.2", diff --git a/web/components/project/chat/components/chat-input.tsx b/web/components/project/chat/components/chat-input.tsx index 7396828..dbce79e 100644 --- a/web/components/project/chat/components/chat-input.tsx +++ b/web/components/project/chat/components/chat-input.tsx @@ -624,7 +624,7 @@ function ChatInputContextMenu() { {files.map((file) => { const imgSrc = `/icons/${getIconForFile(file.name)}` const isSelected = codeContextTabs.some( - (tab) => tab.name === file.name, + (tab) => (tab.path ?? tab.name) === file.id, ) return ( ({ files: [], sourceKey: null }) React.useEffect(() => { - setExtracted(extractFilesFromMessages(messages)) + const next = extractFilesFromMessages(messages) + setExtracted((prev) => { + if (prev.sourceKey !== next.sourceKey) return next + if (prev.files.length !== next.files.length) return next + + for (let i = 0; i < prev.files.length; i++) { + const a = prev.files[i] + const b = next.files[i] + if ( + a.path !== b.path || + (a.code ?? "") !== (b.code ?? "") || + !!a.isNew !== !!b.isNew + ) { + return next + } + } + + return prev + }) }, [messages]) const providedFiles = files ?? [] @@ -156,12 +174,15 @@ export function GeneratedFilesPreview({ React.useEffect(() => { setMergeStatuses((prev) => { - const next: Record = {} + let changed = false + const next: Record = { ...prev } generatedFiles.forEach((file) => { - // Only set to idle if it doesn't exist, preserve existing statuses - next[file.path] = prev[file.path] ?? { status: "idle" as const } + if (!next[file.path]) { + next[file.path] = { status: "idle" as const } + changed = true + } }) - return next + return changed ? next : prev }) }, [generatedFiles]) @@ -177,7 +198,8 @@ export function GeneratedFilesPreview({ const currentPrecomputeMerge = precomputeMergeRef.current // Collect all files to process first, then start ALL merges in parallel - const filesToProcess: Array<{ key: string; code: string }> = [] + const filesToProcess: Array<{ key: string; code: string; isNew?: boolean }> = + [] generatedFilesRef.current.forEach((file) => { if (!file.code) return @@ -213,14 +235,14 @@ export function GeneratedFilesPreview({ // Mark as processed immediately to prevent duplicates processedFilesRef.current.add(key) - filesToProcess.push({ key, code: file.code }) + filesToProcess.push({ key, code: file.code, isNew: file.isNew }) }) // Only proceed if there are files to process if (filesToProcess.length === 0) return // Start ALL merges in parallel (not sequential) - filesToProcess.forEach(({ key, code }) => { + filesToProcess.forEach(({ key, code, isNew }) => { // Set pending status immediately setMergeStatuses((prev) => ({ ...prev, @@ -230,6 +252,7 @@ export function GeneratedFilesPreview({ const mergePromise = currentPrecomputeMerge({ filePath: key, code: code, + isNew, }) mergeJobsRef.current.set(key, mergePromise) @@ -278,6 +301,10 @@ export function GeneratedFilesPreview({ if (status?.status === "ready" && status.result && file.code) { // Always pass targetFilePath to onApplyCode so it can open/activate if needed autoPreviewedRef.current.add(key) + console.log("onApplyCode", file.code, undefined, { + targetFilePath: key, + getMergeStatus: (path: string) => mergeStatusRef.current[path], + }) onApplyCode(file.code, undefined, { targetFilePath: key, getMergeStatus: (path) => mergeStatusRef.current[path], @@ -360,7 +387,11 @@ export function GeneratedFilesPreview({ let job = mergeJobsRef.current.get(key) if (!job && file.code && precomputeMerge) { - job = precomputeMerge({ filePath: key, code: file.code }) + job = precomputeMerge({ + filePath: key, + code: file.code, + isNew: file.isNew, + }) mergeJobsRef.current.set(key, job) setMergeStatuses((prev) => ({ ...prev, diff --git a/web/components/project/chat/index.tsx b/web/components/project/chat/index.tsx index f560de2..d30eb2e 100644 --- a/web/components/project/chat/index.tsx +++ b/web/components/project/chat/index.tsx @@ -166,6 +166,7 @@ function MainChatContent({ const wrappedOnApplyCode = React.useCallback( async (code: string, language?: string): Promise => { + console.log("wrappedOnApplyCode", code, language) if (onApplyCode) { await onApplyCode(code, language, { mergeStatuses, @@ -323,6 +324,7 @@ function ChatContexts() { start: selection.startLineNumber, end: selection.endLineNumber, }, + path: activeTab.id, }) } }, diff --git a/web/components/project/chat/lib/file-utils.ts b/web/components/project/chat/lib/file-utils.ts index 7e0dbba..9f7af9a 100644 --- a/web/components/project/chat/lib/file-utils.ts +++ b/web/components/project/chat/lib/file-utils.ts @@ -8,6 +8,7 @@ export type GeneratedFile = { path: string additions: number code?: string + isNew?: boolean } const HARDCODED_ADDITIONS = 3 @@ -25,10 +26,11 @@ export function stripCodeFence(codeBlock: string) { export function extractFilesFromMarkdown(markdown: string): { path: string code?: string + isNew?: boolean }[] { if (!markdown) return [] - const files: Array<{ path: string; code?: string }> = [] + const files: Array<{ path: string; code?: string; isNew?: boolean }> = [] const codeBlockFileMap = new Map() const codeBlockRegex = /```[\s\S]*?```/g let match @@ -41,16 +43,20 @@ export function extractFilesFromMarkdown(markdown: string): { // Pass the index of where this code block starts in the markdown const codeBlockIndex = match.index - const filePath = extractFilePathFromCode( + const rawFilePath = extractFilePathFromCode( code, markdown, codeBlockFileMap, codeBlockIndex, previousCodeBlockEnd, ) - if (filePath) { - const normalized = normalizePath(filePath) - files.push({ path: normalized, code }) + console.log("filePath", rawFilePath) + if (rawFilePath) { + const isNew = /\(new file\)/i.test(rawFilePath) + const cleanPath = rawFilePath.replace(/\s*\(new file\)\s*$/i, "").trim() + const normalized = normalizePath(cleanPath) + console.log("normalized file path", normalized) + files.push({ path: normalized, code, isNew }) } // Update previous code block end position @@ -62,14 +68,14 @@ export function extractFilesFromMarkdown(markdown: string): { const seenPaths = new Set() let fallbackMatch while ((fallbackMatch = filePattern.exec(markdown)) !== null) { - const cleanPath = fallbackMatch[1] - .replace(/\s*\(new file\)\s*$/i, "") - .trim() + const rawPath = fallbackMatch[1] + const isNew = /\(new file\)/i.test(rawPath) + const cleanPath = rawPath.replace(/\s*\(new file\)\s*$/i, "").trim() if (cleanPath) { const normalized = normalizePath(cleanPath) if (!seenPaths.has(normalized)) { seenPaths.add(normalized) - files.push({ path: normalized }) + files.push({ path: normalized, isNew }) } } } @@ -93,12 +99,13 @@ export function extractFilesFromMessages(messages: Message[]): { if (!latestAssistant?.content) return { files: [], sourceKey: null } const files = extractFilesFromMarkdown(latestAssistant.content).map( - ({ path, code }) => ({ + ({ path, code, isNew }) => ({ id: path, path, name: getDisplayName(path), code, additions: HARDCODED_ADDITIONS, + isNew, }), ) diff --git a/web/components/project/chat/lib/types.ts b/web/components/project/chat/lib/types.ts index d47d271..648a116 100644 --- a/web/components/project/chat/lib/types.ts +++ b/web/components/project/chat/lib/types.ts @@ -14,6 +14,7 @@ export type ContextTab = type: "file" | "image" name: string content: string + path?: string } | { id: string @@ -21,12 +22,14 @@ export type ContextTab = name: string content?: string lineRange?: { start: number; end: number } + path?: string } | { id: string type: "text" name: string content: string + path?: string } export type FileMergeResult = { @@ -37,6 +40,7 @@ export type FileMergeResult = { export type PrecomputeMergeArgs = { filePath: string code: string + isNew?: boolean } export type ApplyMergedFileArgs = FileMergeResult & { diff --git a/web/components/project/chat/lib/utils.ts b/web/components/project/chat/lib/utils.ts index 7bb8310..657b245 100644 --- a/web/components/project/chat/lib/utils.ts +++ b/web/components/project/chat/lib/utils.ts @@ -62,14 +62,15 @@ const processCodeContext = async ({ drafts: EditorSlice["drafts"] }): Promise => { const lineInfo = formatLineInfo(tab.lineRange) + const displayPath = tab.path ?? tab.name const language = processFileType(tab.name) if (tab.content) { - return `Code from ${tab.name}${lineInfo}:\n\`\`\`${language}\n${tab.content}\n\`\`\`` + return `Code from ${displayPath}${lineInfo}:\n\`\`\`${language}\n${tab.content}\n\`\`\`` } const draftContent = drafts[tab.id] if (draftContent !== undefined) { - return `Code from ${tab.name}${lineInfo}:\n\`\`\`${language}\n${draftContent}\n\`\`\`` + return `Code from ${displayPath}${lineInfo}:\n\`\`\`${language}\n${draftContent}\n\`\`\`` } try { @@ -79,10 +80,10 @@ const processCodeContext = async ({ projectId: projectId, }), ) - return `Code from ${tab.name}${lineInfo}:\n\`\`\`${language}\n${data.data}\n\`\`\`` + return `Code from ${displayPath}${lineInfo}:\n\`\`\`${language}\n${data.data}\n\`\`\`` } catch (error) { - console.error(`Failed to fetch content for ${tab.name}:`, error) - return `Code from ${tab.name}${lineInfo}: [Failed to load content]` + console.error(`Failed to fetch content for ${displayPath}:`, error) + return `Code from ${displayPath}${lineInfo}: [Failed to load content]` } } @@ -133,9 +134,11 @@ const getCombinedContext = async ({ const cleanContent = tab.content .replace(/^```[\w-]*\n/, "") .replace(/\n```$/, "") - const fileExt = tab.name.split(".").pop() || "txt" + const displayPath = tab.path ?? tab.name + const fileNameForExt = displayPath.split("/").pop() || displayPath + const fileExt = fileNameForExt.split(".").pop() || "txt" contextMessages.push( - `File ${tab.name}:\n\`\`\`${fileExt}\n${cleanContent}\n\`\`\``, + `File ${displayPath}:\n\`\`\`${fileExt}\n${cleanContent}\n\`\`\``, ) }) diff --git a/web/components/project/hooks/lib/merge-resolver.ts b/web/components/project/hooks/lib/merge-resolver.ts index d2c7085..be7603d 100644 --- a/web/components/project/hooks/lib/merge-resolver.ts +++ b/web/components/project/hooks/lib/merge-resolver.ts @@ -1,5 +1,5 @@ -import { apiClient } from "@/server/client" -import { FileMergeResult } from "../../chat/lib/types" +import { apiClient } from "@/server/client"; +import { FileMergeResult } from "../../chat/lib/types"; interface MergeStatusAccessor { getMergeStatus?: ( @@ -47,6 +47,7 @@ export async function resolveMergeResult( // 3. Compute fresh merge const originalCode = await getCurrentFileContent(normalizedPath) + console.log("originalCode", originalCode) const res = await apiClient.ai["merge-code"].$post({ json: { partialCode: code, diff --git a/web/components/project/hooks/useAIFileActions.ts b/web/components/project/hooks/useAIFileActions.ts index 39c5abf..b856540 100644 --- a/web/components/project/hooks/useAIFileActions.ts +++ b/web/components/project/hooks/useAIFileActions.ts @@ -1,6 +1,6 @@ -import { apiClient } from "@/server/client" import { fileRouter } from "@/lib/api" import { DiffSession, TTab } from "@/lib/types" +import { apiClient } from "@/server/client" import { useAppStore } from "@/store/context" import * as monaco from "monaco-editor" import { useCallback, useEffect, useRef, useState } from "react" @@ -131,6 +131,8 @@ export function useAIFileActions({ // First, check if there's a draft (unsaved changes) const draftContent = getDraft(normalizedPath) + console.log("normalizedPath", normalizedPath) + console.log("draftContent", draftContent) if (draftContent !== undefined) { return draftContent } @@ -142,6 +144,7 @@ export function useAIFileActions({ fileId: normalizedPath, projectId, }) + console.log("response", response) return response?.data ?? "" } catch (error) { console.warn("Failed to fetch current file content:", error) @@ -159,10 +162,19 @@ export function useAIFileActions({ async ({ filePath, code, + isNew, }: PrecomputeMergeArgs): Promise => { const normalizedPath = normalizePath(filePath) - const originalCode = await getCurrentFileContent(normalizedPath) + const originalCode = isNew + ? "" + : await getCurrentFileContent(normalizedPath) + + if (!isNew && originalCode === "") { + throw new Error( + `Failed to load original content for ${normalizedPath}. The file may not exist or the path may be incorrect.`, + ) + } try { const res = await apiClient.ai["merge-code"].$post({ @@ -262,6 +274,7 @@ export function useAIFileActions({ // Use target path if provided, otherwise use target tab const targetPath = normalizedTargetPath || normalizePath(targetTab.id) try { + console.log("code", code) const mergeResult = await resolveMergeResult( targetPath, code, @@ -271,6 +284,9 @@ export function useAIFileActions({ options, ) + console.log("mergeResult", mergeResult) + console.log("targetTab", targetTab) + // Apply to Editor if (mergeResult) { const applied = handleApplyCodeWithDecorations( @@ -338,6 +354,7 @@ export function useAIFileActions({ const pending = pendingDiffsQueueRef.current.get(normalizedPath) if (pending) { pendingDiffsQueueRef.current.delete(normalizedPath) + console.log("pending", pending) handleApplyCodeFromChat(pending.code, pending.language, pending.options) } }, [ diff --git a/web/components/project/hooks/useCodeDiffer.ts b/web/components/project/hooks/useCodeDiffer.ts index c691533..aa8f9d1 100644 --- a/web/components/project/hooks/useCodeDiffer.ts +++ b/web/components/project/hooks/useCodeDiffer.ts @@ -147,9 +147,15 @@ export function useCodeDiffer({ originalCode: string, ): monaco.editor.IEditorDecorationsCollection | null => { const currentEditorRef = editorRefRef.current - if (!currentEditorRef) return null + if (!currentEditorRef) { + console.log("no editorRef") + return null + } const model = currentEditorRef.getModel() - if (!model) return null + if (!model) { + console.log("no model") + return null + } setModelMeta(model, { originalContent: originalCode, @@ -165,6 +171,8 @@ export function useCodeDiffer({ ignoreWhitespace: false, }) + console.log("diffResult", diffResult) + model.setValue(diffResult.combinedLines.join("\n")) model.setEOL(eolSequence) diff --git a/web/components/project/layout/hooks/useChatPanelHandlers.ts b/web/components/project/layout/hooks/useChatPanelHandlers.ts index 1c7c8e8..5485951 100644 --- a/web/components/project/layout/hooks/useChatPanelHandlers.ts +++ b/web/components/project/layout/hooks/useChatPanelHandlers.ts @@ -80,8 +80,15 @@ export function useChatPanelHandlers() { if (!fileIdToUse) { return null } + console.log("fileIdToUse", fileIdToUse) const handlers = getHandlers(fileIdToUse) + if (handlers) { + console.log("handlers", handlers) + } + else { + console.log("no handlers") + } if (handlers?.handleApplyCode) { return handlers.handleApplyCode(mergedCode, originalCode) } @@ -212,6 +219,7 @@ export function useChatPanelHandlers() { language?: string, options?: Parameters[2], ) => { + console.log("onApplyCode", code, language, options) return handleApplyCodeFromChat(code, language, options) }, [handleApplyCodeFromChat, activeFileId, activeTab, activeHandlers], diff --git a/web/lib/utils.ts b/web/lib/utils.ts index 4b6fa31..cd735ec 100644 --- a/web/lib/utils.ts +++ b/web/lib/utils.ts @@ -27,8 +27,8 @@ export function extractFilePathFromCode( const matchInCode = code.match(filePatternInCode) if (matchInCode) { const rawPath = matchInCode[1].trim() - // Strip "(new file)" marker from the path - return rawPath.replace(/\s*\(new file\)\s*$/i, "").trim() + console.log("cleanPath", rawPath) + return rawPath } // Second, try to find file path pattern in the code block @@ -36,7 +36,9 @@ export function extractFilePathFromCode( /(?:^|\n)([a-zA-Z0-9._\/-]+\.(?:html|js|ts|tsx|jsx|css|scss|sass|less|json|md|txt|py|java|cpp|c|h|php|rb|go|rs|swift|kt|dart|vue|svelte))(?:\s|$|\n)/i const matchInCodePath = code.match(filePathPattern) if (matchInCodePath) { - return matchInCodePath[1].trim() + const cleanPath = matchInCodePath[1].trim() + console.log("cleanPath", cleanPath) + return cleanPath } // Third, use current markdown text to find the most recent "File: /path" before this code block if (!markdownText) { @@ -65,11 +67,9 @@ export function extractFilePathFromCode( let match while ((match = filePattern.exec(markdownText)) !== null) { const rawPath = match[1].trim() - // Strip "(new file)" marker from the path - const cleanPath = rawPath.replace(/\s*\(new file\)\s*$/i, "").trim() positions.push({ position: match.index, - filePath: cleanPath, + filePath: rawPath, }) } @@ -97,6 +97,7 @@ export function extractFilePathFromCode( if (codeBlockIndex === undefined) { codeBlockFileMap.set(codeHash, intendedFile) } + console.log("intendedFile", intendedFile) return intendedFile } } diff --git a/web/package.json b/web/package.json index 11b33e4..84bd1a6 100644 --- a/web/package.json +++ b/web/package.json @@ -9,6 +9,7 @@ "lint": "eslint ." }, "dependencies": { + "@ai-sdk/react": "^3.0.96", "@bprogress/next": "^3.2.12", "@clerk/backend": "^1.34.0", "@clerk/nextjs": "^6.20.0", @@ -47,7 +48,6 @@ "@vercel/analytics": "^1.2.2", "@xterm/addon-fit": "^0.10.0", "@xterm/xterm": "^5.5.0", - "@ai-sdk/react": "^3.0.96", "ai": "^6.0.94", "babel-plugin-react-compiler": "^1.0.0", "class-variance-authority": "^0.7.0", @@ -65,6 +65,7 @@ "framer-motion": "^11.2.3", "geist": "^1.3.0", "hono": "^4.7.11", + "jsonrepair": "^3.13.2", "lucide-react": "^0.511.0", "minimatch": "^3.1.2", "monaco-editor": "^0.52.2", @@ -76,8 +77,8 @@ "react-dom": "^19.1.2", "react-hook-form": "^7.54.2", "react-merge-refs": "^3.0.2", - "react-resizable-panels": "^3.0.6", "react-query-kit": "^3.3.1", + "react-resizable-panels": "^3.0.6", "shiki": "^3.11.0", "socket.io-client": "^4.7.5", "sonner": "^1.4.41", From 4ac8c7956ea3a05d9b5bf07c99e33128104a0642 Mon Sep 17 00:00:00 2001 From: abdulrehmann231 Date: Thu, 12 Mar 2026 04:33:07 +0500 Subject: [PATCH 2/7] fix: no editor ref while applying diff view --- ai/src/utils/aider-diff-merger.ts | 2 ++ web/components/project/hooks/useAIFileActions.ts | 5 +++-- web/components/project/layout/components/editor-panel.tsx | 2 ++ .../project/layout/hooks/useChatPanelHandlers.ts | 4 ++-- web/context/editor-context.tsx | 7 +++++++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ai/src/utils/aider-diff-merger.ts b/ai/src/utils/aider-diff-merger.ts index 431d2f8..f256a4f 100644 --- a/ai/src/utils/aider-diff-merger.ts +++ b/ai/src/utils/aider-diff-merger.ts @@ -356,6 +356,8 @@ export function mergeAiderDiff( ): string { const blocks = parseAiderDiff(diffSnippet, filePath) + console.log("mergeAiderDiff blocks", blocks) + if (blocks.length === 0) { return originalCode } diff --git a/web/components/project/hooks/useAIFileActions.ts b/web/components/project/hooks/useAIFileActions.ts index b856540..613ec29 100644 --- a/web/components/project/hooks/useAIFileActions.ts +++ b/web/components/project/hooks/useAIFileActions.ts @@ -340,9 +340,10 @@ export function useAIFileActions({ if (applied !== null) { pendingApplyReadyRef.current.delete(normalizedPath) retryCountRef.current = 0 - } else if (retryCountRef.current < 5) { + } else if (retryCountRef.current < 15) { retryCountRef.current += 1 - const id = setTimeout(() => setRetryApplyTick((t) => t + 1), 150) + const delay = Math.min(150 * retryCountRef.current, 500) + const id = setTimeout(() => setRetryApplyTick((t) => t + 1), delay) return () => clearTimeout(id) } else { pendingApplyReadyRef.current.delete(normalizedPath) diff --git a/web/components/project/layout/components/editor-panel.tsx b/web/components/project/layout/components/editor-panel.tsx index 4d974fe..c334854 100644 --- a/web/components/project/layout/components/editor-panel.tsx +++ b/web/components/project/layout/components/editor-panel.tsx @@ -107,6 +107,8 @@ export function EditorPanel(props: IDockviewPanelProps) { // Register handlers when editorRef or handlers change useEffect(() => { + + console.log("registering handlers", fileId) if (!fileId) return registerHandlers(fileId, { diff --git a/web/components/project/layout/hooks/useChatPanelHandlers.ts b/web/components/project/layout/hooks/useChatPanelHandlers.ts index 5485951..6bb018c 100644 --- a/web/components/project/layout/hooks/useChatPanelHandlers.ts +++ b/web/components/project/layout/hooks/useChatPanelHandlers.ts @@ -12,7 +12,7 @@ import { useAIFileActions } from "../../hooks/useAIFileActions" * This bridges the new Dockview layout with the existing chat/diff functionality */ export function useChatPanelHandlers() { - const { dockRef, getHandlers } = useEditor() + const { dockRef, getHandlers, handlersVersion } = useEditor() const { project: { id: projectId }, } = useProjectContext() @@ -94,7 +94,7 @@ export function useChatPanelHandlers() { } return null }, - [activeFileId, getHandlers], + [activeFileId, getHandlers, handlersVersion], ) // updateFileDraft adapter - get setDraft from store diff --git a/web/context/editor-context.tsx b/web/context/editor-context.tsx index ed8a976..73ac2b7 100644 --- a/web/context/editor-context.tsx +++ b/web/context/editor-context.tsx @@ -52,6 +52,7 @@ interface EditorContextType { registerHandlers: (fileId: string, handlers: EditorHandlers) => void unregisterHandlers: (fileId: string) => void getHandlers: (fileId: string) => EditorHandlers | undefined + handlersVersion: number } const EditorContext = createContext(null) @@ -110,10 +111,15 @@ export function EditorProvider({ children }: { children: ReactNode }) { // Handler registry const handlersMap = useRef>(new Map()) + const [handlersVersion, setHandlersVersion] = useState(0) const registerHandlers = useCallback( (fileId: string, handlers: EditorHandlers) => { + const prev = handlersMap.current.get(fileId) handlersMap.current.set(fileId, handlers) + if (handlers.editorRef !== null && (!prev || prev.editorRef === null)) { + setHandlersVersion((v) => v + 1) + } }, [], ) @@ -146,6 +152,7 @@ export function EditorProvider({ children }: { children: ReactNode }) { registerHandlers, unregisterHandlers, getHandlers, + handlersVersion, }} > {children} From 6c6b1c59a14f0eea382e4fb914e94f796f35a683 Mon Sep 17 00:00:00 2001 From: abdulrehmann231 Date: Thu, 12 Mar 2026 04:58:09 +0500 Subject: [PATCH 3/7] fix: use of ... to abbreviate code --- ai/src/utils/aider-diff-merger.ts | 92 +++++++++++++++++++++++++++++-- ai/src/utils/prompt-builder.ts | 3 + 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/ai/src/utils/aider-diff-merger.ts b/ai/src/utils/aider-diff-merger.ts index f256a4f..00e45e1 100644 --- a/ai/src/utils/aider-diff-merger.ts +++ b/ai/src/utils/aider-diff-merger.ts @@ -248,20 +248,58 @@ function parseBlocks(blockContent: string): Omit[] { return blocks } +/** + * Returns true if the line uses `...` as a code wildcard (not inside a comment). + * e.g. `cva(...)`, `foo(...)`, `{ ... }` — but NOT `// ... existing code ...` + */ +function isEllipsisWildcard(line: string): boolean { + const trimmed = line.trim() + if ( + trimmed.startsWith("//") || + trimmed.startsWith("/*") || + trimmed.startsWith("*") || + trimmed.startsWith("#") + ) { + return false + } + return trimmed.includes("...") +} + +/** + * Checks if a code line matches a search line that contains a `...` wildcard. + * Only the prefix (before `...`) is required. The suffix (after `...`) is + * checked when it appears on the same line but is optional for multi-line spans. + */ +function lineMatchesWithEllipsis( + codeLine: string, + searchLine: string, +): boolean { + const trimmedCode = codeLine.trim() + const trimmedSearch = searchLine.trim() + + const ellipsisIdx = trimmedSearch.indexOf("...") + const prefix = trimmedSearch.substring(0, ellipsisIdx) + const suffix = trimmedSearch.substring(ellipsisIdx + 3) + + if (!trimmedCode.startsWith(prefix)) return false + if (suffix.length > 0 && !trimmedCode.endsWith(suffix)) return false + return true +} + /** * Finds the starting index of a block in the code - * Tries exact match first (including whitespace), then normalized match (ignoring leading whitespace) + * Tries exact match first (including whitespace), then normalized match (ignoring leading whitespace), + * then ellipsis-aware match (treating `...` in non-comment lines as wildcards). * Returns -1 for empty search blocks (new files) instead of null */ function findBlockInCode(code: string, searchLines: string[]): number | null { - // Empty search block means it's a new file - return -1 as a special marker if (searchLines.length === 0) { return -1 } const codeLines = code.split("\n") - // Try to find exact match first (including whitespace) + // Pass 1: exact match (including whitespace) for (let i = 0; i <= codeLines.length - searchLines.length; i++) { let match = true for (let j = 0; j < searchLines.length; j++) { @@ -275,8 +313,7 @@ function findBlockInCode(code: string, searchLines: string[]): number | null { } } - // If exact match fails, try normalized match (ignoring leading whitespace) - // This handles cases where indentation might differ slightly + // Pass 2: normalized match (ignoring leading/trailing whitespace) for (let i = 0; i <= codeLines.length - searchLines.length; i++) { let match = true for (let j = 0; j < searchLines.length; j++) { @@ -292,6 +329,28 @@ function findBlockInCode(code: string, searchLines: string[]): number | null { } } + // Pass 3: ellipsis-aware match — `...` in non-comment lines acts as a wildcard + const hasEllipsis = searchLines.some((l) => isEllipsisWildcard(l)) + if (hasEllipsis) { + for (let i = 0; i <= codeLines.length - searchLines.length; i++) { + let match = true + for (let j = 0; j < searchLines.length; j++) { + if (isEllipsisWildcard(searchLines[j])) { + if (!lineMatchesWithEllipsis(codeLines[i + j], searchLines[j])) { + match = false + break + } + } else { + if (codeLines[i + j].trim() !== searchLines[j].trim()) { + match = false + break + } + } + } + if (match) return i + } + } + return null } @@ -392,10 +451,31 @@ export function mergeAiderDiff( const codeLines = result.split("\n") const matchedOriginalLines = codeLines.slice(searchStart, searchEnd) + // Expand `...` wildcards in replace lines with the original matched content + const expandedReplaceLines = block.replaceLines.map((replaceLine) => { + if (!isEllipsisWildcard(replaceLine)) return replaceLine + + const replaceTrimmed = replaceLine.trim() + const replaceEllipsisIdx = replaceTrimmed.indexOf("...") + const replacePrefix = replaceTrimmed.substring(0, replaceEllipsisIdx) + + for (let i = 0; i < block.searchLines.length; i++) { + if (!isEllipsisWildcard(block.searchLines[i])) continue + const searchTrimmed = block.searchLines[i].trim() + const searchEllipsisIdx = searchTrimmed.indexOf("...") + const searchPrefix = searchTrimmed.substring(0, searchEllipsisIdx) + + if (replacePrefix === searchPrefix && i < matchedOriginalLines.length) { + return matchedOriginalLines[i] + } + } + return replaceLine + }) + // Preserve indentation from original code for unchanged lines const replacementLines = preserveIndentation( matchedOriginalLines, - block.replaceLines, + expandedReplaceLines, block.searchLines, ) const replacement = replacementLines.join("\n") diff --git a/ai/src/utils/prompt-builder.ts b/ai/src/utils/prompt-builder.ts index fe16f0e..6204741 100644 --- a/ai/src/utils/prompt-builder.ts +++ b/ai/src/utils/prompt-builder.ts @@ -59,6 +59,9 @@ MANDATORY Rules for code changes: 🚨 NEVER show complete files for EXISTING files. ALWAYS use "// ... existing code ..." comments for unchanged sections. 🚨 For NEW FILES: Show the complete file content in the REPLACE block with an empty SEARCH block. +🚨 NEVER use "..." to abbreviate actual code. Every code line in SEARCH/REPLACE blocks must be COMPLETE. + - "..." is ONLY allowed inside comment lines like "// ... existing code ..." + - Do NOT write abbreviated expressions like \`cva(...)\`, \`function(...)\`, \`\`, \`{...}\` — write the COMPLETE line of code or skip the unchanged region entirely with a comment. Example format for additions: File: /src/components/Button.tsx From e68c708b4616aa78891bfe3949284312a8eb1e2e Mon Sep 17 00:00:00 2001 From: abdulrehmann231 Date: Thu, 12 Mar 2026 15:49:01 +0500 Subject: [PATCH 4/7] fix: no handlers in diff view --- web/components/project/chat/lib/file-utils.ts | 4 +- .../project/hooks/useAIFileActions.ts | 82 ++++++++++--------- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/web/components/project/chat/lib/file-utils.ts b/web/components/project/chat/lib/file-utils.ts index 9f7af9a..593536a 100644 --- a/web/components/project/chat/lib/file-utils.ts +++ b/web/components/project/chat/lib/file-utils.ts @@ -50,13 +50,11 @@ export function extractFilesFromMarkdown(markdown: string): { codeBlockIndex, previousCodeBlockEnd, ) - console.log("filePath", rawFilePath) if (rawFilePath) { const isNew = /\(new file\)/i.test(rawFilePath) const cleanPath = rawFilePath.replace(/\s*\(new file\)\s*$/i, "").trim() const normalized = normalizePath(cleanPath) - console.log("normalized file path", normalized) - files.push({ path: normalized, code, isNew }) + files.push({ path: normalized, code, isNew }) } // Update previous code block end position diff --git a/web/components/project/hooks/useAIFileActions.ts b/web/components/project/hooks/useAIFileActions.ts index 613ec29..3cc7716 100644 --- a/web/components/project/hooks/useAIFileActions.ts +++ b/web/components/project/hooks/useAIFileActions.ts @@ -229,7 +229,6 @@ export function useAIFileActions({ const matchBy = (tab: TTab) => pathMatchesTab(normalizedTargetPath, tab) targetTab = tabs.find(matchBy) - // If tab doesn't exist, create it if (!targetTab) { const fileName = normalizedTargetPath.split("/").pop() || normalizedTargetPath @@ -241,26 +240,17 @@ export function useAIFileActions({ } } - // Get current activeTab from tabs array (more reliable than closure) const currentActiveTab = tabs.find((t) => t.id === activeTab?.id) || activeTab - // Check if target tab is currently active (compare with current activeTab) const isTargetActive = currentActiveTab ? matchBy(currentActiveTab) : false if (!isTargetActive) { - pendingDiffsQueueRef.current.set(normalizedTargetPath, { - code, - language, - options: { - ...options, - targetFilePath: normalizedTargetPath, - }, - }) - // Open and activate the target file (openFile handles tab creation and activation) openFile(normalizedTargetPath) - return + // Don't return early — proceed to merge + apply with targetFileId. + // The merge is async so by the time it resolves the EditorPanel + // should have had time to mount. If not, the retry mechanism handles it. } } else { // No target path specified, use active tab @@ -268,6 +258,7 @@ export function useAIFileActions({ } if (!targetTab) { + console.log("no target tab") return } @@ -323,47 +314,60 @@ export function useAIFileActions({ ], ) - // Retry pending diffs when active tab changes; also retry ready-to-apply when editor mounts + // Retry all pending ready-to-apply diffs when editors mount or tick fires. + // Processes files one at a time: activates each file's tab to ensure + // Dockview renders its EditorPanel (inactive panels may not mount). useEffect(() => { - if (!activeTab?.id) return + if (pendingApplyReadyRef.current.size === 0) return - const normalizedPath = normalizePath(activeTab.id) - - // First try ready-to-apply (editor was not ready on first attempt) - const ready = pendingApplyReadyRef.current.get(normalizedPath) - if (ready) { + // First pass: try applying all entries that already have handlers ready + for (const [filePath, ready] of Array.from( + pendingApplyReadyRef.current.entries(), + )) { const applied = handleApplyCodeWithDecorations( ready.mergedCode, ready.originalCode, - normalizedPath, + filePath, ) if (applied !== null) { - pendingApplyReadyRef.current.delete(normalizedPath) - retryCountRef.current = 0 - } else if (retryCountRef.current < 15) { - retryCountRef.current += 1 - const delay = Math.min(150 * retryCountRef.current, 500) - const id = setTimeout(() => setRetryApplyTick((t) => t + 1), delay) - return () => clearTimeout(id) - } else { - pendingApplyReadyRef.current.delete(normalizedPath) - retryCountRef.current = 0 + pendingApplyReadyRef.current.delete(filePath) } } - // Then process queue (tab switch case) + if (pendingApplyReadyRef.current.size === 0) { + retryCountRef.current = 0 + return + } + + // Second pass: for the first file still pending, activate its tab so + // Dockview renders the EditorPanel (it won't mount while inactive). + if (retryCountRef.current > 2) { + const [nextFilePath] = pendingApplyReadyRef.current.entries().next() + .value as [string, unknown] + openFile(nextFilePath) + } + + if (retryCountRef.current < 20) { + retryCountRef.current += 1 + const delay = Math.min(200 * Math.ceil(retryCountRef.current / 3), 600) + const id = setTimeout(() => setRetryApplyTick((t) => t + 1), delay) + return () => clearTimeout(id) + } + + pendingApplyReadyRef.current.clear() + retryCountRef.current = 0 + }, [handleApplyCodeWithDecorations, retryApplyTick, openFile]) + + // Process legacy pending diffs queue when active tab changes + useEffect(() => { + if (!activeTab?.id) return + const normalizedPath = normalizePath(activeTab.id) const pending = pendingDiffsQueueRef.current.get(normalizedPath) if (pending) { pendingDiffsQueueRef.current.delete(normalizedPath) - console.log("pending", pending) handleApplyCodeFromChat(pending.code, pending.language, pending.options) } - }, [ - activeTab?.id, - handleApplyCodeFromChat, - handleApplyCodeWithDecorations, - retryApplyTick, - ]) + }, [activeTab?.id, handleApplyCodeFromChat, handleApplyCodeWithDecorations]) const enqueueFileContentUpdate = useCallback( (filePath: string, content: string) => { From 2d56e75558a2bbf44dc25223b716ae30b530931f Mon Sep 17 00:00:00 2001 From: abdulrehmann231 Date: Thu, 12 Mar 2026 17:40:47 +0500 Subject: [PATCH 5/7] fix: incorrect or missing filename in code block --- .../components/generated-files-preview.tsx | 6 +- web/components/ui/code-block/header.tsx | 4 +- web/components/ui/markdown.tsx | 100 +++++++++--------- 3 files changed, 57 insertions(+), 53 deletions(-) diff --git a/web/components/project/chat/components/generated-files-preview.tsx b/web/components/project/chat/components/generated-files-preview.tsx index 47211af..9493f09 100644 --- a/web/components/project/chat/components/generated-files-preview.tsx +++ b/web/components/project/chat/components/generated-files-preview.tsx @@ -498,10 +498,10 @@ export function GeneratedFilesPreview({
{visibleFiles.map((file) => { diff --git a/web/components/ui/code-block/header.tsx b/web/components/ui/code-block/header.tsx index e49e4e4..fdee6a2 100644 --- a/web/components/ui/code-block/header.tsx +++ b/web/components/ui/code-block/header.tsx @@ -60,13 +60,13 @@ export const CodeBlockHeader = ({ } }} className={cn( - "ml-1 truncate font-mono lowercase hover:underline hover:text-foreground", + "ml-1 truncate font-mono hover:underline hover:text-foreground", )} > {displayName} ) : ( - {displayName} + {displayName} )} {isNewFile && ( & { collapsibleCodeBlocks?: boolean } -interface ExtractedFileInfo { - filePath: string - fileName: string | null - isNewFile: boolean -} - interface MarkdownContextType { - fileInfoMap: Map onOpenFile?: (filePath: string) => void collapsibleCodeBlocks?: boolean } // Constants const LANGUAGE_REGEX = /language-([^\s]+)/ -const FILE_WITH_CODE_REGEX = - /^File:\s*([^\s(]+)(?:\s*\(new file\))?\s*\n```\w*\n([\s\S]*?)```/gm const FILE_LINE_REGEX = /^File:\s*[^\n]+\n/gm +const SDFILE_MARKER = /^__SDFILE__:([^:\n]+)(?::(\w+))?\n/ const codePlugin = createCodePlugin({ themes: ["github-light", "github-dark-default"], @@ -73,29 +65,35 @@ const MarkdownContext = createContext(null) // Utility Functions /** - * Parses markdown: extracts file info and strips "File:" lines in one pass + * Embeds file path info as a `__SDFILE__` marker on the first line of each + * code block that follows a `File:` line, then strips leftover `File:` lines. + * + * The marker lives *inside* the code content so it always travels with the + * HAST node — no external map or position calculation needed. The + * `CodeComponent` strips it before rendering. */ -function parseMarkdownFileInfo(markdown: string) { - const fileInfoMap = new Map() - let match: RegExpExecArray | null - - while ((match = FILE_WITH_CODE_REGEX.exec(markdown)) !== null) { - const filePath = match[1] - const codeContent = match[2].trim() - fileInfoMap.set(codeContent, { - filePath, - fileName: filePath.split("/").pop() || null, - isNewFile: match[0].includes("(new file)"), - }) - } - - // Reset regex lastIndex for reuse - FILE_WITH_CODE_REGEX.lastIndex = 0 +function prepareMarkdown(markdown: string): string { + const embedded = markdown.replace( + /^File:\s*([^\s(]+)((?:\s*\(new file\))?)[^\n]*\n(```\w*\n)/gm, + (_, filePath: string, newMarker: string, codeFence: string) => { + const flag = newMarker.trim() ? ":new" : "" + return `${codeFence}__SDFILE__:${filePath}${flag}\n` + }, + ) + return embedded.replace(FILE_LINE_REGEX, "") +} - return { - fileInfoMap, - strippedMarkdown: markdown.replace(FILE_LINE_REGEX, ""), +/** Walk a HAST node tree and collect all text content. */ +function getNodeText(node: Element): string { + let text = "" + for (const child of node.children) { + if (child.type === "text") { + text += child.value + } else if (child.type === "element") { + text += getNodeText(child) + } } + return text } const shouldShowControls = ( @@ -162,21 +160,27 @@ const CodeComponent = ({ const language = (className?.match(LANGUAGE_REGEX)?.[1] ?? "") as BundledLanguage - // Extract code content from children - let code = "" - if ( - isValidElement(children) && - children.props && - typeof children.props === "object" && - "children" in children.props && - typeof (children.props as { children?: unknown }).children === "string" - ) { - code = (children.props as { children: string }).children - } else if (typeof children === "string") { - code = children + let rawCode = node ? getNodeText(node) : "" + if (!rawCode) { + if ( + isValidElement(children) && + children.props && + typeof children.props === "object" && + "children" in children.props && + typeof (children.props as { children?: unknown }).children === "string" + ) { + rawCode = (children.props as { children: string }).children + } else if (typeof children === "string") { + rawCode = children + } } - const fileInfo = markdownCtx?.fileInfoMap.get(code.trim()) + const marker = rawCode.match(SDFILE_MARKER) + const code = marker ? rawCode.replace(SDFILE_MARKER, "") : rawCode + const filePath = marker?.[1] ?? null + const fileName = filePath?.split("/").pop() ?? undefined + const isNewFile = marker?.[2] === "new" + const showCodeControls = shouldShowControls(controlsConfig, "code") const onOpenFile = markdownCtx?.onOpenFile @@ -186,9 +190,9 @@ const CodeComponent = ({ className={cn("overflow-x-auto border-border border-t", className)} code={code.trim()} language={language} - filename={fileInfo?.fileName ?? undefined} - filePath={fileInfo?.filePath ?? null} - isNewFile={fileInfo?.isNewFile} + filename={fileName} + filePath={filePath} + isNewFile={isNewFile} onOpenFile={onOpenFile} collapsible={markdownCtx?.collapsibleCodeBlocks} > @@ -218,13 +222,13 @@ export const Markdown = memo( ({ className, children, onOpenFile, collapsibleCodeBlocks, ...props }: MarkdownProps) => { const rawMarkdown = typeof children === "string" ? children : "" - const { fileInfoMap, strippedMarkdown } = useMemo( - () => parseMarkdownFileInfo(rawMarkdown), + const strippedMarkdown = useMemo( + () => prepareMarkdown(rawMarkdown), [rawMarkdown], ) return ( - + Date: Thu, 12 Mar 2026 17:50:59 +0500 Subject: [PATCH 6/7] chore: removed extra logs --- .../project/chat/components/generated-files-preview.tsx | 4 ---- web/components/project/chat/index.tsx | 2 +- web/components/project/hooks/lib/merge-resolver.ts | 1 - web/components/project/hooks/useAIFileActions.ts | 7 +------ web/components/project/hooks/useCodeDiffer.ts | 1 - web/components/project/layout/components/editor-panel.tsx | 1 - .../project/layout/hooks/useChatPanelHandlers.ts | 4 +--- web/lib/utils.ts | 3 --- 8 files changed, 3 insertions(+), 20 deletions(-) diff --git a/web/components/project/chat/components/generated-files-preview.tsx b/web/components/project/chat/components/generated-files-preview.tsx index 9493f09..d8705ee 100644 --- a/web/components/project/chat/components/generated-files-preview.tsx +++ b/web/components/project/chat/components/generated-files-preview.tsx @@ -301,10 +301,6 @@ export function GeneratedFilesPreview({ if (status?.status === "ready" && status.result && file.code) { // Always pass targetFilePath to onApplyCode so it can open/activate if needed autoPreviewedRef.current.add(key) - console.log("onApplyCode", file.code, undefined, { - targetFilePath: key, - getMergeStatus: (path: string) => mergeStatusRef.current[path], - }) onApplyCode(file.code, undefined, { targetFilePath: key, getMergeStatus: (path) => mergeStatusRef.current[path], diff --git a/web/components/project/chat/index.tsx b/web/components/project/chat/index.tsx index d30eb2e..806c854 100644 --- a/web/components/project/chat/index.tsx +++ b/web/components/project/chat/index.tsx @@ -166,7 +166,7 @@ function MainChatContent({ const wrappedOnApplyCode = React.useCallback( async (code: string, language?: string): Promise => { - console.log("wrappedOnApplyCode", code, language) + if (onApplyCode) { await onApplyCode(code, language, { mergeStatuses, diff --git a/web/components/project/hooks/lib/merge-resolver.ts b/web/components/project/hooks/lib/merge-resolver.ts index be7603d..da5b2a0 100644 --- a/web/components/project/hooks/lib/merge-resolver.ts +++ b/web/components/project/hooks/lib/merge-resolver.ts @@ -47,7 +47,6 @@ export async function resolveMergeResult( // 3. Compute fresh merge const originalCode = await getCurrentFileContent(normalizedPath) - console.log("originalCode", originalCode) const res = await apiClient.ai["merge-code"].$post({ json: { partialCode: code, diff --git a/web/components/project/hooks/useAIFileActions.ts b/web/components/project/hooks/useAIFileActions.ts index 3cc7716..5f8c194 100644 --- a/web/components/project/hooks/useAIFileActions.ts +++ b/web/components/project/hooks/useAIFileActions.ts @@ -131,8 +131,6 @@ export function useAIFileActions({ // First, check if there's a draft (unsaved changes) const draftContent = getDraft(normalizedPath) - console.log("normalizedPath", normalizedPath) - console.log("draftContent", draftContent) if (draftContent !== undefined) { return draftContent } @@ -144,7 +142,6 @@ export function useAIFileActions({ fileId: normalizedPath, projectId, }) - console.log("response", response) return response?.data ?? "" } catch (error) { console.warn("Failed to fetch current file content:", error) @@ -265,7 +262,7 @@ export function useAIFileActions({ // Use target path if provided, otherwise use target tab const targetPath = normalizedTargetPath || normalizePath(targetTab.id) try { - console.log("code", code) + const mergeResult = await resolveMergeResult( targetPath, code, @@ -275,8 +272,6 @@ export function useAIFileActions({ options, ) - console.log("mergeResult", mergeResult) - console.log("targetTab", targetTab) // Apply to Editor if (mergeResult) { diff --git a/web/components/project/hooks/useCodeDiffer.ts b/web/components/project/hooks/useCodeDiffer.ts index aa8f9d1..5db5f19 100644 --- a/web/components/project/hooks/useCodeDiffer.ts +++ b/web/components/project/hooks/useCodeDiffer.ts @@ -171,7 +171,6 @@ export function useCodeDiffer({ ignoreWhitespace: false, }) - console.log("diffResult", diffResult) model.setValue(diffResult.combinedLines.join("\n")) model.setEOL(eolSequence) diff --git a/web/components/project/layout/components/editor-panel.tsx b/web/components/project/layout/components/editor-panel.tsx index c334854..311ea2c 100644 --- a/web/components/project/layout/components/editor-panel.tsx +++ b/web/components/project/layout/components/editor-panel.tsx @@ -108,7 +108,6 @@ export function EditorPanel(props: IDockviewPanelProps) { // Register handlers when editorRef or handlers change useEffect(() => { - console.log("registering handlers", fileId) if (!fileId) return registerHandlers(fileId, { diff --git a/web/components/project/layout/hooks/useChatPanelHandlers.ts b/web/components/project/layout/hooks/useChatPanelHandlers.ts index 6bb018c..84b6f48 100644 --- a/web/components/project/layout/hooks/useChatPanelHandlers.ts +++ b/web/components/project/layout/hooks/useChatPanelHandlers.ts @@ -80,11 +80,10 @@ export function useChatPanelHandlers() { if (!fileIdToUse) { return null } - console.log("fileIdToUse", fileIdToUse) const handlers = getHandlers(fileIdToUse) if (handlers) { - console.log("handlers", handlers) + //handlers } else { console.log("no handlers") @@ -219,7 +218,6 @@ export function useChatPanelHandlers() { language?: string, options?: Parameters[2], ) => { - console.log("onApplyCode", code, language, options) return handleApplyCodeFromChat(code, language, options) }, [handleApplyCodeFromChat, activeFileId, activeTab, activeHandlers], diff --git a/web/lib/utils.ts b/web/lib/utils.ts index cd735ec..0743329 100644 --- a/web/lib/utils.ts +++ b/web/lib/utils.ts @@ -27,7 +27,6 @@ export function extractFilePathFromCode( const matchInCode = code.match(filePatternInCode) if (matchInCode) { const rawPath = matchInCode[1].trim() - console.log("cleanPath", rawPath) return rawPath } @@ -37,7 +36,6 @@ export function extractFilePathFromCode( const matchInCodePath = code.match(filePathPattern) if (matchInCodePath) { const cleanPath = matchInCodePath[1].trim() - console.log("cleanPath", cleanPath) return cleanPath } // Third, use current markdown text to find the most recent "File: /path" before this code block @@ -97,7 +95,6 @@ export function extractFilePathFromCode( if (codeBlockIndex === undefined) { codeBlockFileMap.set(codeHash, intendedFile) } - console.log("intendedFile", intendedFile) return intendedFile } } From 41bfb45930d3f83c618dbb6e91895c6add9517c5 Mon Sep 17 00:00:00 2001 From: abdulrehmann231 Date: Thu, 12 Mar 2026 17:52:27 +0500 Subject: [PATCH 7/7] chore: removed extra logs --- ai/src/utils/aider-diff-merger.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ai/src/utils/aider-diff-merger.ts b/ai/src/utils/aider-diff-merger.ts index 00e45e1..df6f209 100644 --- a/ai/src/utils/aider-diff-merger.ts +++ b/ai/src/utils/aider-diff-merger.ts @@ -415,7 +415,6 @@ export function mergeAiderDiff( ): string { const blocks = parseAiderDiff(diffSnippet, filePath) - console.log("mergeAiderDiff blocks", blocks) if (blocks.length === 0) { return originalCode