Skip to content

Commit 5de97ab

Browse files
feat(svn): 添加对svn-changes提及的支持,主要是让API请求包含svn的status、diff信息
- 在mentionRegex中添加svn-changes匹配项 - 实现获取SVN工作状态的函数并添加调试日志 - 在parseMentions中处理svn-changes提及,返回工作目录变更信息 - 在processUserContentMentions中添加调试日志
1 parent 61799a9 commit 5de97ab

File tree

4 files changed

+89
-31
lines changed

4 files changed

+89
-31
lines changed

src/core/mentions/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { isBinaryFile } from "isbinaryfile"
77
import { mentionRegexGlobal, unescapeSpaces } from "../../shared/context-mentions"
88

99
import { getCommitInfo, getWorkingState } from "../../utils/git"
10+
import { getSvnWorkingState } from "../../utils/svn"
1011
import { getWorkspacePath } from "../../utils/path"
1112

1213
import { openFile } from "../../integrations/misc/open-file"
@@ -95,6 +96,8 @@ export async function parseMentions(
9596
return `Workspace Problems (see below for diagnostics)`
9697
} else if (mention === "git-changes") {
9798
return `Working directory changes (see below for details)`
99+
} else if (mention === "svn-changes") {
100+
return `Working directory changes (see below for details)`
98101
} else if (/^[a-f0-9]{7,40}$/.test(mention)) {
99102
return `Git commit '${mention}' (see below for commit info)`
100103
} else if (mention === "terminal") {
@@ -177,6 +180,29 @@ export async function parseMentions(
177180
} catch (error) {
178181
parsedText += `\n\n<git_working_state>\nError fetching working state: ${error.message}\n</git_working_state>`
179182
}
183+
} else if (mention === "svn-changes") {
184+
try {
185+
const svnWorkingState = await getSvnWorkingState(cwd)
186+
console.log("[DEBUG] SVN working state object:", JSON.stringify(svnWorkingState, null, 2))
187+
188+
// Format the SVN working state properly
189+
let formattedState = ""
190+
if (svnWorkingState.status) {
191+
formattedState += `Status:\n${svnWorkingState.status}\n\n`
192+
}
193+
if (svnWorkingState.diff) {
194+
formattedState += `Diff:\n${svnWorkingState.diff}`
195+
}
196+
if (!formattedState.trim()) {
197+
formattedState = "No changes detected in working directory."
198+
}
199+
200+
console.log("[DEBUG] Formatted SVN state for AI:", formattedState)
201+
parsedText += `\n\n<svn_working_state>\n${formattedState}\n</svn_working_state>`
202+
} catch (error) {
203+
console.error("[DEBUG] Error fetching SVN working state:", error)
204+
parsedText += `\n\n<svn_working_state>\nError fetching SVN working state: ${error.message}\n</svn_working_state>`
205+
}
180206
} else if (/^[a-f0-9]{7,40}$/.test(mention)) {
181207
try {
182208
const commitInfo = await getCommitInfo(mention, cwd)

src/core/mentions/processUserContentMentions.ts

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export async function processUserContentMentions({
2121
rooIgnoreController?: any
2222
showRooIgnoredFiles?: boolean
2323
}) {
24+
console.log("[DEBUG] Processing user content mentions, input userContent:", JSON.stringify(userContent, null, 2))
25+
2426
// Process userContent array, which contains various block types:
2527
// TextBlockParam, ImageBlockParam, ToolUseBlockParam, and ToolResultBlockParam.
2628
// We need to apply parseMentions() to:
@@ -31,39 +33,45 @@ export async function processUserContentMentions({
3133
// (see askFollowupQuestion), we place all user generated content in
3234
// these tags so they can effectively be used as markers for when we
3335
// should parse mentions).
34-
return Promise.all(
36+
const result = await Promise.all(
3537
userContent.map(async (block) => {
3638
const shouldProcessMentions = (text: string) => text.includes("<task>") || text.includes("<feedback>")
3739

3840
if (block.type === "text") {
3941
if (shouldProcessMentions(block.text)) {
42+
console.log("[DEBUG] Processing mentions in text block:", block.text)
43+
const processedText = await parseMentions(
44+
block.text,
45+
cwd,
46+
urlContentFetcher,
47+
fileContextTracker,
48+
rooIgnoreController,
49+
showRooIgnoredFiles,
50+
)
51+
console.log("[DEBUG] Processed text block result:", processedText)
4052
return {
4153
...block,
42-
text: await parseMentions(
43-
block.text,
44-
cwd,
45-
urlContentFetcher,
46-
fileContextTracker,
47-
rooIgnoreController,
48-
showRooIgnoredFiles,
49-
),
54+
text: processedText,
5055
}
5156
}
5257

5358
return block
5459
} else if (block.type === "tool_result") {
5560
if (typeof block.content === "string") {
5661
if (shouldProcessMentions(block.content)) {
62+
console.log("[DEBUG] Processing mentions in tool_result string content:", block.content)
63+
const processedContent = await parseMentions(
64+
block.content,
65+
cwd,
66+
urlContentFetcher,
67+
fileContextTracker,
68+
rooIgnoreController,
69+
showRooIgnoredFiles,
70+
)
71+
console.log("[DEBUG] Processed tool_result string content result:", processedContent)
5772
return {
5873
...block,
59-
content: await parseMentions(
60-
block.content,
61-
cwd,
62-
urlContentFetcher,
63-
fileContextTracker,
64-
rooIgnoreController,
65-
showRooIgnoredFiles,
66-
),
74+
content: processedContent,
6775
}
6876
}
6977

@@ -72,16 +80,22 @@ export async function processUserContentMentions({
7280
const parsedContent = await Promise.all(
7381
block.content.map(async (contentBlock) => {
7482
if (contentBlock.type === "text" && shouldProcessMentions(contentBlock.text)) {
83+
console.log(
84+
"[DEBUG] Processing mentions in tool_result array content:",
85+
contentBlock.text,
86+
)
87+
const processedText = await parseMentions(
88+
contentBlock.text,
89+
cwd,
90+
urlContentFetcher,
91+
fileContextTracker,
92+
rooIgnoreController,
93+
showRooIgnoredFiles,
94+
)
95+
console.log("[DEBUG] Processed tool_result array content result:", processedText)
7596
return {
7697
...contentBlock,
77-
text: await parseMentions(
78-
contentBlock.text,
79-
cwd,
80-
urlContentFetcher,
81-
fileContextTracker,
82-
rooIgnoreController,
83-
showRooIgnoredFiles,
84-
),
98+
text: processedText,
8599
}
86100
}
87101

@@ -98,4 +112,7 @@ export async function processUserContentMentions({
98112
return block
99113
}),
100114
)
115+
116+
console.log("[DEBUG] Final processed userContent for AI:", JSON.stringify(result, null, 2))
117+
return result
101118
}

src/shared/context-mentions.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Mention regex:
99
- `/@`:
1010
- **@**: The mention must start with the '@' symbol.
1111
12-
- `((?:\/|\w+:\/\/)[^\s]+?|problems\b|git-changes\b)`:
12+
- `((?:\/|\w+:\/\/)[^\s]+?|problems\b|git-changes\b|svn-changes\b)`:
1313
- **Capturing Group (`(...)`)**: Captures the part of the string that matches one of the specified patterns.
1414
- `(?:\/|\w+:\/\/)`:
1515
- **Non-Capturing Group (`(?:...)`)**: Groups the alternatives without capturing them for back-referencing.
@@ -46,6 +46,7 @@ Mention regex:
4646
- URLs that start with a protocol (like 'http://') followed by any non-whitespace characters (including query parameters).
4747
- The exact word 'problems'.
4848
- The exact word 'git-changes'.
49+
- The exact word 'svn-changes'.
4950
- The exact word 'terminal'.
5051
- It ensures that any trailing punctuation marks (such as ',', '.', '!', etc.) are not included in the matched mention, allowing the punctuation to follow the mention naturally in the text.
5152
@@ -54,7 +55,7 @@ Mention regex:
5455
5556
*/
5657
export const mentionRegex =
57-
/(?<!\\)@((?:\/|\w+:\/\/)(?:[^\s\\]|\\ )+?|[a-f0-9]{7,40}\b|problems\b|git-changes\b|terminal\b)(?=[.,;:!?]?(?=[\s\r\n]|$))/
58+
/(?<!\\)@((?:\/|\w+:\/\/)(?:[^\s\\]|\\ )+?|[a-f0-9]{7,40}\b|problems\b|git-changes\b|svn-changes\b|terminal\b)(?=[.,;:!?]?(?=[\s\r\n]|$))/
5859
export const mentionRegexGlobal = new RegExp(mentionRegex.source, "g")
5960

6061
export interface MentionSuggestion {

src/utils/svn.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -419,31 +419,45 @@ export async function getSvnWorkingState(cwd: string): Promise<{
419419
diff: string
420420
}> {
421421
try {
422+
console.log("[DEBUG] getSvnWorkingState called with cwd:", cwd)
423+
422424
if (!(await checkSvnInstalled()) || !(await checkSvnRepo(cwd))) {
425+
console.log("[DEBUG] SVN not installed or not a repository")
423426
return { status: "", diff: "" }
424427
}
425428

426429
// Get status
427430
let status = ""
428431
try {
432+
console.log("[DEBUG] Executing 'svn status' command")
429433
const { stdout: statusOutput } = await execAsync("svn status", { cwd })
434+
console.log("[DEBUG] SVN status raw output:", JSON.stringify(statusOutput))
430435
status = truncateOutput(statusOutput, SVN_OUTPUT_LINE_LIMIT)
431-
} catch {
436+
console.log("[DEBUG] SVN status after truncation:", JSON.stringify(status))
437+
} catch (error) {
438+
console.log("[DEBUG] SVN status command failed:", error)
432439
// Status might not be available
433440
}
434441

435442
// Get diff of working changes
436443
let diff = ""
437444
try {
445+
console.log("[DEBUG] Executing 'svn diff' command")
438446
const { stdout: diffOutput } = await execAsync("svn diff", { cwd })
447+
console.log("[DEBUG] SVN diff raw output length:", diffOutput.length)
448+
console.log("[DEBUG] SVN diff raw output preview:", JSON.stringify(diffOutput.substring(0, 500)))
439449
diff = truncateOutput(diffOutput, SVN_OUTPUT_LINE_LIMIT)
440-
} catch {
450+
console.log("[DEBUG] SVN diff after truncation length:", diff.length)
451+
} catch (error) {
452+
console.log("[DEBUG] SVN diff command failed:", error)
441453
// Diff might not be available
442454
}
443455

444-
return { status, diff }
456+
const result = { status, diff }
457+
console.log("[DEBUG] getSvnWorkingState returning:", JSON.stringify(result))
458+
return result
445459
} catch (error) {
446-
console.error("Error getting SVN working state:", error)
460+
console.error("[DEBUG] Error in getSvnWorkingState:", error)
447461
return { status: "", diff: "" }
448462
}
449463
}

0 commit comments

Comments
 (0)