synthesisui 0.16.325 → 0.16.326

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.
@@ -369,9 +369,17 @@ export async function versionBehind(root, opts = {}) {
369
369
  const lock = locks[0];
370
370
  if (!lock?.slug || lock.version == null)
371
371
  return null;
372
- if (!(await credentials(opts.home ?? homedir())))
372
+ /**
373
+ * UM `home` SÓ PARA AS DUAS LEITURAS, e não um por linha.
374
+ *
375
+ * Até 27/08 a primeira respeitava o `home` recebido e a segunda lia o `homedir()` da máquina, o que
376
+ * fazia os dois testes que esperam resultado passarem só onde havia credencial de produção salva.
377
+ * Uma variável dividida não deixa a segunda esquecer.
378
+ */
379
+ const home = opts.home ?? homedir();
380
+ if (!(await credentials(home)))
373
381
  return null;
374
- const token = await readToken();
382
+ const token = await readToken(home);
375
383
  if (!token)
376
384
  return null;
377
385
  /**
@@ -21,6 +21,6 @@ export async function logout() {
21
21
  return;
22
22
  }
23
23
  console.log(`✓ Signed out${existing?.registry ? ` of ${existing.registry}` : ""} on this machine.`);
24
- console.log(` Removed ${credentialsPath}`);
24
+ console.log(` Removed ${credentialsPath()}`);
25
25
  console.log(" Run `synthesisui login` to sign in as someone else.");
26
26
  }
package/dist/config.js CHANGED
@@ -11,8 +11,24 @@ export function resolveRegistry(flag) {
11
11
  const base = flag || process.env.SYNTHESISUI_REGISTRY_URL || DEFAULT_REGISTRY;
12
12
  return base.replace(/\/+$/, ""); // no trailing slash
13
13
  }
14
- /** Where the device-flow token lives - per machine, in the home dir. */
15
- export const credentialsPath = join(homedir(), ".synthesisui", "credentials.json");
14
+ /**
15
+ * Where the device-flow token lives - per machine, in the home dir.
16
+ *
17
+ * `home` É INJETÁVEL PELO MESMO MOTIVO QUE EM `align`: uma verificação que lê o home da máquina que
18
+ * roda o teste não é verificável - ela passa ou falha conforme quem está logado ali.
19
+ *
20
+ * O QUE ISTO CONSERTA, medido em 27/08: `versionBehind` recebia `home` e o respeitava em
21
+ * `credentials(...)`, e uma linha depois chamava `readToken()`, que lia uma CONSTANTE de módulo
22
+ * resolvida com o `homedir()` real. Os dois testes de `decided-waiting` que esperam resultado só
23
+ * passavam porque encontravam a credencial de produção de quem rodava a suíte; num runner limpo eles
24
+ * caíam. Era uma porta declarada aberta e fechada pela metade - e o CLAUDE.md pede fechar a porta em
25
+ * vez de vigiá-la, então ela deixou de ser constante.
26
+ *
27
+ * O comportamento do produto é o mesmo: sem argumento, `homedir()`, exatamente como antes.
28
+ */
29
+ export function credentialsPath(home = homedir()) {
30
+ return join(home, ".synthesisui", "credentials.json");
31
+ }
16
32
  /**
17
33
  * Reads the saved token, if any. Optional for now (open gate); the device-flow
18
34
  * is what writes it. Sent as a Bearer header when present.
@@ -25,9 +41,9 @@ export const credentialsPath = join(homedir(), ".synthesisui", "credentials.json
25
41
  * refused it with a 401 that read as "your session expired" (dono, 31/07). A
26
42
  * session cannot expire on a host that never issued it.
27
43
  */
28
- export async function readCredentials() {
44
+ export async function readCredentials(home) {
29
45
  try {
30
- const raw = await readFile(credentialsPath, "utf8");
46
+ const raw = await readFile(credentialsPath(home), "utf8");
31
47
  const parsed = JSON.parse(raw);
32
48
  if (!parsed.token)
33
49
  return null;
@@ -44,7 +60,7 @@ export function sameRegistry(a, b) {
44
60
  const norm = (u) => u.trim().replace(/\/+$/, "").toLowerCase();
45
61
  return norm(a) === norm(b);
46
62
  }
47
- export async function readToken() {
63
+ export async function readToken(home) {
48
64
  /**
49
65
  * O AMBIENTE GANHA DO ARQUIVO, e é o que permite CI sem navegador.
50
66
  *
@@ -60,7 +76,7 @@ export async function readToken() {
60
76
  if (fromEnv)
61
77
  return fromEnv;
62
78
  try {
63
- const raw = await readFile(credentialsPath, "utf8");
79
+ const raw = await readFile(credentialsPath(home), "utf8");
64
80
  const parsed = JSON.parse(raw);
65
81
  return parsed.token ?? null;
66
82
  }
@@ -69,10 +85,11 @@ export async function readToken() {
69
85
  }
70
86
  }
71
87
  /** Persists the device-flow token (chmod 600, user-only dir). */
72
- export async function writeToken(token, registry) {
73
- await mkdir(dirname(credentialsPath), { recursive: true, mode: 0o700 });
88
+ export async function writeToken(token, registry, home) {
89
+ const path = credentialsPath(home);
90
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
74
91
  const payload = { token, registry, savedAt: new Date().toISOString() };
75
- await writeFile(credentialsPath, `${JSON.stringify(payload, null, 2)}\n`, {
92
+ await writeFile(path, `${JSON.stringify(payload, null, 2)}\n`, {
76
93
  mode: 0o600,
77
94
  });
78
95
  }
@@ -90,10 +107,10 @@ export async function writeToken(token, registry) {
90
107
  * Devolve `false` quando não havia nada - a diferença entre "saí" e "você já
91
108
  * estava fora" é a única coisa que o comando tem para dizer.
92
109
  */
93
- export async function clearCredentials() {
94
- const existing = await readCredentials();
110
+ export async function clearCredentials(home) {
111
+ const existing = await readCredentials(home);
95
112
  try {
96
- await rm(credentialsPath, { force: true });
113
+ await rm(credentialsPath(home), { force: true });
97
114
  }
98
115
  catch {
99
116
  // já não existe, ou o disco recusou - o estado final é o mesmo
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.325",
3
+ "version": "0.16.326",
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": {