synthesisui 0.16.394 → 0.16.396
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/doctor/style-ledger.js +20 -0
- package/dist/index.js +16 -0
- package/dist/where-you-are.js +78 -0
- package/package.json +1 -1
|
@@ -450,6 +450,26 @@ export function describeValueRuler(values) {
|
|
|
450
450
|
const decisions = values.seen - values.structure;
|
|
451
451
|
const closed = values.interpreted + values.answered;
|
|
452
452
|
const percent = decisions > 0 ? Math.round((closed / decisions) * 100) : 0;
|
|
453
|
+
/**
|
|
454
|
+
* NADA PARA MEDIR NÃO É ZERO POR CENTO - e a frase dizia zero três vezes.
|
|
455
|
+
*
|
|
456
|
+
* O QUE O CLIENTE VIA, caminhado em 07/09 num `create-next-app` recém-criado: *"Of the 0 class
|
|
457
|
+
* declarations on your components, 0 are structure. Of the 0 design decisions, 0 are interpreted -
|
|
458
|
+
* 0%."* Três zeros e um 0% sobre um projeto onde a régua não tinha o que medir, porque ele ainda
|
|
459
|
+
* não escreveu um componente - só páginas, e uma página não é componente de design system, o que o
|
|
460
|
+
* próprio relatório explica seis linhas acima.
|
|
461
|
+
*
|
|
462
|
+
* `0%` é um número de DESEMPENHO, e ali não houve desempenho nenhum. É a lei 14 do `CLAUDE.md`:
|
|
463
|
+
* *"um zero pelado lê como falha nossa; um zero com motivo lê como fato"* - e para quem acabou de
|
|
464
|
+
* apontar a plataforma para o próprio projeto, uma linha de 0% é a primeira impressão.
|
|
465
|
+
*
|
|
466
|
+
* A frase que substitui diz o FATO e o caminho, sem inventar percentual: não há componente para
|
|
467
|
+
* medir ainda.
|
|
468
|
+
*/
|
|
469
|
+
if (values.seen === 0)
|
|
470
|
+
return [
|
|
471
|
+
"No component of yours carries a class declaration yet - so there is nothing for this ruler to read. It starts answering once a component exists, and pages do not count as components.",
|
|
472
|
+
];
|
|
453
473
|
return [
|
|
454
474
|
`Of the ${values.seen} class declarations on your components, ${values.structure} are structure (layout plumbing, not design decisions). Of the ${decisions} design decisions, ${closed} are interpreted${values.answered > 0 ? ` (${values.answered} of them answered by you)` : ""} - ${percent}%.`,
|
|
455
475
|
];
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ import { appendEvent } from "./doctor/ledger.js";
|
|
|
34
34
|
import { blueprintTarget, installedSlugs } from "./installed.js";
|
|
35
35
|
import { useLang } from "./lang.js";
|
|
36
36
|
import { RegistryError } from "./registry.js";
|
|
37
|
+
import { bearing, openingFor } from "./where-you-are.js";
|
|
37
38
|
/** Our own version, for pinning the hook and MCP commands we write into a
|
|
38
39
|
* project. Read from the package we are running out of, so a pinned command
|
|
39
40
|
* always names the version that produced it. */
|
|
@@ -155,6 +156,21 @@ async function main() {
|
|
|
155
156
|
const { positionals, flags } = parseFlags(process.argv.slice(2));
|
|
156
157
|
const [command, ...args] = positionals;
|
|
157
158
|
if (!command || flags.help || command === "help") {
|
|
159
|
+
/**
|
|
160
|
+
* A PRIMEIRA LINHA FALA DO PROJETO ONDE ELA FOI RODADA - ver `where-you-are.ts`.
|
|
161
|
+
*
|
|
162
|
+
* A lista continua inteira logo abaixo. O que muda é que quem digita `npx synthesisui` pela
|
|
163
|
+
* primeira vez lê uma frase sobre o próprio repositório antes de 113 linhas que serviam
|
|
164
|
+
* igualmente a um diretório vazio.
|
|
165
|
+
*
|
|
166
|
+
* Só na tela SEM comando: `--help` e `help` são um pedido pela lista, e enfeitar um pedido
|
|
167
|
+
* explícito é o oposto de responder a ele.
|
|
168
|
+
*/
|
|
169
|
+
if (!command && !flags.help) {
|
|
170
|
+
const root = typeof flags.dir === "string" ? flags.dir : process.cwd();
|
|
171
|
+
for (const line of openingFor(await bearing(root)))
|
|
172
|
+
console.log(line);
|
|
173
|
+
}
|
|
158
174
|
console.log(HELP);
|
|
159
175
|
return;
|
|
160
176
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { readdir, stat } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const exists = async (path) => stat(path).then(() => true, () => false);
|
|
4
|
+
const SKIP = new Set(["node_modules", ".next", ".git", "dist", "build", "out"]);
|
|
5
|
+
/**
|
|
6
|
+
* Existe folha de estilo aqui? Para no PRIMEIRO acerto - a pergunta é "existe", não "quantas", e
|
|
7
|
+
* quantas é a resposta que o `doctor` dá depois de ser chamado.
|
|
8
|
+
*/
|
|
9
|
+
async function anyStylesheet(dir, depth = 2) {
|
|
10
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
11
|
+
for (const e of entries) {
|
|
12
|
+
if (e.isFile() && /\.(css|scss|sass|less)$/i.test(e.name))
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (depth <= 0)
|
|
16
|
+
return false;
|
|
17
|
+
for (const e of entries) {
|
|
18
|
+
if (!e.isDirectory() || SKIP.has(e.name) || e.name.startsWith("."))
|
|
19
|
+
continue;
|
|
20
|
+
if (await anyStylesheet(join(dir, e.name), depth - 1))
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
export async function bearing(root) {
|
|
26
|
+
if (!(await exists(join(root, "package.json"))))
|
|
27
|
+
return { where: "no-project", slug: null, hasStyles: false };
|
|
28
|
+
const installed = (await readdir(join(root, "_synthesisui", "ds"), {
|
|
29
|
+
withFileTypes: true,
|
|
30
|
+
}).catch(() => [])).filter((e) => e.isDirectory());
|
|
31
|
+
const hasStyles = await anyStylesheet(root);
|
|
32
|
+
if (installed.length > 0)
|
|
33
|
+
return {
|
|
34
|
+
where: "system-installed",
|
|
35
|
+
slug: installed[0]?.name ?? null,
|
|
36
|
+
hasStyles,
|
|
37
|
+
};
|
|
38
|
+
if (await exists(join(root, "_synthesisui", "config.json")))
|
|
39
|
+
return { where: "configured-without-system", slug: null, hasStyles };
|
|
40
|
+
return { where: "project-untouched", slug: null, hasStyles };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A ABERTURA: uma linha sobre ESTE projeto, e o comando que responde a partir daqui.
|
|
44
|
+
*
|
|
45
|
+
* Não substitui a lista - ela continua inteira logo abaixo. O que muda é que a primeira coisa que a
|
|
46
|
+
* pessoa lê fala do repositório onde ela está, em vez de um sistema da galeria que ela não tem.
|
|
47
|
+
*/
|
|
48
|
+
export function openingFor(b) {
|
|
49
|
+
if (b.where === "no-project")
|
|
50
|
+
return [
|
|
51
|
+
" There is no package.json here, so there is no project to read yet.",
|
|
52
|
+
" Run this from your project's root, or browse what exists:",
|
|
53
|
+
" synthesisui list",
|
|
54
|
+
"",
|
|
55
|
+
];
|
|
56
|
+
if (b.where === "system-installed")
|
|
57
|
+
return [
|
|
58
|
+
` ${b.slug} is installed here.`,
|
|
59
|
+
" This tells you what your code still writes outside it, and what --fix can swap:",
|
|
60
|
+
" synthesisui doctor",
|
|
61
|
+
"",
|
|
62
|
+
];
|
|
63
|
+
if (b.where === "configured-without-system")
|
|
64
|
+
return [
|
|
65
|
+
" This project is configured, and no design system is installed yet.",
|
|
66
|
+
" This reads what you already have and turns it into one - local, free, nothing is sent:",
|
|
67
|
+
" synthesisui import --dry",
|
|
68
|
+
"",
|
|
69
|
+
];
|
|
70
|
+
return [
|
|
71
|
+
b.hasStyles
|
|
72
|
+
? " A project with its own CSS, and nothing of ours in it yet."
|
|
73
|
+
: " A project with no design values written yet - so this starts empty and stays honest about it.",
|
|
74
|
+
" This reads what is here and tells you what has a name and what does not:",
|
|
75
|
+
" synthesisui doctor",
|
|
76
|
+
"",
|
|
77
|
+
];
|
|
78
|
+
}
|
package/package.json
CHANGED