Show warning when claude code hooks are detected but disabled#294724
Show warning when claude code hooks are detected but disabled#294724roblourens merged 5 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR ports functionality to detect Claude Code hook files in a workspace and surface a one-time in-chat warning when those hooks are present but disabled, alongside introducing a new chat.useClaudeHooks setting to control whether Claude-format hooks can execute.
Changes:
- Add
chat.useClaudeHookssetting and wire it into hook discovery/collection (including cache invalidation). - Extend hook collection API to return both collected hooks and a “disabled Claude hooks detected” flag.
- Add a new chat progress/rendering part to display a warning with a Settings link when disabled Claude hooks are detected.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/common/tools/builtinTools/runSubagentTool.ts | Adapts to updated hooks API by extracting hooks from the returned info object. |
| src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.ts | Tracks disabled Claude hooks during hook parsing; skips Claude hooks when setting is disabled; invalidates hooks cache on setting changes. |
| src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsService.ts | Adds IConfiguredHooksInfo and updates getHooks return type. |
| src/vs/workbench/contrib/chat/common/promptSyntax/config/config.ts | Introduces PromptsConfig.USE_CLAUDE_HOOKS constant. |
| src/vs/workbench/contrib/chat/common/model/chatViewModel.ts | Allows renderer pipeline to carry the new disabledClaudeHooks content part. |
| src/vs/workbench/contrib/chat/common/model/chatSessionOperationLog.ts | Treats disabledClaudeHooks as a static serialized response part for storage diffing. |
| src/vs/workbench/contrib/chat/common/model/chatModel.ts | Adds disabledClaudeHooks to progress/serialization unions and ignores it for copy-text generation. |
| src/vs/workbench/contrib/chat/common/chatService/chatServiceImpl.ts | Emits the new warning progress part and persists a “shown” flag in workspace storage. |
| src/vs/workbench/contrib/chat/common/chatService/chatService.ts | Defines IChatDisabledClaudeHooksPart and includes it in IChatProgress. |
| src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts | Renders disabledClaudeHooks via a new content part implementation. |
| src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatDisabledClaudeHooksContent.css | Styles the warning row (icon + italic message). |
| src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDisabledClaudeHooksContentPart.ts | Implements the warning UI with a command link to Settings. |
| src/vs/workbench/contrib/chat/browser/chat.contribution.ts | Registers the new chat.useClaudeHooks setting in configuration schema. |
| src/vs/workbench/contrib/chat/browser/actions/chatCustomizationDiagnosticsAction.ts | Adds diagnostics messaging for the new skip reason claude-hooks-disabled. |
| this.storageService.store(disabledClaudeHooksDismissedKey, true, StorageScope.WORKSPACE, StorageTarget.USER); | ||
| if (hasDisabledClaudeHooks) { | ||
| progressCallback([{ kind: 'disabledClaudeHooks' }]); |
There was a problem hiding this comment.
The dismissal flag is stored before checking hasDisabledClaudeHooks, so the “disabled Claude hooks” warning can be permanently suppressed for the workspace even when there was nothing to warn about (and it also won’t show later if Claude hooks are added). Only persist the dismissal flag when the warning is actually shown (or store a separate “already checked” flag).
| this.storageService.store(disabledClaudeHooksDismissedKey, true, StorageScope.WORKSPACE, StorageTarget.USER); | |
| if (hasDisabledClaudeHooks) { | |
| progressCallback([{ kind: 'disabledClaudeHooks' }]); | |
| if (hasDisabledClaudeHooks) { | |
| progressCallback([{ kind: 'disabledClaudeHooks' }]); | |
| this.storageService.store(disabledClaudeHooksDismissedKey, true, StorageScope.WORKSPACE, StorageTarget.USER); |
| const enableLink = createMarkdownCommandLink({ | ||
| title: localize('chat.disabledClaudeHooks.enableLink', "Enable"), | ||
| id: 'workbench.action.openSettings', | ||
| arguments: [PromptsConfig.USE_CLAUDE_HOOKS], | ||
| }); | ||
| const message = localize('chat.disabledClaudeHooks.message', "Claude Code hooks are available for this workspace. {0}", enableLink); | ||
| const content = new MarkdownString(message, { isTrusted: true }); | ||
|
|
||
| const rendered = this._register(this._markdownRendererService.render(content, { | ||
| actionHandler: (href) => openLinkFromMarkdown(this._openerService, href, true), | ||
| })); |
There was a problem hiding this comment.
MarkdownString is marked isTrusted: true, which allows all command links in the rendered markdown. Since this message only needs to invoke workbench.action.openSettings, it would be safer to restrict trust to an explicit allow-list (e.g. isTrusted: { enabledCommands: ['workbench.action.openSettings'] }).
src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.ts
Show resolved
Hide resolved
…roach-main # Conflicts: # src/vs/workbench/contrib/chat/browser/chat.contribution.ts # src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.ts
Port of #294712 to main