Skip to content

Commit 838e9b2

Browse files
committed
fix(doctor): exclude metadata email lines from Claude Code plugin block detection
Use [^\w\s@] instead of \S in plugin line patterns to prevent Publisher/metadata lines containing @ from being merged into the safety-net plugin block.
1 parent a2fe894 commit 838e9b2

3 files changed

Lines changed: 28 additions & 4 deletions

File tree

dist/bin/cc-safety-net.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5206,8 +5206,8 @@ function detectClaudeCode(pluginListOutput) {
52065206
};
52075207
}
52085208
function _findClaudeSafetyNetPluginBlock(output) {
5209-
const pluginLinePattern = new RegExp(`^\\s*(?:\\S+\\s+)?${_escapeRegExp(CLAUDE_SAFETY_NET_PLUGIN_ID)}\\s*$`);
5210-
const pluginStartPattern = /^\s*(?:\S+\s+)?\S+@\S+\s*$/;
5209+
const pluginLinePattern = new RegExp(`^\\s*(?:[^\\w\\s@]+\\s+)?${_escapeRegExp(CLAUDE_SAFETY_NET_PLUGIN_ID)}\\s*$`);
5210+
const pluginStartPattern = /^\s*(?:[^\w\s@]+\s+)?\S+@\S+\s*$/;
52115211
const lines = output.split(`
52125212
`);
52135213
const startIndex = lines.findIndex((line) => pluginLinePattern.test(line));

src/bin/doctor/hooks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,9 @@ function detectClaudeCode(pluginListOutput: string | null | undefined): HookStat
264264

265265
function _findClaudeSafetyNetPluginBlock(output: string): string | undefined {
266266
const pluginLinePattern = new RegExp(
267-
`^\\s*(?:\\S+\\s+)?${_escapeRegExp(CLAUDE_SAFETY_NET_PLUGIN_ID)}\\s*$`,
267+
`^\\s*(?:[^\\w\\s@]+\\s+)?${_escapeRegExp(CLAUDE_SAFETY_NET_PLUGIN_ID)}\\s*$`,
268268
);
269-
const pluginStartPattern = /^\s*(?:\S+\s+)?\S+@\S+\s*$/;
269+
const pluginStartPattern = /^\s*(?:[^\w\s@]+\s+)?\S+@\S+\s*$/;
270270
const lines = output.split('\n');
271271
const startIndex = lines.findIndex((line) => pluginLinePattern.test(line));
272272

tests/bin/doctor/hooks.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,30 @@ describe('detectAllHooks', () => {
228228
}
229229
});
230230

231+
test('Claude Code: keeps metadata email lines inside the safety-net entry', () => {
232+
const tmpBase = join(tmpdir(), `doctor-hooks-${Date.now()}`);
233+
const homeDir = join(tmpBase, 'home');
234+
const projectDir = join(tmpBase, 'project');
235+
mkdirSync(homeDir, { recursive: true });
236+
mkdirSync(projectDir, { recursive: true });
237+
238+
try {
239+
const hooks = detectAllHooks(projectDir, {
240+
homeDir,
241+
claudePluginListOutput: `Installed plugins:
242+
❯ safety-net@cc-marketplace
243+
Version: 0.8.2
244+
Publisher: author@example.com
245+
Status: ✔ enabled`,
246+
});
247+
const claude = hooks.find((hook) => hook.platform === 'claude-code');
248+
expect(claude?.status).toBe('configured');
249+
expect(claude?.method).toBe('plugin list');
250+
} finally {
251+
rmSync(tmpBase, { recursive: true, force: true });
252+
}
253+
});
254+
231255
test('Claude Code: n/a when plugin list is unavailable', () => {
232256
const tmpBase = join(tmpdir(), `doctor-hooks-${Date.now()}`);
233257
const homeDir = join(tmpBase, 'home');

0 commit comments

Comments
 (0)