synthesisui 0.16.357 → 0.16.358

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.
@@ -9,7 +9,7 @@ import { readRequests } from "../doctor/requests.js";
9
9
  import { declaredReference } from "../group-role.js";
10
10
  import { CHECKER_SINCE, installedBehind, MATERIALISER_SINCE, READER_SINCE, } from "../install-marks.js";
11
11
  import { measuredScope } from "../measured-scope.js";
12
- import { body } from "../output.js";
12
+ import { body, bodyWrapped, paint, section, snippet } from "../output.js";
13
13
  import { SKILLS } from "../skills.js";
14
14
  /**
15
15
  * QUAL CLI MEDIU O CENSO EM DISCO - e era o `reader`, um inteiro, até 11/08.
@@ -625,8 +625,38 @@ export async function nextStepFor(root) {
625
625
  * chutá-lo seria pior que pedir para olhar.
626
626
  */
627
627
  return measured
628
- ? "This repo has been measured and has no system installed here. If you already imported, the system is in your account: `synthesisui list --mine`, then `synthesisui add <slug>`."
629
- : 'This repo has no design system contract yet. Ask me: "import my design system."';
628
+ ? {
629
+ sentence: "This repo has been measured and has no system installed here. If you already imported, the system is in your account: `synthesisui list --mine`, then `synthesisui add <slug>`.",
630
+ headline: "Your system is already in your account. Bring it in here:",
631
+ run: ["synthesisui list --mine", "synthesisui add <slug>"],
632
+ why: "Re-measuring would cost minutes and change nothing the platform already knows.",
633
+ }
634
+ : {
635
+ sentence: 'This repo has no design system contract yet. Ask me: "import my design system."',
636
+ headline: "Open a new agent session in this repo and say:",
637
+ say: "import my design system",
638
+ why: "I read what is already in your code - the colours, the type, the shapes, the components. Nothing is invented.",
639
+ };
640
+ }
641
+ /**
642
+ * A AÇÃO RECOMENDADA, DESENHADA PARA SER VISTA - uma, com título, o literal copiável e o por quê.
643
+ *
644
+ * A hierarquia usa a paleta que já existe e no papel que ela declara: `blue` marca o que é VIVO (o
645
+ * que ele diz ou roda), `dim` é prosa secundária (o por quê e a exigência de sessão nova). A seção
646
+ * traz as linhas em branco de graça, que é o "respiro" pedido.
647
+ */
648
+ export function renderNextStep(next, freshSession) {
649
+ const lines = [section("Do this next"), body(next.headline), ""];
650
+ if (next.say)
651
+ lines.push(paint.blue(snippet([next.say])), "");
652
+ if (next.run?.length)
653
+ lines.push(paint.blue(snippet(next.run)), "");
654
+ lines.push(...bodyWrapped(next.why).map(paint.dim));
655
+ if (freshSession)
656
+ lines.push(...bodyWrapped(freshSession.mcp
657
+ ? "A new session is what loads the skills and tools just installed, and the project's tools ask for approval once - say yes."
658
+ : "A new session is what loads the skills just installed.").map(paint.dim));
659
+ return lines.join("\n");
630
660
  }
631
661
  /**
632
662
  * A CAUDA DE UM COMANDO QUE TERMINOU: o que ainda está fora, ou nada.
@@ -642,10 +672,8 @@ export async function reportWhatIsLeft(root, opts = {}) {
642
672
  const items = await misalignments(root, opts).catch(() => []);
643
673
  if (items.length === 0) {
644
674
  const next = await nextStepFor(root).catch(() => null);
645
- if (next) {
646
- console.log("");
647
- console.log(body(next));
648
- }
675
+ if (next)
676
+ console.log(renderNextStep(next, opts.freshSession));
649
677
  return;
650
678
  }
651
679
  console.log("");
@@ -673,5 +701,5 @@ export async function align(opts) {
673
701
  */
674
702
  const next = await nextStepFor(root).catch(() => null);
675
703
  if (next)
676
- console.log(next);
704
+ console.log(next.sentence);
677
705
  }
@@ -153,7 +153,13 @@ version) {
153
153
  if (next !== current) {
154
154
  const was = pinnedInHook(current);
155
155
  console.log("");
156
- console.log(body(`Updating the terminal check in ${rc} - ${was ? `it was pinned to ${was}` : "it was on an unpinned version"}, moving it to ${version}.`));
156
+ /**
157
+ * DITA, E EM SEGUNDO PLANO. O dono pediu em 03/09 que ela saísse da tela; ela FICA porque
158
+ * reporta uma escrita FORA do repositório, e "um `.zshrc` que muda sem uma palavra é a
159
+ * definição de invasivo" é decisão dele mesmo, de 11/08. O que muda é o peso: cinza claro,
160
+ * como toda prosa secundária, para ela informar sem disputar com a ação recomendada.
161
+ */
162
+ console.log(body(paint.dim(`Updating the terminal check in ${rc} - ${was ? `it was pinned to ${was}` : "it was on an unpinned version"}, moving it to ${version}.`)));
157
163
  await writeFile(rc, next, "utf8").catch(() => { });
158
164
  }
159
165
  return;
@@ -379,18 +385,19 @@ export async function connect(opts) {
379
385
  : `✓ ${skill.label.padEnd(22)} updated to this CLI's pipeline`));
380
386
  }
381
387
  /**
382
- * O CI: escrito só quando pedido, e OFERECIDO sempre - com o que ele faz em duas linhas, porque
383
- * "adicione CI" sem dizer que nada reprova dívida herdada não é uma oferta, é um risco.
388
+ * O CI: escrito quando pedido, e NÃO MAIS OFERECIDO aqui.
389
+ *
390
+ * A oferta era verdadeira e estava no lugar errado: ela ocupava o espaço imediatamente antes da
391
+ * ação recomendada, num repositório onde a pessoa ainda não tem sistema nenhum - então o produto
392
+ * sugeria um portão de PR para uma dívida que ainda não existe. Ela mora agora na documentação do
393
+ * `connect` (dono, 03/09: "vamos deixar isso para uma documentação dentro do synthesisui").
394
+ *
395
+ * `--ci` continua fazendo tudo que fazia: quem pede, recebe.
384
396
  */
385
397
  if (opts.ci) {
386
398
  console.log("");
387
399
  await ci({ dir: root, write: true });
388
400
  }
389
- else {
390
- console.log("");
391
- console.log(body(paint.dim("Your PRs can carry this too: annotations on the exact line, and a check that fails only when the count goes UP - never on the debt you already have.")));
392
- console.log(paint.blue(snippet(["npx synthesisui@latest ci"])));
393
- }
394
401
  /** A mesma versão que a fiação do editor recebe - os dois pinam no mesmo número. */
395
402
  await offerShellHook(opts.shell === true, opts.version);
396
403
  /**
@@ -409,16 +416,13 @@ export async function connect(opts) {
409
416
  const needsRestart = moved(wired.hook) ||
410
417
  moved(wired.session) ||
411
418
  (Array.isArray(wired.mcp) && wired.mcp.some((m) => moved(m.status)));
412
- if (needsRestart) {
413
- console.log("");
414
- console.log(body("Reopen your editor session - all of them are read at startup."));
415
- if (want.mcp &&
416
- Array.isArray(wired.mcp) &&
417
- wired.mcp.some((m) => moved(m.status))) {
418
- console.log(body('A project MCP server needs approving once; say yes when it asks. Then "/mcp" lists synthesisui.'));
419
- }
420
- }
421
- await reportWhatIsLeft(root, { cli: opts.version });
419
+ const mcpMoved = Boolean(want.mcp &&
420
+ Array.isArray(wired.mcp) &&
421
+ wired.mcp.some((m) => moved(m.status)));
422
+ await reportWhatIsLeft(root, {
423
+ cli: opts.version,
424
+ ...(needsRestart ? { freshSession: { mcp: mcpMoved } } : {}),
425
+ });
422
426
  /**
423
427
  * O CUSTO DO HOOK, DITO SEM UM NÚMERO QUE NÃO É NOSSO.
424
428
  *
@@ -434,10 +438,10 @@ export async function connect(opts) {
434
438
  */
435
439
  if (wired.command.startsWith("npx synthesisui@")) {
436
440
  console.log("");
437
- console.log(body("The hook runs through npx, which resolves this package against the"));
438
- console.log(body("registry on every edit - that wait is the network, not the check itself"));
439
- console.log(body("(the analysis is about 80ms). Adding synthesisui to your devDependencies"));
440
- console.log(body("makes npx resolve it locally instead, which is several times faster;"));
441
- console.log(body("run this again afterwards and it will switch by itself."));
441
+ console.log(body(paint.dim("The hook runs through npx, which resolves this package against the")));
442
+ console.log(body(paint.dim("registry on every edit - that wait is the network, not the check itself")));
443
+ console.log(body(paint.dim("(the analysis is about 80ms). Adding synthesisui to your devDependencies")));
444
+ console.log(body(paint.dim("makes npx resolve it locally instead, which is several times faster;")));
445
+ console.log(body(paint.dim("run this again afterwards and it will switch by itself.")));
442
446
  }
443
447
  }
package/dist/output.js CHANGED
@@ -20,6 +20,34 @@ export function snippet(lines) {
20
20
  export function body(line) {
21
21
  return ` ${line}`;
22
22
  }
23
+ /**
24
+ * PROSA LONGA QUEBRADA NA MESMA LARGURA QUE O RESTO DA TELA RESPEITA.
25
+ *
26
+ * Todo parágrafo daqui foi quebrado À MÃO até agora, uma string por linha - o que funciona para
27
+ * texto fixo e não funciona para texto que vem de dado. Medido em 03/09 na ação recomendada do
28
+ * `connect`: a linha do "por quê" saiu com 103 colunas num desenho de 66, e num terminal estreito
29
+ * ela dobra no meio de uma palavra, exatamente na frase que a pessoa mais precisa ler.
30
+ *
31
+ * Quebra por PALAVRA e nunca no meio de uma; uma palavra maior que a largura fica sozinha na linha
32
+ * em vez de ser cortada. Já indenta como `body`, porque a indentação conta para a largura.
33
+ */
34
+ export function bodyWrapped(text, width = WIDTH) {
35
+ const lines = [];
36
+ let current = "";
37
+ for (const word of text.split(/\s+/).filter(Boolean)) {
38
+ if (!current)
39
+ current = word;
40
+ else if (`${current} ${word}`.length <= width)
41
+ current += ` ${word}`;
42
+ else {
43
+ lines.push(current);
44
+ current = word;
45
+ }
46
+ }
47
+ if (current)
48
+ lines.push(current);
49
+ return lines.map(body);
50
+ }
23
51
  /**
24
52
  * Colour, used the way the product uses motion: a quiet base and a few
25
53
  * deliberate accents (dono, 30/07: "um cinza mais escuro e um mais claro,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.357",
3
+ "version": "0.16.358",
4
4
  "description": "Bring SynthesisUI design systems into any project - tokens, typed components, whole pages and an agent-ready CLAUDE.md manifest.",
5
5
  "type": "module",
6
6
  "bin": {