Skip to content

Commit 900282f

Browse files
committed
fix: address DCG integration feedback
1 parent d72130d commit 900282f

3 files changed

Lines changed: 18 additions & 5 deletions

File tree

src/core/tools/ExecuteCommandTool.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,9 @@ export class ExecuteCommandTool extends BaseTool<"execute_command"> {
132132
}
133133

134134
const provider = await task.providerRef.deref()
135-
const providerState = await provider?.getState()
136135
let dcgBlocked = false
137-
if (providerState?.destructiveCommandGuardEnabled === true) {
136+
if (provider?.contextProxy.getValue("destructiveCommandGuardEnabled") === true) {
138137
const { ensureDcgInstalled, runDcg } = await import("../../services/destructive-command-guard")
139-
if (!provider) {
140-
throw new Error(t("common:errors.destructiveCommandGuard.unavailable"))
141-
}
142138
// Resolve through the managed installer on use so an extension update
143139
// automatically installs the newly pinned and verified DCG version.
144140
const binaryPath = await ensureDcgInstalled(provider.context.globalStorageUri.fsPath)
@@ -169,6 +165,7 @@ export class ExecuteCommandTool extends BaseTool<"execute_command"> {
169165
}
170166

171167
const executionId = task.lastMessageTs?.toString() ?? Date.now().toString()
168+
const providerState = await provider?.getState()
172169
const { terminalShellIntegrationDisabled = true } = providerState ?? {}
173170

174171
// Get command execution timeout from VSCode configuration (in seconds)

src/core/tools/__tests__/executeCommandTool.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ describe("executeCommandTool", () => {
8989
supersedePendingAsk: vitest.fn(),
9090
providerRef: {
9191
deref: vitest.fn().mockResolvedValue({
92+
contextProxy: {
93+
getValue: vitest.fn().mockReturnValue(false),
94+
},
9295
getState: vitest.fn().mockResolvedValue({
9396
terminalOutputLineLimit: 500,
9497
terminalOutputCharacterLimit: 100000,
@@ -225,6 +228,7 @@ describe("executeCommandTool", () => {
225228
it("shows a DCG block message as an error before requesting explicit approval", async () => {
226229
const provider = await mockCline.providerRef.deref()
227230
provider.context = { globalStorageUri: { fsPath: "/test/storage" } }
231+
provider.contextProxy.getValue.mockReturnValue(true)
228232
provider.getState.mockResolvedValue({
229233
destructiveCommandGuardEnabled: true,
230234
terminalShellIntegrationDisabled: true,
@@ -252,6 +256,7 @@ describe("executeCommandTool", () => {
252256
it("requests normal approval when DCG allows the command", async () => {
253257
const provider = await mockCline.providerRef.deref()
254258
provider.context = { globalStorageUri: { fsPath: "/test/storage" } }
259+
provider.contextProxy.getValue.mockReturnValue(true)
255260
provider.getState.mockResolvedValue({
256261
destructiveCommandGuardEnabled: true,
257262
terminalShellIntegrationDisabled: true,
@@ -265,11 +270,13 @@ describe("executeCommandTool", () => {
265270
})
266271

267272
expect(mockAskApproval).toHaveBeenCalledWith("command", "echo test")
273+
expect(mockPushToolResult).toHaveBeenCalled()
268274
})
269275

270276
it("installs or updates DCG before evaluating an enabled command", async () => {
271277
const provider = await mockCline.providerRef.deref()
272278
provider.context = { globalStorageUri: { fsPath: "/test/storage" } }
279+
provider.contextProxy.getValue.mockReturnValue(true)
273280
provider.getState.mockResolvedValue({
274281
destructiveCommandGuardEnabled: true,
275282
terminalShellIntegrationDisabled: true,
@@ -287,6 +294,7 @@ describe("executeCommandTool", () => {
287294
it("fails closed when the DCG install or update fails", async () => {
288295
const provider = await mockCline.providerRef.deref()
289296
provider.context = { globalStorageUri: { fsPath: "/test/storage" } }
297+
provider.contextProxy.getValue.mockReturnValue(true)
290298
provider.getState.mockResolvedValue({
291299
destructiveCommandGuardEnabled: true,
292300
terminalShellIntegrationDisabled: true,
@@ -311,6 +319,7 @@ describe("executeCommandTool", () => {
311319
it("fails closed when DCG is unavailable for the current platform", async () => {
312320
const provider = await mockCline.providerRef.deref()
313321
provider.context = { globalStorageUri: { fsPath: "/test/storage" } }
322+
provider.contextProxy.getValue.mockReturnValue(true)
314323
provider.getState.mockResolvedValue({
315324
destructiveCommandGuardEnabled: true,
316325
terminalShellIntegrationDisabled: true,

webview-ui/src/components/chat/__tests__/ChatRow.command-denied.spec.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,11 @@ describe("ChatRow - denied commands", () => {
6767
expect(screen.queryByText("chat:commandExecution.denied")).not.toBeInTheDocument()
6868
expect(screen.getByTestId("command-execution")).toHaveAttribute("data-denied", "false")
6969
})
70+
71+
it("does not show a denied status while a command awaits a decision", () => {
72+
renderCommand()
73+
74+
expect(screen.queryByText("chat:commandExecution.denied")).not.toBeInTheDocument()
75+
expect(screen.getByTestId("command-execution")).toHaveAttribute("data-denied", "false")
76+
})
7077
})

0 commit comments

Comments
 (0)