synthesisui 0.16.200 → 0.16.201

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.
@@ -4,7 +4,7 @@ import { isOlderCli } from "../cli-version.js";
4
4
  import { readToken, resolveRegistry } from "../config.js";
5
5
  import { markSent, readEvents } from "../doctor/ledger.js";
6
6
  import { checkableName, closeRequest, readRequests, verifyAndCloseRequests, } from "../doctor/requests.js";
7
- import { describeDelta, readSyncMark, writeSyncMark, } from "../last-sync.js";
7
+ import { describeDelta, fingerprintReadings, readSyncMark, writeSyncMark, } from "../last-sync.js";
8
8
  import { measuredScope, rememberScope } from "../measured-scope.js";
9
9
  import { body, paint, section, snippet } from "../output.js";
10
10
  import { repoStateOf } from "../repo-state.js";
@@ -363,6 +363,9 @@ export async function remeasure(args) {
363
363
  ?.declarations ?? 0,
364
364
  seen: sum(led?.counted),
365
365
  interpreted: sum(led?.interpreted),
366
+ /** O que cada componente LÊ - ver `readings` em `SyncMark`, e o defeito que ele conserta. */
367
+ ...(args.cli ? { cli: args.cli } : {}),
368
+ readings: fingerprintReadings(census.components),
366
369
  };
367
370
  console.log(body(paint.faint(describeDelta(mark, await readSyncMark(root)))));
368
371
  await writeSyncMark(root, mark);
package/dist/last-sync.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { readFile, writeFile } from "node:fs/promises";
2
3
  import { join } from "node:path";
3
4
  /**
@@ -13,6 +14,30 @@ import { join } from "node:path";
13
14
  * "antes" - e diz isso, em vez de inventar um delta.
14
15
  */
15
16
  export const LAST_SYNC_FILE = ".last-sync.json";
17
+ /**
18
+ * A IMPRESSÃO DA LINHA INTEIRA, e nunca de campos escolhidos a dedo.
19
+ *
20
+ * A tentação é hashear `props` e `count`. A lição deste repositório é que uma lista de campos
21
+ * escrita hoje esquece o campo de amanhã, em silêncio: `origin` nasceu em 10/08 e uma impressão
22
+ * seletiva não o veria. Serializar a linha com as chaves ordenadas custa nada e não tem como
23
+ * envelhecer.
24
+ *
25
+ * `name` sai do valor porque já É a chave - hasheá-lo junto só gastaria bytes.
26
+ */
27
+ export function fingerprintReadings(components) {
28
+ const out = {};
29
+ for (const c of components ?? []) {
30
+ const name = typeof c?.name === "string" ? c.name : null;
31
+ if (!name)
32
+ continue;
33
+ const { name: _drop, ...rest } = c;
34
+ out[name] = createHash("sha256")
35
+ .update(JSON.stringify(rest, Object.keys(rest).sort()))
36
+ .digest("hex")
37
+ .slice(0, 12);
38
+ }
39
+ return out;
40
+ }
16
41
  const path = (root) => join(root, "_synthesisui", LAST_SYNC_FILE);
17
42
  export async function readSyncMark(root) {
18
43
  try {
@@ -47,11 +72,57 @@ export function describeDelta(now, before) {
47
72
  moved("declarations", before.declarations, now.declarations);
48
73
  moved("fragments read", before.interpreted, now.interpreted);
49
74
  moved("fragments seen", before.seen, now.seen);
75
+ /**
76
+ * E O QUE MUDOU DE LEITURA, que é o que um conserto de leitor move. Ver `readings`.
77
+ *
78
+ * Nomeados, e não só contados: "4 components read differently" manda a pessoa procurar; com os
79
+ * nomes ela abre os quatro. O corte em três é o mesmo critério do resto da esteira - alguns
80
+ * mostram a forma, o resto vira contagem.
81
+ */
82
+ const read = readingDelta(now, before);
83
+ if (read)
84
+ parts.push(read);
50
85
  const when = ago(before.at);
51
- return parts.length === 0
52
- ? `nothing moved since your last sync${when ? `, ${when}` : ""}`
53
- : `${parts.join(" · ")} — since your last sync${when ? `, ${when}` : ""}`;
86
+ /**
87
+ * O INSTRUMENTO ANDOU, e isso vem junto do número em vez de depois dele. Ver `cli`.
88
+ */
89
+ const reader = before.cli && now.cli && before.cli !== now.cli
90
+ ? `, and the reader moved ${before.cli} → ${now.cli}, so some of this is us reading better rather than your code changing`
91
+ : "";
92
+ if (parts.length > 0)
93
+ return `${parts.join(" · ")} — since your last sync${when ? `, ${when}` : ""}${reader}`;
94
+ /**
95
+ * NADA MUDOU É DIFERENTE DE NÃO DÁ PARA SABER. Um carimbo de uma versão anterior a esta não tem
96
+ * as impressões, então afirmar que nada mudou seria afirmar sobre o que não foi medido - e é
97
+ * justamente a rodada que ESTREIA um leitor novo que cairia nesse silêncio.
98
+ */
99
+ if (!before.readings)
100
+ return `the four totals are unchanged since your last sync${when ? `, ${when}` : ""} - what each component reads was not recorded back then, so this run has nothing to compare it against. The next one will.`;
101
+ return `nothing moved since your last sync${when ? `, ${when}` : ""}`;
102
+ }
103
+ /** Quantos componentes leem diferente, e quais - ou nada, quando não há o que comparar. */
104
+ function readingDelta(now, before) {
105
+ const was = before.readings;
106
+ const is = now.readings;
107
+ if (!was || !is)
108
+ return null;
109
+ const gone = Object.keys(was).filter((n) => !(n in is));
110
+ const born = Object.keys(is).filter((n) => !(n in was));
111
+ const changed = Object.keys(is).filter((n) => n in was && was[n] !== is[n]);
112
+ const said = [];
113
+ if (changed.length > 0)
114
+ said.push(`${changed.length} ${changedLine(changed)}`);
115
+ if (born.length > 0)
116
+ said.push(`${born.length} new: ${list(born)}`);
117
+ if (gone.length > 0)
118
+ said.push(`${gone.length} gone: ${list(gone)}`);
119
+ return said.length > 0 ? said.join(" · ") : null;
54
120
  }
121
+ const SHOW = 3;
122
+ const list = (names) => names.length <= SHOW
123
+ ? names.join(", ")
124
+ : `${names.slice(0, SHOW).join(", ")} and ${names.length - SHOW} more`;
125
+ const changedLine = (changed) => `component${changed.length === 1 ? "" : "s"} read differently (${list(changed)})`;
55
126
  /** Quanto tempo faz, em palavras. Um carimbo ilegível não vira frase. */
56
127
  function ago(at) {
57
128
  const then = Date.parse(at);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.200",
3
+ "version": "0.16.201",
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": {