melvex-design 1.0.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/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # Melvex Design
2
+
3
+ Skill de direção de arte autônoma, UX, conteúdo e implementação frontend para transformar até um briefing sem instruções estéticas em um site autoral, acessível, rápido, responsivo e sem aparência genérica de IA.
4
+
5
+ Ela preserva a stack existente e funciona diretamente com React, Next.js, Vite, Astro e HTML/CSS. Em WordPress, Webflow e Framer, a implementação depende das ferramentas e do acesso disponíveis.
6
+
7
+ ## Requisitos
8
+
9
+ - Node.js 22.20 ou superior com `npx`.
10
+ - Um agente compatível com o formato de skills.
11
+ - Acesso de escrita à pasta de configuração do usuário.
12
+
13
+ ## Instalação recomendada
14
+
15
+ Instale no Codex com o comando próprio da Melvex:
16
+
17
+ ```powershell
18
+ npx melvex-design
19
+ ```
20
+
21
+ Esse é o instalador oficial da Melvex. Ele mostra somente a interface da marca, executa o mecanismo do Skills CLI em segundo plano e verifica `SKILL.md` e os recursos essenciais antes de informar sucesso. O Codex é o destino padrão para evitar instalações desnecessárias em dezenas de agentes.
22
+
23
+ Para escolher outro agente:
24
+
25
+ ```powershell
26
+ npx melvex-design --agent cursor
27
+ ```
28
+
29
+ Para instalar em mais de um:
30
+
31
+ ```powershell
32
+ npx melvex-design --agent codex --agent claude-code --agent cursor
33
+ ```
34
+
35
+ Use todos os agentes somente quando isso for realmente desejado:
36
+
37
+ ```powershell
38
+ npx melvex-design --all-agents
39
+ ```
40
+
41
+ Para diagnóstico, mostre também a saída técnica capturada do Skills CLI:
42
+
43
+ ```powershell
44
+ npx melvex-design --verbose
45
+ ```
46
+
47
+ Confira todas as opções sem instalar:
48
+
49
+ ```powershell
50
+ npx melvex-design --help
51
+ npx melvex-design --dry-run
52
+ ```
53
+
54
+ ## Instalação direta pelo Skills CLI
55
+
56
+ O comando externo continua disponível como alternativa:
57
+
58
+ ```powershell
59
+ npx skills add jaop2158-sketch/melvex-design --skill melvex-design --global --yes --agent codex
60
+ ```
61
+
62
+ O visual dessa alternativa pertence ao pacote `skills`, não à Melvex. Ela instala a skill, mas não instala o programa Codex CLI. O comando `npx skills use ... --agent codex` só consegue abrir o agente quando `codex --version` já funciona no terminal.
63
+
64
+ ## Instalador alternativo para PowerShell
65
+
66
+ Para uma instalação guiada sem depender do pacote `melvex-design` publicado no npm, use o script PowerShell. Ele apresenta as etapas da Melvex, verifica os arquivos essenciais e captura a saída original do Skills CLI para não misturar as duas interfaces.
67
+
68
+ Baixe e inspecione antes de executar:
69
+
70
+ ```powershell
71
+ Invoke-WebRequest -Uri "https://raw.githubusercontent.com/jaop2158-sketch/melvex-design/main/install.ps1" -OutFile ".\install-melvex.ps1"
72
+ Get-Content ".\install-melvex.ps1"
73
+ powershell -ExecutionPolicy Bypass -File ".\install-melvex.ps1"
74
+ ```
75
+
76
+ Para diagnóstico, exiba também a saída original capturada:
77
+
78
+ ```powershell
79
+ powershell -ExecutionPolicy Bypass -File ".\install-melvex.ps1" -ShowCliOutput
80
+ ```
81
+
82
+ Por segurança, o instalador não cria arquivos no projeto atual por padrão. Para também registrar o workflow `/melvex-design`, execute dentro do projeto ou informe o caminho:
83
+
84
+ ```powershell
85
+ powershell -ExecutionPolicy Bypass -File ".\install-melvex.ps1" -InstallWorkflow -ProjectPath "C:\caminho\do\projeto"
86
+ ```
87
+
88
+ Para substituir um workflow Melvex diferente, criando backup:
89
+
90
+ ```powershell
91
+ powershell -ExecutionPolicy Bypass -File ".\install-melvex.ps1" -InstallWorkflow -ForceWorkflow -ProjectPath "C:\caminho\do\projeto"
92
+ ```
93
+
94
+ ## Verificar a instalação
95
+
96
+ PowerShell:
97
+
98
+ ```powershell
99
+ Test-Path "$env:USERPROFILE\.agents\skills\melvex-design\SKILL.md"
100
+ Select-String -Path "$env:USERPROFILE\.agents\skills\melvex-design\SKILL.md" -Pattern "^name: melvex-design$"
101
+ ```
102
+
103
+ Bash:
104
+
105
+ ```bash
106
+ test -f ~/.agents/skills/melvex-design/SKILL.md
107
+ grep -q '^name: melvex-design$' ~/.agents/skills/melvex-design/SKILL.md
108
+ ```
109
+
110
+ Se a instalação estiver correta mas a skill ainda não aparecer, atualize a lista de skills ou abra uma nova sessão do agente.
111
+
112
+ ## Uso
113
+
114
+ - Antigravity e Claude Code: `/melvex-design <briefing>`
115
+ - Codex: `$melvex-design <briefing>`
116
+ - Cursor e demais agentes: mencione `melvex-design` ou use o mecanismo de skills da plataforma.
117
+
118
+ Exemplo:
119
+
120
+ ```text
121
+ $melvex-design Crie um site premium para uma clínica, preserve a stack atual, não invente avaliações e valide mobile, acessibilidade e performance.
122
+ ```
123
+
124
+ Você não precisa descrever o design. Um briefing focado apenas em conteúdo também deve gerar direção visual completa:
125
+
126
+ ```text
127
+ $melvex-design Crie um site para uma oficina de restauração de móveis. Preciso de início, serviços, processo, trabalhos realizados e contato. O objetivo é receber pedidos de orçamento pelo WhatsApp.
128
+ ```
129
+
130
+ A skill deve inferir conceito, tipografia, paleta, composição, mídia, gesto visual, movimento e adaptação mobile a partir do assunto. Site básico significa menos complexidade funcional, não visual sem personalidade.
131
+
132
+ Também é possível pedir uma auditoria sem edição:
133
+
134
+ ```text
135
+ $melvex-design Audite este site e priorize os problemas, mas não altere nenhum arquivo.
136
+ ```
137
+
138
+ ## Limitações
139
+
140
+ - Pesquisa de referências depende de acesso web.
141
+ - Métricas reais de Core Web Vitals exigem dados ou ferramentas adequadas; a skill não inventa notas.
142
+ - Publicação, serviços externos e alterações em produção continuam exigindo autorização explícita.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { run } from "../src/cli.js";
4
+
5
+ process.exitCode = await run(process.argv.slice(2));
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "melvex-design",
3
+ "version": "1.0.0",
4
+ "description": "Instalador oficial da skill Melvex Design com uma experiência de terminal própria.",
5
+ "type": "module",
6
+ "bin": {
7
+ "melvex-design": "bin/melvex-design.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "src"
12
+ ],
13
+ "scripts": {
14
+ "lint": "node --check bin/melvex-design.js && node --check src/cli.js",
15
+ "test": "node --test",
16
+ "package:check": "npm pack --dry-run",
17
+ "prepublishOnly": "npm run lint && npm test"
18
+ },
19
+ "keywords": [
20
+ "agent-skills",
21
+ "ai-design",
22
+ "codex",
23
+ "frontend-design",
24
+ "web-design"
25
+ ],
26
+ "author": "jaop2158-sketch",
27
+ "license": "UNLICENSED",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/jaop2158-sketch/melvex-design.git"
31
+ },
32
+ "homepage": "https://github.com/jaop2158-sketch/melvex-design#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/jaop2158-sketch/melvex-design/issues"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "engines": {
40
+ "node": ">=22.20.0"
41
+ },
42
+ "dependencies": {
43
+ "skills": "1.5.21"
44
+ }
45
+ }
package/src/cli.js ADDED
@@ -0,0 +1,417 @@
1
+ import { spawn } from "node:child_process";
2
+ import { constants as fsConstants } from "node:fs";
3
+ import { access, readFile, writeFile } from "node:fs/promises";
4
+ import { createRequire } from "node:module";
5
+ import os from "node:os";
6
+ import path from "node:path";
7
+
8
+ const require = createRequire(import.meta.url);
9
+
10
+ export const PACKAGE_NAME = "melvex-design";
11
+ export const PACKAGE_VERSION = "1.0.0";
12
+ export const SKILL_NAME = "melvex-design";
13
+ export const SKILL_SOURCE = "jaop2158-sketch/melvex-design";
14
+ export const DEFAULT_AGENTS = ["codex"];
15
+
16
+ const REQUIRED_FILES = [
17
+ "SKILL.md",
18
+ "references/visual-direction.md",
19
+ "references/quality-gates.md",
20
+ "scripts/ui-static-audit.mjs",
21
+ ];
22
+
23
+ const ANSI = {
24
+ reset: "\u001b[0m",
25
+ bold: "\u001b[1m",
26
+ dim: "\u001b[2m",
27
+ magenta: "\u001b[35m",
28
+ brightMagenta: "\u001b[95m",
29
+ cyan: "\u001b[36m",
30
+ green: "\u001b[32m",
31
+ yellow: "\u001b[33m",
32
+ red: "\u001b[31m",
33
+ white: "\u001b[97m",
34
+ };
35
+
36
+ function unique(values) {
37
+ return [...new Set(values)];
38
+ }
39
+
40
+ function splitAgents(value) {
41
+ return value
42
+ .split(",")
43
+ .map((agent) => agent.trim())
44
+ .filter(Boolean);
45
+ }
46
+
47
+ export function parseArgs(argv) {
48
+ const options = {
49
+ agents: [],
50
+ allAgents: false,
51
+ verbose: false,
52
+ dryRun: false,
53
+ color: Boolean(process.stdout.isTTY) && !process.env.NO_COLOR,
54
+ help: false,
55
+ version: false,
56
+ };
57
+
58
+ for (let index = 0; index < argv.length; index += 1) {
59
+ const argument = argv[index];
60
+
61
+ if (argument === "--agent" || argument === "-a") {
62
+ const value = argv[index + 1];
63
+ if (!value || value.startsWith("-")) {
64
+ throw new Error("Informe um agente depois de --agent.");
65
+ }
66
+ options.agents.push(...splitAgents(value));
67
+ index += 1;
68
+ continue;
69
+ }
70
+
71
+ if (argument.startsWith("--agent=")) {
72
+ options.agents.push(...splitAgents(argument.slice("--agent=".length)));
73
+ continue;
74
+ }
75
+
76
+ if (argument === "--all-agents") {
77
+ options.allAgents = true;
78
+ continue;
79
+ }
80
+
81
+ if (argument === "--verbose") {
82
+ options.verbose = true;
83
+ continue;
84
+ }
85
+
86
+ if (argument === "--dry-run") {
87
+ options.dryRun = true;
88
+ continue;
89
+ }
90
+
91
+ if (argument === "--no-color") {
92
+ options.color = false;
93
+ continue;
94
+ }
95
+
96
+ if (argument === "--help" || argument === "-h") {
97
+ options.help = true;
98
+ continue;
99
+ }
100
+
101
+ if (argument === "--version" || argument === "-V") {
102
+ options.version = true;
103
+ continue;
104
+ }
105
+
106
+ throw new Error(`Opção desconhecida: ${argument}`);
107
+ }
108
+
109
+ options.agents = unique(options.agents);
110
+ if (options.allAgents && options.agents.length > 0) {
111
+ throw new Error("Use --all-agents ou --agent, não os dois juntos.");
112
+ }
113
+ if (!options.allAgents && options.agents.length === 0) {
114
+ options.agents = [...DEFAULT_AGENTS];
115
+ }
116
+
117
+ return options;
118
+ }
119
+
120
+ export function buildSkillsArgs(options) {
121
+ const args = [
122
+ "add",
123
+ SKILL_SOURCE,
124
+ "--skill",
125
+ SKILL_NAME,
126
+ "--global",
127
+ "--yes",
128
+ ];
129
+
130
+ if (options.allAgents) {
131
+ args.push("--agent", "*");
132
+ return args;
133
+ }
134
+
135
+ for (const agent of options.agents) {
136
+ args.push("--agent", agent);
137
+ }
138
+ return args;
139
+ }
140
+
141
+ function paint(enabled, color, value) {
142
+ return enabled ? `${ANSI[color]}${value}${ANSI.reset}` : value;
143
+ }
144
+
145
+ function printBanner(color) {
146
+ const edge = paint(color, "brightMagenta", "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
147
+ console.log("");
148
+ console.log(` ${edge}`);
149
+ console.log(
150
+ ` ${paint(color, "bold", "MELVEX")} ${paint(color, "brightMagenta", "/ DESIGN")}`,
151
+ );
152
+ console.log(` ${paint(color, "dim", "Direção visual autônoma para agentes de IA")}`);
153
+ console.log(` ${edge}`);
154
+ console.log("");
155
+ }
156
+
157
+ function printStep(number, total, label, color) {
158
+ const marker = paint(color, "brightMagenta", `◆ ${number}/${total}`);
159
+ console.log(`${marker} ${paint(color, "white", label)}`);
160
+ }
161
+
162
+ function printSuccess(message, color) {
163
+ console.log(`${paint(color, "green", "✓")} ${message}`);
164
+ }
165
+
166
+ function printInfo(message, color) {
167
+ console.log(`${paint(color, "cyan", "i")} ${message}`);
168
+ }
169
+
170
+ function printWarning(message, color) {
171
+ console.log(`${paint(color, "yellow", "!")} ${message}`);
172
+ }
173
+
174
+ function printError(message, color) {
175
+ console.error(`${paint(color, "red", "×")} ${message}`);
176
+ }
177
+
178
+ export function helpText() {
179
+ return `Melvex Design ${PACKAGE_VERSION}
180
+
181
+ Instala a skill Melvex Design com uma interface própria.
182
+
183
+ Uso:
184
+ npx melvex-design [opções]
185
+
186
+ Opções:
187
+ -a, --agent <nome> Instalar em um agente. Pode ser repetido.
188
+ --all-agents Instalar em todos os agentes suportados.
189
+ --verbose Mostrar a saída técnica do Skills CLI.
190
+ --dry-run Mostrar o que seria executado sem instalar.
191
+ --no-color Desativar cores ANSI.
192
+ -h, --help Mostrar esta ajuda.
193
+ -V, --version Mostrar a versão.
194
+
195
+ Exemplos:
196
+ npx melvex-design
197
+ npx melvex-design --agent cursor
198
+ npx melvex-design -a codex -a claude-code
199
+ npx melvex-design --all-agents
200
+
201
+ Sem opções, a instalação é direcionada ao Codex.`;
202
+ }
203
+
204
+ function resolveSkillsBinary() {
205
+ try {
206
+ return require.resolve("skills/bin/cli.mjs");
207
+ } catch (error) {
208
+ if (error.code === "MODULE_NOT_FOUND") {
209
+ throw new Error(
210
+ "A dependência interna 'skills' não está instalada. Se estiver testando o código clonado, execute npm ci e tente novamente.",
211
+ );
212
+ }
213
+ throw error;
214
+ }
215
+ }
216
+
217
+ function startSpinner(label, color, verbose) {
218
+ if (!process.stdout.isTTY || verbose) {
219
+ printInfo(label, color);
220
+ return () => {};
221
+ }
222
+
223
+ const frames = ["◒", "◐", "◓", "◑"];
224
+ let frame = 0;
225
+ const render = () => {
226
+ const symbol = paint(color, "brightMagenta", frames[frame % frames.length]);
227
+ process.stdout.write(`\r${symbol} ${label}`);
228
+ frame += 1;
229
+ };
230
+ render();
231
+ const timer = setInterval(render, 90);
232
+
233
+ return () => {
234
+ clearInterval(timer);
235
+ process.stdout.write("\r\u001b[2K");
236
+ };
237
+ }
238
+
239
+ async function executeSkills(args, options) {
240
+ const skillsBinary = resolveSkillsBinary();
241
+ const output = [];
242
+ const child = spawn(process.execPath, [skillsBinary, ...args], {
243
+ env: {
244
+ ...process.env,
245
+ FORCE_COLOR: "0",
246
+ NO_COLOR: "1",
247
+ },
248
+ stdio: ["ignore", "pipe", "pipe"],
249
+ windowsHide: true,
250
+ });
251
+
252
+ const collect = (chunk) => {
253
+ const text = chunk.toString();
254
+ output.push(text);
255
+ if (options.verbose) {
256
+ process.stdout.write(paint(options.color, "dim", text));
257
+ }
258
+ };
259
+
260
+ child.stdout.on("data", collect);
261
+ child.stderr.on("data", collect);
262
+
263
+ return new Promise((resolve, reject) => {
264
+ child.once("error", reject);
265
+ child.once("close", (code, signal) => {
266
+ resolve({
267
+ code: code ?? 1,
268
+ signal,
269
+ output: output.join(""),
270
+ });
271
+ });
272
+ });
273
+ }
274
+
275
+ function candidateSkillDirectories(homeDirectories) {
276
+ const relativeDirectories = [
277
+ [".agents", "skills", SKILL_NAME],
278
+ [".config", "agents", "skills", SKILL_NAME],
279
+ [".codex", "skills", SKILL_NAME],
280
+ [".claude", "skills", SKILL_NAME],
281
+ [".cursor", "skills", SKILL_NAME],
282
+ ];
283
+
284
+ return unique(homeDirectories.filter(Boolean)).flatMap((home) =>
285
+ relativeDirectories.map((parts) => path.join(home, ...parts)),
286
+ );
287
+ }
288
+
289
+ export async function verifyInstalledSkill(homeDirectories = [os.homedir()]) {
290
+ const checked = [];
291
+
292
+ for (const directory of candidateSkillDirectories(homeDirectories)) {
293
+ checked.push(directory);
294
+ const skillFile = path.join(directory, "SKILL.md");
295
+ try {
296
+ await access(skillFile, fsConstants.R_OK);
297
+ const content = await readFile(skillFile, "utf8");
298
+ if (!/^name:\s*melvex-design\s*$/m.test(content)) {
299
+ continue;
300
+ }
301
+ for (const requiredFile of REQUIRED_FILES) {
302
+ await access(path.join(directory, ...requiredFile.split("/")), fsConstants.R_OK);
303
+ }
304
+ return { directory, checked };
305
+ } catch {
306
+ // Continue looking through canonical and agent-specific install paths.
307
+ }
308
+ }
309
+
310
+ return { directory: null, checked };
311
+ }
312
+
313
+ async function saveDiagnosticLog(content) {
314
+ const filename = `melvex-design-${Date.now()}.log`;
315
+ const logPath = path.join(os.tmpdir(), filename);
316
+ await writeFile(logPath, content || "Nenhuma saída foi recebida do Skills CLI.\n", {
317
+ encoding: "utf8",
318
+ mode: 0o600,
319
+ });
320
+ return logPath;
321
+ }
322
+
323
+ function resolveHomeDirectories() {
324
+ return unique([
325
+ os.homedir(),
326
+ process.env.USERPROFILE,
327
+ process.env.HOME,
328
+ ].filter(Boolean));
329
+ }
330
+
331
+ export async function run(argv) {
332
+ let options;
333
+ try {
334
+ options = parseArgs(argv);
335
+ } catch (error) {
336
+ printError(error.message, Boolean(process.stderr.isTTY) && !process.env.NO_COLOR);
337
+ console.error("Use npx melvex-design --help para ver as opções.");
338
+ return 2;
339
+ }
340
+
341
+ if (options.version) {
342
+ console.log(PACKAGE_VERSION);
343
+ return 0;
344
+ }
345
+ if (options.help) {
346
+ console.log(helpText());
347
+ return 0;
348
+ }
349
+
350
+ printBanner(options.color);
351
+ const totalSteps = 4;
352
+
353
+ printStep(1, totalSteps, "Verificando o ambiente", options.color);
354
+ printSuccess(`Node.js ${process.versions.node}`, options.color);
355
+ printSuccess("Instalador oficial da Melvex carregado", options.color);
356
+
357
+ printStep(2, totalSteps, "Preparando a instalação", options.color);
358
+ const target = options.allAgents ? "todos os agentes suportados" : options.agents.join(", ");
359
+ printInfo(`Destino: ${target}`, options.color);
360
+ printInfo(`Fonte: github.com/${SKILL_SOURCE}`, options.color);
361
+
362
+ const skillsArgs = buildSkillsArgs(options);
363
+ if (options.dryRun) {
364
+ printWarning("Simulação: nenhum arquivo foi alterado.", options.color);
365
+ console.log(`skills ${skillsArgs.join(" ")}`);
366
+ return 0;
367
+ }
368
+
369
+ printStep(3, totalSteps, "Instalando a skill", options.color);
370
+ const stopSpinner = startSpinner(
371
+ "Baixando e configurando Melvex Design...",
372
+ options.color,
373
+ options.verbose,
374
+ );
375
+ let result;
376
+ try {
377
+ result = await executeSkills(skillsArgs, options);
378
+ } catch (error) {
379
+ stopSpinner();
380
+ printError(`Não foi possível iniciar a instalação: ${error.message}`, options.color);
381
+ return 1;
382
+ }
383
+ stopSpinner();
384
+
385
+ printStep(4, totalSteps, "Validando os arquivos instalados", options.color);
386
+ const verification = await verifyInstalledSkill(resolveHomeDirectories());
387
+
388
+ if (!verification.directory) {
389
+ const logPath = await saveDiagnosticLog(result.output);
390
+ printError("A skill não foi encontrada nos locais esperados.", options.color);
391
+ printInfo(`Diagnóstico salvo em: ${logPath}`, options.color);
392
+ printInfo("Execute novamente com --verbose para acompanhar os detalhes.", options.color);
393
+ return 1;
394
+ }
395
+
396
+ printSuccess("SKILL.md e recursos essenciais verificados", options.color);
397
+ if (result.code !== 0) {
398
+ const logPath = await saveDiagnosticLog(result.output);
399
+ printWarning("A skill principal foi instalada, mas uma integração opcional falhou.", options.color);
400
+ printInfo(`Diagnóstico salvo em: ${logPath}`, options.color);
401
+ }
402
+
403
+ console.log("");
404
+ console.log(paint(options.color, "green", " INSTALAÇÃO CONCLUÍDA"));
405
+ console.log("");
406
+ console.log(` Skill ${paint(options.color, "white", SKILL_NAME)}`);
407
+ console.log(` Local ${paint(options.color, "dim", verification.directory)}`);
408
+ console.log(` Agentes ${paint(options.color, "dim", target)}`);
409
+ console.log("");
410
+ console.log(paint(options.color, "brightMagenta", " Teste agora com:"));
411
+ console.log(
412
+ " $melvex-design Crie um site bonito para uma clínica. Infira toda a direção visual.",
413
+ );
414
+ console.log("");
415
+ printInfo("Se a skill ainda não aparecer, atualize a lista de skills do agente.", options.color);
416
+ return 0;
417
+ }