ux-toolkit 0.1.0

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/dist/cli.js ADDED
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import { parseArgs } from "util";
5
+
6
+ // src/installer.ts
7
+ import { existsSync, mkdirSync, cpSync, readdirSync } from "fs";
8
+ import { join as join2, dirname as dirname2 } from "path";
9
+
10
+ // src/paths.ts
11
+ import { homedir } from "os";
12
+ import { join, dirname } from "path";
13
+ import { fileURLToPath } from "url";
14
+ var __dirname = dirname(fileURLToPath(import.meta.url));
15
+ function getPackageRoot() {
16
+ return join(__dirname, "..");
17
+ }
18
+ function getGlobalConfigDir() {
19
+ return join(homedir(), ".config", "opencode");
20
+ }
21
+ function getProjectConfigDir(projectRoot = process.cwd()) {
22
+ return join(projectRoot, ".opencode");
23
+ }
24
+ function getDestinationPaths(global, projectRoot) {
25
+ const baseDir = global ? getGlobalConfigDir() : getProjectConfigDir(projectRoot);
26
+ return {
27
+ skills: join(baseDir, "skills"),
28
+ agents: join(baseDir, "agents"),
29
+ commands: join(baseDir, "commands")
30
+ };
31
+ }
32
+
33
+ // src/installer.ts
34
+ async function install(options = {}) {
35
+ const {
36
+ global: isGlobal = false,
37
+ projectRoot = process.cwd(),
38
+ categories = ["skills", "agents", "commands"],
39
+ force = false,
40
+ verbose = false
41
+ } = options;
42
+ const result = {
43
+ installed: [],
44
+ skipped: [],
45
+ errors: []
46
+ };
47
+ const packageRoot = getPackageRoot();
48
+ const destinations = getDestinationPaths(isGlobal, projectRoot);
49
+ const log = (msg) => {
50
+ if (verbose) console.log(msg);
51
+ };
52
+ if (categories.includes("skills")) {
53
+ const skillsDir = join2(packageRoot, "skills");
54
+ if (existsSync(skillsDir)) {
55
+ const skills = readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
56
+ for (const skill of skills) {
57
+ const src = join2(skillsDir, skill);
58
+ const dest = join2(destinations.skills, skill);
59
+ try {
60
+ if (existsSync(dest) && !force) {
61
+ result.skipped.push(`skill:${skill}`);
62
+ log(`Skipped skill/${skill} (already exists)`);
63
+ continue;
64
+ }
65
+ mkdirSync(dirname2(dest), { recursive: true });
66
+ cpSync(src, dest, { recursive: true });
67
+ result.installed.push(`skill:${skill}`);
68
+ log(`Installed skill/${skill}`);
69
+ } catch (err) {
70
+ result.errors.push(`skill:${skill}: ${err}`);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ if (categories.includes("agents")) {
76
+ const agentsDir = join2(packageRoot, "agents");
77
+ if (existsSync(agentsDir)) {
78
+ const agents = readdirSync(agentsDir).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
79
+ for (const agent of agents) {
80
+ const src = join2(agentsDir, `${agent}.md`);
81
+ const dest = join2(destinations.agents, `${agent}.md`);
82
+ try {
83
+ if (existsSync(dest) && !force) {
84
+ result.skipped.push(`agent:${agent}`);
85
+ log(`Skipped agents/${agent}.md (already exists)`);
86
+ continue;
87
+ }
88
+ mkdirSync(dirname2(dest), { recursive: true });
89
+ cpSync(src, dest);
90
+ result.installed.push(`agent:${agent}`);
91
+ log(`Installed agents/${agent}.md`);
92
+ } catch (err) {
93
+ result.errors.push(`agent:${agent}: ${err}`);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ if (categories.includes("commands")) {
99
+ const commandsDir = join2(packageRoot, "commands");
100
+ if (existsSync(commandsDir)) {
101
+ const commands = readdirSync(commandsDir).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
102
+ for (const command of commands) {
103
+ const src = join2(commandsDir, `${command}.md`);
104
+ const dest = join2(destinations.commands, `${command}.md`);
105
+ try {
106
+ if (existsSync(dest) && !force) {
107
+ result.skipped.push(`command:${command}`);
108
+ log(`Skipped commands/${command}.md (already exists)`);
109
+ continue;
110
+ }
111
+ mkdirSync(dirname2(dest), { recursive: true });
112
+ cpSync(src, dest);
113
+ result.installed.push(`command:${command}`);
114
+ log(`Installed commands/${command}.md`);
115
+ } catch (err) {
116
+ result.errors.push(`command:${command}: ${err}`);
117
+ }
118
+ }
119
+ }
120
+ }
121
+ return result;
122
+ }
123
+
124
+ // src/manifest.ts
125
+ var SKILLS = [
126
+ {
127
+ name: "ux-heuristics",
128
+ description: "Nielsen's 10 usability heuristics with evaluation methodology",
129
+ category: "core"
130
+ },
131
+ {
132
+ name: "wcag-accessibility",
133
+ description: "WCAG 2.2 compliance checklist and ARIA patterns",
134
+ category: "core"
135
+ },
136
+ {
137
+ name: "visual-design-system",
138
+ description: "Layout, typography, color theory, spacing systems",
139
+ category: "core"
140
+ },
141
+ {
142
+ name: "interaction-patterns",
143
+ description: "Micro-interactions, loading states, feedback mechanisms",
144
+ category: "core"
145
+ },
146
+ {
147
+ name: "react-ux-patterns",
148
+ description: "React/Next.js specific UX patterns",
149
+ category: "framework"
150
+ },
151
+ {
152
+ name: "mobile-responsive-ux",
153
+ description: "Touch targets, gestures, responsive patterns",
154
+ category: "core"
155
+ }
156
+ ];
157
+ var AGENTS = [
158
+ {
159
+ name: "ux-auditor",
160
+ description: "Full UX audit against heuristics (read-only)",
161
+ mode: "analysis"
162
+ },
163
+ {
164
+ name: "ux-engineer",
165
+ description: "UX analysis + implements fixes",
166
+ mode: "fix"
167
+ },
168
+ {
169
+ name: "accessibility-auditor",
170
+ description: "WCAG 2.2 compliance review (read-only)",
171
+ mode: "analysis"
172
+ },
173
+ {
174
+ name: "accessibility-engineer",
175
+ description: "Accessibility fixes",
176
+ mode: "fix"
177
+ },
178
+ {
179
+ name: "visual-reviewer",
180
+ description: "Design system consistency check",
181
+ mode: "analysis"
182
+ },
183
+ {
184
+ name: "interaction-reviewer",
185
+ description: "Micro-interactions and feedback review",
186
+ mode: "analysis"
187
+ }
188
+ ];
189
+ var COMMANDS = [
190
+ {
191
+ name: "ux-audit",
192
+ description: "Comprehensive UX audit"
193
+ },
194
+ {
195
+ name: "a11y-check",
196
+ description: "Quick accessibility scan"
197
+ },
198
+ {
199
+ name: "design-review",
200
+ description: "Visual consistency check"
201
+ },
202
+ {
203
+ name: "screenshot-review",
204
+ description: "Visual review from screenshot"
205
+ }
206
+ ];
207
+
208
+ // src/cli.ts
209
+ var HELP = `
210
+ ux-toolkit - AI-powered UI/UX review toolkit
211
+
212
+ USAGE:
213
+ npx ux-toolkit <command> [options]
214
+
215
+ COMMANDS:
216
+ install Install skills, agents, and commands
217
+ list List available components
218
+
219
+ OPTIONS:
220
+ --global, -g Install to global config (~/.config/opencode)
221
+ --project, -p Install to project config (.opencode/)
222
+ --force, -f Overwrite existing files
223
+ --verbose, -v Verbose output
224
+ --help, -h Show this help
225
+
226
+ EXAMPLES:
227
+ npx ux-toolkit install --global
228
+ npx ux-toolkit install --project --force
229
+ npx ux-toolkit list
230
+ `;
231
+ async function main() {
232
+ const { values, positionals } = parseArgs({
233
+ allowPositionals: true,
234
+ options: {
235
+ global: { type: "boolean", short: "g", default: false },
236
+ project: { type: "boolean", short: "p", default: false },
237
+ force: { type: "boolean", short: "f", default: false },
238
+ verbose: { type: "boolean", short: "v", default: false },
239
+ help: { type: "boolean", short: "h", default: false }
240
+ }
241
+ });
242
+ if (values.help || positionals.length === 0) {
243
+ console.log(HELP);
244
+ process.exit(0);
245
+ }
246
+ const command = positionals[0];
247
+ switch (command) {
248
+ case "install": {
249
+ const isGlobal = values.global || !values.project;
250
+ console.log(`
251
+ Installing UX Toolkit ${isGlobal ? "globally" : "to project"}...
252
+ `);
253
+ const result = await install({
254
+ global: isGlobal,
255
+ force: values.force,
256
+ verbose: values.verbose
257
+ });
258
+ if (result.installed.length > 0) {
259
+ console.log(`Installed ${result.installed.length} components:`);
260
+ result.installed.forEach((item) => console.log(` + ${item}`));
261
+ }
262
+ if (result.skipped.length > 0) {
263
+ console.log(`
264
+ Skipped ${result.skipped.length} (already exist, use --force to overwrite):`);
265
+ result.skipped.forEach((item) => console.log(` - ${item}`));
266
+ }
267
+ if (result.errors.length > 0) {
268
+ console.error(`
269
+ Errors:`);
270
+ result.errors.forEach((err) => console.error(` ! ${err}`));
271
+ process.exit(1);
272
+ }
273
+ console.log("\nDone!");
274
+ break;
275
+ }
276
+ case "list": {
277
+ console.log("\nSkills:");
278
+ SKILLS.forEach((s) => console.log(` ${s.name.padEnd(25)} ${s.description}`));
279
+ console.log("\nAgents:");
280
+ AGENTS.forEach((a) => console.log(` ${a.name.padEnd(25)} ${a.description}`));
281
+ console.log("\nCommands:");
282
+ COMMANDS.forEach((c) => console.log(` /${c.name.padEnd(24)} ${c.description}`));
283
+ break;
284
+ }
285
+ default:
286
+ console.error(`Unknown command: ${command}`);
287
+ console.log(HELP);
288
+ process.exit(1);
289
+ }
290
+ }
291
+ main().catch((err) => {
292
+ console.error("Error:", err);
293
+ process.exit(1);
294
+ });
295
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts","../src/installer.ts","../src/paths.ts","../src/manifest.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { parseArgs } from 'node:util';\nimport { install } from './installer.js';\nimport { SKILLS, AGENTS, COMMANDS } from './manifest.js';\n\nconst HELP = `\nux-toolkit - AI-powered UI/UX review toolkit\n\nUSAGE:\n npx ux-toolkit <command> [options]\n\nCOMMANDS:\n install Install skills, agents, and commands\n list List available components\n\nOPTIONS:\n --global, -g Install to global config (~/.config/opencode)\n --project, -p Install to project config (.opencode/)\n --force, -f Overwrite existing files\n --verbose, -v Verbose output\n --help, -h Show this help\n\nEXAMPLES:\n npx ux-toolkit install --global\n npx ux-toolkit install --project --force\n npx ux-toolkit list\n`;\n\nasync function main() {\n const { values, positionals } = parseArgs({\n allowPositionals: true,\n options: {\n global: { type: 'boolean', short: 'g', default: false },\n project: { type: 'boolean', short: 'p', default: false },\n force: { type: 'boolean', short: 'f', default: false },\n verbose: { type: 'boolean', short: 'v', default: false },\n help: { type: 'boolean', short: 'h', default: false },\n },\n });\n\n if (values.help || positionals.length === 0) {\n console.log(HELP);\n process.exit(0);\n }\n\n const command = positionals[0];\n\n switch (command) {\n case 'install': {\n const isGlobal = values.global || !values.project;\n\n console.log(`\\nInstalling UX Toolkit ${isGlobal ? 'globally' : 'to project'}...\\n`);\n\n const result = await install({\n global: isGlobal,\n force: values.force,\n verbose: values.verbose,\n });\n\n if (result.installed.length > 0) {\n console.log(`Installed ${result.installed.length} components:`);\n result.installed.forEach((item) => console.log(` + ${item}`));\n }\n\n if (result.skipped.length > 0) {\n console.log(`\\nSkipped ${result.skipped.length} (already exist, use --force to overwrite):`);\n result.skipped.forEach((item) => console.log(` - ${item}`));\n }\n\n if (result.errors.length > 0) {\n console.error(`\\nErrors:`);\n result.errors.forEach((err) => console.error(` ! ${err}`));\n process.exit(1);\n }\n\n console.log('\\nDone!');\n break;\n }\n\n case 'list': {\n console.log('\\nSkills:');\n SKILLS.forEach((s) => console.log(` ${s.name.padEnd(25)} ${s.description}`));\n\n console.log('\\nAgents:');\n AGENTS.forEach((a) => console.log(` ${a.name.padEnd(25)} ${a.description}`));\n\n console.log('\\nCommands:');\n COMMANDS.forEach((c) => console.log(` /${c.name.padEnd(24)} ${c.description}`));\n break;\n }\n\n default:\n console.error(`Unknown command: ${command}`);\n console.log(HELP);\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error('Error:', err);\n process.exit(1);\n});\n","import { existsSync, mkdirSync, cpSync, readdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { getPackageRoot, getDestinationPaths } from './paths.js';\n\nexport interface InstallOptions {\n /** Install globally to ~/.config/opencode */\n global?: boolean;\n /** Project root for local installation */\n projectRoot?: string;\n /** Only install specific categories */\n categories?: ('skills' | 'agents' | 'commands')[];\n /** Overwrite existing files */\n force?: boolean;\n /** Verbose output */\n verbose?: boolean;\n}\n\nexport interface InstallResult {\n installed: string[];\n skipped: string[];\n errors: string[];\n}\n\nexport async function install(options: InstallOptions = {}): Promise<InstallResult> {\n const {\n global: isGlobal = false,\n projectRoot = process.cwd(),\n categories = ['skills', 'agents', 'commands'],\n force = false,\n verbose = false,\n } = options;\n\n const result: InstallResult = {\n installed: [],\n skipped: [],\n errors: [],\n };\n\n const packageRoot = getPackageRoot();\n const destinations = getDestinationPaths(isGlobal, projectRoot);\n\n const log = (msg: string) => {\n if (verbose) console.log(msg);\n };\n\n if (categories.includes('skills')) {\n const skillsDir = join(packageRoot, 'skills');\n if (existsSync(skillsDir)) {\n const skills = readdirSync(skillsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name);\n\n for (const skill of skills) {\n const src = join(skillsDir, skill);\n const dest = join(destinations.skills, skill);\n\n try {\n if (existsSync(dest) && !force) {\n result.skipped.push(`skill:${skill}`);\n log(`Skipped skill/${skill} (already exists)`);\n continue;\n }\n\n mkdirSync(dirname(dest), { recursive: true });\n cpSync(src, dest, { recursive: true });\n result.installed.push(`skill:${skill}`);\n log(`Installed skill/${skill}`);\n } catch (err) {\n result.errors.push(`skill:${skill}: ${err}`);\n }\n }\n }\n }\n\n if (categories.includes('agents')) {\n const agentsDir = join(packageRoot, 'agents');\n if (existsSync(agentsDir)) {\n const agents = readdirSync(agentsDir)\n .filter((f) => f.endsWith('.md'))\n .map((f) => f.replace('.md', ''));\n\n for (const agent of agents) {\n const src = join(agentsDir, `${agent}.md`);\n const dest = join(destinations.agents, `${agent}.md`);\n\n try {\n if (existsSync(dest) && !force) {\n result.skipped.push(`agent:${agent}`);\n log(`Skipped agents/${agent}.md (already exists)`);\n continue;\n }\n\n mkdirSync(dirname(dest), { recursive: true });\n cpSync(src, dest);\n result.installed.push(`agent:${agent}`);\n log(`Installed agents/${agent}.md`);\n } catch (err) {\n result.errors.push(`agent:${agent}: ${err}`);\n }\n }\n }\n }\n\n if (categories.includes('commands')) {\n const commandsDir = join(packageRoot, 'commands');\n if (existsSync(commandsDir)) {\n const commands = readdirSync(commandsDir)\n .filter((f) => f.endsWith('.md'))\n .map((f) => f.replace('.md', ''));\n\n for (const command of commands) {\n const src = join(commandsDir, `${command}.md`);\n const dest = join(destinations.commands, `${command}.md`);\n\n try {\n if (existsSync(dest) && !force) {\n result.skipped.push(`command:${command}`);\n log(`Skipped commands/${command}.md (already exists)`);\n continue;\n }\n\n mkdirSync(dirname(dest), { recursive: true });\n cpSync(src, dest);\n result.installed.push(`command:${command}`);\n log(`Installed commands/${command}.md`);\n } catch (err) {\n result.errors.push(`command:${command}: ${err}`);\n }\n }\n }\n }\n\n return result;\n}\n","import { homedir } from 'node:os';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport function getPackageRoot(): string {\n return join(__dirname, '..');\n}\n\nexport function getSkillPath(skillName: string): string {\n return join(getPackageRoot(), 'skills', skillName, 'SKILL.md');\n}\n\nexport function getAgentPath(agentName: string): string {\n return join(getPackageRoot(), 'agents', `${agentName}.md`);\n}\n\nexport function getCommandPath(commandName: string): string {\n return join(getPackageRoot(), 'commands', `${commandName}.md`);\n}\n\nexport function getGlobalConfigDir(): string {\n return join(homedir(), '.config', 'opencode');\n}\n\nexport function getProjectConfigDir(projectRoot: string = process.cwd()): string {\n return join(projectRoot, '.opencode');\n}\n\nexport function getDestinationPaths(global: boolean, projectRoot?: string) {\n const baseDir = global ? getGlobalConfigDir() : getProjectConfigDir(projectRoot);\n\n return {\n skills: join(baseDir, 'skills'),\n agents: join(baseDir, 'agents'),\n commands: join(baseDir, 'commands'),\n };\n}\n","export const SKILLS = [\n {\n name: 'ux-heuristics',\n description: \"Nielsen's 10 usability heuristics with evaluation methodology\",\n category: 'core',\n },\n {\n name: 'wcag-accessibility',\n description: 'WCAG 2.2 compliance checklist and ARIA patterns',\n category: 'core',\n },\n {\n name: 'visual-design-system',\n description: 'Layout, typography, color theory, spacing systems',\n category: 'core',\n },\n {\n name: 'interaction-patterns',\n description: 'Micro-interactions, loading states, feedback mechanisms',\n category: 'core',\n },\n {\n name: 'react-ux-patterns',\n description: 'React/Next.js specific UX patterns',\n category: 'framework',\n },\n {\n name: 'mobile-responsive-ux',\n description: 'Touch targets, gestures, responsive patterns',\n category: 'core',\n },\n] as const;\n\nexport const AGENTS = [\n {\n name: 'ux-auditor',\n description: 'Full UX audit against heuristics (read-only)',\n mode: 'analysis',\n },\n {\n name: 'ux-engineer',\n description: 'UX analysis + implements fixes',\n mode: 'fix',\n },\n {\n name: 'accessibility-auditor',\n description: 'WCAG 2.2 compliance review (read-only)',\n mode: 'analysis',\n },\n {\n name: 'accessibility-engineer',\n description: 'Accessibility fixes',\n mode: 'fix',\n },\n {\n name: 'visual-reviewer',\n description: 'Design system consistency check',\n mode: 'analysis',\n },\n {\n name: 'interaction-reviewer',\n description: 'Micro-interactions and feedback review',\n mode: 'analysis',\n },\n] as const;\n\nexport const COMMANDS = [\n {\n name: 'ux-audit',\n description: 'Comprehensive UX audit',\n },\n {\n name: 'a11y-check',\n description: 'Quick accessibility scan',\n },\n {\n name: 'design-review',\n description: 'Visual consistency check',\n },\n {\n name: 'screenshot-review',\n description: 'Visual review from screenshot',\n },\n] as const;\n\nexport type SkillName = (typeof SKILLS)[number]['name'];\nexport type AgentName = (typeof AGENTS)[number]['name'];\nexport type CommandName = (typeof COMMANDS)[number]['name'];\n"],"mappings":"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","names":["join","dirname","join","dirname"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AGENTS: () => AGENTS,
24
+ COMMANDS: () => COMMANDS,
25
+ SKILLS: () => SKILLS,
26
+ getAgentPath: () => getAgentPath,
27
+ getCommandPath: () => getCommandPath,
28
+ getSkillPath: () => getSkillPath,
29
+ install: () => install
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/installer.ts
34
+ var import_node_fs = require("fs");
35
+ var import_node_path2 = require("path");
36
+
37
+ // src/paths.ts
38
+ var import_node_os = require("os");
39
+ var import_node_path = require("path");
40
+ var import_node_url = require("url");
41
+ var import_meta = {};
42
+ var __dirname = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
43
+ function getPackageRoot() {
44
+ return (0, import_node_path.join)(__dirname, "..");
45
+ }
46
+ function getSkillPath(skillName) {
47
+ return (0, import_node_path.join)(getPackageRoot(), "skills", skillName, "SKILL.md");
48
+ }
49
+ function getAgentPath(agentName) {
50
+ return (0, import_node_path.join)(getPackageRoot(), "agents", `${agentName}.md`);
51
+ }
52
+ function getCommandPath(commandName) {
53
+ return (0, import_node_path.join)(getPackageRoot(), "commands", `${commandName}.md`);
54
+ }
55
+ function getGlobalConfigDir() {
56
+ return (0, import_node_path.join)((0, import_node_os.homedir)(), ".config", "opencode");
57
+ }
58
+ function getProjectConfigDir(projectRoot = process.cwd()) {
59
+ return (0, import_node_path.join)(projectRoot, ".opencode");
60
+ }
61
+ function getDestinationPaths(global, projectRoot) {
62
+ const baseDir = global ? getGlobalConfigDir() : getProjectConfigDir(projectRoot);
63
+ return {
64
+ skills: (0, import_node_path.join)(baseDir, "skills"),
65
+ agents: (0, import_node_path.join)(baseDir, "agents"),
66
+ commands: (0, import_node_path.join)(baseDir, "commands")
67
+ };
68
+ }
69
+
70
+ // src/installer.ts
71
+ async function install(options = {}) {
72
+ const {
73
+ global: isGlobal = false,
74
+ projectRoot = process.cwd(),
75
+ categories = ["skills", "agents", "commands"],
76
+ force = false,
77
+ verbose = false
78
+ } = options;
79
+ const result = {
80
+ installed: [],
81
+ skipped: [],
82
+ errors: []
83
+ };
84
+ const packageRoot = getPackageRoot();
85
+ const destinations = getDestinationPaths(isGlobal, projectRoot);
86
+ const log = (msg) => {
87
+ if (verbose) console.log(msg);
88
+ };
89
+ if (categories.includes("skills")) {
90
+ const skillsDir = (0, import_node_path2.join)(packageRoot, "skills");
91
+ if ((0, import_node_fs.existsSync)(skillsDir)) {
92
+ const skills = (0, import_node_fs.readdirSync)(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
93
+ for (const skill of skills) {
94
+ const src = (0, import_node_path2.join)(skillsDir, skill);
95
+ const dest = (0, import_node_path2.join)(destinations.skills, skill);
96
+ try {
97
+ if ((0, import_node_fs.existsSync)(dest) && !force) {
98
+ result.skipped.push(`skill:${skill}`);
99
+ log(`Skipped skill/${skill} (already exists)`);
100
+ continue;
101
+ }
102
+ (0, import_node_fs.mkdirSync)((0, import_node_path2.dirname)(dest), { recursive: true });
103
+ (0, import_node_fs.cpSync)(src, dest, { recursive: true });
104
+ result.installed.push(`skill:${skill}`);
105
+ log(`Installed skill/${skill}`);
106
+ } catch (err) {
107
+ result.errors.push(`skill:${skill}: ${err}`);
108
+ }
109
+ }
110
+ }
111
+ }
112
+ if (categories.includes("agents")) {
113
+ const agentsDir = (0, import_node_path2.join)(packageRoot, "agents");
114
+ if ((0, import_node_fs.existsSync)(agentsDir)) {
115
+ const agents = (0, import_node_fs.readdirSync)(agentsDir).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
116
+ for (const agent of agents) {
117
+ const src = (0, import_node_path2.join)(agentsDir, `${agent}.md`);
118
+ const dest = (0, import_node_path2.join)(destinations.agents, `${agent}.md`);
119
+ try {
120
+ if ((0, import_node_fs.existsSync)(dest) && !force) {
121
+ result.skipped.push(`agent:${agent}`);
122
+ log(`Skipped agents/${agent}.md (already exists)`);
123
+ continue;
124
+ }
125
+ (0, import_node_fs.mkdirSync)((0, import_node_path2.dirname)(dest), { recursive: true });
126
+ (0, import_node_fs.cpSync)(src, dest);
127
+ result.installed.push(`agent:${agent}`);
128
+ log(`Installed agents/${agent}.md`);
129
+ } catch (err) {
130
+ result.errors.push(`agent:${agent}: ${err}`);
131
+ }
132
+ }
133
+ }
134
+ }
135
+ if (categories.includes("commands")) {
136
+ const commandsDir = (0, import_node_path2.join)(packageRoot, "commands");
137
+ if ((0, import_node_fs.existsSync)(commandsDir)) {
138
+ const commands = (0, import_node_fs.readdirSync)(commandsDir).filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
139
+ for (const command of commands) {
140
+ const src = (0, import_node_path2.join)(commandsDir, `${command}.md`);
141
+ const dest = (0, import_node_path2.join)(destinations.commands, `${command}.md`);
142
+ try {
143
+ if ((0, import_node_fs.existsSync)(dest) && !force) {
144
+ result.skipped.push(`command:${command}`);
145
+ log(`Skipped commands/${command}.md (already exists)`);
146
+ continue;
147
+ }
148
+ (0, import_node_fs.mkdirSync)((0, import_node_path2.dirname)(dest), { recursive: true });
149
+ (0, import_node_fs.cpSync)(src, dest);
150
+ result.installed.push(`command:${command}`);
151
+ log(`Installed commands/${command}.md`);
152
+ } catch (err) {
153
+ result.errors.push(`command:${command}: ${err}`);
154
+ }
155
+ }
156
+ }
157
+ }
158
+ return result;
159
+ }
160
+
161
+ // src/manifest.ts
162
+ var SKILLS = [
163
+ {
164
+ name: "ux-heuristics",
165
+ description: "Nielsen's 10 usability heuristics with evaluation methodology",
166
+ category: "core"
167
+ },
168
+ {
169
+ name: "wcag-accessibility",
170
+ description: "WCAG 2.2 compliance checklist and ARIA patterns",
171
+ category: "core"
172
+ },
173
+ {
174
+ name: "visual-design-system",
175
+ description: "Layout, typography, color theory, spacing systems",
176
+ category: "core"
177
+ },
178
+ {
179
+ name: "interaction-patterns",
180
+ description: "Micro-interactions, loading states, feedback mechanisms",
181
+ category: "core"
182
+ },
183
+ {
184
+ name: "react-ux-patterns",
185
+ description: "React/Next.js specific UX patterns",
186
+ category: "framework"
187
+ },
188
+ {
189
+ name: "mobile-responsive-ux",
190
+ description: "Touch targets, gestures, responsive patterns",
191
+ category: "core"
192
+ }
193
+ ];
194
+ var AGENTS = [
195
+ {
196
+ name: "ux-auditor",
197
+ description: "Full UX audit against heuristics (read-only)",
198
+ mode: "analysis"
199
+ },
200
+ {
201
+ name: "ux-engineer",
202
+ description: "UX analysis + implements fixes",
203
+ mode: "fix"
204
+ },
205
+ {
206
+ name: "accessibility-auditor",
207
+ description: "WCAG 2.2 compliance review (read-only)",
208
+ mode: "analysis"
209
+ },
210
+ {
211
+ name: "accessibility-engineer",
212
+ description: "Accessibility fixes",
213
+ mode: "fix"
214
+ },
215
+ {
216
+ name: "visual-reviewer",
217
+ description: "Design system consistency check",
218
+ mode: "analysis"
219
+ },
220
+ {
221
+ name: "interaction-reviewer",
222
+ description: "Micro-interactions and feedback review",
223
+ mode: "analysis"
224
+ }
225
+ ];
226
+ var COMMANDS = [
227
+ {
228
+ name: "ux-audit",
229
+ description: "Comprehensive UX audit"
230
+ },
231
+ {
232
+ name: "a11y-check",
233
+ description: "Quick accessibility scan"
234
+ },
235
+ {
236
+ name: "design-review",
237
+ description: "Visual consistency check"
238
+ },
239
+ {
240
+ name: "screenshot-review",
241
+ description: "Visual review from screenshot"
242
+ }
243
+ ];
244
+ // Annotate the CommonJS export names for ESM import in node:
245
+ 0 && (module.exports = {
246
+ AGENTS,
247
+ COMMANDS,
248
+ SKILLS,
249
+ getAgentPath,
250
+ getCommandPath,
251
+ getSkillPath,
252
+ install
253
+ });
254
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/installer.ts","../src/paths.ts","../src/manifest.ts"],"sourcesContent":["export { install } from './installer.js';\nexport type { InstallOptions } from './installer.js';\nexport { getSkillPath, getAgentPath, getCommandPath } from './paths.js';\nexport { SKILLS, AGENTS, COMMANDS } from './manifest.js';\n","import { existsSync, mkdirSync, cpSync, readdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { getPackageRoot, getDestinationPaths } from './paths.js';\n\nexport interface InstallOptions {\n /** Install globally to ~/.config/opencode */\n global?: boolean;\n /** Project root for local installation */\n projectRoot?: string;\n /** Only install specific categories */\n categories?: ('skills' | 'agents' | 'commands')[];\n /** Overwrite existing files */\n force?: boolean;\n /** Verbose output */\n verbose?: boolean;\n}\n\nexport interface InstallResult {\n installed: string[];\n skipped: string[];\n errors: string[];\n}\n\nexport async function install(options: InstallOptions = {}): Promise<InstallResult> {\n const {\n global: isGlobal = false,\n projectRoot = process.cwd(),\n categories = ['skills', 'agents', 'commands'],\n force = false,\n verbose = false,\n } = options;\n\n const result: InstallResult = {\n installed: [],\n skipped: [],\n errors: [],\n };\n\n const packageRoot = getPackageRoot();\n const destinations = getDestinationPaths(isGlobal, projectRoot);\n\n const log = (msg: string) => {\n if (verbose) console.log(msg);\n };\n\n if (categories.includes('skills')) {\n const skillsDir = join(packageRoot, 'skills');\n if (existsSync(skillsDir)) {\n const skills = readdirSync(skillsDir, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name);\n\n for (const skill of skills) {\n const src = join(skillsDir, skill);\n const dest = join(destinations.skills, skill);\n\n try {\n if (existsSync(dest) && !force) {\n result.skipped.push(`skill:${skill}`);\n log(`Skipped skill/${skill} (already exists)`);\n continue;\n }\n\n mkdirSync(dirname(dest), { recursive: true });\n cpSync(src, dest, { recursive: true });\n result.installed.push(`skill:${skill}`);\n log(`Installed skill/${skill}`);\n } catch (err) {\n result.errors.push(`skill:${skill}: ${err}`);\n }\n }\n }\n }\n\n if (categories.includes('agents')) {\n const agentsDir = join(packageRoot, 'agents');\n if (existsSync(agentsDir)) {\n const agents = readdirSync(agentsDir)\n .filter((f) => f.endsWith('.md'))\n .map((f) => f.replace('.md', ''));\n\n for (const agent of agents) {\n const src = join(agentsDir, `${agent}.md`);\n const dest = join(destinations.agents, `${agent}.md`);\n\n try {\n if (existsSync(dest) && !force) {\n result.skipped.push(`agent:${agent}`);\n log(`Skipped agents/${agent}.md (already exists)`);\n continue;\n }\n\n mkdirSync(dirname(dest), { recursive: true });\n cpSync(src, dest);\n result.installed.push(`agent:${agent}`);\n log(`Installed agents/${agent}.md`);\n } catch (err) {\n result.errors.push(`agent:${agent}: ${err}`);\n }\n }\n }\n }\n\n if (categories.includes('commands')) {\n const commandsDir = join(packageRoot, 'commands');\n if (existsSync(commandsDir)) {\n const commands = readdirSync(commandsDir)\n .filter((f) => f.endsWith('.md'))\n .map((f) => f.replace('.md', ''));\n\n for (const command of commands) {\n const src = join(commandsDir, `${command}.md`);\n const dest = join(destinations.commands, `${command}.md`);\n\n try {\n if (existsSync(dest) && !force) {\n result.skipped.push(`command:${command}`);\n log(`Skipped commands/${command}.md (already exists)`);\n continue;\n }\n\n mkdirSync(dirname(dest), { recursive: true });\n cpSync(src, dest);\n result.installed.push(`command:${command}`);\n log(`Installed commands/${command}.md`);\n } catch (err) {\n result.errors.push(`command:${command}: ${err}`);\n }\n }\n }\n }\n\n return result;\n}\n","import { homedir } from 'node:os';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport function getPackageRoot(): string {\n return join(__dirname, '..');\n}\n\nexport function getSkillPath(skillName: string): string {\n return join(getPackageRoot(), 'skills', skillName, 'SKILL.md');\n}\n\nexport function getAgentPath(agentName: string): string {\n return join(getPackageRoot(), 'agents', `${agentName}.md`);\n}\n\nexport function getCommandPath(commandName: string): string {\n return join(getPackageRoot(), 'commands', `${commandName}.md`);\n}\n\nexport function getGlobalConfigDir(): string {\n return join(homedir(), '.config', 'opencode');\n}\n\nexport function getProjectConfigDir(projectRoot: string = process.cwd()): string {\n return join(projectRoot, '.opencode');\n}\n\nexport function getDestinationPaths(global: boolean, projectRoot?: string) {\n const baseDir = global ? getGlobalConfigDir() : getProjectConfigDir(projectRoot);\n\n return {\n skills: join(baseDir, 'skills'),\n agents: join(baseDir, 'agents'),\n commands: join(baseDir, 'commands'),\n };\n}\n","export const SKILLS = [\n {\n name: 'ux-heuristics',\n description: \"Nielsen's 10 usability heuristics with evaluation methodology\",\n category: 'core',\n },\n {\n name: 'wcag-accessibility',\n description: 'WCAG 2.2 compliance checklist and ARIA patterns',\n category: 'core',\n },\n {\n name: 'visual-design-system',\n description: 'Layout, typography, color theory, spacing systems',\n category: 'core',\n },\n {\n name: 'interaction-patterns',\n description: 'Micro-interactions, loading states, feedback mechanisms',\n category: 'core',\n },\n {\n name: 'react-ux-patterns',\n description: 'React/Next.js specific UX patterns',\n category: 'framework',\n },\n {\n name: 'mobile-responsive-ux',\n description: 'Touch targets, gestures, responsive patterns',\n category: 'core',\n },\n] as const;\n\nexport const AGENTS = [\n {\n name: 'ux-auditor',\n description: 'Full UX audit against heuristics (read-only)',\n mode: 'analysis',\n },\n {\n name: 'ux-engineer',\n description: 'UX analysis + implements fixes',\n mode: 'fix',\n },\n {\n name: 'accessibility-auditor',\n description: 'WCAG 2.2 compliance review (read-only)',\n mode: 'analysis',\n },\n {\n name: 'accessibility-engineer',\n description: 'Accessibility fixes',\n mode: 'fix',\n },\n {\n name: 'visual-reviewer',\n description: 'Design system consistency check',\n mode: 'analysis',\n },\n {\n name: 'interaction-reviewer',\n description: 'Micro-interactions and feedback review',\n mode: 'analysis',\n },\n] as const;\n\nexport const COMMANDS = [\n {\n name: 'ux-audit',\n description: 'Comprehensive UX audit',\n },\n {\n name: 'a11y-check',\n description: 'Quick accessibility scan',\n },\n {\n name: 'design-review',\n description: 'Visual consistency check',\n },\n {\n name: 'screenshot-review',\n description: 'Visual review from screenshot',\n },\n] as const;\n\nexport type SkillName = (typeof SKILLS)[number]['name'];\nexport type AgentName = (typeof AGENTS)[number]['name'];\nexport type CommandName = (typeof COMMANDS)[number]['name'];\n"],"mappings":"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","names":["import_node_path"]}