@brookmind/ai-toolkit 1.1.7 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +42 -14
- package/dist/__tests__/constants.test.d.ts +2 -0
- package/dist/__tests__/constants.test.d.ts.map +1 -0
- package/dist/__tests__/constants.test.js +102 -0
- package/dist/__tests__/constants.test.js.map +1 -0
- package/dist/__tests__/index.test.d.ts +2 -0
- package/dist/__tests__/index.test.d.ts.map +1 -0
- package/dist/__tests__/index.test.js +114 -0
- package/dist/__tests__/index.test.js.map +1 -0
- package/dist/__tests__/integration/installer.test.d.ts +2 -0
- package/dist/__tests__/integration/installer.test.d.ts.map +1 -0
- package/dist/__tests__/integration/installer.test.js +425 -0
- package/dist/__tests__/integration/installer.test.js.map +1 -0
- package/dist/__tests__/services/installers.test.d.ts +2 -0
- package/dist/__tests__/services/installers.test.d.ts.map +1 -0
- package/dist/__tests__/services/installers.test.js +222 -0
- package/dist/__tests__/services/installers.test.js.map +1 -0
- package/dist/__tests__/services/opencode.test.d.ts +2 -0
- package/dist/__tests__/services/opencode.test.d.ts.map +1 -0
- package/dist/__tests__/services/opencode.test.js +120 -0
- package/dist/__tests__/services/opencode.test.js.map +1 -0
- package/dist/__tests__/ui/categorize.test.d.ts +2 -0
- package/dist/__tests__/ui/categorize.test.d.ts.map +1 -0
- package/dist/__tests__/ui/categorize.test.js +194 -0
- package/dist/__tests__/ui/categorize.test.js.map +1 -0
- package/dist/__tests__/ui/choices.test.d.ts +2 -0
- package/dist/__tests__/ui/choices.test.d.ts.map +1 -0
- package/dist/__tests__/ui/choices.test.js +180 -0
- package/dist/__tests__/ui/choices.test.js.map +1 -0
- package/dist/__tests__/ui/display.test.d.ts +2 -0
- package/dist/__tests__/ui/display.test.d.ts.map +1 -0
- package/dist/__tests__/ui/display.test.js +142 -0
- package/dist/__tests__/ui/display.test.js.map +1 -0
- package/dist/__tests__/utils/fs.test.d.ts +2 -0
- package/dist/__tests__/utils/fs.test.d.ts.map +1 -0
- package/dist/__tests__/utils/fs.test.js +142 -0
- package/dist/__tests__/utils/fs.test.js.map +1 -0
- package/dist/__tests__/utils/terminal.test.d.ts +2 -0
- package/dist/__tests__/utils/terminal.test.d.ts.map +1 -0
- package/dist/__tests__/utils/terminal.test.js +97 -0
- package/dist/__tests__/utils/terminal.test.js.map +1 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +40 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -332
- package/dist/index.js.map +1 -1
- package/dist/services/installers.d.ts +8 -0
- package/dist/services/installers.d.ts.map +1 -0
- package/dist/services/installers.js +79 -0
- package/dist/services/installers.js.map +1 -0
- package/dist/services/opencode.d.ts +3 -0
- package/dist/services/opencode.d.ts.map +1 -0
- package/dist/services/opencode.js +33 -0
- package/dist/services/opencode.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/categorize.d.ts +6 -0
- package/dist/ui/categorize.d.ts.map +1 -0
- package/dist/ui/categorize.js +69 -0
- package/dist/ui/categorize.js.map +1 -0
- package/dist/ui/choices.d.ts +6 -0
- package/dist/ui/choices.d.ts.map +1 -0
- package/dist/ui/choices.js +70 -0
- package/dist/ui/choices.js.map +1 -0
- package/dist/ui/display.d.ts +8 -0
- package/dist/ui/display.d.ts.map +1 -0
- package/dist/ui/display.js +86 -0
- package/dist/ui/display.js.map +1 -0
- package/dist/utils/fs.d.ts +5 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +40 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/terminal.d.ts +5 -0
- package/dist/utils/terminal.d.ts.map +1 -0
- package/dist/utils/terminal.js +18 -0
- package/dist/utils/terminal.js.map +1 -0
- package/package.json +29 -5
- package/agents/code-reviewer.md +0 -35
- package/agents/code-simplifier.md +0 -52
- package/commands/create-pr-description.md +0 -102
- package/commands/create-pr.md +0 -76
- package/commands/create-react-tests.md +0 -207
- package/mcps/context7/.mcp.json +0 -13
- package/mcps/expo-mcp/.mcp.json +0 -13
- package/mcps/figma-mcp/.mcp.json +0 -10
- package/skills/github-cli/SKILL.md +0 -125
- package/skills/pdf-processing-pro/FORMS.md +0 -610
- package/skills/pdf-processing-pro/OCR.md +0 -137
- package/skills/pdf-processing-pro/SKILL.md +0 -296
- package/skills/pdf-processing-pro/TABLES.md +0 -626
- package/skills/pdf-processing-pro/scripts/analyze_form.py +0 -307
- package/skills/react-best-practices/AGENTS.md +0 -915
- package/skills/react-best-practices/README.md +0 -127
- package/skills/react-best-practices/SKILL.md +0 -110
- package/skills/react-best-practices/metadata.json +0 -14
- package/skills/react-best-practices/rules/_sections.md +0 -41
- package/skills/react-best-practices/rules/_template.md +0 -28
- package/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -80
- package/skills/react-best-practices/rules/advanced-use-latest.md +0 -76
- package/skills/react-best-practices/rules/async-defer-await.md +0 -80
- package/skills/react-best-practices/rules/async-dependencies.md +0 -36
- package/skills/react-best-practices/rules/async-parallel.md +0 -28
- package/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -100
- package/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -42
- package/skills/react-best-practices/rules/bundle-conditional.md +0 -106
- package/skills/react-best-practices/rules/bundle-preload.md +0 -44
- package/skills/react-best-practices/rules/client-event-listeners.md +0 -131
- package/skills/react-best-practices/rules/client-swr-dedup.md +0 -133
- package/skills/react-best-practices/rules/js-batch-dom-css.md +0 -82
- package/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
- package/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
- package/skills/react-best-practices/rules/js-cache-storage.md +0 -70
- package/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
- package/skills/react-best-practices/rules/js-early-exit.md +0 -50
- package/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/skills/react-best-practices/rules/js-index-maps.md +0 -37
- package/skills/react-best-practices/rules/js-length-check-first.md +0 -49
- package/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
- package/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/skills/react-best-practices/rules/rendering-activity.md +0 -90
- package/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -65
- package/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
- package/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
- package/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/skills/react-best-practices/rules/rerender-memo.md +0 -85
- package/skills/react-best-practices/rules/rerender-transitions.md +0 -40
- package/skills/skill-creator/LICENSE.txt +0 -202
- package/skills/skill-creator/SKILL.md +0 -209
- package/skills/skill-creator/scripts/init_skill.py +0 -303
- package/skills/skill-creator/scripts/package_skill.py +0 -110
- package/skills/skill-creator/scripts/quick_validate.py +0 -65
- package/skills/spring-boot-development/EXAMPLES.md +0 -2346
- package/skills/spring-boot-development/README.md +0 -595
- package/skills/spring-boot-development/SKILL.md +0 -1519
- package/themes/README.md +0 -68
- package/themes/claude-vivid.json +0 -72
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { buildAgentChoices, buildSkillChoices, buildCommandChoices, buildMcpChoices, } from '../../ui/choices.js';
|
|
3
|
+
vi.mock('../../utils/fs.js', () => ({
|
|
4
|
+
exists: vi.fn(),
|
|
5
|
+
readJsonConfig: vi.fn(),
|
|
6
|
+
}));
|
|
7
|
+
vi.mock('../../services/installers.js', () => ({
|
|
8
|
+
getInstalledMcps: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
vi.mock('../../constants.js', async (importOriginal) => {
|
|
11
|
+
const original = await importOriginal();
|
|
12
|
+
return {
|
|
13
|
+
...original,
|
|
14
|
+
getDescription: vi.fn((name) => {
|
|
15
|
+
const descriptions = {
|
|
16
|
+
'test-agent': 'Test agent description',
|
|
17
|
+
'test-skill': 'Test skill description',
|
|
18
|
+
'test-command': 'Test command description',
|
|
19
|
+
'test-mcp': 'Test MCP description',
|
|
20
|
+
};
|
|
21
|
+
return descriptions[name] ?? null;
|
|
22
|
+
}),
|
|
23
|
+
MCP_DISPLAY_NAMES: {
|
|
24
|
+
'pg-aiguide': 'postgres-mcp',
|
|
25
|
+
},
|
|
26
|
+
OPENCODE_DIR: '/fake/opencode',
|
|
27
|
+
TOOLS_DIR: '/fake/tools',
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
describe('ui/choices', () => {
|
|
31
|
+
let mockExists;
|
|
32
|
+
let mockReadJsonConfig;
|
|
33
|
+
let mockGetInstalledMcps;
|
|
34
|
+
beforeEach(async () => {
|
|
35
|
+
vi.resetAllMocks();
|
|
36
|
+
const fsModule = await import('../../utils/fs.js');
|
|
37
|
+
mockExists = fsModule.exists;
|
|
38
|
+
mockReadJsonConfig = fsModule.readJsonConfig;
|
|
39
|
+
const installersModule = await import('../../services/installers.js');
|
|
40
|
+
mockGetInstalledMcps = installersModule.getInstalledMcps;
|
|
41
|
+
mockExists.mockResolvedValue(false);
|
|
42
|
+
mockReadJsonConfig.mockResolvedValue({});
|
|
43
|
+
mockGetInstalledMcps.mockResolvedValue(new Set());
|
|
44
|
+
});
|
|
45
|
+
afterEach(() => {
|
|
46
|
+
vi.clearAllMocks();
|
|
47
|
+
});
|
|
48
|
+
describe('buildAgentChoices', () => {
|
|
49
|
+
it('should return empty array for empty agents', async () => {
|
|
50
|
+
const result = await buildAgentChoices([]);
|
|
51
|
+
expect(result).toEqual([]);
|
|
52
|
+
});
|
|
53
|
+
it('should build choices for new agents', async () => {
|
|
54
|
+
mockExists.mockResolvedValue(false);
|
|
55
|
+
const result = await buildAgentChoices(['test-agent']);
|
|
56
|
+
expect(result).toHaveLength(1);
|
|
57
|
+
expect(result[0].value).toBe('test-agent');
|
|
58
|
+
expect(result[0].name).toContain('test-agent');
|
|
59
|
+
expect(result[0].name).toContain('Test agent description');
|
|
60
|
+
expect(result[0].name).not.toContain('(installed)');
|
|
61
|
+
});
|
|
62
|
+
it('should mark installed agents', async () => {
|
|
63
|
+
mockExists.mockResolvedValue(true);
|
|
64
|
+
const result = await buildAgentChoices(['test-agent']);
|
|
65
|
+
expect(result[0].name).toContain('(installed)');
|
|
66
|
+
});
|
|
67
|
+
it('should build choices for multiple agents', async () => {
|
|
68
|
+
mockExists.mockResolvedValueOnce(false).mockResolvedValueOnce(true);
|
|
69
|
+
const result = await buildAgentChoices(['agent1', 'agent2']);
|
|
70
|
+
expect(result).toHaveLength(2);
|
|
71
|
+
expect(result[0].value).toBe('agent1');
|
|
72
|
+
expect(result[1].value).toBe('agent2');
|
|
73
|
+
});
|
|
74
|
+
it('should handle agents without description', async () => {
|
|
75
|
+
mockExists.mockResolvedValue(false);
|
|
76
|
+
const result = await buildAgentChoices(['unknown-agent']);
|
|
77
|
+
expect(result[0].value).toBe('unknown-agent');
|
|
78
|
+
expect(result[0].name).toContain('unknown-agent');
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe('buildSkillChoices', () => {
|
|
82
|
+
it('should return empty array for empty skills', async () => {
|
|
83
|
+
const result = await buildSkillChoices([]);
|
|
84
|
+
expect(result).toEqual([]);
|
|
85
|
+
});
|
|
86
|
+
it('should build choices for new skills', async () => {
|
|
87
|
+
mockExists.mockResolvedValue(false);
|
|
88
|
+
const result = await buildSkillChoices(['test-skill']);
|
|
89
|
+
expect(result).toHaveLength(1);
|
|
90
|
+
expect(result[0].value).toBe('test-skill');
|
|
91
|
+
expect(result[0].name).toContain('test-skill');
|
|
92
|
+
expect(result[0].name).toContain('Test skill description');
|
|
93
|
+
});
|
|
94
|
+
it('should mark installed skills', async () => {
|
|
95
|
+
mockExists.mockResolvedValue(true);
|
|
96
|
+
const result = await buildSkillChoices(['test-skill']);
|
|
97
|
+
expect(result[0].name).toContain('(installed)');
|
|
98
|
+
});
|
|
99
|
+
it('should build choices for multiple skills', async () => {
|
|
100
|
+
mockExists.mockResolvedValueOnce(false).mockResolvedValueOnce(true);
|
|
101
|
+
const result = await buildSkillChoices(['skill1', 'skill2']);
|
|
102
|
+
expect(result).toHaveLength(2);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe('buildCommandChoices', () => {
|
|
106
|
+
it('should return empty array for empty commands', async () => {
|
|
107
|
+
const result = await buildCommandChoices([]);
|
|
108
|
+
expect(result).toEqual([]);
|
|
109
|
+
});
|
|
110
|
+
it('should build choices for new commands', async () => {
|
|
111
|
+
mockExists.mockResolvedValue(false);
|
|
112
|
+
const result = await buildCommandChoices(['test-command']);
|
|
113
|
+
expect(result).toHaveLength(1);
|
|
114
|
+
expect(result[0].value).toBe('test-command');
|
|
115
|
+
expect(result[0].name).toContain('test-command');
|
|
116
|
+
expect(result[0].name).toContain('Test command description');
|
|
117
|
+
});
|
|
118
|
+
it('should mark installed commands', async () => {
|
|
119
|
+
mockExists.mockResolvedValue(true);
|
|
120
|
+
const result = await buildCommandChoices(['test-command']);
|
|
121
|
+
expect(result[0].name).toContain('(installed)');
|
|
122
|
+
});
|
|
123
|
+
it('should build choices for multiple commands', async () => {
|
|
124
|
+
mockExists.mockResolvedValueOnce(true).mockResolvedValueOnce(false);
|
|
125
|
+
const result = await buildCommandChoices(['cmd1', 'cmd2']);
|
|
126
|
+
expect(result).toHaveLength(2);
|
|
127
|
+
expect(result[0].name).toContain('(installed)');
|
|
128
|
+
expect(result[1].name).not.toContain('(installed)');
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe('buildMcpChoices', () => {
|
|
132
|
+
it('should return empty array for empty mcps', async () => {
|
|
133
|
+
const result = await buildMcpChoices([]);
|
|
134
|
+
expect(result).toEqual([]);
|
|
135
|
+
});
|
|
136
|
+
it('should build choices for new mcps', async () => {
|
|
137
|
+
mockGetInstalledMcps.mockResolvedValue(new Set());
|
|
138
|
+
mockReadJsonConfig.mockResolvedValue({
|
|
139
|
+
mcpServers: { 'test-server': {} },
|
|
140
|
+
});
|
|
141
|
+
const result = await buildMcpChoices(['test-mcp']);
|
|
142
|
+
expect(result).toHaveLength(1);
|
|
143
|
+
expect(result[0].value).toBe('test-mcp');
|
|
144
|
+
expect(result[0].name).toContain('test-mcp');
|
|
145
|
+
});
|
|
146
|
+
it('should mark installed mcps based on server names', async () => {
|
|
147
|
+
mockGetInstalledMcps.mockResolvedValue(new Set(['test-server']));
|
|
148
|
+
mockReadJsonConfig.mockResolvedValue({
|
|
149
|
+
mcpServers: { 'test-server': {} },
|
|
150
|
+
});
|
|
151
|
+
const result = await buildMcpChoices(['test-mcp']);
|
|
152
|
+
expect(result[0].name).toContain('(installed)');
|
|
153
|
+
});
|
|
154
|
+
it('should use display name from MCP_DISPLAY_NAMES', async () => {
|
|
155
|
+
mockGetInstalledMcps.mockResolvedValue(new Set());
|
|
156
|
+
mockReadJsonConfig.mockResolvedValue({
|
|
157
|
+
mcpServers: { 'pg-server': {} },
|
|
158
|
+
});
|
|
159
|
+
const result = await buildMcpChoices(['pg-aiguide']);
|
|
160
|
+
expect(result[0].name).toContain('postgres-mcp');
|
|
161
|
+
expect(result[0].value).toBe('pg-aiguide');
|
|
162
|
+
});
|
|
163
|
+
it('should handle mcps without servers', async () => {
|
|
164
|
+
mockGetInstalledMcps.mockResolvedValue(new Set());
|
|
165
|
+
mockReadJsonConfig.mockResolvedValue({});
|
|
166
|
+
const result = await buildMcpChoices(['test-mcp']);
|
|
167
|
+
expect(result).toHaveLength(1);
|
|
168
|
+
expect(result[0].name).not.toContain('(installed)');
|
|
169
|
+
});
|
|
170
|
+
it('should build choices for multiple mcps', async () => {
|
|
171
|
+
mockGetInstalledMcps.mockResolvedValue(new Set(['server1']));
|
|
172
|
+
mockReadJsonConfig
|
|
173
|
+
.mockResolvedValueOnce({ mcpServers: { server1: {} } })
|
|
174
|
+
.mockResolvedValueOnce({ mcpServers: { server2: {} } });
|
|
175
|
+
const result = await buildMcpChoices(['mcp1', 'mcp2']);
|
|
176
|
+
expect(result).toHaveLength(2);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
//# sourceMappingURL=choices.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"choices.test.js","sourceRoot":"","sources":["../../../src/__tests__/ui/choices.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/ui/display.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { displayHeader, formatCategorized, formatTheme, showSelectionResult, getSeparator, displaySummary, } from '../../ui/display.js';
|
|
3
|
+
vi.mock('../../utils/fs.js', () => ({
|
|
4
|
+
readJsonConfig: vi.fn(),
|
|
5
|
+
}));
|
|
6
|
+
vi.mock('../../utils/terminal.js', () => ({
|
|
7
|
+
clearScreen: vi.fn(),
|
|
8
|
+
}));
|
|
9
|
+
describe('ui/display', () => {
|
|
10
|
+
let mockReadJsonConfig;
|
|
11
|
+
let mockClearScreen;
|
|
12
|
+
let consoleLogSpy;
|
|
13
|
+
beforeEach(async () => {
|
|
14
|
+
vi.resetAllMocks();
|
|
15
|
+
const fsModule = await import('../../utils/fs.js');
|
|
16
|
+
mockReadJsonConfig = fsModule.readJsonConfig;
|
|
17
|
+
const terminalModule = await import('../../utils/terminal.js');
|
|
18
|
+
mockClearScreen = terminalModule.clearScreen;
|
|
19
|
+
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => undefined);
|
|
20
|
+
mockReadJsonConfig.mockResolvedValue({ version: '1.0.0' });
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
consoleLogSpy.mockRestore();
|
|
24
|
+
vi.clearAllMocks();
|
|
25
|
+
});
|
|
26
|
+
describe('displayHeader', () => {
|
|
27
|
+
it('should read package.json and display header', async () => {
|
|
28
|
+
await displayHeader();
|
|
29
|
+
expect(mockReadJsonConfig).toHaveBeenCalled();
|
|
30
|
+
expect(mockClearScreen).toHaveBeenCalled();
|
|
31
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
32
|
+
});
|
|
33
|
+
it('should call clearScreen', async () => {
|
|
34
|
+
await displayHeader();
|
|
35
|
+
expect(mockClearScreen).toHaveBeenCalled();
|
|
36
|
+
});
|
|
37
|
+
it('should display logo', async () => {
|
|
38
|
+
await displayHeader();
|
|
39
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe('formatCategorized', () => {
|
|
43
|
+
it('should return "none" for empty categorized items', () => {
|
|
44
|
+
const cat = { new: [], update: [] };
|
|
45
|
+
const result = formatCategorized(cat);
|
|
46
|
+
expect(result).toContain('none');
|
|
47
|
+
});
|
|
48
|
+
it('should format only new items', () => {
|
|
49
|
+
const cat = { new: ['item1', 'item2'], update: [] };
|
|
50
|
+
const result = formatCategorized(cat);
|
|
51
|
+
expect(result).toContain('+ item1, item2');
|
|
52
|
+
});
|
|
53
|
+
it('should format only update items', () => {
|
|
54
|
+
const cat = { new: [], update: ['item1', 'item2'] };
|
|
55
|
+
const result = formatCategorized(cat);
|
|
56
|
+
expect(result).toContain('↻ item1, item2');
|
|
57
|
+
});
|
|
58
|
+
it('should format mixed new and update items', () => {
|
|
59
|
+
const cat = { new: ['new1'], update: ['upd1'] };
|
|
60
|
+
const result = formatCategorized(cat);
|
|
61
|
+
expect(result).toContain('+ new1');
|
|
62
|
+
expect(result).toContain('↻ upd1');
|
|
63
|
+
});
|
|
64
|
+
it('should join items with comma and space', () => {
|
|
65
|
+
const cat = { new: ['a', 'b', 'c'], update: [] };
|
|
66
|
+
const result = formatCategorized(cat);
|
|
67
|
+
expect(result).toContain('a, b, c');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('formatTheme', () => {
|
|
71
|
+
it('should return "none" when installThemeChoice is false', () => {
|
|
72
|
+
const result = formatTheme(false, false);
|
|
73
|
+
expect(result).toContain('none');
|
|
74
|
+
});
|
|
75
|
+
it('should return new format when installing new theme', () => {
|
|
76
|
+
const result = formatTheme(true, false);
|
|
77
|
+
expect(result).toContain('+ claude-vivid');
|
|
78
|
+
});
|
|
79
|
+
it('should return update format when updating theme', () => {
|
|
80
|
+
const result = formatTheme(true, true);
|
|
81
|
+
expect(result).toContain('↻ claude-vivid');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
describe('showSelectionResult', () => {
|
|
85
|
+
it('should show checkmark for count > 0', () => {
|
|
86
|
+
showSelectionResult(3, 'agents');
|
|
87
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
88
|
+
const call = consoleLogSpy.mock.calls[0][0];
|
|
89
|
+
expect(call).toContain('✓');
|
|
90
|
+
expect(call).toContain('3 agents selected');
|
|
91
|
+
});
|
|
92
|
+
it('should show dim message for count = 0', () => {
|
|
93
|
+
showSelectionResult(0, 'skills');
|
|
94
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
95
|
+
const call = consoleLogSpy.mock.calls[0][0];
|
|
96
|
+
expect(call).toContain('No skills selected');
|
|
97
|
+
});
|
|
98
|
+
it('should use singular/plural label as provided', () => {
|
|
99
|
+
showSelectionResult(1, 'item');
|
|
100
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
101
|
+
const call = consoleLogSpy.mock.calls[0][0];
|
|
102
|
+
expect(call).toContain('1 item selected');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe('getSeparator', () => {
|
|
106
|
+
it('should return separator line', () => {
|
|
107
|
+
const result = getSeparator();
|
|
108
|
+
expect(result).toContain('─'.repeat(50));
|
|
109
|
+
});
|
|
110
|
+
it('should return consistent length', () => {
|
|
111
|
+
const result1 = getSeparator();
|
|
112
|
+
const result2 = getSeparator();
|
|
113
|
+
expect(result1).toBe(result2);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
describe('displaySummary', () => {
|
|
117
|
+
it('should display summary with all categories', () => {
|
|
118
|
+
const agents = { new: ['a1'], update: [] };
|
|
119
|
+
const skills = { new: [], update: ['s1'] };
|
|
120
|
+
const commands = { new: ['c1'], update: ['c2'] };
|
|
121
|
+
const mcps = { new: [], update: [] };
|
|
122
|
+
displaySummary(agents, skills, commands, mcps, false, false);
|
|
123
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
124
|
+
});
|
|
125
|
+
it('should display summary box', () => {
|
|
126
|
+
const empty = { new: [], update: [] };
|
|
127
|
+
displaySummary(empty, empty, empty, empty, false, false);
|
|
128
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
129
|
+
});
|
|
130
|
+
it('should include all category labels', () => {
|
|
131
|
+
const empty = { new: [], update: [] };
|
|
132
|
+
displaySummary(empty, empty, empty, empty, true, false);
|
|
133
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
134
|
+
});
|
|
135
|
+
it('should count theme update in totalUpdate', () => {
|
|
136
|
+
const empty = { new: [], update: [] };
|
|
137
|
+
displaySummary(empty, empty, empty, empty, true, true);
|
|
138
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
//# sourceMappingURL=display.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.test.js","sourceRoot":"","sources":["../../../src/__tests__/ui/display.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/utils/fs.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { mkdir, rm, writeFile } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { exists, getDirectories, getFiles, readJsonConfig } from '../../utils/fs.js';
|
|
6
|
+
describe('utils/fs', () => {
|
|
7
|
+
const testDir = join(tmpdir(), 'ai-toolkit-fs-test');
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
await mkdir(testDir, { recursive: true });
|
|
10
|
+
});
|
|
11
|
+
afterEach(async () => {
|
|
12
|
+
await rm(testDir, { recursive: true, force: true });
|
|
13
|
+
});
|
|
14
|
+
describe('exists', () => {
|
|
15
|
+
it('should return true for existing directory', async () => {
|
|
16
|
+
const result = await exists(testDir);
|
|
17
|
+
expect(result).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
it('should return true for existing file', async () => {
|
|
20
|
+
const filePath = join(testDir, 'test.txt');
|
|
21
|
+
await writeFile(filePath, 'test content');
|
|
22
|
+
const result = await exists(filePath);
|
|
23
|
+
expect(result).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
it('should return false for non-existing path', async () => {
|
|
26
|
+
const result = await exists(join(testDir, 'non-existing'));
|
|
27
|
+
expect(result).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
it('should return false for non-existing nested path', async () => {
|
|
30
|
+
const result = await exists(join(testDir, 'a', 'b', 'c', 'd'));
|
|
31
|
+
expect(result).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe('getDirectories', () => {
|
|
35
|
+
it('should return empty array for empty directory', async () => {
|
|
36
|
+
const result = await getDirectories(testDir);
|
|
37
|
+
expect(result).toEqual([]);
|
|
38
|
+
});
|
|
39
|
+
it('should return only directories, not files', async () => {
|
|
40
|
+
await mkdir(join(testDir, 'dir1'));
|
|
41
|
+
await mkdir(join(testDir, 'dir2'));
|
|
42
|
+
await writeFile(join(testDir, 'file.txt'), 'content');
|
|
43
|
+
const result = await getDirectories(testDir);
|
|
44
|
+
expect(result).toHaveLength(2);
|
|
45
|
+
expect(result).toContain('dir1');
|
|
46
|
+
expect(result).toContain('dir2');
|
|
47
|
+
expect(result).not.toContain('file.txt');
|
|
48
|
+
});
|
|
49
|
+
it('should return empty array for non-existing directory', async () => {
|
|
50
|
+
const result = await getDirectories(join(testDir, 'non-existing'));
|
|
51
|
+
expect(result).toEqual([]);
|
|
52
|
+
});
|
|
53
|
+
it('should return empty array on error', async () => {
|
|
54
|
+
const result = await getDirectories('/root/definitely/does/not/exist/xyz');
|
|
55
|
+
expect(result).toEqual([]);
|
|
56
|
+
});
|
|
57
|
+
it('should handle directory with only files', async () => {
|
|
58
|
+
await writeFile(join(testDir, 'file1.txt'), 'content1');
|
|
59
|
+
await writeFile(join(testDir, 'file2.txt'), 'content2');
|
|
60
|
+
const result = await getDirectories(testDir);
|
|
61
|
+
expect(result).toEqual([]);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe('getFiles', () => {
|
|
65
|
+
it('should return files with specified extension', async () => {
|
|
66
|
+
await writeFile(join(testDir, 'file1.md'), 'content1');
|
|
67
|
+
await writeFile(join(testDir, 'file2.md'), 'content2');
|
|
68
|
+
await writeFile(join(testDir, 'file3.txt'), 'content3');
|
|
69
|
+
const result = await getFiles(testDir, '.md');
|
|
70
|
+
expect(result).toHaveLength(2);
|
|
71
|
+
expect(result).toContain('file1');
|
|
72
|
+
expect(result).toContain('file2');
|
|
73
|
+
expect(result).not.toContain('file3');
|
|
74
|
+
});
|
|
75
|
+
it('should return empty array when no files match extension', async () => {
|
|
76
|
+
await writeFile(join(testDir, 'file1.txt'), 'content1');
|
|
77
|
+
await writeFile(join(testDir, 'file2.txt'), 'content2');
|
|
78
|
+
const result = await getFiles(testDir, '.md');
|
|
79
|
+
expect(result).toEqual([]);
|
|
80
|
+
});
|
|
81
|
+
it('should return empty array for empty directory', async () => {
|
|
82
|
+
const result = await getFiles(testDir, '.md');
|
|
83
|
+
expect(result).toEqual([]);
|
|
84
|
+
});
|
|
85
|
+
it('should return empty array for non-existing directory', async () => {
|
|
86
|
+
const result = await getFiles(join(testDir, 'non-existing'), '.md');
|
|
87
|
+
expect(result).toEqual([]);
|
|
88
|
+
});
|
|
89
|
+
it('should not include directories', async () => {
|
|
90
|
+
await mkdir(join(testDir, 'dir.md'));
|
|
91
|
+
await writeFile(join(testDir, 'file.md'), 'content');
|
|
92
|
+
const result = await getFiles(testDir, '.md');
|
|
93
|
+
expect(result).toHaveLength(1);
|
|
94
|
+
expect(result).toContain('file');
|
|
95
|
+
});
|
|
96
|
+
it('should strip extension from file names', async () => {
|
|
97
|
+
await writeFile(join(testDir, 'my-file.json'), '{}');
|
|
98
|
+
const result = await getFiles(testDir, '.json');
|
|
99
|
+
expect(result).toEqual(['my-file']);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
describe('readJsonConfig', () => {
|
|
103
|
+
it('should read and parse valid JSON file', async () => {
|
|
104
|
+
const jsonPath = join(testDir, 'config.json');
|
|
105
|
+
const data = { key: 'value', number: 42, nested: { foo: 'bar' } };
|
|
106
|
+
await writeFile(jsonPath, JSON.stringify(data));
|
|
107
|
+
const result = await readJsonConfig(jsonPath);
|
|
108
|
+
expect(result).toEqual(data);
|
|
109
|
+
});
|
|
110
|
+
it('should return empty object for non-existing file', async () => {
|
|
111
|
+
const result = await readJsonConfig(join(testDir, 'non-existing.json'));
|
|
112
|
+
expect(result).toEqual({});
|
|
113
|
+
});
|
|
114
|
+
it('should return empty object for invalid JSON', async () => {
|
|
115
|
+
const jsonPath = join(testDir, 'invalid.json');
|
|
116
|
+
await writeFile(jsonPath, '{ invalid json }');
|
|
117
|
+
const result = await readJsonConfig(jsonPath);
|
|
118
|
+
expect(result).toEqual({});
|
|
119
|
+
});
|
|
120
|
+
it('should return empty object for empty file', async () => {
|
|
121
|
+
const jsonPath = join(testDir, 'empty.json');
|
|
122
|
+
await writeFile(jsonPath, '');
|
|
123
|
+
const result = await readJsonConfig(jsonPath);
|
|
124
|
+
expect(result).toEqual({});
|
|
125
|
+
});
|
|
126
|
+
it('should handle JSON with arrays', async () => {
|
|
127
|
+
const jsonPath = join(testDir, 'array.json');
|
|
128
|
+
const data = { items: [1, 2, 3], names: ['a', 'b'] };
|
|
129
|
+
await writeFile(jsonPath, JSON.stringify(data));
|
|
130
|
+
const result = await readJsonConfig(jsonPath);
|
|
131
|
+
expect(result).toEqual(data);
|
|
132
|
+
});
|
|
133
|
+
it('should handle deeply nested JSON', async () => {
|
|
134
|
+
const jsonPath = join(testDir, 'nested.json');
|
|
135
|
+
const data = { level1: { level2: { level3: { value: 'deep' } } } };
|
|
136
|
+
await writeFile(jsonPath, JSON.stringify(data));
|
|
137
|
+
const result = await readJsonConfig(jsonPath);
|
|
138
|
+
expect(result).toEqual(data);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
//# sourceMappingURL=fs.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.test.js","sourceRoot":"","sources":["../../../src/__tests__/utils/fs.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/utils/terminal.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import { setupScrollRegion, resetScrollRegion, handleResize, clearScreen, } from '../../utils/terminal.js';
|
|
3
|
+
import { BOTTOM_PADDING } from '../../constants.js';
|
|
4
|
+
describe('utils/terminal', () => {
|
|
5
|
+
let writeSpy;
|
|
6
|
+
let originalRows;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
|
|
9
|
+
originalRows = process.stdout.rows;
|
|
10
|
+
});
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
writeSpy.mockRestore();
|
|
13
|
+
Object.defineProperty(process.stdout, 'rows', {
|
|
14
|
+
value: originalRows,
|
|
15
|
+
writable: true,
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe('setupScrollRegion', () => {
|
|
19
|
+
it('should set scroll region when terminal has enough rows', () => {
|
|
20
|
+
Object.defineProperty(process.stdout, 'rows', { value: 40, writable: true });
|
|
21
|
+
setupScrollRegion();
|
|
22
|
+
expect(writeSpy).toHaveBeenCalledTimes(2);
|
|
23
|
+
expect(writeSpy).toHaveBeenNthCalledWith(1, `\x1b[1;${40 - BOTTOM_PADDING}r`);
|
|
24
|
+
expect(writeSpy).toHaveBeenNthCalledWith(2, '\x1b[H');
|
|
25
|
+
});
|
|
26
|
+
it('should not set scroll region when terminal is too small', () => {
|
|
27
|
+
Object.defineProperty(process.stdout, 'rows', { value: 10, writable: true });
|
|
28
|
+
setupScrollRegion();
|
|
29
|
+
expect(writeSpy).not.toHaveBeenCalled();
|
|
30
|
+
});
|
|
31
|
+
it('should use default rows (24) when process.stdout.rows is undefined', () => {
|
|
32
|
+
Object.defineProperty(process.stdout, 'rows', { value: undefined, writable: true });
|
|
33
|
+
setupScrollRegion();
|
|
34
|
+
expect(writeSpy).toHaveBeenCalledTimes(2);
|
|
35
|
+
expect(writeSpy).toHaveBeenNthCalledWith(1, `\x1b[1;${24 - BOTTOM_PADDING}r`);
|
|
36
|
+
expect(writeSpy).toHaveBeenNthCalledWith(2, '\x1b[H');
|
|
37
|
+
});
|
|
38
|
+
it('should not set scroll region at boundary (rows = BOTTOM_PADDING + 10)', () => {
|
|
39
|
+
Object.defineProperty(process.stdout, 'rows', {
|
|
40
|
+
value: BOTTOM_PADDING + 10,
|
|
41
|
+
writable: true,
|
|
42
|
+
});
|
|
43
|
+
setupScrollRegion();
|
|
44
|
+
expect(writeSpy).not.toHaveBeenCalled();
|
|
45
|
+
});
|
|
46
|
+
it('should set scroll region when rows is just above boundary', () => {
|
|
47
|
+
Object.defineProperty(process.stdout, 'rows', {
|
|
48
|
+
value: BOTTOM_PADDING + 11,
|
|
49
|
+
writable: true,
|
|
50
|
+
});
|
|
51
|
+
setupScrollRegion();
|
|
52
|
+
expect(writeSpy).toHaveBeenCalledTimes(2);
|
|
53
|
+
});
|
|
54
|
+
it('should handle very large terminal rows', () => {
|
|
55
|
+
Object.defineProperty(process.stdout, 'rows', { value: 200, writable: true });
|
|
56
|
+
setupScrollRegion();
|
|
57
|
+
expect(writeSpy).toHaveBeenCalledTimes(2);
|
|
58
|
+
expect(writeSpy).toHaveBeenNthCalledWith(1, `\x1b[1;${200 - BOTTOM_PADDING}r`);
|
|
59
|
+
});
|
|
60
|
+
it('should use default rows (24) when rows is 0', () => {
|
|
61
|
+
Object.defineProperty(process.stdout, 'rows', { value: 0, writable: true });
|
|
62
|
+
setupScrollRegion();
|
|
63
|
+
// 0 is falsy, so it falls back to 24
|
|
64
|
+
expect(writeSpy).toHaveBeenCalledTimes(2);
|
|
65
|
+
expect(writeSpy).toHaveBeenNthCalledWith(1, `\x1b[1;${24 - BOTTOM_PADDING}r`);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('resetScrollRegion', () => {
|
|
69
|
+
it('should write reset escape sequence', () => {
|
|
70
|
+
resetScrollRegion();
|
|
71
|
+
expect(writeSpy).toHaveBeenCalledTimes(1);
|
|
72
|
+
expect(writeSpy).toHaveBeenCalledWith('\x1b[r');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('handleResize', () => {
|
|
76
|
+
it('should call setupScrollRegion logic when terminal has enough rows', () => {
|
|
77
|
+
Object.defineProperty(process.stdout, 'rows', { value: 40, writable: true });
|
|
78
|
+
handleResize();
|
|
79
|
+
expect(writeSpy).toHaveBeenCalledTimes(2);
|
|
80
|
+
expect(writeSpy).toHaveBeenNthCalledWith(1, `\x1b[1;${40 - BOTTOM_PADDING}r`);
|
|
81
|
+
expect(writeSpy).toHaveBeenNthCalledWith(2, '\x1b[H');
|
|
82
|
+
});
|
|
83
|
+
it('should not write when terminal is too small', () => {
|
|
84
|
+
Object.defineProperty(process.stdout, 'rows', { value: 5, writable: true });
|
|
85
|
+
handleResize();
|
|
86
|
+
expect(writeSpy).not.toHaveBeenCalled();
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('clearScreen', () => {
|
|
90
|
+
it('should write clear screen and home cursor escape sequences', () => {
|
|
91
|
+
clearScreen();
|
|
92
|
+
expect(writeSpy).toHaveBeenCalledTimes(1);
|
|
93
|
+
expect(writeSpy).toHaveBeenCalledWith('\x1b[2J\x1b[H');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=terminal.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.test.js","sourceRoot":"","sources":["../../../src/__tests__/utils/terminal.test.ts"],"names":[],"mappings":"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"}
|