ux-toolkit 0.5.0 → 0.5.3
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 +4 -4
- package/dist/cli.js +63 -39
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +12577 -594
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -316
- package/dist/index.d.ts +28 -316
- package/dist/index.js +12578 -570
- package/dist/index.js.map +1 -1
- package/package.json +10 -1
- /package/commands/{a11y-check.md → ux-a11y-check.md} +0 -0
- /package/commands/{design-review.md → ux-design-review.md} +0 -0
- /package/commands/{screenshot-review.md → ux-screenshot-review.md} +0 -0
package/README.md
CHANGED
|
@@ -130,9 +130,9 @@ This installs to `.opencode/` in your current directory.
|
|
|
130
130
|
| Command | Description |
|
|
131
131
|
|---------|-------------|
|
|
132
132
|
| `/ux-audit` | Comprehensive UX audit |
|
|
133
|
-
| `/a11y-check` | Quick accessibility scan |
|
|
134
|
-
| `/design-review` | Visual consistency check |
|
|
135
|
-
| `/screenshot-review` | Visual review from screenshot |
|
|
133
|
+
| `/ux-a11y-check` | Quick accessibility scan |
|
|
134
|
+
| `/ux-design-review` | Visual consistency check |
|
|
135
|
+
| `/ux-screenshot-review` | Visual review from screenshot |
|
|
136
136
|
|
|
137
137
|
## Usage Examples
|
|
138
138
|
|
|
@@ -143,7 +143,7 @@ This installs to `.opencode/` in your current directory.
|
|
|
143
143
|
/ux-audit src/components/Button.tsx
|
|
144
144
|
|
|
145
145
|
# Check accessibility
|
|
146
|
-
/a11y-check src/pages/index.tsx
|
|
146
|
+
/ux-a11y-check src/pages/index.tsx
|
|
147
147
|
|
|
148
148
|
# Invoke agent directly
|
|
149
149
|
@ux-auditor Review the login flow for usability issues
|
package/dist/cli.js
CHANGED
|
@@ -12,13 +12,40 @@ import { createInterface } from "readline";
|
|
|
12
12
|
|
|
13
13
|
// src/installer.ts
|
|
14
14
|
import { existsSync as existsSync2, mkdirSync, cpSync, readdirSync, rmSync, statSync } from "fs";
|
|
15
|
-
import {
|
|
15
|
+
import { dirname as dirname2 } from "path";
|
|
16
16
|
|
|
17
17
|
// src/paths.ts
|
|
18
18
|
import { homedir, platform } from "os";
|
|
19
|
-
import {
|
|
19
|
+
import { dirname, resolve } from "path";
|
|
20
20
|
import { fileURLToPath } from "url";
|
|
21
21
|
import { existsSync } from "fs";
|
|
22
|
+
|
|
23
|
+
// src/utils.ts
|
|
24
|
+
import { join as pathJoin } from "path";
|
|
25
|
+
function safeJoin(...paths) {
|
|
26
|
+
const stringPaths = [];
|
|
27
|
+
for (const p of paths) {
|
|
28
|
+
if (typeof p === "string") {
|
|
29
|
+
stringPaths.push(p);
|
|
30
|
+
} else if (p != null) {
|
|
31
|
+
const str = String(p);
|
|
32
|
+
if (str && str !== "[object Object]" && str !== "undefined" && str !== "null") {
|
|
33
|
+
stringPaths.push(str);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (stringPaths.length === 0) {
|
|
38
|
+
return ".";
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
return pathJoin(...stringPaths);
|
|
42
|
+
} catch {
|
|
43
|
+
const sep = stringPaths[0].includes("\\") ? "\\" : "/";
|
|
44
|
+
return stringPaths.join(sep).replace(/[/\\]+/g, sep);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/paths.ts
|
|
22
49
|
function getCurrentDirname() {
|
|
23
50
|
try {
|
|
24
51
|
if (import.meta?.url) {
|
|
@@ -28,7 +55,7 @@ function getCurrentDirname() {
|
|
|
28
55
|
}
|
|
29
56
|
try {
|
|
30
57
|
const packageJsonPath = __require.resolve("ux-toolkit/package.json");
|
|
31
|
-
return
|
|
58
|
+
return safeJoin(dirname(packageJsonPath), "dist");
|
|
32
59
|
} catch {
|
|
33
60
|
}
|
|
34
61
|
const cwd = process.cwd();
|
|
@@ -47,7 +74,7 @@ function getCurrentDirname() {
|
|
|
47
74
|
}
|
|
48
75
|
var currentDirname = getCurrentDirname();
|
|
49
76
|
function getPackageRoot() {
|
|
50
|
-
return
|
|
77
|
+
return safeJoin(currentDirname, "..");
|
|
51
78
|
}
|
|
52
79
|
function getGlobalConfigDir() {
|
|
53
80
|
if (process.env.UX_TOOLKIT_CONFIG_DIR) {
|
|
@@ -59,9 +86,9 @@ function getGlobalConfigDir() {
|
|
|
59
86
|
const home = homedir();
|
|
60
87
|
const currentPlatform = platform();
|
|
61
88
|
if (currentPlatform === "linux" && process.env.XDG_CONFIG_HOME) {
|
|
62
|
-
return
|
|
89
|
+
return safeJoin(process.env.XDG_CONFIG_HOME, "opencode");
|
|
63
90
|
}
|
|
64
|
-
return
|
|
91
|
+
return safeJoin(home, ".config", "opencode");
|
|
65
92
|
}
|
|
66
93
|
function isOpenCodeInstalled() {
|
|
67
94
|
return existsSync(getGlobalConfigDir());
|
|
@@ -70,7 +97,7 @@ function getClaudeConfigDir() {
|
|
|
70
97
|
if (process.env.CLAUDE_CONFIG_DIR) {
|
|
71
98
|
return resolve(process.env.CLAUDE_CONFIG_DIR);
|
|
72
99
|
}
|
|
73
|
-
return
|
|
100
|
+
return safeJoin(homedir(), ".claude");
|
|
74
101
|
}
|
|
75
102
|
function isClaudeInstalled() {
|
|
76
103
|
return existsSync(getClaudeConfigDir());
|
|
@@ -92,7 +119,7 @@ function getPlatformInfo() {
|
|
|
92
119
|
}
|
|
93
120
|
function getProjectConfigDir(projectRoot = process.cwd(), target = "opencode") {
|
|
94
121
|
const dirName = target === "claude" ? ".claude" : ".opencode";
|
|
95
|
-
return
|
|
122
|
+
return safeJoin(projectRoot, dirName);
|
|
96
123
|
}
|
|
97
124
|
function getDestinationPaths(global, projectRoot, target = "opencode") {
|
|
98
125
|
let baseDir;
|
|
@@ -102,9 +129,9 @@ function getDestinationPaths(global, projectRoot, target = "opencode") {
|
|
|
102
129
|
baseDir = getProjectConfigDir(projectRoot, target);
|
|
103
130
|
}
|
|
104
131
|
return {
|
|
105
|
-
skills:
|
|
106
|
-
agents:
|
|
107
|
-
commands:
|
|
132
|
+
skills: safeJoin(baseDir, "skills"),
|
|
133
|
+
agents: safeJoin(baseDir, "agents"),
|
|
134
|
+
commands: safeJoin(baseDir, "commands")
|
|
108
135
|
};
|
|
109
136
|
}
|
|
110
137
|
|
|
@@ -346,15 +373,15 @@ var COMMANDS = [
|
|
|
346
373
|
description: "Comprehensive UX audit"
|
|
347
374
|
},
|
|
348
375
|
{
|
|
349
|
-
name: "a11y-check",
|
|
376
|
+
name: "ux-a11y-check",
|
|
350
377
|
description: "Quick accessibility scan"
|
|
351
378
|
},
|
|
352
379
|
{
|
|
353
|
-
name: "design-review",
|
|
380
|
+
name: "ux-design-review",
|
|
354
381
|
description: "Visual consistency check"
|
|
355
382
|
},
|
|
356
383
|
{
|
|
357
|
-
name: "screenshot-review",
|
|
384
|
+
name: "ux-screenshot-review",
|
|
358
385
|
description: "Visual review from screenshot"
|
|
359
386
|
}
|
|
360
387
|
];
|
|
@@ -390,7 +417,7 @@ async function install(options = {}) {
|
|
|
390
417
|
if (verbose) console.log(msg);
|
|
391
418
|
};
|
|
392
419
|
if (effectiveCategories.includes("skills")) {
|
|
393
|
-
const skillsDir =
|
|
420
|
+
const skillsDir = safeJoin(packageRoot, "skills");
|
|
394
421
|
if (existsSync2(skillsDir)) {
|
|
395
422
|
let skills = readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
396
423
|
if (specificSkills?.length) {
|
|
@@ -398,8 +425,8 @@ async function install(options = {}) {
|
|
|
398
425
|
skills = skills.filter((s) => requested.has(s.toLowerCase()));
|
|
399
426
|
}
|
|
400
427
|
for (const skill of skills) {
|
|
401
|
-
const src =
|
|
402
|
-
const dest =
|
|
428
|
+
const src = safeJoin(skillsDir, skill);
|
|
429
|
+
const dest = safeJoin(destinations.skills, skill);
|
|
403
430
|
try {
|
|
404
431
|
if (existsSync2(dest) && !force) {
|
|
405
432
|
result.skipped.push(`skill:${skill}`);
|
|
@@ -417,7 +444,7 @@ async function install(options = {}) {
|
|
|
417
444
|
}
|
|
418
445
|
}
|
|
419
446
|
if (effectiveCategories.includes("agents")) {
|
|
420
|
-
const agentsDir =
|
|
447
|
+
const agentsDir = safeJoin(packageRoot, "agents");
|
|
421
448
|
if (existsSync2(agentsDir)) {
|
|
422
449
|
let agents = readdirSync(agentsDir).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
423
450
|
if (specificAgents?.length) {
|
|
@@ -425,8 +452,8 @@ async function install(options = {}) {
|
|
|
425
452
|
agents = agents.filter((a) => requested.has(a.toLowerCase()));
|
|
426
453
|
}
|
|
427
454
|
for (const agent of agents) {
|
|
428
|
-
const src =
|
|
429
|
-
const dest =
|
|
455
|
+
const src = safeJoin(agentsDir, `${agent}.md`);
|
|
456
|
+
const dest = safeJoin(destinations.agents, `${agent}.md`);
|
|
430
457
|
try {
|
|
431
458
|
if (existsSync2(dest) && !force) {
|
|
432
459
|
result.skipped.push(`agent:${agent}`);
|
|
@@ -444,7 +471,7 @@ async function install(options = {}) {
|
|
|
444
471
|
}
|
|
445
472
|
}
|
|
446
473
|
if (effectiveCategories.includes("commands")) {
|
|
447
|
-
const commandsDir =
|
|
474
|
+
const commandsDir = safeJoin(packageRoot, "commands");
|
|
448
475
|
if (existsSync2(commandsDir)) {
|
|
449
476
|
let commands = readdirSync(commandsDir).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
450
477
|
if (specificCommands?.length) {
|
|
@@ -452,8 +479,8 @@ async function install(options = {}) {
|
|
|
452
479
|
commands = commands.filter((c) => requested.has(c.toLowerCase()));
|
|
453
480
|
}
|
|
454
481
|
for (const command of commands) {
|
|
455
|
-
const src =
|
|
456
|
-
const dest =
|
|
482
|
+
const src = safeJoin(commandsDir, `${command}.md`);
|
|
483
|
+
const dest = safeJoin(destinations.commands, `${command}.md`);
|
|
457
484
|
try {
|
|
458
485
|
if (existsSync2(dest) && !force) {
|
|
459
486
|
result.skipped.push(`command:${command}`);
|
|
@@ -493,13 +520,13 @@ function getTargetStatus(target, isGlobal, projectRoot) {
|
|
|
493
520
|
const available = target === "opencode" ? isOpenCodeInstalled() : isClaudeInstalled();
|
|
494
521
|
const destinations = getDestinationPaths(isGlobal, projectRoot, target);
|
|
495
522
|
const skillStatuses = SKILLS.map(
|
|
496
|
-
(s) => checkComponentStatus(
|
|
523
|
+
(s) => checkComponentStatus(safeJoin(destinations.skills, s.name), s.name)
|
|
497
524
|
);
|
|
498
525
|
const agentStatuses = AGENTS.map(
|
|
499
|
-
(a) => checkComponentStatus(
|
|
526
|
+
(a) => checkComponentStatus(safeJoin(destinations.agents, `${a.name}.md`), a.name)
|
|
500
527
|
);
|
|
501
528
|
const commandStatuses = COMMANDS.map(
|
|
502
|
-
(c) => checkComponentStatus(
|
|
529
|
+
(c) => checkComponentStatus(safeJoin(destinations.commands, `${c.name}.md`), c.name)
|
|
503
530
|
);
|
|
504
531
|
return {
|
|
505
532
|
target,
|
|
@@ -551,7 +578,7 @@ async function uninstall(options = {}) {
|
|
|
551
578
|
const ourCommands = COMMANDS.map((c) => c.name);
|
|
552
579
|
if (categories.includes("skills")) {
|
|
553
580
|
for (const skill of ourSkills) {
|
|
554
|
-
const dest =
|
|
581
|
+
const dest = safeJoin(destinations.skills, skill);
|
|
555
582
|
try {
|
|
556
583
|
if (!existsSync2(dest)) {
|
|
557
584
|
result.notFound.push(`skill:${skill}`);
|
|
@@ -568,7 +595,7 @@ async function uninstall(options = {}) {
|
|
|
568
595
|
}
|
|
569
596
|
if (categories.includes("agents")) {
|
|
570
597
|
for (const agent of ourAgents) {
|
|
571
|
-
const dest =
|
|
598
|
+
const dest = safeJoin(destinations.agents, `${agent}.md`);
|
|
572
599
|
try {
|
|
573
600
|
if (!existsSync2(dest)) {
|
|
574
601
|
result.notFound.push(`agent:${agent}`);
|
|
@@ -585,7 +612,7 @@ async function uninstall(options = {}) {
|
|
|
585
612
|
}
|
|
586
613
|
if (categories.includes("commands")) {
|
|
587
614
|
for (const command of ourCommands) {
|
|
588
|
-
const dest =
|
|
615
|
+
const dest = safeJoin(destinations.commands, `${command}.md`);
|
|
589
616
|
try {
|
|
590
617
|
if (!existsSync2(dest)) {
|
|
591
618
|
result.notFound.push(`command:${command}`);
|
|
@@ -936,13 +963,12 @@ Errors:`);
|
|
|
936
963
|
ok.push(`Node.js ${nodeVersion}`);
|
|
937
964
|
}
|
|
938
965
|
const platformInfo = getPlatformInfo();
|
|
966
|
+
const { existsSync: existsSync3 } = await import("fs");
|
|
939
967
|
if (platformInfo.opencode.exists) {
|
|
940
968
|
ok.push(`OpenCode detected at ${platformInfo.opencode.configDir}`);
|
|
941
|
-
const
|
|
942
|
-
const
|
|
943
|
-
const
|
|
944
|
-
const agentsDir = join3(platformInfo.opencode.configDir, "agents");
|
|
945
|
-
const commandsDir = join3(platformInfo.opencode.configDir, "commands");
|
|
969
|
+
const skillsDir = safeJoin(platformInfo.opencode.configDir, "skills");
|
|
970
|
+
const agentsDir = safeJoin(platformInfo.opencode.configDir, "agents");
|
|
971
|
+
const commandsDir = safeJoin(platformInfo.opencode.configDir, "commands");
|
|
946
972
|
if (!existsSync3(skillsDir)) {
|
|
947
973
|
warnings.push("OpenCode skills directory missing");
|
|
948
974
|
}
|
|
@@ -957,11 +983,9 @@ Errors:`);
|
|
|
957
983
|
}
|
|
958
984
|
if (platformInfo.claude.exists) {
|
|
959
985
|
ok.push(`Claude Code detected at ${platformInfo.claude.configDir}`);
|
|
960
|
-
const
|
|
961
|
-
const
|
|
962
|
-
const
|
|
963
|
-
const agentsDir = join3(platformInfo.claude.configDir, "agents");
|
|
964
|
-
const commandsDir = join3(platformInfo.claude.configDir, "commands");
|
|
986
|
+
const skillsDir = safeJoin(platformInfo.claude.configDir, "skills");
|
|
987
|
+
const agentsDir = safeJoin(platformInfo.claude.configDir, "agents");
|
|
988
|
+
const commandsDir = safeJoin(platformInfo.claude.configDir, "commands");
|
|
965
989
|
if (!existsSync3(skillsDir)) {
|
|
966
990
|
warnings.push("Claude Code skills directory missing");
|
|
967
991
|
}
|