-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathintercepts.test.ts
More file actions
116 lines (106 loc) · 3.95 KB
/
Copy pathintercepts.test.ts
File metadata and controls
116 lines (106 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { describe, expect, it } from 'vitest';
import {
getInterceptMarkdown,
intercept,
isClaudeClient,
META_INTERCEPT_REASON,
} from './intercepts.ts';
describe('intercepts', () => {
it.each([
['no-instance', 'Storybook is not running'],
['addon-missing', '@storybook/addon-mcp'],
['mcp-starting', 'starting up'],
['mcp-error', 'reported an error'],
['invalid-cwd', 'absolute path'],
['storybook-too-old', 'storybook-upgrade'],
] as const)('%s contains an actionable hint', (reason, needle) => {
expect(getInterceptMarkdown(reason)).toContain(needle);
});
it('no-instance omits Claude launch repair guidance for generic clients', () => {
const md = getInterceptMarkdown('no-instance');
expect(md).toContain('Storybook is not running');
expect(md).not.toContain('storybook-setup-claude-launch');
});
it('no-instance includes Claude launch repair guidance for Claude clients', () => {
const md = getInterceptMarkdown('no-instance', undefined, {
clientInfo: { name: 'claude-code', version: '2.1.145' },
});
expect(md).toContain('storybook-setup-claude-launch');
expect(md).toContain('.claude/launch.json');
});
it('storybook-too-old reports the detected version, the required version, and points to the upgrade skill', () => {
const md = getInterceptMarkdown('storybook-too-old', { version: '9.0.5' });
expect(md).toMatchInlineSnapshot(`
"The Storybook installed at this cwd is version \`9.0.5\`, but this plugin requires \`9.1.16\` or newer.
Ask the user whether they want to upgrade Storybook. If they agree, invoke the \`storybook-upgrade\` skill to perform the upgrade, then run:
\`\`\`
npx storybook add @storybook/addon-mcp
\`\`\`
to install the MCP addon. After the upgrade, call the \`clear-storybook-version-cache\` tool with the same \`cwd\` so the proxy re-detects the new version. Restart Storybook, then retry the tool call."
`);
});
it('no-instance lists running candidates when any are provided', () => {
const records = [
{
schemaVersion: 1 as const,
instanceId: 'a',
pid: 1,
cwd: '/a',
url: 'http://localhost:6006',
port: 6006,
mcp: { status: 'ready' as const, endpoint: 'http://localhost:6006/mcp' },
},
];
const md = getInterceptMarkdown('no-instance', { records });
expect(md).toContain('Running Storybooks');
expect(md).toContain('/a');
expect(md).toContain('http://localhost:6006');
expect(md).not.toContain('storybook-setup-claude-launch');
const claudeMd = getInterceptMarkdown(
'no-instance',
{ records },
{ clientInfo: { name: 'Claude Code', version: '2.1.145' } },
);
expect(claudeMd).toContain('storybook-setup-claude-launch');
});
it('multiple-matches lists conflicting pids', () => {
const md = getInterceptMarkdown('multiple-matches', {
records: [
{
schemaVersion: 1,
instanceId: 'a',
pid: 111,
cwd: '/same',
url: 'http://localhost:6006',
port: 6006,
mcp: { status: 'ready', endpoint: 'http://localhost:6006/mcp' },
},
{
schemaVersion: 1,
instanceId: 'b',
pid: 222,
cwd: '/same',
url: 'http://localhost:6007',
port: 6007,
mcp: { status: 'ready', endpoint: 'http://localhost:6007/mcp' },
},
],
});
expect(md).toContain('111');
expect(md).toContain('222');
expect(md).toContain('/same');
});
it('intercept() returns a tool result with isError and namespaced reason metadata', () => {
const result = intercept('no-instance');
expect(result.isError).toBe(true);
expect(result._meta).toEqual({ [META_INTERCEPT_REASON]: 'no-instance' });
expect(META_INTERCEPT_REASON).toBe('storybook.dev/interceptReason');
expect(result.content[0]?.type).toBe('text');
});
it('detects Claude from MCP client metadata', () => {
expect(isClaudeClient({ name: 'claude-code' })).toBe(true);
expect(isClaudeClient({ title: 'Claude Code' })).toBe(true);
expect(isClaudeClient({ name: 'test-client' })).toBe(false);
expect(isClaudeClient(undefined)).toBe(false);
});
});