Skip to content

Commit cbc756d

Browse files
committed
refactor: remove commandPatterns.ts and simplify command parsing
- Remove unnecessary commandPatterns.ts wrapper module - Use extractPatternsFromCommand directly from command-parser.ts - Simplify command/output parsing logic in CommandExecution.tsx - Move CommandPattern interface to components that use it - All tests passing
1 parent 627ea84 commit cbc756d

File tree

6 files changed

+44
-560
lines changed

6 files changed

+44
-560
lines changed

webview-ui/src/components/chat/CommandExecution.tsx

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ import { cn } from "@src/lib/utils"
1313
import { Button } from "@src/components/ui"
1414
import CodeBlock from "../common/CodeBlock"
1515
import { CommandPatternSelector } from "./CommandPatternSelector"
16-
import {
17-
extractCommandPatterns,
18-
getPatternDescription,
19-
parseCommandAndOutput,
20-
CommandPattern,
21-
} from "../../utils/commandPatterns"
16+
import { extractPatternsFromCommand } from "../../utils/command-parser"
17+
18+
interface CommandPattern {
19+
pattern: string
20+
description?: string
21+
}
2222

2323
interface CommandExecutionProps {
2424
executionId: string
@@ -37,8 +37,28 @@ export const CommandExecution = ({ executionId, text, icon, title }: CommandExec
3737
} = useExtensionState()
3838

3939
const { command, output: parsedOutput } = useMemo(() => {
40-
// Use the enhanced parser from commandPatterns
41-
return parseCommandAndOutput(text || "")
40+
// Parse command and output using the "Output:" separator
41+
const outputSeparator = "Output:"
42+
const outputIndex = text?.indexOf(`\n${outputSeparator}`) ?? -1
43+
44+
if (outputIndex !== -1) {
45+
// Text is split into command and output
46+
const cmd = text!.slice(0, outputIndex).trim()
47+
// Skip the newline and "Output:" text
48+
const afterSeparator = outputIndex + 1 + outputSeparator.length
49+
let startOfOutput = afterSeparator
50+
if (text![afterSeparator] === "\n") {
51+
startOfOutput = afterSeparator + 1
52+
}
53+
const out = text!.slice(startOfOutput).trim()
54+
return { command: cmd, output: out }
55+
} else if (text?.indexOf(outputSeparator) === 0) {
56+
// Edge case: text starts with "Output:" (no command)
57+
return { command: "", output: text.slice(outputSeparator.length).trim() }
58+
} else {
59+
// No output separator found, the entire text is the command
60+
return { command: text?.trim() || "", output: "" }
61+
}
4262
}, [text])
4363

4464
// If we aren't opening the VSCode terminal for this command then we default
@@ -54,20 +74,12 @@ export const CommandExecution = ({ executionId, text, icon, title }: CommandExec
5474

5575
// Extract command patterns from the actual command that was executed
5676
const commandPatterns = useMemo<CommandPattern[]>(() => {
57-
const patterns: CommandPattern[] = []
58-
59-
// Always extract patterns from the actual command that was executed
60-
// We don't use AI suggestions because the patterns should reflect
61-
// what was actually executed, not what the AI thinks might be useful
62-
const extractedPatterns = extractCommandPatterns(command)
63-
extractedPatterns.forEach((pattern) => {
64-
patterns.push({
65-
pattern,
66-
description: getPatternDescription(pattern),
67-
})
68-
})
69-
70-
return patterns
77+
// Extract patterns from the actual command that was executed
78+
const extractedPatterns = extractPatternsFromCommand(command)
79+
return extractedPatterns.map((pattern) => ({
80+
pattern,
81+
description: `${pattern} commands`,
82+
}))
7183
}, [command])
7284

7385
// Handle pattern changes

webview-ui/src/components/chat/CommandPatternSelector.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ import { Check, ChevronDown, Info, X } from "lucide-react"
33
import { cn } from "../../lib/utils"
44
import { useTranslation, Trans } from "react-i18next"
55
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
6-
import { CommandPattern } from "../../utils/commandPatterns"
76
import { StandardTooltip } from "../ui/standard-tooltip"
87

8+
interface CommandPattern {
9+
pattern: string
10+
description?: string
11+
}
12+
913
interface CommandPatternSelectorProps {
1014
patterns: CommandPattern[]
1115
allowedCommands: string[]

webview-ui/src/components/chat/__tests__/CommandExecution.spec.tsx

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,6 @@ vi.mock("../../common/CodeBlock", () => ({
2121
default: ({ source }: { source: string }) => <div data-testid="code-block">{source}</div>,
2222
}))
2323

24-
// Mock the commandPatterns module but use the actual implementation
25-
vi.mock("../../../utils/commandPatterns", async () => {
26-
const actual = await vi.importActual<typeof import("../../../utils/commandPatterns")>(
27-
"../../../utils/commandPatterns",
28-
)
29-
return {
30-
...actual,
31-
parseCommandAndOutput: actual.parseCommandAndOutput,
32-
extractCommandPatterns: actual.extractCommandPatterns,
33-
getPatternDescription: actual.getPatternDescription,
34-
}
35-
})
36-
3724
vi.mock("../CommandPatternSelector", () => ({
3825
CommandPatternSelector: ({ patterns, onAllowPatternChange, onDenyPatternChange }: any) => (
3926
<div data-testid="command-pattern-selector">

webview-ui/src/components/chat/__tests__/CommandPatternSelector.spec.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ import React from "react"
22
import { render, screen, fireEvent } from "@testing-library/react"
33
import { describe, it, expect, vi } from "vitest"
44
import { CommandPatternSelector } from "../CommandPatternSelector"
5-
import { CommandPattern } from "../../../utils/commandPatterns"
65
import { TooltipProvider } from "../../../components/ui/tooltip"
76

7+
interface CommandPattern {
8+
pattern: string
9+
description?: string
10+
}
11+
812
// Mock react-i18next
913
vi.mock("react-i18next", () => ({
1014
useTranslation: () => ({

0 commit comments

Comments
 (0)