ui-ux-master 1.1.0 → 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/README.md +109 -3
- package/SKILL.md +38 -20
- package/ai-discovery/ui-ux-master.manifest.json +84 -0
- package/bin/ui-ux-master-mcp.mjs +243 -0
- package/bin/ui-ux-master.mjs +6 -4
- package/docs/mcp-server.md +106 -0
- package/docs/package-publishing.md +82 -0
- package/index.cjs +37 -0
- package/index.d.ts +17 -0
- package/index.mjs +27 -0
- package/llms.txt +24 -0
- package/package.json +91 -8
- package/scripts/validate_skill.py +69 -4
- package/system-prompts/ui-ux-master-compact.md +5 -0
- package/system-prompts/ui-ux-master-mcp-add-on.md +49 -0
- package/system-prompts/ui-ux-master-system-add-on.md +47 -0
- package/tests/install-smoke.test.mjs +64 -4
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# UI/UX Master System Prompt Add-on
|
|
2
|
+
|
|
3
|
+
Use this add-on in any AI coding agent that supports custom instructions, system prompts, project rules, or model context.
|
|
4
|
+
|
|
5
|
+
## Activation Rule
|
|
6
|
+
|
|
7
|
+
Activate UI/UX Master only when the user includes `/ui-ux-master` in the request. If the user does not include `/ui-ux-master`, do not apply this workflow automatically.
|
|
8
|
+
|
|
9
|
+
## Source of Truth
|
|
10
|
+
|
|
11
|
+
When active, read `.ui-ux-master/SKILL.md` first. If `.ui-ux-master/` is not available, read the installed `ui-ux-master` package files. Use these references when relevant:
|
|
12
|
+
|
|
13
|
+
- `.ui-ux-master/references/ui-ux-memory-workflow.md`
|
|
14
|
+
- `.ui-ux-master/references/ui-ux-frontend-implementation-rules.md`
|
|
15
|
+
- `.ui-ux-master/references/ui-ux-complete-checklist.md`
|
|
16
|
+
- `.ui-ux-master/references/wcag-aa-quick-reference.md`
|
|
17
|
+
- `.ui-ux-master/references/accessibility-advanced-patterns.md`
|
|
18
|
+
- `.ui-ux-master/references/design-system-playbook.md`
|
|
19
|
+
- `.ui-ux-master/templates/ui-ux-memory.md`
|
|
20
|
+
|
|
21
|
+
## Required Behavior
|
|
22
|
+
|
|
23
|
+
1. Treat the rest of the prompt after `/ui-ux-master` as the user task.
|
|
24
|
+
2. Check for existing UI/UX memory before designing: `.ui-ux-memory.md`, `docs/ui-ux-memory.md`, `docs/design/ui-ux-memory.md`, or `design/ui-ux-memory.md`.
|
|
25
|
+
3. Inspect existing brand, tokens, components, CSS, routes, screenshots, dependencies, and similar screens before proposing UI changes.
|
|
26
|
+
4. Preserve existing design conventions unless the user asks for redesign or rebrand.
|
|
27
|
+
5. Include accessibility, responsive behavior, screen states, error/empty/loading/success states, content design, localization risks, platform conventions, analytics, QA, and developer handoff.
|
|
28
|
+
6. If implementing frontend code, follow existing stack conventions and avoid arbitrary new dependencies.
|
|
29
|
+
7. State whether UI/UX memory was read, created, updated, or unavailable.
|
|
30
|
+
|
|
31
|
+
## Default Output Shape
|
|
32
|
+
|
|
33
|
+
When the user does not request a specific format, return:
|
|
34
|
+
|
|
35
|
+
- Product/user goal
|
|
36
|
+
- Assumptions and evidence confidence
|
|
37
|
+
- UX/IA/flow recommendations
|
|
38
|
+
- Visual and interaction direction
|
|
39
|
+
- Component/state specifications
|
|
40
|
+
- Accessibility and responsive requirements
|
|
41
|
+
- Content/copy recommendations
|
|
42
|
+
- Implementation handoff and acceptance criteria
|
|
43
|
+
- QA checklist and next steps
|
|
44
|
+
|
|
45
|
+
## Quality Bar
|
|
46
|
+
|
|
47
|
+
Do not stop at pretty screens. Produce senior-level UI/UX work that is usable, accessible, coherent, implementable, brand-consistent, and measurable.
|
|
@@ -2,11 +2,12 @@ import assert from 'node:assert/strict';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
-
import { execFileSync } from 'node:child_process';
|
|
5
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
6
6
|
import test from 'node:test';
|
|
7
7
|
|
|
8
8
|
const root = path.resolve(import.meta.dirname, '..');
|
|
9
9
|
const bin = path.join(root, 'bin', 'ui-ux-master.mjs');
|
|
10
|
+
const mcpBin = path.join(root, 'bin', 'ui-ux-master-mcp.mjs');
|
|
10
11
|
const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
11
12
|
const templates = [
|
|
12
13
|
'agent-templates/claude/commands/ui-ux-master.md',
|
|
@@ -22,10 +23,21 @@ function run(args, cwd = root) {
|
|
|
22
23
|
return execFileSync(process.execPath, [bin, ...args], { cwd, encoding: 'utf8' });
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
function runMcp(messages) {
|
|
27
|
+
const input = messages.map(m => JSON.stringify(m)).join('\n') + '\n';
|
|
28
|
+
const res = spawnSync(process.execPath, [mcpBin], { input, encoding: 'utf8', cwd: root, timeout: 5000 });
|
|
29
|
+
assert.equal(res.status, 0, res.stderr);
|
|
30
|
+
return res.stdout.trim().split(/\n+/).map(line => JSON.parse(line));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
test('package exposes cli and mcp bins with Rupak Biswas author', () => {
|
|
34
|
+
assert.equal(pkg.author, 'Rupak Biswas');
|
|
26
35
|
assert.equal(pkg.bin['ui-ux-master'], './bin/ui-ux-master.mjs');
|
|
36
|
+
assert.equal(pkg.bin['ui-ux-master-mcp'], './bin/ui-ux-master-mcp.mjs');
|
|
27
37
|
assert.ok(fs.existsSync(bin));
|
|
38
|
+
assert.ok(fs.existsSync(mcpBin));
|
|
28
39
|
assert.ok(fs.readFileSync(bin, 'utf8').startsWith('#!/usr/bin/env node'));
|
|
40
|
+
assert.ok(fs.readFileSync(mcpBin, 'utf8').startsWith('#!/usr/bin/env node'));
|
|
29
41
|
});
|
|
30
42
|
|
|
31
43
|
test('agent templates include trigger and avoid local absolute paths', () => {
|
|
@@ -38,10 +50,29 @@ test('agent templates include trigger and avoid local absolute paths', () => {
|
|
|
38
50
|
}
|
|
39
51
|
});
|
|
40
52
|
|
|
53
|
+
test('discovery assets and system prompts exist', () => {
|
|
54
|
+
const required = [
|
|
55
|
+
'llms.txt',
|
|
56
|
+
'ai-discovery/ui-ux-master.manifest.json',
|
|
57
|
+
'system-prompts/ui-ux-master-system-add-on.md',
|
|
58
|
+
'system-prompts/ui-ux-master-compact.md',
|
|
59
|
+
'system-prompts/ui-ux-master-mcp-add-on.md',
|
|
60
|
+
'docs/mcp-server.md',
|
|
61
|
+
];
|
|
62
|
+
for (const rel of required) {
|
|
63
|
+
const text = fs.readFileSync(path.join(root, rel), 'utf8');
|
|
64
|
+
assert.match(text, /\/ui-ux-master/);
|
|
65
|
+
}
|
|
66
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(root, 'ai-discovery/ui-ux-master.manifest.json'), 'utf8'));
|
|
67
|
+
assert.equal(manifest.author, 'Rupak Biswas');
|
|
68
|
+
assert.equal(manifest.activation.trigger, '/ui-ux-master');
|
|
69
|
+
assert.equal(manifest.entrypoints.mcp_server_bin, 'ui-ux-master-mcp');
|
|
70
|
+
});
|
|
71
|
+
|
|
41
72
|
test('cli help doctor and where work', () => {
|
|
42
|
-
assert.match(run(['--help']), /ui-ux-master
|
|
73
|
+
assert.match(run(['--help']), /ui-ux-master-mcp/);
|
|
43
74
|
assert.match(run(['where']).trim(), /UI-UX Skills|ui-ux-master/i);
|
|
44
|
-
assert.match(run(['doctor', '--dry-run']), /
|
|
75
|
+
assert.match(run(['doctor', '--dry-run']), /bin\/ui-ux-master-mcp\.mjs|bin\\ui-ux-master-mcp\.mjs/);
|
|
45
76
|
});
|
|
46
77
|
|
|
47
78
|
test('project install dry-run does not write', () => {
|
|
@@ -58,6 +89,9 @@ test('project install writes expected files and is idempotent', () => {
|
|
|
58
89
|
run(['install', '--project', '--dir', dir]);
|
|
59
90
|
run(['install', '--project', '--dir', dir]);
|
|
60
91
|
assert.ok(fs.existsSync(path.join(dir, '.ui-ux-master', 'SKILL.md')));
|
|
92
|
+
assert.ok(fs.existsSync(path.join(dir, '.ui-ux-master', 'llms.txt')));
|
|
93
|
+
assert.ok(fs.existsSync(path.join(dir, '.ui-ux-master', 'ai-discovery', 'ui-ux-master.manifest.json')));
|
|
94
|
+
assert.ok(fs.existsSync(path.join(dir, '.ui-ux-master', 'system-prompts', 'ui-ux-master-system-add-on.md')));
|
|
61
95
|
assert.ok(fs.existsSync(path.join(dir, '.ui-ux-master', 'references', 'ui-ux-memory-workflow.md')));
|
|
62
96
|
assert.ok(fs.existsSync(path.join(dir, '.ui-ux-master', 'templates', 'ui-ux-memory.md')));
|
|
63
97
|
assert.ok(fs.existsSync(path.join(dir, '.claude', 'commands', 'ui-ux-master.md')));
|
|
@@ -69,3 +103,29 @@ test('project install writes expected files and is idempotent', () => {
|
|
|
69
103
|
assert.match(agents, /\.ui-ux-master\/SKILL\.md/);
|
|
70
104
|
assert.match(agents, /\/ui-ux-master/);
|
|
71
105
|
});
|
|
106
|
+
|
|
107
|
+
test('mcp server lists tools resources prompts and can return the skill', () => {
|
|
108
|
+
const responses = runMcp([
|
|
109
|
+
{ jsonrpc: '2.0', id: 1, method: 'initialize', params: {} },
|
|
110
|
+
{ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} },
|
|
111
|
+
{ jsonrpc: '2.0', id: 3, method: 'resources/list', params: {} },
|
|
112
|
+
{ jsonrpc: '2.0', id: 4, method: 'prompts/list', params: {} },
|
|
113
|
+
{ jsonrpc: '2.0', id: 5, method: 'tools/call', params: { name: 'get_asset', arguments: { name: 'system_prompt' } } },
|
|
114
|
+
]);
|
|
115
|
+
assert.equal(responses[0].result.serverInfo.name, 'ui-ux-master');
|
|
116
|
+
assert.ok(responses[1].result.tools.some(t => t.name === 'generate_system_prompt'));
|
|
117
|
+
assert.ok(responses[2].result.resources.some(r => r.uri === 'ui-ux-master://skill'));
|
|
118
|
+
assert.ok(responses[2].result.resources.some(r => r.uri === 'ui-ux-master://memory-template'));
|
|
119
|
+
assert.ok(responses[3].result.prompts.some(p => p.name === 'ui-ux-audit'));
|
|
120
|
+
assert.match(responses[4].result.content[0].text, /Activation Rule/);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('mcp server handles prompt retrieval and unknown methods correctly', () => {
|
|
124
|
+
const responses = runMcp([
|
|
125
|
+
{ jsonrpc: '2.0', id: 1, method: 'prompts/get', params: { name: 'ui-ux-design-system', arguments: { scope: 'admin dashboard' } } },
|
|
126
|
+
{ jsonrpc: '2.0', id: 2, method: 'not/a-method', params: {} },
|
|
127
|
+
]);
|
|
128
|
+
assert.match(responses[0].result.messages[0].content.text, /\/ui-ux-master/);
|
|
129
|
+
assert.match(responses[0].result.messages[0].content.text, /admin dashboard/);
|
|
130
|
+
assert.equal(responses[1].error.code, -32601);
|
|
131
|
+
});
|