Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/core/prompts/__tests__/__snapshots__/system.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ exports[`SYSTEM_PROMPT should exclude diff strategy tool description when diffEn

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -472,6 +478,12 @@ exports[`SYSTEM_PROMPT should exclude diff strategy tool description when diffEn

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -939,6 +951,12 @@ exports[`SYSTEM_PROMPT should explicitly handle undefined mcpHub 1`] = `

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -1406,6 +1424,12 @@ exports[`SYSTEM_PROMPT should handle different browser viewport sizes 1`] = `

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -1929,6 +1953,12 @@ exports[`SYSTEM_PROMPT should include MCP server info when mcpHub is provided 1`

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -2464,6 +2494,12 @@ exports[`SYSTEM_PROMPT should include browser actions when supportsComputerUse i

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -2987,6 +3023,12 @@ exports[`SYSTEM_PROMPT should include diff strategy tool description when diffEn

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -3544,6 +3586,12 @@ exports[`SYSTEM_PROMPT should maintain consistent system prompt 1`] = `

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -4053,6 +4101,12 @@ exports[`addCustomInstructions should exclude MCP server creation info when disa

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -4597,6 +4651,12 @@ exports[`addCustomInstructions should generate correct prompt for architect mode

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -5055,6 +5115,12 @@ exports[`addCustomInstructions should generate correct prompt for ask mode 1`] =

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down Expand Up @@ -5430,6 +5496,12 @@ exports[`addCustomInstructions should include MCP server creation info when enab

====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>

====

TOOL USE

You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
Expand Down
1 change: 1 addition & 0 deletions src/core/prompts/sections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { getMcpServersSection } from "./mcp-servers"
export { getToolUseGuidelinesSection } from "./tool-use-guidelines"
export { getCapabilitiesSection } from "./capabilities"
export { getModesSection } from "./modes"
export { markdownFormattingSection } from "./markdown-formatting"
7 changes: 7 additions & 0 deletions src/core/prompts/sections/markdown-formatting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function markdownFormattingSection(): string {
return `====

MARKDOWN RULES

ALL responses MUST show ANY \`language construct\` OR filename reterence as clickable, exactly as [\`filename OR language.declaration()\`](relative/file/path.ext:line); line is required for \`syntax\` and optional for filename links. This applies to ALL markdown responses and ALSO those in <attempt_completion>`
}
3 changes: 3 additions & 0 deletions src/core/prompts/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
getCapabilitiesSection,
getModesSection,
addCustomInstructions,
markdownFormattingSection,
} from "./sections"
import { loadSystemPromptFile } from "./sections/custom-system-prompt"
import { formatLanguage } from "../../shared/language"
Expand Down Expand Up @@ -65,6 +66,8 @@ async function generatePrompt(

const basePrompt = `${roleDefinition}

${markdownFormattingSection()}

${getSharedToolUseSection()}

${getToolDescriptionsForMode(
Expand Down
2 changes: 1 addition & 1 deletion src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We
openImage(message.text!)
break
case "openFile":
openFile(message.text!, message.values as { create?: boolean; content?: string })
openFile(message.text!, message.values as { create?: boolean; content?: string; line?: number })
break
case "openMention":
openMention(message.text)
Expand Down
8 changes: 7 additions & 1 deletion src/integrations/misc/open-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export async function openImage(dataUri: string) {
interface OpenFileOptions {
create?: boolean
content?: string
line?: number
}

export async function openFile(filePath: string, options: OpenFileOptions = {}) {
Expand Down Expand Up @@ -75,7 +76,12 @@ export async function openFile(filePath: string, options: OpenFileOptions = {})
} catch {} // not essential, sometimes tab operations fail

const document = await vscode.workspace.openTextDocument(uri)
await vscode.window.showTextDocument(document, { preview: false })
const selection =
options.line !== undefined ? new vscode.Selection(options.line - 1, 0, options.line - 1, 0) : undefined
await vscode.window.showTextDocument(document, {
preview: false,
selection,
})
} catch (error) {
if (error instanceof Error) {
vscode.window.showErrorMessage(`Could not open file: ${error.message}`)
Expand Down
54 changes: 50 additions & 4 deletions webview-ui/src/components/common/MarkdownBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useRemark } from "react-remark"
import styled from "styled-components"
import { visit } from "unist-util-visit"

import { vscode } from "@src/utils/vscode"
import { useExtensionState } from "@src/context/ExtensionStateContext"

import CodeBlock from "./CodeBlock"
Expand Down Expand Up @@ -109,11 +110,14 @@ const StyledMarkdown = styled.div`
}

a {
text-decoration: none;
}
a {
color: var(--vscode-textLink-foreground);
text-decoration-line: underline;
text-decoration-style: dotted;
text-decoration-color: var(--vscode-textLink-foreground);
&:hover {
text-decoration: underline;
color: var(--vscode-textLink-activeForeground);
text-decoration-style: solid;
text-decoration-color: var(--vscode-textLink-activeForeground);
}
}
`
Expand All @@ -138,6 +142,48 @@ const MarkdownBlock = memo(({ markdown }: MarkdownBlockProps) => {
rehypePlugins: [],
rehypeReactOptions: {
components: {
a: ({ href, children }: any) => {
return (
<a
href={href}
title={href}
onClick={(e) => {
// Only process file:// protocol or local file paths
const isLocalPath =
href.startsWith("file://") || href.startsWith("/") || !href.includes("://")

if (!isLocalPath) {
return
}

e.preventDefault()

// Handle absolute vs project-relative paths
let filePath = href.replace("file://", "")

// Extract line number if present
const match = filePath.match(/(.*):(\d+)(-\d+)?$/)
let values = undefined
if (match) {
filePath = match[1]
values = { line: parseInt(match[2]) }
}

// Add ./ prefix if needed
if (!filePath.startsWith("/") && !filePath.startsWith("./")) {
filePath = "./" + filePath
}

vscode.postMessage({
type: "openFile",
text: filePath,
values,
})
}}>
{children}
</a>
)
},
pre: ({ node: _, children }: any) => {
// Check for Mermaid diagrams first
if (Array.isArray(children) && children.length === 1 && React.isValidElement(children[0])) {
Expand Down