synthesisui 0.16.428 → 0.16.429

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/claude-md.js CHANGED
@@ -184,14 +184,29 @@ best reasoning you produce.`;
184
184
  * A checagem é LOCAL e grátis: o censo grava qual CLI o mediu (`ledger.cli`) e o servidor MCP É o CLI,
185
185
  * então comparar as duas versões é aritmética em disco. Nada aqui telefona para casa - é a mesma
186
186
  * decisão que mantém o hook instalado.
187
+ *
188
+ * O TEXTO DEIXOU DE DIZER "IT COSTS NOTHING" em 16/09, e a correção é de fidelidade, não de estilo.
189
+ * Medido: `remeasure` não recusa por versão - ele mede e ENVIA em toda chamada, e a comparação de
190
+ * versões só imprime um aviso. Então a frase antiga descrevia um comportamento que o código nunca
191
+ * teve, e a cota diária do plano grátis transformou essa imprecisão em consequência: o agente
192
+ * gastaria o teto da pessoa seguindo uma instrução nossa, escrita no repositório dela, dizendo que
193
+ * não custava nada.
194
+ *
195
+ * O que o bloco diz agora é o que a régua do plano diz: PERGUNTAR é livre, ENVIAR tem teto - e
196
+ * quando o teto chega, o agente repassa a frase em vez de tentar de novo.
187
197
  */
188
198
  const REFRESH = `
189
199
 
190
200
  **Call \`refresh_system\` once before you write UI here, or before you describe what
191
- this system holds.** Not "if you think the measurement is stale" - always, once per
192
- session. It costs nothing when nothing changed: the tool holds both versions and
193
- refuses politely when there is nothing to refresh, so calling it is cheaper than
194
- deciding whether to.
201
+ this system holds** - once per session, not once per file, and never in a loop.
202
+
203
+ It is an UPDATE and not a question: it re-measures this repository and sends it. On
204
+ the free plan that counts against the updates the plan covers per day, and when the
205
+ day's updates are used up the tool says so and nothing is lost - the measurement
206
+ stays on disk, and every question you ask about this system keeps being answered.
207
+ Asking is always free; it is sending that has a ceiling. If it says the ceiling was
208
+ reached, say that to the person and carry on with what you already know - do not
209
+ retry it.
195
210
 
196
211
  It re-measures this repo with the current reader, reuses what was already written
197
212
  about this app, and sends it - a newer reader sees styles the old one could not, and
@@ -1790,13 +1790,27 @@ cli) {
1790
1790
  const token = await readToken();
1791
1791
  if (!token)
1792
1792
  return fromContract("Not signed in, so nothing could be sent. A person has to run `synthesisui login` once in the terminal - it opens a browser, and I cannot complete it for them.");
1793
- const { out } = await capturing(() => remeasure({
1793
+ const { out, value: refused } = await capturing(() => remeasure({
1794
1794
  root,
1795
1795
  base: resolveRegistry(),
1796
1796
  token,
1797
1797
  slug,
1798
1798
  cli: VERSION,
1799
1799
  }));
1800
+ /**
1801
+ * O TETO DO PLANO CHEGA AO AGENTE COMO RESPOSTA, e não como silêncio.
1802
+ *
1803
+ * Esta ferramenta é uma ATUALIZAÇÃO, não uma consulta: ela re-mede o repositório e envia.
1804
+ * Então ela conta contra o teto diário do plano grátis, e quando o teto é atingido o envio
1805
+ * não acontece. Sem esta linha o agente receberia a saída capturada sem a recusa dentro
1806
+ * dela - `remeasure` devolve o motivo em vez de imprimi-lo, para o `sync` poder dizê-lo por
1807
+ * último no terminal - e concluiria que a medição subiu.
1808
+ *
1809
+ * A frase vem do servidor inteira, com o endereço junto, porque aqui não há terminal para
1810
+ * quebrar linha: quem lê é o agente, e ele precisa do endereço para repassar à pessoa.
1811
+ */
1812
+ if (refused)
1813
+ return fromContract(`${refused.message}${refused.url ? `\n\n ${refused.url}` : ""}\n\nNothing was lost: the measurement is on disk and every question you ask about this system keeps being answered. Say this to the person instead of retrying.`);
1800
1814
  /**
1801
1815
  * E A DEFASAGEM DO HOOK, EM TRÊS LINHAS - não num parágrafo.
1802
1816
  *
@@ -168,8 +168,20 @@ export async function sync(opts) {
168
168
  * Então: a plataforma devolve o que já foi decidido (o escopo e a leitura), o CLI mede com o leitor
169
169
  * ATUAL, funde a leitura no censo fresco, AVISA o que seria reescrito, e envia. Sem entrevista.
170
170
  */
171
- if (!opts.recordOnly)
172
- await remeasure({
171
+ /**
172
+ * A RECUSA É GUARDADA PARA O FIM, e essa é a diferença entre informar e enganar.
173
+ *
174
+ * O comando continua depois da medição: ele fecha pedidos, manda o registro de checagens e
175
+ * termina imprimindo "N checks sent". Uma recusa dita no meio disso rola para cima, e a ÚLTIMA
176
+ * linha da tela anuncia sucesso para uma rodada em que o design system dela não foi atualizado.
177
+ *
178
+ * O registro de checagens SOBE mesmo assim, e isso é deliberado: é outra rota, é o que alimenta
179
+ * "você está na v2 e existe a v4", e não é o envio pesado que a cota governa. Dizer as duas
180
+ * coisas na ordem em que aconteceram é mais honesto que abortar tudo.
181
+ */
182
+ const refused = opts.recordOnly
183
+ ? null
184
+ : await remeasure({
173
185
  root,
174
186
  base,
175
187
  token,
@@ -206,6 +218,7 @@ export async function sync(opts) {
206
218
  if (emptyLedger && !repo && forms.length === 0) {
207
219
  console.log(section("Sync"));
208
220
  console.log(body("Nothing recorded yet. The record fills as the hook checks writes and doctor runs."));
221
+ sayRefused(refused);
209
222
  return;
210
223
  }
211
224
  const res = await fetch(`${base}/api/ledger`, {
@@ -308,21 +321,29 @@ export async function sync(opts) {
308
321
  * nada, que é o caso normal.
309
322
  */
310
323
  await reportWhatIsLeft(root);
324
+ sayRefused(refused);
311
325
  }
312
326
  /**
313
- * MEDE DE NOVO, AVISA, E ENVIA - o corpo do `sync` que faz um leitor novo chegar num sistema.
327
+ * O QUE NÃO FOI ENVIADO, DITO POR ÚLTIMO - e o "por último" é o desenho, não um detalhe.
314
328
  *
315
- * A ordem é a lei aqui, e cada passo existe por um caso real:
329
+ * A pessoa lê a última seção da tela e é ela que decide o que ela conclui do comando. O registro
330
+ * de checagens subiu de verdade, então a linha "N checks sent" é verdadeira e fica; o que não
331
+ * pode é ela ser a ÚLTIMA coisa numa rodada em que o design system não foi atualizado.
316
332
  *
317
- * 1. a plataforma devolve o ESCOPO e a LEITURA já gravados. Sem isto, o `sync` teria que
318
- * perguntar de novo o que já foi decidido, e um agente reescreveria 261 anatomias.
319
- * 2. mede com o leitor ATUAL - é o único passo que precisa estar nesta máquina, porque o fonte
320
- * dele não sai daqui.
321
- * 3. funde a leitura gravada no censo fresco. A anatomia é do agente; a medição é nossa.
322
- * 4. AVISA antes de enviar o que seria reescrito, e pergunta. Avisar depois de escrever não é
323
- * avisar.
324
- * 5. envia para a rota que atualiza o RASCUNHO pelo slug - nada publicado se move.
333
+ * NÃO SE LÊ COMO ERRO: a frase vem do servidor, que é quem conhece o teto, a contagem e a hora em
334
+ * que a próxima libera. E o endereço vai em linha própria, indentado, como toda ação que o
335
+ * terminal oferece - prosa quebra em 66 colunas e um endereço no meio de um parágrafo não se
336
+ * distingue do parágrafo.
325
337
  */
338
+ function sayRefused(refused) {
339
+ if (!refused)
340
+ return;
341
+ console.log("");
342
+ console.log(section("Your system was not updated"));
343
+ console.log(body(refused.message));
344
+ if (refused.url)
345
+ console.log(body(` ${paint.blue(refused.url)}`));
346
+ }
326
347
  export async function remeasure(args) {
327
348
  const { root, base, token, slug } = args;
328
349
  const head = await fetch(`${base}/api/registry/ds/${slug}/reading`, {
@@ -333,7 +354,7 @@ export async function remeasure(args) {
333
354
  console.log(body(head
334
355
  ? `The registry answered ${head.status} for this system's reading, so nothing was re-measured. The record below still travels.`
335
356
  : "Could not reach the registry, so nothing was re-measured. The record below still travels."));
336
- return;
357
+ return null;
337
358
  }
338
359
  const stored = (await head.json());
339
360
  /**
@@ -343,7 +364,7 @@ export async function remeasure(args) {
343
364
  if (!stored.hasCensus) {
344
365
  console.log(section("Sync"));
345
366
  console.log(body(`"${slug}" did not come from an import, so there is no measurement to refresh. Import it first: npx synthesisui import`));
346
- return;
367
+ return null;
347
368
  }
348
369
  /**
349
370
  * A DISTÂNCIA ATÉ O CLI PUBLICADO, dita onde ele já está.
@@ -461,7 +482,7 @@ export async function remeasure(args) {
461
482
  : null;
462
483
  if (!census) {
463
484
  console.log(body("The measurement failed, so nothing was sent."));
464
- return;
485
+ return null;
465
486
  }
466
487
  /** A LEITURA GRAVADA ENTRA NO CENSO FRESCO - ver a rota `reading`. */
467
488
  if (stored.reading)
@@ -564,7 +585,7 @@ export async function remeasure(args) {
564
585
  .join(" · "))));
565
586
  if (!(await askToOverwrite())) {
566
587
  console.log(body("Nothing was sent. Your draft is untouched."));
567
- return;
588
+ return null;
568
589
  }
569
590
  }
570
591
  /**
@@ -634,11 +655,33 @@ export async function remeasure(args) {
634
655
  : {}),
635
656
  }),
636
657
  }).catch(() => null);
658
+ /**
659
+ * O TETO DE ATUALIZAÇÕES DO PLANO GRÁTIS - e ele NÃO se lê como um erro, porque não é um.
660
+ *
661
+ * O QUE ELA VIVE: o envio parou porque o plano dela atualiza um número de vezes por dia, e a
662
+ * frase diz quantas já foram, que a medição continua no disco dela, que as perguntas do agente
663
+ * seguem respondendo, e a HORA em que a próxima libera. O endereço do plano vai em linha
664
+ * própria, indentado, como toda ação que o terminal oferece - prosa quebra em 66 colunas e um
665
+ * endereço enterrado no meio de um parágrafo não se distingue do parágrafo.
666
+ *
667
+ * A FRASE VEM DO SERVIDOR e não é escrita aqui: é ele quem conhece o teto, a contagem e o
668
+ * horário. Uma segunda redação deste texto no CLI é o dia em que alguém muda a cota e o
669
+ * terminal continua anunciando a antiga - e o terminal é onde a pessoa está parada.
670
+ */
671
+ if (res?.status === 429) {
672
+ const door = (await res.json().catch(() => null));
673
+ return {
674
+ kind: "quota",
675
+ message: door?.message ??
676
+ "Your free plan has reached its updates for today, so your design system was not updated.",
677
+ url: door?.url ?? null,
678
+ };
679
+ }
637
680
  if (!res?.ok) {
638
681
  console.log(body(res
639
682
  ? `The registry answered ${res.status}. Nothing was written.`
640
683
  : "Could not reach the registry. Nothing was written."));
641
- return;
684
+ return null;
642
685
  }
643
686
  const out = (await res.json());
644
687
  console.log("");
@@ -842,6 +885,8 @@ export async function remeasure(args) {
842
885
  console.log(body(paint.faint(`${work.measured} declared piece${work.measured === 1 ? "" : "s"} of work re-checked against this measurement`)));
843
886
  if (!args.full)
844
887
  console.log(body(paint.faint("everything the reader saw: npx synthesisui sync --full")));
888
+ /** Chegou até aqui: a medição foi enviada e escrita. Nada a recusar. */
889
+ return null;
845
890
  }
846
891
  /**
847
892
  * Pergunta uma vez, e só num terminal de verdade.
@@ -235,7 +235,7 @@
235
235
  * chama `wireAgent`, então rodar o comando é o caminho de volta - e ele só alarga a string que era
236
236
  * nossa, nunca um filtro que uma pessoa escreveu.
237
237
  */
238
- export const MATERIALISER_SINCE = "0.16.424";
238
+ export const MATERIALISER_SINCE = "0.16.429";
239
239
  /**
240
240
  * A ÚLTIMA VERSÃO EM QUE O QUE O HOOK RODA MUDOU.
241
241
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.428",
3
+ "version": "0.16.429",
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": {