{"version":3,"file":"index.mjs","names":["WHOAMI_PATH","pkg.version","applyCssVars","same","applyCssRules","merge","applyBaseRules","addImport","applyThemeVars","applyThemeCssRules","applyThemeBaseRules","addThemeImport","path","semver","postcss","MiniSearch","CONFIG_FILE","DEFAULT_REGISTRY","SITE_URL","CONFIG_SCHEMA_URL","TELEMETRY_HEADERS","ITEM_KINDS","ITEM_ACCESS","TOKEN_ENV","WHOAMI_PATH","MCP_CLIENTS","credentialsFile","homedir","dir","platform","env","home","readSavedToken","readFile","file","token","saveToken","mkdir","writeFile","fetchAccount","url","registryUrl","response","fetch","headers","account","newState","randomBytes","authorizeUrl","hostname","callback","state","client","host","SlabUIError","itemNameSchema","z","namespaceSchema","versionSchema","hashSchema","kindSchema","accessSchema","registryDependencySchema","dependenciesSchema","requireTarget","requireContent","item","itemFileInputSchema","itemFileSchema","cssVarsMapSchema","cssVarsSchema","baseRulesSchema","ruleNameSchema","cssRulesSchema","itemFields","itemSchema","versionPathSchema","versionEntrySchema","registryEntrySchema","entry","registrySchema","version","current","telemetryDisabled","telemetryHeaders","command","fetchedIndexes","createRegistryClient","baseUrl","registry","expandHeaders","indexPromise","proHeaders","hasAuthorization","header","expandValue","\"SLABUI_TOKEN\"","savedToken","name","get","extraHeaders","pro","parse","json","body","check","result","schema","fetchIndex","index","checkSchemaVersion","error","published","hash","outdated","value","resolved","where","createHash","installedItemSchema","configSchema","TSCONFIG_FILES","CSS_CANDIDATES","exists","access","loadTsconfig","root","parseTsconfig","aliasPrefix","wildcard","tsconfig","key","resolveCssFile","css","prefix","absolute","aliasToPath","createPathsMatcher","alias","detectCss","candidate","readConfig","writeConfig","config","isRelativeAlias","detectDefaults","cssDefault","detected","styles","initProject","force","aliases","resolveProjectPath","refuse","relativePath","reason","absoluteRoot","target","isInside","existing","nearestExisting","lstat","realRoot","realpath","realExisting","relative","SCRIPT_EXTENSIONS","IMPORT_PATTERN","CSS_IMPORT_PATTERN","isStylesheet","rewriteCssImports","content","next","replace","specifier","match","keyword","quote","isScriptFile","rewriteImports","matchFile","extension","files","stripScriptExtension","parseItemRef","rest","ref","slash","at","range","itemKey","resolveRegistry","\"SLABUI_REGISTRY_URL\"","resolveVersion","versions","KIND_ALIAS","destinationOf","toRelative","context","importSpecifier","base","destination","from","isBlock","itemDestinations","blockDestinations","blockDir","reachableKeys","dependency","addInstalledDependencies","items","destinations","clientFor","materializeFile","stylesheet","reachable","warnings","relativeImport","matched","installed","to","folders","common","segment","parts","normalized","LOCKFILES","parsePackageSpec","spec","detectPackageManager","declared","readManifest","manager","parent","planPackages","manifest","plan","visit","list","minimum","npm","npmDev","installCommand","dev","packages","runInstall","args","child","spawn","reject","code","resolve","installPackages","dependencies","confirm","toInstall","skipInstall","planInstall","clients","constraints","chosen","order","createClient","outOfRange","who","previous","accepts","ranges","refs","planned","THEME_NAME","isThemeName","themeSelector","dark","COLOR","applyCssVars$1","changes","mappings","theme","vars","withColorMappings","wanted","remote","group","remoteVars","baseVars","names","block","findBlock","remoteValue","baseValue","declaration","node","local","record","shouldRemove","createBlock","same$1","overwrite","ensureDarkVariant","blockSelector","normalize","selector","variant","last","a","b","defaultTheme","AT_RULE","ruleName","rule","applyCssRules$1","kind","field","remoteRules","baseRules","options","remoteSource","baseSource","findRule","label","merge$1","ruleSource","appendRule","source","parseRule","applyBaseRules$1","selectors","remoteDecls","baseDecls","props","prop","layer","findBaseLayer","findRuleBySelector","appendBaseRule","remove","add","same","lastVariant","firstUtility","clone","normalizeSelector","importPath","sameImport","imports","addImport$1","applyCssVars","applyCssRules","applyBaseRules","addImport","BASE_FILE","UTILITIES_FILE","CSS_TEMPLATE_VARS","themeSubset","mode","tokens","pick","themeVars","uses","applyCssTemplate","ensureSideFile","sibling","updateStylesheet","readGlobals","warning","addThemeTokens","action","updateCssRules","merge","rules","hasRules","hasBase","apply","run","globals","globalsFile","addItems","blockPath","firstInstall","blocks","targetDir","askPath","owners","owner","added","cssChanges","ruleChanges","own","licenses","chooseVersion","major","sameMajor","compareItem","materialize","normalizeNewlines","baseFiles","remoteFiles","diffItem","splitVersion","comparison","patches","before","after","createTwoFilesPatch","outdatedItems","keys","compareInstalled","latest","status","LABELS","updateItems","queue","processed","missing","applyFile","dependencyKey","write","rm","merged","resolution","resolveConflict","login","loginWithBrowser","server","createServer","req","res","page","finish","timer","timeout","done","onUrl","port","message","searchRegistries","results","engine","sources","type","isDefault","namespace","term","id","defaultClient","readConfigIfExists","searchItems","itemInfo","raw"],"sources":["../src/constants.ts","../../account/src/credentials.ts","../../account/src/index.ts","../src/errors.ts","../src/schemas/shared.ts","../src/schemas/item.ts","../src/schemas/registry.ts","../package.json","../src/telemetry.ts","../src/client.ts","../src/schemas/config.ts","../src/project.ts","../src/init.ts","../src/paths.ts","../src/imports.ts","../src/resolve.ts","../src/install/destinations.ts","../src/install/materialize.ts","../src/install/npm.ts","../src/install/plan.ts","../../theme-core/src/attribute.ts","../../theme-core/src/css.ts","../../theme-core/src/default-theme.ts","../../theme-core/src/rules.ts","../../theme-core/src/theme-files.ts","../src/css.ts","../src/css-template.ts","../src/install/styles.ts","../src/install/add.ts","../src/install/compare.ts","../src/install/diff.ts","../src/install/outdated.ts","../src/install/update.ts","../src/login.ts","../src/search.ts","../src/query.ts"],"sourcesContent":["export const CONFIG_FILE = \"slabui.json\"\n\nexport const DEFAULT_REGISTRY = {\n  namespace: \"@slabui\",\n  url: \"https://slabui.com/r\",\n} as const\n\n// Formato do índice (`registry.json`) e do item (`<versão>.json`). Mudam\n// separados: trocar o do item mudaria o hash das versões já publicadas.\nexport const INDEX_SCHEMA_VERSION = 2\nexport const ITEM_SCHEMA_VERSION = 1\n\nexport const SITE_URL = \"https://slabui.com\"\n\n// Schemas do índice e dos itens (gerados pelo `build`).\nexport const SCHEMA_URL = `${SITE_URL}/schema`\n\n// Schema do slabui.json, o arquivo que o usuário edita.\nexport const CONFIG_SCHEMA_URL = `${SITE_URL}/schema.json`\n\nexport const INITIAL_VERSION = \"1.0.0\"\n\n// Cabeçalhos de telemetria que o CLI envia ao registry (ver telemetry.ts).\nexport const TELEMETRY_HEADERS = {\n  command: \"x-slabui-command\",\n  optOut: \"x-slabui-telemetry\",\n} as const\n\nexport const ITEM_KINDS = [\n  \"ui\",\n  \"component\",\n  \"lib\",\n  \"hook\",\n  \"util\",\n  \"style\",\n  \"file\",\n  \"theme\",\n  \"block\",\n  \"example\",\n] as const\n\nexport type ItemKind = (typeof ITEM_KINDS)[number]\n\n// Quem pode baixar o item: `pro` exige um token de assinatura.\nexport const ITEM_ACCESS = [\"free\", \"pro\"] as const\n\nexport type ItemAccess = (typeof ITEM_ACCESS)[number]\n\n// Variável com o token do registry padrão (o `slabui login` grava um arquivo).\nexport const TOKEN_ENV = \"SLABUI_TOKEN\"\n\n// Troca a URL do registry da SlabUI (cópia local, staging). Não documentada.\nexport const REGISTRY_URL_ENV = \"SLABUI_REGISTRY_URL\"\n\n// Rota do registry que diz de quem é o token (`slabui login`).\nexport const WHOAMI_PATH = \"whoami.json\"\n\n// Pasta de cada tipo no registry publicado: `<pasta>/<item>/<versão>.json`.\nexport const KIND_FOLDERS: Record<ItemKind, string> = {\n  ui: \"ui\",\n  component: \"components\",\n  lib: \"lib\",\n  hook: \"hooks\",\n  util: \"utils\",\n  style: \"styles\",\n  file: \"files\",\n  theme: \"themes\",\n  block: \"blocks\",\n  example: \"examples\",\n}\n\nexport const MCP_CLIENTS = [\n  \"claude\",\n  \"cursor\",\n  \"vscode\",\n  \"zed\",\n  \"codex\",\n] as const\n\nexport type McpClient = (typeof MCP_CLIENTS)[number]\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\"\nimport { homedir } from \"node:os\"\nimport path from \"node:path\"\n\n// Token da conta SlabUI gravado pelo `slabui login` ou pelo \"Entrar\" do\n// editor de tema, fora do projeto para não ir parar no git. O CLI e o editor\n// usam o mesmo arquivo.\n\ntype Env = Record<string, string | undefined>\n\nexport function credentialsFile(\n  env: Env = process.env,\n  platform: NodeJS.Platform = process.platform,\n  home = homedir(),\n) {\n  const dir =\n    platform === \"win32\"\n      ? path.join(env.APPDATA ?? path.join(home, \"AppData/Roaming\"), \"slabui\")\n      : path.join(env.XDG_CONFIG_HOME || path.join(home, \".config\"), \"slabui\")\n  return path.join(dir, \"credentials.json\")\n}\n\nexport async function readSavedToken(\n  file = credentialsFile(),\n): Promise<string | undefined> {\n  try {\n    const { token } = JSON.parse(await readFile(file, \"utf8\")) as {\n      token?: unknown\n    }\n    return typeof token === \"string\" && token ? token : undefined\n  } catch {\n    return undefined\n  }\n}\n\nexport async function saveToken(token: string, file = credentialsFile()) {\n  await mkdir(path.dirname(file), { recursive: true })\n  await writeFile(file, `${JSON.stringify({ token })}\\n`, { mode: 0o600 })\n}\n\n// `false` quando não havia token gravado.\nexport async function removeToken(file = credentialsFile()): Promise<boolean> {\n  const existed = (await readSavedToken(file)) !== undefined\n  await rm(file, { force: true })\n  return existed\n}\n","import { randomBytes } from \"node:crypto\"\nimport { readFileSync } from \"node:fs\"\nimport { hostname } from \"node:os\"\nimport path from \"node:path\"\n\nexport {\n  credentialsFile,\n  readSavedToken,\n  removeToken,\n  saveToken,\n} from \"./credentials\"\nexport {\n  ACCOUNT_PUBLIC_KEY,\n  type AccountClaims,\n  SIGNATURE_TTL_S,\n  signAccount,\n  tokenHash,\n  verifyAccount,\n} from \"./signature\"\n\n// Conta SlabUI do CLI e do editor de tema (só Node). O token identifica a\n// conta no registry padrão; o `whoami.json` diz o plano.\n\nexport const DEFAULT_REGISTRY_URL = \"https://slabui.com/r\"\n\n// Variável com o token, antes do arquivo de credenciais.\nexport const TOKEN_ENV = \"SLABUI_TOKEN\"\n\n// Rota do registry que diz de quem é o token.\nexport const WHOAMI_PATH = \"whoami.json\"\n\nexport type Account = {\n  name?: string\n  image?: string\n  // Nome do plano (\"Free\", \"Pro Yearly\"…).\n  plan?: string\n  // `[\"pro\"]` com assinatura ativa; `[]` no plano free.\n  access: string[]\n  // `access` assinado pelo site (ver `verifyAccount`).\n  signature?: string\n}\n\n// URL do registry padrão: a do `slabui.json` da raiz (`registries[\"@slabui\"]`,\n// para desenvolver contra um registry local) ou a de produção.\nexport function defaultRegistryUrl(root?: string): string {\n  if (root === undefined) {\n    return DEFAULT_REGISTRY_URL\n  }\n  try {\n    const config = JSON.parse(\n      readFileSync(path.join(root, \"slabui.json\"), \"utf8\"),\n    ) as { registries?: Record<string, unknown> }\n    const entry = config.registries?.[\"@slabui\"]\n    const url =\n      typeof entry === \"string\"\n        ? entry\n        : (entry as { url?: unknown } | undefined)?.url\n    return typeof url === \"string\" && url ? url : DEFAULT_REGISTRY_URL\n  } catch {\n    return DEFAULT_REGISTRY_URL\n  }\n}\n\n// Confere o token no `whoami.json`: a conta, ou `null` se o token não vale.\n// Erros de rede sobem para quem chamou decidir.\nexport async function fetchAccount({\n  registryUrl,\n  token,\n  fetch = globalThis.fetch,\n  headers = {},\n}: {\n  registryUrl: string\n  token: string\n  fetch?: typeof globalThis.fetch\n  headers?: Record<string, string>\n}): Promise<Account | null> {\n  const url = `${registryUrl.replace(/\\/+$/, \"\")}/${WHOAMI_PATH}`\n  const response = await fetch(url, {\n    headers: { ...headers, authorization: `Bearer ${token.trim()}` },\n    signal: AbortSignal.timeout(15_000),\n  })\n  if (response.status === 401) {\n    return null\n  }\n  if (!response.ok) {\n    throw new Error(`Error ${response.status} while fetching ${url}.`)\n  }\n  const account = (await response.json()) as Account\n  return { ...account, access: account.access ?? [] }\n}\n\n// Valor aleatório que volta no callback, para só aceitar o login pedido aqui.\nexport function newState() {\n  return randomBytes(24).toString(\"base64url\")\n}\n\n// Página do site (na origem do registry) em que a pessoa entra e autoriza;\n// o token volta para o `callback` local com o `state`.\nexport function authorizeUrl({\n  registryUrl,\n  callback,\n  state,\n  client,\n  host = hostname(),\n}: {\n  registryUrl: string\n  callback: string\n  state: string\n  client: string\n  host?: string\n}) {\n  const url = new URL(\"/cli/authorize\", new URL(registryUrl).origin)\n  url.searchParams.set(\"callback\", callback)\n  url.searchParams.set(\"state\", state)\n  url.searchParams.set(\"client\", client)\n  url.searchParams.set(\"host\", host.replace(/\\.local$/, \"\").slice(0, 60))\n  return url.toString()\n}\n","// Erro esperado (entrada ou configuração inválida): o CLI mostra só a mensagem.\nexport class SlabUIError extends Error {\n  override name = \"SlabUIError\"\n}\n","import { z } from \"zod\"\n\nimport { ITEM_ACCESS, ITEM_KINDS } from \"../constants\"\n\nexport const itemNameSchema = z\n  .string()\n  .regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, \"name must be kebab-case\")\n\nexport const namespaceSchema = z\n  .string()\n  .regex(/^@[a-z0-9-]+$/, \"namespace must look like @name\")\n\n// Versões publicadas são geradas pelo `build`, então sempre X.Y.Z.\nexport const versionSchema = z\n  .string()\n  .regex(/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$/, \"version must be X.Y.Z\")\n\nexport const hashSchema = z\n  .string()\n  .regex(/^sha256-[A-Za-z0-9+/]+={0,2}$/, \"hash must be sha256-<base64>\")\n\nexport const kindSchema = z.enum(ITEM_KINDS)\n\nexport const accessSchema = z.enum(ITEM_ACCESS)\n\n// `[@ns/]nome`: sem namespace é o registry padrão.\n\n// `[@ns/]nome[@versão]`. O intervalo semver é interpretado na resolução de nomes.\nexport const registryDependencySchema = z\n  .string()\n  .regex(\n    /^(@[a-z0-9-]+\\/)?[a-z0-9]+(-[a-z0-9]+)*(@\\S+)?$/,\n    \"dependency must look like [@ns/]name[@version]\",\n  )\n\nexport const dependenciesSchema = z.object({\n  registry: z.array(registryDependencySchema).default([]),\n  npm: z.array(z.string().min(1)).default([]),\n  npmDev: z.array(z.string().min(1)).default([]),\n})\n\nexport type Dependencies = z.infer<typeof dependenciesSchema>\n","import { z } from \"zod\"\n\nimport { ITEM_SCHEMA_VERSION } from \"../constants\"\nimport {\n  accessSchema,\n  dependenciesSchema,\n  itemNameSchema,\n  kindSchema,\n  versionSchema,\n} from \"./shared\"\n\nconst requireTarget = [\n  (file: { kind: string; target?: string }) =>\n    file.kind !== \"file\" || file.target !== undefined,\n  { message: 'a file with kind \"file\" needs a target', path: [\"target\"] },\n] satisfies [unknown, { message: string; path: string[] }]\n\n// Um tema pode ter só `cssVars`; um item de CSS, só as regras.\nconst requireContent = [\n  (item: {\n    files: unknown[]\n    cssVars?: unknown\n    css?: unknown\n    utilities?: unknown[]\n    variants?: unknown[]\n    base?: unknown\n  }) =>\n    item.files.length > 0 ||\n    item.cssVars !== undefined ||\n    item.css !== undefined ||\n    (item.utilities?.length ?? 0) > 0 ||\n    (item.variants?.length ?? 0) > 0 ||\n    item.base !== undefined,\n  { message: \"the item needs files, cssVars or CSS rules\", path: [\"files\"] },\n] satisfies [unknown, { message: string; path: string[] }]\n\n// A segurança do caminho (`../`, absolutos) é checada na gravação, não aqui.\nexport const itemFileInputSchema = z\n  .object({\n    path: z.string().min(1),\n    kind: kindSchema,\n    target: z.string().min(1).optional(),\n  })\n  .refine(...requireTarget)\n\nexport const itemFileSchema = z\n  .object({\n    path: z.string().min(1),\n    kind: kindSchema,\n    target: z.string().min(1).optional(),\n    content: z.string(),\n  })\n  .refine(...requireTarget)\n\nconst cssVarsMapSchema = z.record(z.string(), z.string())\n\nexport const cssVarsSchema = z.object({\n  theme: cssVarsMapSchema.optional(),\n  light: cssVarsMapSchema.optional(),\n  dark: cssVarsMapSchema.optional(),\n})\n\n// Declarações de base por seletor: `{ body: { overflow: \"hidden\" } }`.\nconst baseRulesSchema = z.record(\n  z.string().min(1),\n  z.record(z.string().min(1), z.string().min(1)),\n)\n\nconst ruleNameSchema = z.string().regex(/^[a-z][\\w-]*$/)\n\n// Regras de CSS do item publicado, além das variáveis: `@utility` e\n// `@custom-variant` pelo nome, com o texto completo, para o `utilities.css`,\n// e as declarações de base para o `base.css`.\nexport const cssRulesSchema = z.object({\n  utilities: z.record(ruleNameSchema, z.string().min(1)).optional(),\n  variants: z.record(ruleNameSchema, z.string().min(1)).optional(),\n  base: baseRulesSchema.optional(),\n})\n\n// Campos comuns à entrada do `build` e ao item publicado.\nconst itemFields = {\n  name: itemNameSchema,\n  kind: kindSchema,\n  title: z.string().min(1).optional(),\n  description: z.string().min(1),\n  dependencies: dependenciesSchema.prefault({}),\n  cssVars: cssVarsSchema.optional(),\n}\n\nexport const itemSchema = z\n  .object({\n    $schema: z.string().optional(),\n    schemaVersion: z.literal(ITEM_SCHEMA_VERSION),\n    ...itemFields,\n    version: versionSchema,\n    files: z.array(itemFileSchema).default([]),\n    css: cssRulesSchema.optional(),\n  })\n  .refine(...requireContent)\n\n// Item na entrada do `build`: sem versão e sem o conteúdo dos arquivos,\n// com os metadados que vão só para o índice.\nexport const itemInputSchema = z\n  .object({\n    ...itemFields,\n    categories: z.array(z.string().min(1)).optional(),\n    keywords: z.array(z.string().min(1)).optional(),\n    docs: z.url().optional(),\n    // Fica só no índice: mudar o acesso não gera versão nova.\n    access: accessSchema.optional(),\n    // O `build` soma às dependências as descobertas pelos imports.\n    inferDependencies: z.boolean().optional(),\n    files: z.array(itemFileInputSchema).default([]),\n    // `@utility` e `@custom-variant` que o item usa, pelo nome: o `build`\n    // busca o texto delas no CSS global do autor (e nos CSS que ele importa).\n    utilities: z.array(ruleNameSchema).optional(),\n    variants: z.array(ruleNameSchema).optional(),\n    // Declarações no `@layer base` (`body`, `html`…). Só quando não houver\n    // outro caminho: mudam o app inteiro.\n    base: baseRulesSchema.optional(),\n  })\n  .refine(...requireContent)\n\nexport type ItemFile = z.infer<typeof itemFileSchema>\nexport type Item = z.infer<typeof itemSchema>\nexport type ItemInput = z.input<typeof itemInputSchema>\nexport type CssVars = z.infer<typeof cssVarsSchema>\nexport type CssRules = z.infer<typeof cssRulesSchema>\n","import { z } from \"zod\"\n\nimport { INDEX_SCHEMA_VERSION } from \"../constants\"\nimport {\n  accessSchema,\n  dependenciesSchema,\n  hashSchema,\n  itemNameSchema,\n  kindSchema,\n  namespaceSchema,\n  versionSchema,\n} from \"./shared\"\n\n// Caminho relativo à URL do registry (`ui/button/1.0.0.json`), sem `..`,\n// barra inicial ou esquema.\nexport const versionPathSchema = z\n  .string()\n  .regex(\n    /^(?!.*(^|\\/)\\.\\.?(\\/|$))[A-Za-z0-9._-]+(\\/[A-Za-z0-9._-]+)*\\.json$/,\n    \"path must be a relative path to a .json file\",\n  )\n\nexport const versionEntrySchema = z.object({\n  hash: hashSchema,\n  path: versionPathSchema,\n})\n\nexport const registryEntrySchema = z\n  .object({\n    kind: kindSchema,\n    title: z.string().min(1).optional(),\n    description: z.string().min(1),\n    categories: z.array(z.string().min(1)).optional(),\n    keywords: z.array(z.string().min(1)).optional(),\n    docs: z.url().optional(),\n    // Ausente é `free`; `pro` exige um token de assinatura para baixar.\n    access: accessSchema.optional(),\n    dependencies: dependenciesSchema.prefault({}),\n    // Variáveis do tema que a versão mais recente usa (`radius`, `primary`…),\n    // para o editor de tema mostrar só os componentes que um token afeta.\n    tokens: z.array(z.string().min(1)).optional(),\n    latest: versionSchema,\n    versions: z.record(versionSchema, versionEntrySchema),\n  })\n  .refine((entry) => entry.latest in entry.versions, {\n    message: \"latest must exist in versions\",\n    path: [\"latest\"],\n  })\n\nexport const registrySchema = z.object({\n  $schema: z.string().optional(),\n  schemaVersion: z.literal(INDEX_SCHEMA_VERSION),\n  namespace: namespaceSchema.optional(),\n  homepage: z.url().optional(),\n  mcp: z.url().optional(),\n  // Página da licença dos itens; o `add` mostra na primeira instalação.\n  license: z.url().optional(),\n  items: z.record(itemNameSchema, registryEntrySchema),\n})\n\nexport type VersionEntry = z.infer<typeof versionEntrySchema>\nexport type RegistryEntry = z.infer<typeof registryEntrySchema>\nexport type Registry = z.infer<typeof registrySchema>\n","","import pkg from \"../package.json\" with { type: \"json\" }\nimport { TELEMETRY_HEADERS } from \"./constants\"\n\n// O CLI não faz requisições a mais: só identifica as que já faz ao registry\n// com a versão do slabui e o comando, para o autor do registry separar\n// instalação de atualização. SLABUI_TELEMETRY_DISABLED=1 (ou DO_NOT_TRACK=1)\n// tira o comando e pede para não ser contado.\n\nlet current: string | undefined\n\n// Chamado pelo CLI antes de cada comando (`add`, `update`, `mcp init`…).\nexport function setTelemetryCommand(command: string | undefined) {\n  current = command\n}\n\nexport function telemetryDisabled(env: Record<string, string | undefined>) {\n  return env.SLABUI_TELEMETRY_DISABLED === \"1\" || env.DO_NOT_TRACK === \"1\"\n}\n\nexport function telemetryHeaders(\n  env: Record<string, string | undefined>,\n  command = current,\n): Record<string, string> {\n  const headers: Record<string, string> = {\n    \"user-agent\": `slabui/${pkg.version}`,\n  }\n  if (telemetryDisabled(env)) {\n    headers[TELEMETRY_HEADERS.optOut] = \"off\"\n  } else if (command) {\n    headers[TELEMETRY_HEADERS.command] = command\n  }\n  return headers\n}\n","import { createHash } from \"node:crypto\"\n\nimport { z } from \"zod\"\n\nimport type { ResolvedRegistry } from \"./resolve\"\n\nimport { CONFIG_FILE, INDEX_SCHEMA_VERSION, TOKEN_ENV } from \"./constants\"\nimport { readSavedToken } from \"./credentials\"\nimport { SlabUIError } from \"./errors\"\nimport { type Item, itemSchema } from \"./schemas/item\"\nimport { type Registry, registrySchema } from \"./schemas/registry\"\nimport { telemetryHeaders } from \"./telemetry\"\n\nconst TIMEOUT_MS = 30_000\n\n// Índices já baixados neste processo, por namespace. Os avisos do fim do\n// comando usam estes, sem fazer requisições novas.\nconst fetchedIndexes = new Map<string, Registry>()\n\nexport function fetchedIndex(namespace: string): Registry | undefined {\n  return fetchedIndexes.get(namespace)\n}\n\nexport type RegistryClientOptions = {\n  fetch?: typeof fetch\n  env?: Record<string, string | undefined>\n  // Comando enviado na telemetria; padrão: o comando do CLI em execução.\n  command?: string\n  // Token gravado pelo `slabui login`; padrão: o arquivo do usuário.\n  savedToken?: () => Promise<string | undefined>\n}\n\nexport type RegistryClient = {\n  index(): Promise<Registry>\n  item(name: string, version: string): Promise<Item>\n}\n\nexport function createRegistryClient(\n  registry: ResolvedRegistry,\n  {\n    fetch = globalThis.fetch,\n    env = process.env,\n    command,\n    savedToken = () => readSavedToken(),\n  }: RegistryClientOptions = {},\n): RegistryClient {\n  const baseUrl = registry.url.replace(/\\/+$/, \"\")\n  // Os headers do registry (slabui.json) vêm por último e podem substituir\n  // os de telemetria.\n  const headers = {\n    ...telemetryHeaders(env, command),\n    ...expandHeaders(registry.headers, env),\n  }\n  let indexPromise: Promise<Registry> | undefined\n\n  // Header de autenticação dos itens pro no registry padrão. Só é procurado\n  // quando um item pro é baixado, para um `${VAR}` sem valor não quebrar a\n  // instalação de itens free.\n  async function proHeaders(name: string): Promise<Record<string, string>> {\n    const hasAuthorization = Object.keys(headers).some(\n      (header) => header.toLowerCase() === \"authorization\",\n    )\n    if (!registry.isDefault || hasAuthorization) {\n      return {}\n    }\n    const token =\n      (registry.token === undefined\n        ? undefined\n        : expandValue(registry.token, `\"token\" in ${CONFIG_FILE}`, env)) ||\n      env[TOKEN_ENV] ||\n      (await savedToken())\n    if (!token) {\n      throw new SlabUIError(\n        `\"${name}\" is a Pro item. Run \"slabui login\" or set ${TOKEN_ENV} to install it.`,\n      )\n    }\n    return { authorization: `Bearer ${token}` }\n  }\n\n  async function get(\n    url: string,\n    { extraHeaders = {}, pro }: { extraHeaders?: object; pro?: string } = {},\n  ): Promise<Uint8Array> {\n    let response: Response\n    try {\n      response = await fetch(url, {\n        headers: { ...headers, ...extraHeaders },\n        signal: AbortSignal.timeout(TIMEOUT_MS),\n      })\n    } catch {\n      throw new SlabUIError(`Could not reach ${url}.`)\n    }\n\n    if (pro !== undefined && registry.isDefault && response.status === 401) {\n      throw new SlabUIError(\n        `The token was refused while fetching the Pro item \"${pro}\". Run \"slabui login\" again or check ${TOKEN_ENV}.`,\n      )\n    }\n    if (pro !== undefined && registry.isDefault && response.status === 403) {\n      throw new SlabUIError(\n        `Your token does not give access to the Pro item \"${pro}\". Check your SlabUI Pro subscription.`,\n      )\n    }\n    if (response.status === 401 || response.status === 403) {\n      throw new SlabUIError(`Access denied to ${url} (${response.status}).`)\n    }\n    if (response.status === 404) {\n      throw new SlabUIError(`Not found: ${url}.`)\n    }\n    if (!response.ok) {\n      throw new SlabUIError(`Error ${response.status} while fetching ${url}.`)\n    }\n\n    return new Uint8Array(await response.arrayBuffer())\n  }\n\n  function parse<T>(\n    url: string,\n    body: Uint8Array,\n    schema: z.ZodType<T>,\n    check?: (url: string, json: unknown) => void,\n  ): T {\n    let json: unknown\n    try {\n      json = JSON.parse(new TextDecoder().decode(body))\n    } catch {\n      throw new SlabUIError(`${url} is not valid JSON.`)\n    }\n    check?.(url, json)\n\n    const result = schema.safeParse(json)\n    if (!result.success) {\n      throw new SlabUIError(\n        `${url} does not match the expected format:\\n${z.prettifyError(result.error)}`,\n      )\n    }\n    return result.data\n  }\n\n  async function fetchIndex(): Promise<Registry> {\n    const url = `${baseUrl}/registry.json`\n    const index = parse(url, await get(url), registrySchema, checkSchemaVersion)\n    fetchedIndexes.set(registry.namespace, index)\n    return index\n  }\n\n  // Uma busca por cliente; em caso de erro, a próxima chamada tenta de novo.\n  function index(): Promise<Registry> {\n    indexPromise ??= fetchIndex().catch((error) => {\n      indexPromise = undefined\n      throw error\n    })\n    return indexPromise\n  }\n\n  return {\n    index,\n\n    async item(name, version) {\n      const entry = (await index()).items[name]\n      if (entry === undefined) {\n        throw new SlabUIError(\n          `Item \"${name}\" does not exist in the \"${registry.namespace}\" registry.`,\n        )\n      }\n      const published = entry.versions[version]\n      if (published === undefined) {\n        throw new SlabUIError(\n          `Version ${version} of \"${name}\" does not exist in the \"${registry.namespace}\" registry.`,\n        )\n      }\n\n      const url = `${baseUrl}/${published.path}`\n      const body =\n        entry.access === \"pro\"\n          ? await get(url, { extraHeaders: await proHeaders(name), pro: name })\n          : await get(url)\n      if (hash(body) !== published.hash) {\n        throw new SlabUIError(\n          `${url} does not match the hash in the index. The file may have been changed on the server.`,\n        )\n      }\n\n      const item = parse(url, body, itemSchema)\n      if (item.name !== name || item.version !== version) {\n        throw new SlabUIError(\n          `${url} contains ${item.name}@${item.version}, not ${name}@${version}.`,\n        )\n      }\n      return item\n    },\n  }\n}\n\n// Antes da validação, para dar uma mensagem útil quando o formato do índice\n// não é o que este CLI conhece.\nexport function checkSchemaVersion(\n  file: string,\n  json: unknown,\n  outdated = \"The registry needs to be published again in the current format.\",\n) {\n  const version =\n    json && typeof json === \"object\" && \"schemaVersion\" in json\n      ? json.schemaVersion\n      : undefined\n  if (typeof version !== \"number\" || version === INDEX_SCHEMA_VERSION) {\n    return\n  }\n  if (version > INDEX_SCHEMA_VERSION) {\n    throw new SlabUIError(\n      `${file} uses format ${version}, which this version of slabui does not support. Update it with \\`pnpm add -D slabui@latest\\`.`,\n    )\n  }\n  throw new SlabUIError(\n    `${file} uses format ${version}, which is no longer supported. ${outdated}`,\n  )\n}\n\n// `${VAR}` vira o valor da variável de ambiente. Mensagens nunca mostram valores.\nexport function expandHeaders(\n  headers: Record<string, string>,\n  env: Record<string, string | undefined> = process.env,\n): Record<string, string> {\n  return Object.fromEntries(\n    Object.entries(headers).map(([header, value]) => [\n      header,\n      expandValue(value, `the \"${header}\" header`, env),\n    ]),\n  )\n}\n\nfunction expandValue(\n  value: string,\n  where: string,\n  env: Record<string, string | undefined>,\n): string {\n  return value.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, name: string) => {\n    const resolved = env[name]\n    if (resolved === undefined) {\n      throw new SlabUIError(\n        `Environment variable ${name}, used in ${where}, is not set.`,\n      )\n    }\n    return resolved\n  })\n}\n\nexport function hash(body: Uint8Array): string {\n  return `sha256-${createHash(\"sha256\").update(body).digest(\"base64\")}`\n}\n","import { z } from \"zod\"\n\nimport { itemNameSchema, versionSchema } from \"./shared\"\n\nexport const installedItemSchema = z.object({\n  version: versionSchema,\n  files: z.array(z.string().min(1)),\n})\n\nexport const configSchema = z.object({\n  $schema: z.string().optional(),\n  // Token do registry padrão para itens pro. Use `${SLABUI_TOKEN}` para não\n  // gravar o valor no arquivo; sem ele, vale a variável ou o `slabui login`.\n  token: z.string().min(1).optional(),\n  css: z.string().min(1).optional(),\n  aliases: z.object({\n    components: z.string().min(1),\n    ui: z.string().min(1),\n    lib: z.string().min(1),\n    hooks: z.string().min(1),\n    utils: z.string().min(1),\n    styles: z.string().min(1),\n  }),\n  items: z.record(itemNameSchema, installedItemSchema).default({}),\n})\n\nexport type InstalledItem = z.infer<typeof installedItemSchema>\nexport type Config = z.infer<typeof configSchema>\n","import { access, readFile, writeFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport {\n  createPathsMatcher,\n  parseTsconfig,\n  type TsConfigResult,\n} from \"get-tsconfig\"\nimport { applyEdits, modify, parse } from \"jsonc-parser\"\nimport { z } from \"zod\"\n\nimport { CONFIG_FILE } from \"./constants\"\nimport { SlabUIError } from \"./errors\"\nimport { type Config, configSchema } from \"./schemas/config\"\n\nconst TSCONFIG_FILES = [\"tsconfig.json\", \"jsconfig.json\"]\n\nconst CSS_CANDIDATES = [\n  \"app/globals.css\",\n  \"src/app/globals.css\",\n  \"styles/globals.css\",\n  \"src/styles/globals.css\",\n  \"app/global.css\",\n  \"src/index.css\",\n  \"src/styles.css\",\n]\n\nexport async function exists(file: string) {\n  return access(file).then(\n    () => true,\n    () => false,\n  )\n}\n\n// tsconfig.json (ou jsconfig.json) da raiz do projeto, com `extends` resolvido.\nexport async function loadTsconfig(root: string): Promise<TsConfigResult> {\n  for (const name of TSCONFIG_FILES) {\n    const file = path.join(root, name)\n    if (await exists(file)) {\n      try {\n        return { path: file, config: parseTsconfig(file) }\n      } catch (error) {\n        throw new SlabUIError(\n          `Could not read ${name}: ${(error as Error).message}`,\n        )\n      }\n    }\n  }\n  throw new SlabUIError(\n    `No tsconfig.json or jsconfig.json in ${root}. slabui uses its \"paths\" to resolve the aliases.`,\n  )\n}\n\n// Prefixo do alias principal dos `paths` (`\"@/*\"` → `\"@/\"`).\nexport function aliasPrefix(tsconfig: TsConfigResult): string | undefined {\n  const keys = Object.keys(tsconfig.config.compilerOptions?.paths ?? {})\n  const wildcard = keys.filter((key) => key.endsWith(\"/*\"))\n  const preferred =\n    wildcard.find((key) => key === \"@/*\") ??\n    wildcard.find((key) => key === \"~/*\") ??\n    wildcard[0]\n  return preferred?.slice(0, -1)\n}\n\n// Caminho do CSS global relativo à raiz: aceita alias (`@/styles/globals.css`)\n// ou caminho a partir da raiz (`app/globals.css`).\nexport function resolveCssFile(\n  tsconfig: TsConfigResult,\n  root: string,\n  css: string | undefined,\n): string | undefined {\n  if (css === undefined) {\n    return undefined\n  }\n  const prefix = aliasPrefix(tsconfig)\n  const absolute =\n    prefix !== undefined && css.startsWith(prefix)\n      ? aliasToPath(tsconfig, css)\n      : undefined\n  return absolute === undefined\n    ? css\n    : path.relative(root, absolute).split(path.sep).join(\"/\")\n}\n\n// Pasta onde um alias (`@/components/ui`) é gravado, pelos `paths`.\nexport function aliasToPath(\n  tsconfig: TsConfigResult,\n  alias: string,\n): string | undefined {\n  return createPathsMatcher(tsconfig)?.(alias)[0]\n}\n\nexport async function detectCss(root: string): Promise<string | undefined> {\n  for (const candidate of CSS_CANDIDATES) {\n    if (await exists(path.join(root, candidate))) {\n      return candidate\n    }\n  }\n  return undefined\n}\n\nexport async function readConfig(root: string): Promise<Config> {\n  const file = path.join(root, CONFIG_FILE)\n  const body = await readFile(file, \"utf8\").catch(() => undefined)\n  if (body === undefined) {\n    throw new SlabUIError(\n      `${CONFIG_FILE} not found in ${root}. Run \"slabui init\" first.`,\n    )\n  }\n\n  let json: unknown\n  try {\n    json = JSON.parse(body)\n  } catch {\n    throw new SlabUIError(`${CONFIG_FILE} is not valid JSON.`)\n  }\n\n  const result = configSchema.safeParse(json)\n  if (!result.success) {\n    throw new SlabUIError(\n      `${CONFIG_FILE} has errors:\\n${z.prettifyError(result.error)}`,\n    )\n  }\n  return result.data\n}\n\nexport async function writeConfig(root: string, config: Config) {\n  await writeFile(\n    path.join(root, CONFIG_FILE),\n    `${JSON.stringify(config, null, 2)}\\n`,\n  )\n}\n\n// Alias escrito como pasta relativa à raiz (`./src/ui`), para projetos sem\n// `paths` no tsconfig (bibliotecas): os imports entre arquivos saem relativos.\nexport function isRelativeAlias(alias: string) {\n  return alias.startsWith(\"./\") || alias.startsWith(\"../\")\n}\n\n// Alias criado pelo `init` quando o tsconfig não tem `paths`.\nexport const DEFAULT_ALIAS = \"@/*\"\n\n// Pasta sugerida para o alias: `src`, se existir, ou a raiz.\nexport async function defaultAliasFolder(root: string): Promise<string> {\n  return (await exists(path.join(root, \"src\"))) ? \"src\" : \".\"\n}\n\ntype JsonConfig = {\n  compilerOptions?: { baseUrl?: string; paths?: unknown }\n  references?: { path: string }[]\n}\n\n// Cria o alias `@/*` apontando para `folder` (relativa à raiz; padrão:\n// `src`, se existir, ou a raiz), com os comentários e a formatação do arquivo. Em projetos com `references`\n// (Vite: `tsconfig.json` + `tsconfig.app.json`), grava nos dois: o da raiz\n// para o slabui e o do app para a compilação. Devolve os arquivos alterados.\nexport async function createPathAlias(\n  root: string,\n  { folder }: { folder?: string } = {},\n): Promise<string[]> {\n  const { path: rootConfig } = await loadTsconfig(root)\n  const target = path.resolve(root, folder ?? (await defaultAliasFolder(root)))\n\n  const files = [rootConfig]\n  const changed: string[] = []\n  const references =\n    (parse(await readFile(rootConfig, \"utf8\")) as JsonConfig).references ?? []\n  for (const reference of references) {\n    const resolved = path.resolve(path.dirname(rootConfig), reference.path)\n    const file = resolved.endsWith(\".json\")\n      ? resolved\n      : path.join(resolved, \"tsconfig.json\")\n    // Só o do app (não o do vite.config, `tsconfig.node.json`).\n    if (/app/.test(path.basename(file)) && (await exists(file))) {\n      files.push(file)\n    }\n  }\n\n  for (const file of files) {\n    const text = await readFile(file, \"utf8\")\n    const config = parse(text) as JsonConfig\n    if (config.compilerOptions?.paths) {\n      continue\n    }\n    // Os `paths` são relativos ao `baseUrl` (ou à pasta do arquivo).\n    const base = path.resolve(\n      path.dirname(file),\n      config.compilerOptions?.baseUrl ?? \".\",\n    )\n    const relative = path.relative(base, target).split(path.sep).join(\"/\")\n    const value = relative ? `./${relative}/*` : \"./*\"\n    const indent = text.match(/\\n( +|\\t)\"/)?.[1] ?? \"  \"\n    const edits = modify(\n      text,\n      [\"compilerOptions\", \"paths\", DEFAULT_ALIAS],\n      [value],\n      {\n        formattingOptions: {\n          insertSpaces: !indent.startsWith(\"\\t\"),\n          tabSize: indent.startsWith(\"\\t\") ? 1 : indent.length,\n        },\n      },\n    )\n    await writeFile(file, applyEdits(text, edits))\n    changed.push(file)\n  }\n  return changed\n}\n","import path from \"node:path\"\n\nimport type { Config } from \"./schemas/config\"\n\nimport { CONFIG_FILE, CONFIG_SCHEMA_URL } from \"./constants\"\nimport { SlabUIError } from \"./errors\"\nimport {\n  aliasPrefix,\n  aliasToPath,\n  detectCss,\n  exists,\n  isRelativeAlias,\n  loadTsconfig,\n  writeConfig,\n} from \"./project\"\n\nexport type Aliases = Config[\"aliases\"]\n\n// Valores sugeridos pelo `init`, a partir dos `paths` do tsconfig. Sem um CSS\n// global no projeto, o padrão é `<styles>/globals.css`.\nexport async function detectDefaults(\n  root: string,\n): Promise<{ aliases: Aliases; css: string; cssDetected: boolean }> {\n  const tsconfig = await loadTsconfig(root)\n  const prefix = aliasPrefix(tsconfig)\n  if (prefix === undefined) {\n    throw new SlabUIError(\n      'The tsconfig has no alias in \"paths\" (e.g. \"@/*\": [\"./*\"]). slabui uses it to place files and write imports.',\n    )\n  }\n\n  return {\n    aliases: {\n      components: `${prefix}components`,\n      ui: `${prefix}components/ui`,\n      lib: `${prefix}lib`,\n      hooks: `${prefix}hooks`,\n      utils: `${prefix}utils`,\n      styles: `${prefix}styles`,\n    },\n    ...(await cssDefault(root, `${prefix}styles`)),\n  }\n}\n\nexport async function cssDefault(\n  root: string,\n  styles: string,\n): Promise<{ css: string; cssDetected: boolean }> {\n  const detected = await detectCss(root)\n  return detected === undefined\n    ? { css: `${styles}/globals.css`, cssDetected: false }\n    : { css: detected, cssDetected: true }\n}\n\nexport async function initProject({\n  root,\n  aliases,\n  css,\n  force = false,\n}: {\n  root: string\n  aliases: Aliases\n  css?: string\n  force?: boolean\n}): Promise<Config> {\n  if (!force && (await exists(path.join(root, CONFIG_FILE)))) {\n    throw new SlabUIError(\n      `${CONFIG_FILE} already exists. Use --force to create it again.`,\n    )\n  }\n\n  const tsconfig = await loadTsconfig(root)\n  for (const [name, alias] of Object.entries(aliases)) {\n    if (!isRelativeAlias(alias) && aliasToPath(tsconfig, alias) === undefined) {\n      throw new SlabUIError(\n        `Alias \"${alias}\" (${name}) does not match any \"paths\" in the tsconfig.`,\n      )\n    }\n  }\n\n  const config: Config = {\n    $schema: CONFIG_SCHEMA_URL,\n    ...(css && { css }),\n    aliases,\n    items: {},\n  }\n  await writeConfig(root, config)\n  return config\n}\n","import { lstat, realpath } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport { SlabUIError } from \"./errors\"\n\n// Os arquivos vêm de um servidor: qualquer caminho que saia da raiz do\n// projeto (`../`, absoluto, link simbólico) é recusado antes da gravação.\nexport async function resolveProjectPath(\n  root: string,\n  relativePath: string,\n): Promise<string> {\n  const refuse = (reason: string) =>\n    new SlabUIError(`Path \"${relativePath}\" refused: ${reason}.`)\n\n  if (relativePath === \"\") {\n    throw refuse(\"it is empty\")\n  }\n  if (relativePath.includes(\"\\0\")) {\n    throw refuse(\"it contains a null character\")\n  }\n  // `\\` é recusada para o caminho ser lido igual em qualquer sistema.\n  if (relativePath.includes(\"\\\\\")) {\n    throw refuse(\"use / as the separator\")\n  }\n  if (\n    path.posix.isAbsolute(relativePath) ||\n    path.win32.isAbsolute(relativePath)\n  ) {\n    throw refuse(\"it is absolute\")\n  }\n\n  const absoluteRoot = path.resolve(root)\n  const target = path.resolve(absoluteRoot, relativePath)\n  if (target === absoluteRoot) {\n    throw refuse(\"it points to the project root\")\n  }\n  if (!isInside(absoluteRoot, target)) {\n    throw refuse(\"it leaves the project root\")\n  }\n\n  const existing = await nearestExisting(target)\n  // Gravar num link simbólico alteraria o arquivo para onde ele aponta.\n  if (existing === target && (await lstat(target)).isSymbolicLink()) {\n    throw refuse(\"the target is a symbolic link\")\n  }\n\n  const realRoot = await realpath(absoluteRoot)\n  const realExisting = await realpath(existing).catch(() => {\n    throw refuse(\"it goes through a broken symbolic link\")\n  })\n  if (!isInside(realRoot, realExisting)) {\n    throw refuse(\"it goes through a symbolic link outside the project\")\n  }\n\n  return path.join(realExisting, path.relative(existing, target))\n}\n\nfunction isInside(root: string, target: string) {\n  const relative = path.relative(root, target)\n  return (\n    relative === \"\" ||\n    (relative !== \"..\" &&\n      !relative.startsWith(`..${path.sep}`) &&\n      !path.isAbsolute(relative))\n  )\n}\n\n// Sobe até o caminho mais próximo que existe (o arquivo pode ainda não existir).\nasync function nearestExisting(target: string): Promise<string> {\n  let current = target\n  while (true) {\n    try {\n      await lstat(current)\n      return current\n    } catch (error) {\n      if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n        throw error\n      }\n      current = path.dirname(current)\n    }\n  }\n}\n","import path from \"node:path\"\n\n// Prefixo canônico dos imports entre arquivos do registry, como publicados.\nexport const REGISTRY_IMPORT_PREFIX = \"@/registry/\"\n\n// `@reference`/`@import` do CSS global do projeto, como publicados. No `add`,\n// vira o caminho até o `css` do slabui.json.\nexport const CSS_ENTRY_IMPORT = \"slabui:css\"\n\nconst SCRIPT_EXTENSIONS = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mts\", \".cts\", \".mjs\"]\n\n// `import x from \"a\"`, `import \"a\"`, `export * from \"a\"` e `import(\"a\")`.\nconst IMPORT_PATTERN =\n  /(\\bfrom\\s+|\\bimport\\s+|\\bimport\\s*\\(\\s*)([\"'])([^\"'\\n]+)\\2/g\n\n// `@import \"a\"` e `@reference \"a\"` (o `url()` não é tratado).\nconst CSS_IMPORT_PATTERN = /(@(?:import|reference)\\s+)([\"'])([^\"'\\n]+)\\2/g\n\nexport function isStylesheet(file: string) {\n  return path.posix.extname(file) === \".css\"\n}\n\nexport function rewriteCssImports(\n  content: string,\n  replace: (specifier: string) => string | undefined,\n): string {\n  return content.replace(\n    CSS_IMPORT_PATTERN,\n    (match, keyword: string, quote: string, specifier: string) => {\n      const next = replace(specifier)\n      return next === undefined ? match : `${keyword}${quote}${next}${quote}`\n    },\n  )\n}\n\nexport function isScriptFile(file: string) {\n  return SCRIPT_EXTENSIONS.includes(path.posix.extname(file))\n}\n\n// Troca cada especificador de import pelo retorno de `replace` (ou mantém, se\n// ele devolver `undefined`).\nexport function rewriteImports(\n  content: string,\n  replace: (specifier: string) => string | undefined,\n): string {\n  return content.replace(\n    IMPORT_PATTERN,\n    (match, keyword: string, quote: string, specifier: string) => {\n      const next = replace(specifier)\n      return next === undefined ? match : `${keyword}${quote}${next}${quote}`\n    },\n  )\n}\n\n// Acha, entre os caminhos conhecidos, o arquivo que um import sem extensão\n// (`ui/button`) ou de pasta (`ui/button` → `ui/button/index.tsx`) aponta.\nexport function matchFile(\n  target: string,\n  files: ReadonlySet<string>,\n): string | undefined {\n  const candidates = [\n    target,\n    ...SCRIPT_EXTENSIONS.map((extension) => `${target}${extension}`),\n    ...SCRIPT_EXTENSIONS.map((extension) => `${target}/index${extension}`),\n  ]\n  return candidates.find((candidate) => files.has(candidate))\n}\n\nexport function stripScriptExtension(file: string) {\n  const extension = path.posix.extname(file)\n  return SCRIPT_EXTENSIONS.includes(extension)\n    ? file.slice(0, -extension.length)\n    : file\n}\n","import semver from \"semver\"\n\nimport type { Config } from \"./schemas/config\"\nimport type { RegistryEntry } from \"./schemas/registry\"\n\nimport { DEFAULT_REGISTRY, REGISTRY_URL_ENV } from \"./constants\"\nimport { SlabUIError } from \"./errors\"\nimport { itemNameSchema } from \"./schemas/shared\"\n\nexport type ItemRef = {\n  name: string\n  // Versão exata ou intervalo semver; ausente para a mais recente.\n  range?: string\n}\n\nexport type ResolvedRegistry = {\n  namespace: string\n  url: string\n  headers: Record<string, string>\n  isDefault: boolean\n  // `token` do slabui.json (pode ter `${VAR}`); só no registry padrão.\n  token?: string\n}\n\n// `nome[@versão]`. Só o registry da SlabUI: `@slabui/x` vira `x`, e outros\n// namespaces são recusados.\nexport function parseItemRef(ref: string): ItemRef {\n  let rest = ref\n\n  if (rest.startsWith(\"@\")) {\n    const slash = rest.indexOf(\"/\")\n    if (slash === -1) {\n      throw new SlabUIError(`\"${ref}\" has no item name after the namespace.`)\n    }\n    const namespace = rest.slice(0, slash)\n    if (namespace !== DEFAULT_REGISTRY.namespace) {\n      throw new SlabUIError(\n        `\"${ref}\" is not from the SlabUI registry. Only SlabUI items can be installed.`,\n      )\n    }\n    rest = rest.slice(slash + 1)\n  }\n\n  const at = rest.indexOf(\"@\")\n  const name = at === -1 ? rest : rest.slice(0, at)\n  const range = at === -1 ? undefined : rest.slice(at + 1)\n\n  if (!itemNameSchema.safeParse(name).success) {\n    throw new SlabUIError(`\"${name}\" is not a valid item name (kebab-case).`)\n  }\n  // `validRange(\"\")` devolve \"*\", então a versão vazia é recusada à parte.\n  if (range !== undefined && (!range || semver.validRange(range) === null)) {\n    throw new SlabUIError(`\"${range}\" is not a valid version or range.`)\n  }\n\n  return {\n    name,\n    ...(range !== undefined && { range }),\n  }\n}\n\n// Chave do item em `items` no slabui.json.\nexport function itemKey(ref: ItemRef): string {\n  return ref.name\n}\n\n// O registry da SlabUI. A URL pode ser trocada pelo `SLABUI_REGISTRY_URL`\n// (cópia local, staging).\nexport function resolveRegistry(\n  token?: Config[\"token\"],\n  env: Record<string, string | undefined> = process.env,\n): ResolvedRegistry {\n  return {\n    namespace: DEFAULT_REGISTRY.namespace,\n    url: env[REGISTRY_URL_ENV] || DEFAULT_REGISTRY.url,\n    headers: {},\n    isDefault: true,\n    ...(token !== undefined && { token }),\n  }\n}\n\nexport function resolveVersion(\n  ref: ItemRef,\n  entry: Pick<RegistryEntry, \"latest\" | \"versions\">,\n): string {\n  if (ref.range === undefined) {\n    return entry.latest\n  }\n\n  const versions = Object.keys(entry.versions)\n  const version = semver.maxSatisfying(versions, ref.range)\n  if (version === null) {\n    throw new SlabUIError(\n      `No version of \"${itemKey(ref)}\" satisfies \"${ref.range}\". Available: ${semver.sort(versions).join(\", \")}.`,\n    )\n  }\n\n  return version\n}\n","import path from \"node:path\"\n\nimport type { TsConfigResult } from \"get-tsconfig\"\nimport type { Config } from \"../schemas/config\"\nimport type { ItemFile } from \"../schemas/item\"\n\nimport { SlabUIError } from \"../errors\"\nimport { stripScriptExtension } from \"../imports\"\nimport { aliasPrefix, aliasToPath, isRelativeAlias } from \"../project\"\n\ntype Context = {\n  root: string\n  aliases: Config[\"aliases\"]\n  tsconfig: TsConfigResult\n}\n\nconst KIND_ALIAS = {\n  ui: \"ui\",\n  component: \"components\",\n  lib: \"lib\",\n  hook: \"hooks\",\n  util: \"utils\",\n  style: \"styles\",\n} as const\n\n// Caminho no projeto (relativo à raiz, com `/`) onde o arquivo é gravado: o\n// `target` tem prioridade; sem ele, o alias do `kind` + o nome do arquivo.\nexport function destinationOf(file: ItemFile, context: Context): string {\n  if (file.target !== undefined) {\n    const target = file.target\n    const fromAlias = target.startsWith(aliasPrefix(context.tsconfig) ?? \"\\0\")\n      ? aliasToPath(context.tsconfig, target)\n      : undefined\n    return toRelative(fromAlias ?? path.resolve(context.root, target), context)\n  }\n\n  if (!(file.kind in KIND_ALIAS)) {\n    throw new SlabUIError(\n      `Files with kind \"${file.kind}\" cannot be installed by add yet (${file.path}).`,\n    )\n  }\n  const alias =\n    context.aliases[KIND_ALIAS[file.kind as keyof typeof KIND_ALIAS]]\n  // Estilos mantêm as subpastas (`styles/ui/table.css` → `<styles>/ui/table.css`);\n  // os outros tipos usam só o nome do arquivo.\n  const relative =\n    file.kind === \"style\"\n      ? file.path.split(\"/\").slice(1).join(\"/\") ||\n        path.posix.basename(file.path)\n      : path.posix.basename(file.path)\n  const resolved = isRelativeAlias(alias)\n    ? path.resolve(context.root, alias, relative)\n    : aliasToPath(context.tsconfig, `${alias}/${relative}`)\n  if (resolved === undefined) {\n    throw new SlabUIError(\n      `Alias \"${alias}\" does not match any \"paths\" in the tsconfig.`,\n    )\n  }\n  return toRelative(resolved, context)\n}\n\n// Import para um arquivo instalado, de dentro de outro arquivo instalado:\n// pelo alias principal dos `paths` quando possível, senão relativo.\nexport function importSpecifier(\n  destination: string,\n  from: string,\n  context: Context,\n): string {\n  const prefix = aliasPrefix(context.tsconfig)\n  const marker = \"__slabui__\"\n  const base =\n    prefix === undefined\n      ? undefined\n      : aliasToPath(context.tsconfig, `${prefix}${marker}`)?.slice(\n          0,\n          -marker.length,\n        )\n  const absolute = path.resolve(context.root, destination)\n\n  if (prefix !== undefined && base !== undefined && absolute.startsWith(base)) {\n    const inside = path.relative(base, absolute).split(path.sep).join(\"/\")\n    return `${prefix}${stripScriptExtension(inside)}`\n  }\n\n  let relative = path.posix.relative(path.posix.dirname(from), destination)\n  if (!relative.startsWith(\".\")) {\n    relative = `./${relative}`\n  }\n  return stripScriptExtension(relative)\n}\n\nfunction toRelative(absolute: string, context: Context) {\n  return path.relative(context.root, absolute).split(path.sep).join(\"/\")\n}\n","import path from \"node:path\"\n\nimport type { TsConfigResult } from \"get-tsconfig\"\nimport type { RegistryClient } from \"../client\"\nimport type { Config } from \"../schemas/config\"\nimport type { Item, ItemFile } from \"../schemas/item\"\n\nimport {\n  CSS_ENTRY_IMPORT,\n  isScriptFile,\n  isStylesheet,\n  matchFile,\n  REGISTRY_IMPORT_PREFIX,\n  rewriteCssImports,\n  rewriteImports,\n} from \"../imports\"\nimport {\n  itemKey,\n  parseItemRef,\n  type ResolvedRegistry,\n  resolveRegistry,\n} from \"../resolve\"\nimport { destinationOf, importSpecifier } from \"./destinations\"\n\n// Como um item publicado vira arquivos no projeto: o destino de cada arquivo\n// e o conteúdo com os imports reescritos. Usado pelo add, diff e update.\n\nexport type MaterializeContext = {\n  root: string\n  aliases: Config[\"aliases\"]\n  tsconfig: TsConfigResult\n  css?: string\n}\n\n// Destinos por item (chave do slabui.json) → path publicado → path no projeto.\nexport type Destinations = Map<string, Map<string, string>>\n\nexport function isBlock(item: Item) {\n  return item.kind === \"block\" || item.kind === \"example\"\n}\n\nexport function itemDestinations(\n  item: Item,\n  context: MaterializeContext,\n  blockDir?: string,\n): Map<string, string> {\n  return isBlock(item)\n    ? blockDestinations(item, blockDir as string)\n    : new Map(\n        item.files.map((file) => [file.path, destinationOf(file, context)]),\n      )\n}\n\n// Itens cujos arquivos um item pode importar: ele e as dependências.\nexport function reachableKeys(key: string, item: Item) {\n  return [\n    key,\n    ...item.dependencies.registry.map((dependency) =>\n      itemKey(parseItemRef(dependency)),\n    ),\n  ]\n}\n\n// Destinos das dependências já instaladas que ainda não estão em\n// `destinations`, a partir da versão instalada.\nexport async function addInstalledDependencies(\n  items: Item[],\n  {\n    config,\n    context,\n    destinations,\n    clientFor,\n  }: {\n    config: Pick<Config, \"items\" | \"token\">\n    context: MaterializeContext\n    destinations: Destinations\n    clientFor: (registry: ResolvedRegistry) => RegistryClient\n  },\n) {\n  for (const item of items) {\n    for (const dependency of item.dependencies.registry) {\n      const ref = parseItemRef(dependency)\n      const key = itemKey(ref)\n      const current = config.items[key]\n      if (destinations.has(key) || current === undefined) {\n        continue\n      }\n      const client = clientFor(resolveRegistry(config.token))\n      destinations.set(\n        key,\n        itemDestinations(await client.item(ref.name, current.version), context),\n      )\n    }\n  }\n}\n\n// Conteúdo como o add grava: imports `@/registry/` para os arquivos\n// instalados e `slabui:css` para o `css` do slabui.json.\nexport function materializeFile(\n  file: ItemFile,\n  {\n    key,\n    item,\n    destination,\n    destinations,\n    context,\n    warnings,\n  }: {\n    key: string\n    item: Item\n    destination: string\n    destinations: Destinations\n    context: MaterializeContext\n    warnings: string[]\n  },\n): string {\n  const stylesheet = isStylesheet(file.path)\n  if (!isScriptFile(file.path) && !stylesheet) {\n    return file.content\n  }\n\n  const reachable = reachableKeys(key, item)\n  const replace = (specifier: string) => {\n    if (specifier === CSS_ENTRY_IMPORT) {\n      if (context.css === undefined) {\n        warnings.push(\n          `\"${key}\": ${destination} uses the global CSS, but \"css\" is not set in slabui.json.`,\n        )\n        return undefined\n      }\n      return relativeImport(context.css, destination)\n    }\n    if (!specifier.startsWith(REGISTRY_IMPORT_PREFIX)) {\n      return undefined\n    }\n    const target = specifier.slice(REGISTRY_IMPORT_PREFIX.length)\n    for (const candidate of reachable) {\n      const files = destinations.get(candidate)\n      const matched = files && matchFile(target, new Set(files.keys()))\n      if (matched) {\n        const installed = files.get(matched) as string\n        // CSS não entende os aliases do tsconfig: sempre relativo.\n        return stylesheet\n          ? relativeImport(installed, destination)\n          : importSpecifier(installed, destination, context)\n      }\n    }\n    warnings.push(\n      `\"${key}\": could not rewrite the import ${specifier} in ${destination}.`,\n    )\n    return undefined\n  }\n\n  return stylesheet\n    ? rewriteCssImports(file.content, replace)\n    : rewriteImports(file.content, replace)\n}\n\n// Caminho relativo de `from` até `to` (ambos relativos à raiz do projeto).\nfunction relativeImport(to: string, from: string) {\n  const relative = path.posix.relative(path.posix.dirname(from), to)\n  return relative.startsWith(\".\") ? relative : `./${relative}`\n}\n\n// Arquivos do block relativos à pasta comum a todos, dentro de `dir`.\nfunction blockDestinations(item: Item, dir: string) {\n  const folders = item.files.map((file) =>\n    path.posix.dirname(file.path).split(\"/\"),\n  )\n  const common: string[] = []\n  for (const [index, segment] of (folders[0] ?? []).entries()) {\n    if (folders.every((parts) => parts[index] === segment)) {\n      common.push(segment)\n    } else {\n      break\n    }\n  }\n  const base = common.join(\"/\")\n  const normalized = path.posix.normalize(dir.split(path.sep).join(\"/\"))\n  return new Map(\n    item.files.map((file) => [\n      file.path,\n      path.posix.join(normalized, path.posix.relative(base, file.path)),\n    ]),\n  )\n}\n","import { spawn } from \"node:child_process\"\nimport { readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport semver from \"semver\"\n\nimport { SlabUIError } from \"../errors\"\nimport { exists } from \"../project\"\n\nexport type PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\"\n\nconst LOCKFILES: [string, PackageManager][] = [\n  [\"pnpm-lock.yaml\", \"pnpm\"],\n  [\"bun.lock\", \"bun\"],\n  [\"bun.lockb\", \"bun\"],\n  [\"yarn.lock\", \"yarn\"],\n  [\"package-lock.json\", \"npm\"],\n]\n\n// `clsx`, `clsx@2.0.0`, `@base-ui/react@^1` → nome e intervalo.\nexport function parsePackageSpec(spec: string): {\n  name: string\n  range?: string\n} {\n  const at = spec.indexOf(\"@\", spec.startsWith(\"@\") ? 1 : 0)\n  return at === -1\n    ? { name: spec }\n    : { name: spec.slice(0, at), range: spec.slice(at + 1) || undefined }\n}\n\n// Pelo `packageManager` do package.json ou pelo lockfile, subindo as pastas\n// (num monorepo, o lockfile fica na raiz).\nexport async function detectPackageManager(\n  root: string,\n): Promise<PackageManager> {\n  const manifest = await readManifest(root)\n  const declared = manifest?.packageManager?.split(\"@\")[0]\n  if (declared && [\"pnpm\", \"npm\", \"yarn\", \"bun\"].includes(declared)) {\n    return declared as PackageManager\n  }\n\n  let dir = path.resolve(root)\n  while (true) {\n    for (const [file, manager] of LOCKFILES) {\n      if (await exists(path.join(dir, file))) {\n        return manager\n      }\n    }\n    const parent = path.dirname(dir)\n    if (parent === dir) {\n      return \"npm\"\n    }\n    dir = parent\n  }\n}\n\ntype Manifest = {\n  packageManager?: string\n  dependencies?: Record<string, string>\n  devDependencies?: Record<string, string>\n}\n\nasync function readManifest(root: string): Promise<Manifest | undefined> {\n  const body = await readFile(path.join(root, \"package.json\"), \"utf8\").catch(\n    () => undefined,\n  )\n  return body === undefined ? undefined : (JSON.parse(body) as Manifest)\n}\n\nexport type PackagePlan = {\n  install: string[]\n  installDev: string[]\n  // Instalados numa versão que não atende ao pedido.\n  conflicts: { spec: string; installed: string }[]\n}\n\n// Só instala o que falta; o que já está no package.json fica, e conflitos de\n// versão são devolvidos para quem chama decidir.\nexport async function planPackages(\n  root: string,\n  { npm, npmDev }: { npm: string[]; npmDev: string[] },\n): Promise<PackagePlan> {\n  const manifest = (await readManifest(root)) ?? {}\n  const declared = { ...manifest.devDependencies, ...manifest.dependencies }\n  const plan: PackagePlan = { install: [], installDev: [], conflicts: [] }\n\n  const visit = (spec: string, list: string[]) => {\n    const { name, range } = parsePackageSpec(spec)\n    const current = declared[name]\n    if (current === undefined) {\n      if (!list.includes(spec)) {\n        list.push(spec)\n      }\n      return\n    }\n    const minimum = semver.minVersion(current)\n    if (range && minimum && !semver.satisfies(minimum, range)) {\n      plan.conflicts.push({ spec, installed: current })\n    }\n  }\n\n  for (const spec of new Set(npm)) {\n    visit(spec, plan.install)\n  }\n  for (const spec of new Set(npmDev)) {\n    visit(spec, plan.installDev)\n  }\n  return plan\n}\n\nexport function installCommand(\n  manager: PackageManager,\n  packages: string[],\n  dev: boolean,\n): [string, string[]] {\n  const verb = manager === \"npm\" ? \"install\" : \"add\"\n  const devFlag = manager === \"bun\" ? \"--dev\" : \"-D\"\n  return [manager, [verb, ...(dev ? [devFlag] : []), ...packages]]\n}\n\nexport async function runInstall(\n  root: string,\n  manager: PackageManager,\n  packages: string[],\n  dev: boolean,\n) {\n  if (packages.length === 0) {\n    return\n  }\n  const [command, args] = installCommand(manager, packages, dev)\n  await new Promise<void>((resolve, reject) => {\n    const child = spawn(command, args, { cwd: root, stdio: \"inherit\" })\n    child.on(\"error\", (error) =>\n      reject(new SlabUIError(`Could not run ${command}: ${error.message}`)),\n    )\n    child.on(\"exit\", (code) =>\n      code === 0\n        ? resolve()\n        : reject(\n            new SlabUIError(\n              `${command} ${args.join(\" \")} exited with code ${code}.`,\n            ),\n          ),\n    )\n  })\n}\n\n// Só os pacotes que faltam; conflitos de versão são perguntados (ou mantidos,\n// com aviso). Devolve o que foi instalado.\nexport async function installPackages(\n  root: string,\n  dependencies: { npm: string[]; npmDev: string[] },\n  {\n    confirm,\n    skipInstall = false,\n    warnings,\n  }: {\n    confirm?: (message: string) => Promise<boolean>\n    skipInstall?: boolean\n    warnings: string[]\n  },\n): Promise<string[]> {\n  const packages = await planPackages(root, dependencies)\n  for (const { spec, installed } of packages.conflicts) {\n    const upgrade = confirm\n      ? await confirm(\n          `The project has ${installed}, but ${spec} is required. Update it?`,\n        )\n      : false\n    if (upgrade) {\n      packages.install.push(spec)\n    } else {\n      warnings.push(\n        `Kept ${parsePackageSpec(spec).name}@${installed}; the item requires ${spec}.`,\n      )\n    }\n  }\n\n  const toInstall = [...packages.install, ...packages.installDev]\n  if (toInstall.length === 0) {\n    return []\n  }\n  if (skipInstall) {\n    warnings.push(\n      `Packages not installed (--skip-install): ${toInstall.join(\" \")}`,\n    )\n    return []\n  }\n  const manager = await detectPackageManager(root)\n  await runInstall(root, manager, packages.install, false)\n  await runInstall(root, manager, packages.installDev, true)\n  return toInstall\n}\n","import semver from \"semver\"\n\nimport type { Config } from \"../schemas/config\"\nimport type { Item } from \"../schemas/item\"\n\nimport { createRegistryClient, type RegistryClient } from \"../client\"\nimport { SlabUIError } from \"../errors\"\nimport {\n  type ItemRef,\n  itemKey,\n  parseItemRef,\n  type ResolvedRegistry,\n  resolveRegistry,\n} from \"../resolve\"\n\nexport type PlannedItem = {\n  // Chave em `items` do slabui.json (`button`, `@acme/data-table`).\n  key: string\n  registry: ResolvedRegistry\n  item: Item\n}\n\nexport type InstallPlan = {\n  // Na ordem de instalação: dependências antes de quem depende delas.\n  items: PlannedItem[]\n  // Já instalados numa versão que atende ao pedido.\n  installed: string[]\n  warnings: string[]\n}\n\ntype Constraint = { range?: string; by?: string }\n\ntype Options = {\n  refs: string[]\n  config: Pick<Config, \"items\" | \"token\">\n  createClient?: (registry: ResolvedRegistry) => RegistryClient\n}\n\n// Resolve os itens pedidos e as dependências de registry, recursivamente,\n// escolhendo para cada item a maior versão que atende a todos os pedidos.\nexport async function planInstall({\n  refs,\n  config,\n  createClient = (registry) => createRegistryClient(registry),\n}: Options): Promise<InstallPlan> {\n  const clients = new Map<string, RegistryClient>()\n  const constraints = new Map<string, Constraint[]>()\n  const chosen = new Map<string, PlannedItem>()\n  const order: string[] = []\n  const installed = new Set<string>()\n  const warnings: string[] = []\n\n  function clientFor(registry: ResolvedRegistry) {\n    let client = clients.get(registry.namespace)\n    if (client === undefined) {\n      client = createClient(registry)\n      clients.set(registry.namespace, client)\n    }\n    return client\n  }\n\n  async function visit(ref: ItemRef, by?: string): Promise<void> {\n    const key = itemKey(ref)\n    const list = constraints.get(key) ?? []\n    list.push({ range: ref.range, by })\n    constraints.set(key, list)\n\n    const current = config.items[key]\n    if (current !== undefined) {\n      const outOfRange = list.filter(\n        ({ range }) => range && !semver.satisfies(current.version, range),\n      )\n      if (outOfRange.length === 0) {\n        installed.add(key)\n      } else {\n        for (const { range, by: who } of outOfRange) {\n          warnings.push(\n            `\"${key}\" is installed at ${current.version}, but ${who ? `\"${who}\"` : \"the request\"} requires ${range}. Run \"slabui update ${key}\".`,\n          )\n        }\n      }\n      return\n    }\n\n    const previous = chosen.get(key)\n    if (previous && list.every(({ range }) => accepts(previous, range))) {\n      return\n    }\n\n    const registry = resolveRegistry(config.token)\n    const client = clientFor(registry)\n    const entry = (await client.index()).items[ref.name]\n    if (entry === undefined) {\n      throw new SlabUIError(\n        `Item \"${ref.name}\" does not exist in the \"${registry.namespace}\" registry.`,\n      )\n    }\n\n    const versions = Object.keys(entry.versions)\n    const ranges = list.flatMap(({ range }) => (range ? [range] : []))\n    const version =\n      ranges.length === 0\n        ? entry.latest\n        : (semver.rsort(\n            versions.filter((candidate) =>\n              ranges.every((range) => semver.satisfies(candidate, range)),\n            ),\n          )[0] ?? null)\n    if (version === null) {\n      const asked = list\n        .map(\n          ({ range, by: who }) =>\n            `${range ?? \"latest\"} (${who ?? \"requested\"})`,\n        )\n        .join(\", \")\n      throw new SlabUIError(\n        `No version of \"${key}\" satisfies every request: ${asked}. Available: ${semver.sort(versions).join(\", \")}.`,\n      )\n    }\n\n    const item = await client.item(ref.name, version)\n    chosen.set(key, { key, registry, item })\n\n    for (const dependency of item.dependencies.registry) {\n      await visit(parseItemRef(dependency), key)\n    }\n    if (!order.includes(key)) {\n      order.push(key)\n    }\n  }\n\n  for (const ref of refs) {\n    await visit(parseItemRef(ref))\n  }\n\n  return {\n    items: order.map((key) => chosen.get(key) as PlannedItem),\n    installed: [...installed],\n    warnings,\n  }\n}\n\nfunction accepts(planned: PlannedItem, range: string | undefined) {\n  return range === undefined || semver.satisfies(planned.item.version, range)\n}\n","// Multi-tema estático: cada tema é um CSS em `styles/themes/<nome>.css`,\n// aplicado pelo atributo no `<html>`. Sem dependências, para o layout do app\n// (Next) ou o navegador importarem.\n\nexport const THEME_ATTRIBUTE = \"data-slabui-theme\"\n\n// Variável de ambiente que escolhe o tema quando o código não define o\n// atributo.\nexport const THEME_ENV = \"SLABUI_THEME\"\n\n// Vai num seletor CSS e num caminho de arquivo: só letras, números e `-`.\nconst THEME_NAME = /^[a-z0-9][a-z0-9-]*$/i\n\nexport function isThemeName(name: string): boolean {\n  return THEME_NAME.test(name)\n}\n\n// `:root[data-slabui-theme=\"loja-a\"]` e, no modo escuro, com `.dark`.\nexport function themeSelector(name: string, dark = false): string {\n  if (!isThemeName(name)) {\n    throw new Error(`Invalid theme name: \"${name}\"`)\n  }\n  return `:root[${THEME_ATTRIBUTE}=\"${name}\"]${dark ? \".dark\" : \"\"}`\n}\n\n// Atributo do `<html>` com o tema da variável de ambiente (ou o informado):\n// `<html {...themeAttribute()}>`. Sem tema, um objeto vazio.\nexport function themeAttribute(\n  theme: string | undefined = typeof process === \"undefined\"\n    ? undefined\n    : process.env[THEME_ENV],\n): Record<string, string> {\n  return theme && isThemeName(theme) ? { [THEME_ATTRIBUTE]: theme } : {}\n}\n","import postcss, {\n  type AtRule,\n  type Container,\n  type Root,\n  type Rule,\n} from \"postcss\"\n\nimport type { ThemeGroup, ThemeTokens } from \"./types\"\n\nimport { themeSelector } from \"./attribute\"\n\nexport type CssVarChange = {\n  group: ThemeGroup\n  name: string\n  action: \"added\" | \"updated\" | \"kept\" | \"removed\" | \"unchanged\"\n}\n\nexport type CssVarsResult = {\n  css: string\n  changes: CssVarChange[]\n  warnings: string[]\n}\n\nexport type ApplyCssVarsOptions = {\n  // Variáveis da versão instalada (no update); ausente no add.\n  base?: ThemeTokens\n  overwrite?: boolean\n  // Variável removida na versão nova: remover? Ausente = manter.\n  shouldRemove?: (group: ThemeGroup, name: string) => Promise<boolean>\n  // Arquivo de um tema (`styles/themes/<nome>.css`): os blocos são\n  // `:root[data-slabui-theme=\"<nome>\"]` (e `.dark`) no lugar de `:root`/`.dark`.\n  theme?: string\n}\n\nconst COLOR =\n  /^\\s*(oklch|oklab|lch|lab|hsla?|rgba?|hwb|color)\\(|^\\s*#[0-9a-f]{3,8}\\s*$/i\n\n// Aplica as variáveis de um item no CSS global, com merge por variável.\nexport async function applyCssVars(\n  css: string,\n  remote: ThemeTokens,\n  { base, overwrite = false, shouldRemove, theme }: ApplyCssVarsOptions = {},\n): Promise<CssVarsResult> {\n  const root = postcss.parse(css)\n  const changes: CssVarChange[] = []\n  const warnings: string[] = []\n  // Num arquivo de tema, os `--color-*` já estão no `@theme inline` do CSS\n  // global; uma cor nova do tema declara o dela no próprio arquivo.\n  const mappings = (vars: ThemeTokens) =>\n    theme ? vars : withColorMappings(vars)\n  const wanted = mappings(remote)\n  const previous = base ? mappings(base) : undefined\n\n  for (const group of [\"theme\", \"light\", \"dark\"] as const) {\n    const remoteVars = wanted[group] ?? {}\n    const baseVars = previous?.[group] ?? {}\n    const names = new Set([\n      ...Object.keys(remoteVars),\n      ...Object.keys(baseVars),\n    ])\n    if (names.size === 0) {\n      continue\n    }\n    let block = findBlock(root, group, theme)\n\n    for (const name of names) {\n      const remoteValue = remoteVars[name]\n      const baseValue = baseVars[name]\n      const declaration = block?.nodes?.find(\n        (node) => node.type === \"decl\" && node.prop === `--${name}`,\n      ) as postcss.Declaration | undefined\n      const local = declaration?.value\n      const record = (action: CssVarChange[\"action\"]) =>\n        changes.push({ group, name, action })\n\n      if (remoteValue === undefined) {\n        // Removida na versão nova.\n        if (local === undefined) {\n          continue\n        }\n        if (shouldRemove && (await shouldRemove(group, name))) {\n          declaration?.remove()\n          record(\"removed\")\n        } else {\n          warnings.push(\n            `--${name} (${group}) was removed in the new version; kept in the CSS.`,\n          )\n          record(\"kept\")\n        }\n        continue\n      }\n\n      if (local === undefined) {\n        if (baseValue !== undefined) {\n          // Apagada do CSS pelo usuário: não recria.\n          record(\"kept\")\n          continue\n        }\n        block ??= createBlock(root, group, theme)\n        block.raws.semicolon = true\n        block.raws.after = \"\\n\"\n        block.append(\n          postcss.decl({\n            prop: `--${name}`,\n            value: remoteValue,\n            raws: { before: \"\\n  \" },\n          }),\n        )\n        record(\"added\")\n        continue\n      }\n\n      if (same(local, remoteValue)) {\n        record(\"unchanged\")\n      } else if (\n        overwrite ||\n        (baseValue !== undefined && same(local, baseValue))\n      ) {\n        ;(declaration as postcss.Declaration).value = remoteValue\n        record(\"updated\")\n      } else {\n        warnings.push(\n          `--${name} (${group}) has a custom value in the CSS (${local}); kept instead of ${remoteValue}.`,\n        )\n        record(\"kept\")\n      }\n    }\n  }\n\n  // O arquivo de um tema é importado pelo CSS global, que já tem a variante.\n  if (!theme && Object.keys(wanted.dark ?? {}).length > 0) {\n    ensureDarkVariant(root)\n  }\n\n  return { css: root.toString(), changes, warnings }\n}\n\n// Cada cor de light/dark ganha `--color-<nome>: var(--<nome>)` no `theme`,\n// para o Tailwind 4 gerar as utilidades (`bg-<nome>`) e aceitar o `@apply`.\nexport function withColorMappings(vars: ThemeTokens): ThemeTokens {\n  const theme = { ...vars.theme }\n  for (const group of [vars.light, vars.dark]) {\n    for (const [name, value] of Object.entries(group ?? {})) {\n      if (COLOR.test(value) && theme[`color-${name}`] === undefined) {\n        theme[`color-${name}`] = `var(--${name})`\n      }\n    }\n  }\n  return {\n    ...vars,\n    ...(Object.keys(theme).length > 0 && { theme }),\n  }\n}\n\n// Seletor do bloco de cada grupo: `:root`/`.dark` no CSS global, ou os do\n// tema no arquivo de um tema.\nfunction blockSelector(group: \"light\" | \"dark\", theme?: string) {\n  if (theme) {\n    return themeSelector(theme, group === \"dark\")\n  }\n  return group === \"light\" ? \":root\" : \".dark\"\n}\n\n// Compara seletores sem espaços nem aspas (`[a=\"x\"]` = `[a='x']` = `[a=x]`).\nconst normalize = (selector: string) => selector.replace(/[\"'\\s]/g, \"\")\n\nexport function findBlock(\n  root: Root,\n  group: ThemeGroup,\n  theme?: string,\n): Container | undefined {\n  return root.nodes.find((node) =>\n    group === \"theme\"\n      ? node.type === \"atrule\" &&\n        node.name === \"theme\" &&\n        node.params.trim() === \"inline\"\n      : node.type === \"rule\" &&\n        normalize(node.selector) === normalize(blockSelector(group, theme)),\n  ) as Container | undefined\n}\n\nfunction createBlock(\n  root: Root,\n  group: ThemeGroup,\n  theme?: string,\n): AtRule | Rule {\n  const block =\n    group === \"theme\"\n      ? postcss.atRule({ name: \"theme\", params: \"inline\" })\n      : postcss.rule({ selector: blockSelector(group, theme) })\n  block.raws = {\n    before: root.nodes.length > 0 ? \"\\n\\n\" : \"\",\n    between: \" \",\n    after: \"\\n\",\n    semicolon: true,\n  }\n  root.append(block)\n  return block\n}\n\n// `@custom-variant dark` depois dos `@import`, se o CSS não declara a variante.\nfunction ensureDarkVariant(root: Root) {\n  const declared = root.nodes.some(\n    (node) =>\n      node.type === \"atrule\" &&\n      node.name === \"custom-variant\" &&\n      node.params.trim().startsWith(\"dark\"),\n  )\n  if (declared) {\n    return\n  }\n  const variant = postcss.atRule({\n    name: \"custom-variant\",\n    params: \"dark (&:is(.dark *))\",\n  })\n  const imports = root.nodes.filter(\n    (node) => node.type === \"atrule\" && node.name === \"import\",\n  )\n  const last = imports.at(-1)\n  if (last) {\n    variant.raws = { before: \"\\n\\n\" }\n    last.after(variant)\n  } else {\n    variant.raws = { before: \"\" }\n    root.prepend(variant)\n  }\n}\n\nfunction same(a: string, b: string) {\n  return a.replace(/\\s+/g, \" \").trim() === b.replace(/\\s+/g, \" \").trim()\n}\n","import type { ThemeTokens } from \"./types\"\n\n// Tema padrão da SlabUI. Os `--color-<nome>: var(--<nome>)` do `@theme inline`\n// não ficam aqui: saem das cores de `light` e `dark` na gravação.\nexport const defaultTheme = {\n  theme: {\n    \"font-sans\": \"var(--font-sans)\",\n    \"font-heading\": \"var(--font-heading)\",\n    \"font-mono\": \"var(--font-mono)\",\n\n    \"radius-sm\": \"calc(var(--radius) * 0.6)\",\n    \"radius-md\": \"calc(var(--radius) * 0.8)\",\n    \"radius-lg\": \"var(--radius)\",\n    \"radius-xl\": \"calc(var(--radius) * 1.4)\",\n    \"radius-2xl\": \"calc(var(--radius) * 1.8)\",\n    \"radius-3xl\": \"calc(var(--radius) * 2.2)\",\n    \"radius-4xl\": \"calc(var(--radius) * 2.6)\",\n\n    \"breakpoint-3xl\": \"1600px\",\n    \"breakpoint-4xl\": \"2000px\",\n\n    \"text-xxs\": \"0.625rem\",\n    \"text-2xxs\": \"0.688rem\",\n    \"text-2xs\": \"0.813rem\",\n    \"text-2xs--line-height\": \"calc(1.125 / 0.813)\",\n    \"text-2sm\": \"0.938rem\",\n    \"text-2sm--line-height\": \"calc(1.625 / 0.938)\",\n\n    spacing: \"var(--spacing)\",\n\n    \"focus-size\": \"calc(var(--focus-size))\",\n    \"focus-offset\": \"var(--focus-offset)\",\n\n    // `destructive` (estados inválidos dos componentes) é a cor `danger`.\n    \"color-destructive\": \"var(--danger)\",\n  },\n  light: {\n    spacing: \"0.25rem\",\n    radius: \"0.65rem\",\n    background: \"oklch(1 0 0)\",\n    // Cor da barra de rolagem (base.css).\n    \"scrollbar-thumb\": \"oklch(0.922 0 0)\",\n    foreground: \"oklch(0.145 0 0)\",\n    card: \"oklch(1 0 0)\",\n    \"card-foreground\": \"oklch(0.145 0 0)\",\n    popover: \"oklch(1 0 0)\",\n    \"popover-foreground\": \"oklch(0.145 0 0)\",\n    muted: \"oklch(0.97 0 0)\",\n    \"muted-foreground\": \"oklch(0.556 0 0)\",\n    accent: \"oklch(0.97 0 0)\",\n    \"accent-foreground\": \"oklch(0.205 0 0)\",\n    border: \"oklch(0.922 0 0)\",\n    input: \"oklch(0.922 0 0)\",\n    ring: \"oklch(0.708 0 0)\",\n    \"chart-1\": \"oklch(0.646 0.222 41.116)\",\n    \"chart-2\": \"oklch(0.6 0.118 184.704)\",\n    \"chart-3\": \"oklch(0.398 0.07 227.392)\",\n    \"chart-4\": \"oklch(0.828 0.189 84.429)\",\n    \"chart-5\": \"oklch(0.769 0.188 70.08)\",\n    sidebar: \"oklch(0.985 0 0)\",\n    \"sidebar-foreground\": \"oklch(0.145 0 0)\",\n    \"sidebar-primary\": \"oklch(0.205 0 0)\",\n    \"sidebar-primary-foreground\": \"oklch(0.985 0 0)\",\n    \"sidebar-accent\": \"oklch(0.97 0 0)\",\n    \"sidebar-accent-foreground\": \"oklch(0.205 0 0)\",\n    \"sidebar-border\": \"oklch(0.922 0 0)\",\n    \"sidebar-ring\": \"oklch(0.708 0 0)\",\n\n    primary: \"oklch(70% 0.1435 227.76)\",\n    \"primary-foreground\": \"oklch(0.985 0 0)\",\n    secondary: \"oklch(0.97 0 0)\",\n    \"secondary-foreground\": \"oklch(0.205 0 0)\",\n    danger: \"oklch(0.577 0.245 27.325)\",\n    \"danger-foreground\": \"oklch(0.985 0 0)\",\n    success: \"oklch(0.728 0.125 139.6)\",\n    \"success-foreground\": \"oklch(0.985 0 0)\",\n    warning: \"oklch(0.784 0.181 44.7)\",\n    \"warning-foreground\": \"oklch(0.985 0 0)\",\n    inverted: \"oklch(0.205 0 0)\",\n    \"inverted-foreground\": \"oklch(0.97 0 0)\",\n\n    focus: \"oklch(0.7 0.181 44.7)\",\n    \"focus-size\": \"2.5px\",\n    \"focus-offset\": \"2px\",\n\n    table: \"oklch(0.94 0 0 / 65%)\",\n    \"table-content\": \"oklch(1 0 0)\",\n    \"table-hover\": \"oklch(0.98 0 0 / 10%)\",\n  },\n  dark: {\n    background: \"oklch(0.145 0 0)\",\n    \"scrollbar-thumb\": \"oklch(0.269 0 0)\",\n    foreground: \"oklch(0.985 0 0)\",\n    card: \"oklch(0.205 0 0)\",\n    \"card-foreground\": \"oklch(0.985 0 0)\",\n    popover: \"oklch(0.205 0 0)\",\n    \"popover-foreground\": \"oklch(0.985 0 0)\",\n    secondary: \"oklch(0.269 0 0)\",\n    \"secondary-foreground\": \"oklch(0.985 0 0)\",\n    muted: \"oklch(0.269 0 0)\",\n    \"muted-foreground\": \"oklch(0.708 0 0)\",\n    accent: \"oklch(0.269 0 0)\",\n    \"accent-foreground\": \"oklch(0.985 0 0)\",\n    border: \"oklch(1 0 0 / 10%)\",\n    input: \"oklch(1 0 0 / 15%)\",\n    ring: \"oklch(0.556 0 0)\",\n    \"chart-1\": \"oklch(0.488 0.243 264.376)\",\n    \"chart-2\": \"oklch(0.696 0.17 162.48)\",\n    \"chart-3\": \"oklch(0.769 0.188 70.08)\",\n    \"chart-4\": \"oklch(0.627 0.265 303.9)\",\n    \"chart-5\": \"oklch(0.645 0.246 16.439)\",\n    sidebar: \"oklch(0.205 0 0)\",\n    \"sidebar-foreground\": \"oklch(0.985 0 0)\",\n    \"sidebar-primary\": \"oklch(0.488 0.243 264.376)\",\n    \"sidebar-primary-foreground\": \"oklch(0.985 0 0)\",\n    \"sidebar-accent\": \"oklch(0.269 0 0)\",\n    \"sidebar-accent-foreground\": \"oklch(0.985 0 0)\",\n    \"sidebar-border\": \"oklch(1 0 0 / 10%)\",\n    \"sidebar-ring\": \"oklch(0.556 0 0)\",\n\n    primary: \"oklch(66% 0.1435 227.76)\",\n    \"primary-foreground\": \"oklch(0.985 0 0)\",\n    danger: \"oklch(0.704 0.191 22.216)\",\n    \"danger-foreground\": \"oklch(0.985 0 0)\",\n    success: \"oklch(0.728 0.125 139.6)\",\n    \"success-foreground\": \"oklch(0.985 0 0)\",\n    warning: \"oklch(0.784 0.181 44.7)\",\n    \"warning-foreground\": \"oklch(0.985 0 0)\",\n    inverted: \"oklch(0.922 0 0)\",\n    \"inverted-foreground\": \"oklch(0.205 0 0)\",\n\n    focus: \"oklch(0.7 0.181 44.7)\",\n\n    table: \"oklch(0.265 0 0)\",\n    \"table-content\": \"oklch(0.205 0 0)\",\n    \"table-hover\": \"oklch(0.22 0 0)\",\n  },\n} satisfies ThemeTokens\n","import postcss, {\n  type AtRule,\n  type Container,\n  type Root,\n  type Rule,\n} from \"postcss\"\n\n// Regras de CSS que os itens trazem além das variáveis do tema:\n//\n// - `utilities` e `variants`: `@utility <nome>` e `@custom-variant <nome>`,\n//   com o texto completo da regra, no `utilities.css`. O merge é pelo nome.\n// - `base`: declarações em seletores de elemento (`body`, `html`, `*`…),\n//   dentro do `@layer base` do `base.css`. O merge é por seletor e\n//   propriedade.\n//\n// As regras de merge são as mesmas das variáveis: o que falta é adicionado, o\n// que o usuário mudou fica, e no update o que não foi mexido acompanha a\n// versão nova.\nexport type CssRules = {\n  utilities?: Record<string, string>\n  variants?: Record<string, string>\n  base?: Record<string, Record<string, string>>\n}\n\nexport type CssRuleKind = \"utility\" | \"variant\" | \"base\"\n\nexport type CssRuleChange = {\n  kind: CssRuleKind\n  // Nome da utility ou da variante; na base, `<seletor> { <propriedade> }`.\n  name: string\n  action: \"added\" | \"updated\" | \"kept\" | \"removed\" | \"unchanged\"\n}\n\nexport type CssRulesResult = {\n  css: string\n  changes: CssRuleChange[]\n  warnings: string[]\n}\n\nexport type ApplyCssRulesOptions = {\n  // Regras da versão instalada (no update); ausente no add.\n  base?: CssRules\n  overwrite?: boolean\n  // Regra removida na versão nova: remover? Ausente = manter.\n  shouldRemove?: (kind: CssRuleKind, name: string) => Promise<boolean>\n}\n\nconst AT_RULE = { utility: \"utility\", variant: \"custom-variant\" } as const\n\n// Nome de uma `@utility`/`@custom-variant` pelo começo dos parâmetros\n// (`no-scrollbar`, `fixed (&:is(.layout-fixed *))`).\nexport function ruleName(rule: AtRule): string {\n  return rule.params.trim().split(/[\\s({]/)[0] ?? \"\"\n}\n\n// As `@utility` e `@custom-variant` de um CSS, pelo nome, com o texto de cada\n// uma. A variante `dark` fica de fora: é do tema, e o CSS global cuida dela.\nexport function readCssRules(\n  css: string,\n): Required<Pick<CssRules, \"utilities\" | \"variants\">> {\n  const root = postcss.parse(css)\n  const utilities: Record<string, string> = {}\n  const variants: Record<string, string> = {}\n  root.each((node) => {\n    if (node.type !== \"atrule\") {\n      return\n    }\n    const name = ruleName(node)\n    if (node.name === AT_RULE.utility) {\n      utilities[name] = ruleSource(node)\n    } else if (node.name === AT_RULE.variant && name !== \"dark\") {\n      variants[name] = ruleSource(node)\n    }\n  })\n  return { utilities, variants }\n}\n\n// Aplica as `@utility` e `@custom-variant` de um item, com merge pelo nome.\nexport async function applyCssRules(\n  css: string,\n  remote: Pick<CssRules, \"utilities\" | \"variants\">,\n  options: ApplyCssRulesOptions = {},\n): Promise<CssRulesResult> {\n  const root = postcss.parse(css)\n  const changes: CssRuleChange[] = []\n  const warnings: string[] = []\n\n  for (const kind of [\"variant\", \"utility\"] as const) {\n    const field = kind === \"utility\" ? \"utilities\" : \"variants\"\n    const remoteRules = remote[field] ?? {}\n    const baseRules = options.base?.[field] ?? {}\n    const names = new Set([\n      ...Object.keys(remoteRules),\n      ...Object.keys(baseRules),\n    ])\n\n    for (const name of names) {\n      const remoteSource = remoteRules[name]\n      const baseSource = baseRules[name]\n      const local = findRule(root, kind, name)\n      const label = `${field === \"utilities\" ? \"@utility\" : \"@custom-variant\"} ${name}`\n\n      const result = await merge({\n        local: local && ruleSource(local),\n        remote: remoteSource,\n        base: baseSource,\n        options,\n        kind,\n        name,\n        label,\n        warnings,\n        add: (source) => appendRule(root, kind, source),\n        replace: (source) => {\n          const next = parseRule(source)\n          next.raws.before = local?.raws.before ?? \"\"\n          local?.replaceWith(next)\n        },\n        remove: () => local?.remove(),\n      })\n      if (result) {\n        changes.push({ kind, name, action: result })\n      }\n    }\n  }\n\n  return { css: root.toString(), changes, warnings }\n}\n\n// Aplica as declarações de base de um item no `@layer base`, com merge por\n// seletor e propriedade.\nexport async function applyBaseRules(\n  css: string,\n  remote: CssRules[\"base\"] = {},\n  options: ApplyCssRulesOptions = {},\n): Promise<CssRulesResult> {\n  const root = postcss.parse(css)\n  const changes: CssRuleChange[] = []\n  const warnings: string[] = []\n  const previous = options.base?.base ?? {}\n\n  const selectors = new Set([...Object.keys(remote), ...Object.keys(previous)])\n  for (const selector of selectors) {\n    const remoteDecls = remote[selector] ?? {}\n    const baseDecls = previous[selector] ?? {}\n    const props = new Set([\n      ...Object.keys(remoteDecls),\n      ...Object.keys(baseDecls),\n    ])\n\n    for (const prop of props) {\n      const layer = findBaseLayer(root)\n      let rule = layer && findRuleBySelector(layer, selector)\n      const declaration = rule?.nodes.find(\n        (node) => node.type === \"decl\" && node.prop === prop,\n      ) as postcss.Declaration | undefined\n      const name = `${selector} { ${prop} }`\n\n      const result = await merge({\n        local: declaration?.value,\n        remote: remoteDecls[prop],\n        base: baseDecls[prop],\n        options,\n        kind: \"base\",\n        name,\n        label: `${prop} in ${selector}`,\n        warnings,\n        add: (value) => {\n          rule ??= appendBaseRule(root, selector)\n          rule.append(postcss.decl({ prop, value, raws: { before: \"\\n    \" } }))\n        },\n        replace: (value) => {\n          if (declaration) {\n            declaration.value = value\n          }\n        },\n        remove: () => {\n          declaration?.remove()\n          if (rule?.nodes.length === 0) {\n            rule.remove()\n          }\n        },\n      })\n      if (result) {\n        changes.push({ kind: \"base\", name, action: result })\n      }\n    }\n  }\n\n  return { css: root.toString(), changes, warnings }\n}\n\n// Mesmas regras do merge das variáveis (`applyCssVars`).\nasync function merge({\n  local,\n  remote,\n  base,\n  options,\n  kind,\n  name,\n  label,\n  warnings,\n  add,\n  replace,\n  remove,\n}: {\n  local: string | undefined\n  remote: string | undefined\n  base: string | undefined\n  options: ApplyCssRulesOptions\n  kind: CssRuleKind\n  name: string\n  label: string\n  warnings: string[]\n  add: (value: string) => void\n  replace: (value: string) => void\n  remove: () => void\n}): Promise<CssRuleChange[\"action\"] | undefined> {\n  if (remote === undefined) {\n    // Removida na versão nova.\n    if (local === undefined) {\n      return undefined\n    }\n    if (options.shouldRemove && (await options.shouldRemove(kind, name))) {\n      remove()\n      return \"removed\"\n    }\n    warnings.push(`${label} was removed in the new version; kept in the CSS.`)\n    return \"kept\"\n  }\n\n  if (local === undefined) {\n    if (base !== undefined) {\n      // Apagada pelo usuário: não recria.\n      return \"kept\"\n    }\n    add(remote)\n    return \"added\"\n  }\n\n  if (same(local, remote)) {\n    return \"unchanged\"\n  }\n  if (options.overwrite || (base !== undefined && same(local, base))) {\n    replace(remote)\n    return \"updated\"\n  }\n  warnings.push(`${label} was changed in the CSS; kept instead of the new one.`)\n  return \"kept\"\n}\n\nfunction findRule(\n  root: Root,\n  kind: \"utility\" | \"variant\",\n  name: string,\n): AtRule | undefined {\n  return root.nodes.find(\n    (node): node is AtRule =>\n      node.type === \"atrule\" &&\n      node.name === AT_RULE[kind] &&\n      ruleName(node) === name,\n  )\n}\n\n// Variantes antes das utilities: uma utility pode usar uma variante.\nfunction appendRule(root: Root, kind: \"utility\" | \"variant\", source: string) {\n  const rule = parseRule(source)\n  const lastVariant = root.nodes.findLast(\n    (node) => node.type === \"atrule\" && node.name === AT_RULE.variant,\n  )\n  if (kind === \"variant\") {\n    const firstUtility = root.nodes.find(\n      (node) => node.type === \"atrule\" && node.name === AT_RULE.utility,\n    )\n    if (lastVariant) {\n      rule.raws.before = \"\\n\"\n      lastVariant.after(rule)\n      return\n    }\n    if (firstUtility) {\n      rule.raws.before = firstUtility.raws.before ?? \"\"\n      firstUtility.raws.before = \"\\n\\n\"\n      firstUtility.before(rule)\n      return\n    }\n  }\n  rule.raws.before = root.nodes.length > 0 ? \"\\n\\n\" : \"\"\n  root.append(rule)\n  root.raws.after = \"\\n\"\n}\n\nfunction parseRule(source: string): AtRule {\n  const node = postcss.parse(source.trim()).first\n  if (node?.type !== \"atrule\") {\n    throw new Error(`Not a CSS at-rule: ${source}`)\n  }\n  return node\n}\n\n// Texto da regra sem os espaços de antes (é o que vai para o item publicado).\nfunction ruleSource(rule: AtRule): string {\n  const clone = rule.clone()\n  clone.raws.before = \"\"\n  // Sem bloco (`@custom-variant x (…);`), o `;` é do pai: vai junto.\n  return clone.nodes === undefined ? `${clone.toString()};` : clone.toString()\n}\n\nfunction findBaseLayer(root: Root): Container | undefined {\n  return root.nodes.find(\n    (node) =>\n      node.type === \"atrule\" &&\n      node.name === \"layer\" &&\n      node.params.trim() === \"base\",\n  ) as Container | undefined\n}\n\nfunction findRuleBySelector(\n  layer: Container,\n  selector: string,\n): Rule | undefined {\n  return layer.nodes?.find(\n    (node): node is Rule =>\n      node.type === \"rule\" &&\n      normalizeSelector(node.selector) === normalizeSelector(selector),\n  )\n}\n\nfunction appendBaseRule(root: Root, selector: string): Rule {\n  let layer = findBaseLayer(root)\n  if (layer === undefined) {\n    layer = postcss.atRule({ name: \"layer\", params: \"base\" })\n    layer.raws = {\n      before: root.nodes.length > 0 ? \"\\n\\n\" : \"\",\n      between: \" \",\n      after: \"\\n\",\n    }\n    root.append(layer)\n    root.raws.after = \"\\n\"\n  }\n  const rule = postcss.rule({ selector })\n  rule.raws = {\n    before: (layer.nodes?.length ?? 0) > 0 ? \"\\n\\n  \" : \"\\n  \",\n    between: \" \",\n    after: \"\\n  \",\n    semicolon: true,\n  }\n  layer.append(rule)\n  layer.raws.after = \"\\n\"\n  return rule\n}\n\n// Compara seletores sem os espaços (`a > b` = `a>b`) e sem as aspas.\nconst normalizeSelector = (selector: string) => selector.replace(/[\"'\\s]/g, \"\")\n\nfunction same(a: string, b: string) {\n  const normalize = (value: string) =>\n    value\n      .replace(/\\s+/g, \" \")\n      .replace(/\\s*([{};:,])\\s*/g, \"$1\")\n      .replace(/;}/g, \"}\")\n      .replace(/;$/, \"\")\n      .trim()\n  return normalize(a) === normalize(b)\n}\n","import postcss, { type AtRule, type Root } from \"postcss\"\n\nimport { isThemeName, THEME_ATTRIBUTE } from \"./attribute\"\nimport { findBlock } from \"./css\"\n\nexport type UnsetTokens = Partial<Record<\"light\" | \"dark\", string[]>>\n\nconst VAR_NAME = /^[\\w-]+$/\n\n// Tira variáveis dos blocos (`:root`/`.dark` ou os de um tema): num tema, a\n// variável volta a vir do CSS global.\nexport function removeTokens(\n  css: string,\n  unset: UnsetTokens,\n  { theme }: { theme?: string } = {},\n): string {\n  const root = postcss.parse(css)\n  for (const group of [\"light\", \"dark\"] as const) {\n    const names = new Set(\n      (unset[group] ?? []).filter((name) => VAR_NAME.test(name)),\n    )\n    if (names.size === 0) {\n      continue\n    }\n    findBlock(root, group, theme)?.each((node) => {\n      if (node.type === \"decl\" && names.has(node.prop.slice(2))) {\n        node.remove()\n      }\n    })\n  }\n  return root.toString()\n}\n\n// Conteúdo inicial do arquivo de um tema novo.\nexport function themeFileHeader(name: string): string {\n  return `/* Tema \"${name}\": só o que muda em relação ao CSS global. Aplicado com\n   <html ${THEME_ATTRIBUTE}=\"${name}\"> ou SLABUI_THEME=${name}. */\n`\n}\n\n// Troca o nome do tema nos seletores do arquivo\n// (`[data-slabui-theme=\"a\"]` → `[data-slabui-theme=\"b\"]`).\nexport function renameThemeSelectors(\n  css: string,\n  from: string,\n  to: string,\n): string {\n  if (!isThemeName(from) || !isThemeName(to)) {\n    throw new Error(`Invalid theme name: \"${from}\" → \"${to}\"`)\n  }\n  const pattern = new RegExp(\n    `\\\\[${THEME_ATTRIBUTE}\\\\s*=\\\\s*([\"']?)${from}\\\\1\\\\s*\\\\]`,\n    \"g\",\n  )\n  const root = postcss.parse(css)\n  root.walkRules((rule) => {\n    rule.selector = rule.selector.replace(\n      pattern,\n      `[${THEME_ATTRIBUTE}=\"${to}\"]`,\n    )\n  })\n  root.walkComments((comment) => {\n    comment.text = comment.text\n      .replaceAll(`\"${from}\"`, `\"${to}\"`)\n      .replaceAll(`SLABUI_THEME=${from}`, `SLABUI_THEME=${to}`)\n  })\n  return root.toString()\n}\n\n// Caminho de um `@import \"x\"` ou `@import url(\"x\")`.\nfunction importPath(rule: AtRule) {\n  return rule.params\n    .trim()\n    .replace(/^url\\((.*)\\)/, \"$1\")\n    .split(/\\s/)[0]\n    ?.replace(/^[\"']|[\"']$/g, \"\")\n}\n\nconst sameImport = (a: string | undefined, b: string) =>\n  a !== undefined && a.replace(/^\\.\\//, \"\") === b.replace(/^\\.\\//, \"\")\n\nfunction imports(root: Root) {\n  return root.nodes.filter(\n    (node): node is AtRule => node.type === \"atrule\" && node.name === \"import\",\n  )\n}\n\n// Caminhos dos `@import` locais (`./x.css`, `../x.css`) de um CSS.\nexport function localImports(css: string): string[] {\n  return imports(postcss.parse(css))\n    .map(importPath)\n    .filter(\n      (target): target is string =>\n        target?.startsWith(\"./\") === true || target?.startsWith(\"../\") === true,\n    )\n}\n\n// `@import` do tema no CSS global, depois dos outros imports.\nexport function addThemeImport(css: string, path: string): string {\n  return addImport(css, path)\n}\n\n// `@import \"<path>\"` no CSS, depois dos outros imports, se ainda não houver\n// (`./base.css` e `base.css` são o mesmo).\nexport function addImport(css: string, path: string): string {\n  const root = postcss.parse(css)\n  const existing = imports(root)\n  if (existing.some((rule) => sameImport(importPath(rule), path))) {\n    return css\n  }\n  const rule = postcss.atRule({ name: \"import\", params: `\"${path}\"` })\n  const last = existing.at(-1)\n  if (last) {\n    rule.raws = { before: \"\\n\" }\n    last.after(rule)\n  } else {\n    rule.raws = { before: \"\" }\n    root.prepend(rule)\n  }\n  return root.toString()\n}\n\nexport function removeThemeImport(css: string, path: string): string {\n  const root = postcss.parse(css)\n  for (const rule of imports(root)) {\n    if (sameImport(importPath(rule), path)) {\n      rule.remove()\n    }\n  }\n  return root.toString()\n}\n\nexport function renameThemeImport(css: string, from: string, to: string) {\n  const root = postcss.parse(css)\n  for (const rule of imports(root)) {\n    if (sameImport(importPath(rule), from)) {\n      rule.params = `\"${to}\"`\n    }\n  }\n  return root.toString()\n}\n","import {\n  addImport as addThemeImport,\n  applyBaseRules as applyThemeBaseRules,\n  applyCssRules as applyThemeCssRules,\n  applyCssVars as applyThemeVars,\n} from \"@slabui/theme-core\"\n\nimport type { CssRules, CssVars } from \"./schemas/item\"\n\ntype Group = \"theme\" | \"light\" | \"dark\"\n\n// Os mesmos tipos do `@slabui/theme-core`, declarados aqui: os tipos publicados do\n// registry não apontam para o pacote, que vai embutido no build.\nexport type CssVarChange = {\n  group: Group\n  name: string\n  action: \"added\" | \"updated\" | \"kept\" | \"removed\" | \"unchanged\"\n}\n\nexport type CssVarsResult = {\n  css: string\n  changes: CssVarChange[]\n  warnings: string[]\n}\n\nexport type ApplyCssVarsOptions = {\n  base?: CssVars\n  overwrite?: boolean\n  shouldRemove?: (group: Group, name: string) => Promise<boolean>\n}\n\n// O merge das variáveis no CSS global vem do `@slabui/theme-core`.\nexport const applyCssVars: (\n  css: string,\n  remote: CssVars,\n  options?: ApplyCssVarsOptions,\n) => Promise<CssVarsResult> = applyThemeVars\n\nexport type CssRuleKind = \"utility\" | \"variant\" | \"base\"\n\nexport type CssRuleChange = {\n  kind: CssRuleKind\n  name: string\n  action: CssVarChange[\"action\"]\n}\n\nexport type CssRulesResult = {\n  css: string\n  changes: CssRuleChange[]\n  warnings: string[]\n}\n\nexport type ApplyCssRulesOptions = {\n  base?: CssRules\n  overwrite?: boolean\n  shouldRemove?: (kind: CssRuleKind, name: string) => Promise<boolean>\n}\n\n// O merge das `@utility`/`@custom-variant` (pelo nome) e das declarações de\n// base (por seletor e propriedade) também vem do `@slabui/theme-core`.\nexport const applyCssRules: (\n  css: string,\n  remote: Pick<CssRules, \"utilities\" | \"variants\">,\n  options?: ApplyCssRulesOptions,\n) => Promise<CssRulesResult> = applyThemeCssRules\n\nexport const applyBaseRules: (\n  css: string,\n  remote: CssRules[\"base\"],\n  options?: ApplyCssRulesOptions,\n) => Promise<CssRulesResult> = applyThemeBaseRules\n\nexport const addImport: (css: string, path: string) => string = addThemeImport\n\n// \"CSS rules: 1 added, 1 kept.\" (utilities, variantes e base).\nexport function summarizeRules(changes: CssRuleChange[]): string | undefined {\n  const parts = ([\"added\", \"updated\", \"kept\", \"removed\"] as const).flatMap(\n    (action) => {\n      const count = changes.filter((change) => change.action === action).length\n      return count === 0 ? [] : [`${count} ${action}`]\n    },\n  )\n  return parts.length === 0 ? undefined : `CSS rules: ${parts.join(\", \")}.`\n}\n\n// \"CSS: 3 variáveis adicionadas, 1 atualizada, 1 mantida\" (sem as inalteradas).\nexport function summarizeCss(changes: CssVarChange[]): string | undefined {\n  const labels: [CssVarChange[\"action\"], string, string][] = [\n    [\"added\", \"added\", \"added\"],\n    [\"updated\", \"updated\", \"updated\"],\n    [\"kept\", \"kept\", \"kept\"],\n    [\"removed\", \"removed\", \"removed\"],\n  ]\n  const parts = labels.flatMap(([action, one, many]) => {\n    const count = changes.filter((change) => change.action === action).length\n    return count === 0 ? [] : [`${count} ${count === 1 ? one : many}`]\n  })\n  return parts.length === 0 ? undefined : `CSS variables: ${parts.join(\", \")}.`\n}\n","import { defaultTheme } from \"@slabui/theme-core\"\n\nimport type { CssVars } from \"./schemas/item\"\n\n// Templates dos CSS que o `init` cria (ou completa) e que o `add` e o\n// `update` usam quando faltam. O CSS fica em três arquivos, na mesma pasta:\n//\n// - o CSS global (`globals.css`): o tema, com as variáveis em `:root`,\n//   `.dark` e `@theme inline`. É o arquivo que o editor de tema grava.\n// - `base.css`: regras de elemento (`*`, `body`) no `@layer base`.\n// - `utilities.css`: `@utility` e `@custom-variant` dos componentes.\n//\n// O CSS global importa os outros dois. Cada `slabui add` acrescenta o que o\n// item usa: as variáveis no global, as utilities e as variantes no\n// `utilities.css` e as declarações de base no `base.css`.\n\nexport const BASE_FILE = \"base.css\"\nexport const UTILITIES_FILE = \"utilities.css\"\n\n// Só para arquivo novo: as variáveis vêm depois, do tema.\nexport const CSS_GLOBALS = `@import \"tailwindcss\";\n@import \"./${BASE_FILE}\";\n@import \"./${UTILITIES_FILE}\";\n`\n\nexport const BASE_HEADER = `/* Element styles (*, html, body), imported by the global CSS. The theme\n   variables stay in the global CSS; components add here what they need in\n   the whole app. */\n`\n\n// Só quando o CSS global é novo: num CSS que já existe, o `@layer base` dele\n// continua valendo.\nexport const CSS_BASE = `${BASE_HEADER}\n@layer base {\n  * {\n    @apply border-border outline-ring/50;\n    scrollbar-width: thin;\n    scrollbar-color: var(--scrollbar-thumb) transparent;\n  }\n\n  *::-webkit-scrollbar {\n    width: 8px;\n    height: 8px;\n  }\n\n  *::-webkit-scrollbar-thumb {\n    background-color: var(--scrollbar-thumb);\n    border-radius: 9999px;\n    border: 2px solid transparent;\n    background-clip: content-box;\n  }\n\n  *::-webkit-scrollbar-track {\n    background-color: transparent;\n  }\n\n  body {\n    @apply bg-background text-foreground;\n    -webkit-font-smoothing: antialiased;\n    font-synthesis-weight: none;\n    text-rendering: optimizeLegibility;\n  }\n}\n`\n\nexport const UTILITIES_HEADER = `/* @utility and @custom-variant, imported by the global CSS. slabui add\n   adds the ones components use; the ones you change are kept as they are. */\n`\n\nexport const CSS_UTILITIES = `${UTILITIES_HEADER}\n@utility no-scrollbar {\n  -ms-overflow-style: none;\n  scrollbar-width: none;\n\n  &::-webkit-scrollbar {\n    display: none;\n  }\n}\n`\n\n// Variáveis que o `init` grava: o raio, o espaçamento e só as cores que o\n// `base.css` usa, com o `@theme inline` delas (e as fontes e os tamanhos de\n// texto, que não dependem de variáveis do tema). Cada\n// componente acrescenta as dele no `add`, com os valores do tema padrão.\nexport const TEMPLATE_TOKENS = [\n  \"background\",\n  \"foreground\",\n  \"border\",\n  \"input\",\n  \"ring\",\n  \"radius\",\n  \"spacing\",\n  \"scrollbar-thumb\",\n] as const\n\nexport const CSS_TEMPLATE_VARS: CssVars = themeSubset(TEMPLATE_TOKENS)\n\n// O tema padrão só com as variáveis pedidas (em `:root` e `.dark`). Uma\n// entrada do `@theme inline` depende das variáveis de `:root`/`.dark` que ela\n// cita (`--radius-lg: var(--radius)`, `--focus-size: calc(var(--focus-size))`)\n// e só entra com todas elas: sem o valor, a entrada fica inválida. Com\n// `theme: \"all\"` (o `init`), vão também as que não citam nenhuma (fontes,\n// tamanhos de texto); com `\"aliases\"` (o `add`), só as que citam alguma\n// variável pedida. O `--color-<nome>` de cada cor sai das cores, na gravação.\nexport function themeSubset(\n  tokens: readonly string[],\n  { theme: mode = \"all\" }: { theme?: \"all\" | \"aliases\" } = {},\n): CssVars {\n  const names = new Set(tokens)\n  const pick = (group: Record<string, string>) =>\n    Object.fromEntries(\n      Object.entries(group).filter(([name]) => names.has(name)),\n    )\n  const themeVars = new Set([\n    ...Object.keys(defaultTheme.light),\n    ...Object.keys(defaultTheme.dark),\n  ])\n  const theme = Object.fromEntries(\n    Object.entries(defaultTheme.theme).filter(([, value]) => {\n      const uses = [...value.matchAll(/var\\(--([\\w-]+)/g)]\n        .map(([, name]) => name as string)\n        .filter((name) => themeVars.has(name))\n      if (!uses.every((name) => names.has(name))) {\n        return false\n      }\n      return mode === \"all\" || uses.length > 0\n    }),\n  )\n  return {\n    theme,\n    light: pick(defaultTheme.light),\n    dark: pick(defaultTheme.dark),\n  }\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { CssRules, CssVars } from \"../schemas/item\"\n\nimport {\n  type ApplyCssRulesOptions,\n  addImport,\n  applyBaseRules,\n  applyCssRules,\n  applyCssVars,\n  type CssRuleChange,\n  type CssVarChange,\n} from \"../css\"\nimport {\n  BASE_FILE,\n  BASE_HEADER,\n  CSS_BASE,\n  CSS_GLOBALS,\n  CSS_TEMPLATE_VARS,\n  CSS_UTILITIES,\n  themeSubset,\n  UTILITIES_FILE,\n  UTILITIES_HEADER,\n} from \"../css-template\"\nimport { resolveProjectPath } from \"../paths\"\n\nexport type TemplateResult = {\n  created: boolean\n  changes: CssVarChange[]\n  // `base.css` e `utilities.css` criados agora, relativos à raiz.\n  files: string[]\n}\n\n// Cria o CSS global com o template ou, se ele existe, acrescenta as variáveis\n// do template que faltam (mantém as que já estão lá). Cria também o\n// `utilities.css` e, num CSS global novo, o `base.css`, ao lado dele.\nexport async function applyCssTemplate(\n  root: string,\n  file: string,\n): Promise<TemplateResult> {\n  const absolute = await resolveProjectPath(root, file)\n  const current = await readFile(absolute, \"utf8\").catch(() => undefined)\n  const result = await applyCssVars(current ?? CSS_GLOBALS, CSS_TEMPLATE_VARS)\n  if (current === undefined || result.css !== current) {\n    await mkdir(path.dirname(absolute), { recursive: true })\n    await writeFile(absolute, result.css)\n  }\n\n  const files: string[] = []\n  if (await ensureSideFile(root, file, UTILITIES_FILE, CSS_UTILITIES)) {\n    files.push(sibling(file, UTILITIES_FILE))\n  }\n  // Um CSS que já existe tem o `@layer base` dele: não ganha outro.\n  if (\n    current === undefined &&\n    (await ensureSideFile(root, file, BASE_FILE, CSS_BASE))\n  ) {\n    files.push(sibling(file, BASE_FILE))\n  }\n  return { created: current === undefined, changes: result.changes, files }\n}\n\n// Aplica as variáveis CSS de um item no `css` do slabui.json. Se o arquivo\n// não existe, cria com o template antes.\nexport async function updateStylesheet(\n  root: string,\n  file: string | undefined,\n  key: string,\n  vars: CssVars,\n  options: Parameters<typeof applyCssVars>[2] & { warnings: string[] },\n): Promise<CssVarChange[]> {\n  if (file === undefined) {\n    options.warnings.push(\n      `\"${key}\": has CSS variables, but \"css\" is not set in slabui.json; add them to your CSS manually.`,\n    )\n    return []\n  }\n  const current = await readGlobals(root, file, options.warnings)\n\n  const result = await applyCssVars(current, vars, options)\n  options.warnings.push(\n    ...result.warnings.map((warning) => `\"${key}\": ${warning}`),\n  )\n  if (result.css !== current) {\n    await writeFile(await resolveProjectPath(root, file), result.css)\n  }\n  return result.changes\n}\n\n// Variáveis do tema padrão que o item usa (os `tokens` do índice) e faltam\n// no CSS global: o `init` cria só o mínimo, e cada componente traz as dele.\n// Nunca troca um valor que já está no CSS.\nexport async function addThemeTokens(\n  root: string,\n  file: string | undefined,\n  key: string,\n  tokens: string[] | undefined,\n  warnings: string[],\n): Promise<CssVarChange[]> {\n  if (file === undefined || tokens === undefined || tokens.length === 0) {\n    return []\n  }\n  const vars = themeSubset(tokens, { theme: \"aliases\" })\n  // Um valor diferente do padrão é o tema do projeto: sem aviso.\n  const local: string[] = []\n  const changes = await updateStylesheet(root, file, key, vars, {\n    overwrite: false,\n    warnings: local,\n  })\n  warnings.push(...local.filter((warning) => !warning.includes(\"custom value\")))\n  return changes.filter(({ action }) => action === \"added\")\n}\n\n// Aplica as regras de CSS de um item: as `@utility` e `@custom-variant` no\n// `utilities.css` e as declarações de base no `base.css`, ao lado do CSS\n// global (criados, e importados por ele, quando faltam).\nexport async function updateCssRules(\n  root: string,\n  file: string | undefined,\n  key: string,\n  rules: CssRules,\n  options: Omit<ApplyCssRulesOptions, \"base\"> & {\n    base?: CssRules\n    warnings: string[]\n  },\n): Promise<CssRuleChange[]> {\n  const { warnings, ...merge } = options\n  const wanted = (field: keyof CssRules) =>\n    Object.keys(rules[field] ?? {}).length > 0 ||\n    Object.keys(options.base?.[field] ?? {}).length > 0\n  const hasRules = wanted(\"utilities\") || wanted(\"variants\")\n  const hasBase = wanted(\"base\")\n  if (!hasRules && !hasBase) {\n    return []\n  }\n  if (file === undefined) {\n    warnings.push(\n      `\"${key}\": has CSS rules (@utility, @custom-variant or base), but \"css\" is not set in slabui.json; add them to your CSS manually.`,\n    )\n    return []\n  }\n  await readGlobals(root, file, warnings)\n\n  const changes: CssRuleChange[] = []\n  const apply = async (\n    name: string,\n    header: string,\n    run: (css: string) => ReturnType<typeof applyCssRules>,\n  ) => {\n    await ensureSideFile(root, file, name, header)\n    const absolute = await resolveProjectPath(root, sibling(file, name))\n    const current = await readFile(absolute, \"utf8\")\n    const result = await run(current)\n    warnings.push(...result.warnings.map((warning) => `\"${key}\": ${warning}`))\n    if (result.css !== current) {\n      await writeFile(absolute, result.css)\n    }\n    changes.push(...result.changes)\n  }\n\n  if (hasRules) {\n    await apply(UTILITIES_FILE, UTILITIES_HEADER, (css) =>\n      applyCssRules(css, rules, merge),\n    )\n  }\n  if (hasBase) {\n    await apply(BASE_FILE, BASE_HEADER, (css) =>\n      applyBaseRules(css, rules.base, merge),\n    )\n  }\n  return changes\n}\n\n// O CSS global; se não existe, cria com o template antes.\nasync function readGlobals(root: string, file: string, warnings: string[]) {\n  const absolute = await resolveProjectPath(root, file)\n  const current = await readFile(absolute, \"utf8\").catch(() => undefined)\n  if (current !== undefined) {\n    return current\n  }\n  await applyCssTemplate(root, file)\n  warnings.push(\n    `${file} did not exist; it was created with the default template.`,\n  )\n  return readFile(absolute, \"utf8\")\n}\n\n// Cria `<pasta do CSS global>/<name>` com `content`, se não existe, e garante\n// o `@import` dele no CSS global. Devolve se o arquivo foi criado.\nasync function ensureSideFile(\n  root: string,\n  globals: string,\n  name: string,\n  content: string,\n): Promise<boolean> {\n  const absolute = await resolveProjectPath(root, sibling(globals, name))\n  const exists = await readFile(absolute, \"utf8\")\n    .then(() => true)\n    .catch(() => false)\n  if (!exists) {\n    await mkdir(path.dirname(absolute), { recursive: true })\n    await writeFile(absolute, content)\n  }\n\n  const globalsFile = await resolveProjectPath(root, globals)\n  const css = await readFile(globalsFile, \"utf8\")\n  const next = addImport(css, `./${name}`)\n  if (next !== css) {\n    await writeFile(globalsFile, next)\n  }\n  return !exists\n}\n\nfunction sibling(file: string, name: string) {\n  return path.posix.join(path.posix.dirname(file.replaceAll(\"\\\\\", \"/\")), name)\n}\n","import { mkdir, writeFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { CssRuleChange, CssVarChange } from \"../css\"\nimport type { ResolvedRegistry } from \"../resolve\"\n\nimport { createRegistryClient, type RegistryClient } from \"../client\"\nimport { DEFAULT_REGISTRY } from \"../constants\"\nimport { SlabUIError } from \"../errors\"\nimport { resolveProjectPath } from \"../paths\"\nimport {\n  exists,\n  loadTsconfig,\n  readConfig,\n  resolveCssFile,\n  writeConfig,\n} from \"../project\"\nimport {\n  addInstalledDependencies,\n  type Destinations,\n  isBlock,\n  itemDestinations,\n  type MaterializeContext,\n  materializeFile,\n} from \"./materialize\"\nimport { installPackages } from \"./npm\"\nimport { planInstall } from \"./plan\"\nimport { addThemeTokens, updateCssRules, updateStylesheet } from \"./styles\"\n\nexport type AddOptions = {\n  root: string\n  refs: string[]\n  overwrite?: boolean\n  skipInstall?: boolean\n  // Ausente fora do modo interativo: o add não pergunta.\n  confirm?: (message: string) => Promise<boolean>\n  // Pasta (relativa à raiz) de blocks e examples; sem ela, `askPath` pergunta.\n  path?: string\n  askPath?: (items: string[]) => Promise<string>\n  createClient?: (registry: ResolvedRegistry) => RegistryClient\n}\n\nexport type AddResult = {\n  // `block`: block ou example, gravado no --path e fora de `items`.\n  added: { key: string; version: string; files: string[]; block: boolean }[]\n  installed: string[]\n  packages: string[]\n  // Variáveis CSS aplicadas no `css` do slabui.json.\n  cssChanges: CssVarChange[]\n  // `@utility`, `@custom-variant` e base (`utilities.css` e `base.css`).\n  ruleChanges: CssRuleChange[]\n  // Licença de cada registry instalado pela primeira vez no projeto.\n  licenses: { namespace: string; url: string }[]\n  warnings: string[]\n}\n\nexport async function addItems({\n  root,\n  refs,\n  overwrite = false,\n  skipInstall = false,\n  confirm,\n  path: blockPath,\n  askPath,\n  createClient = (registry) => createRegistryClient(registry),\n}: AddOptions): Promise<AddResult> {\n  const config = await readConfig(root)\n  const tsconfig = await loadTsconfig(root)\n  const context: MaterializeContext = {\n    root,\n    aliases: config.aliases,\n    tsconfig,\n    css: resolveCssFile(tsconfig, root, config.css),\n  }\n  const clients = new Map<string, RegistryClient>()\n  const clientFor = (registry: ResolvedRegistry) => {\n    let client = clients.get(registry.namespace)\n    if (client === undefined) {\n      client = createClient(registry)\n      clients.set(registry.namespace, client)\n    }\n    return client\n  }\n  // A licença do registry aparece no primeiro add do projeto.\n  const firstInstall = Object.keys(config.items).length === 0\n\n  const plan = await planInstall({ refs, config, createClient: clientFor })\n  const warnings = [...plan.warnings]\n\n  // Blocks e examples vão para o --path, preservando a estrutura dos arquivos.\n  const blocks = plan.items.filter(({ item }) => isBlock(item))\n  let targetDir = blockPath\n  if (blocks.length > 0 && targetDir === undefined) {\n    const names = blocks.map(({ key }) => key)\n    if (askPath === undefined) {\n      throw new SlabUIError(\n        `${names.map((name) => `\"${name}\"`).join(\", \")} ${names.length > 1 ? \"are blocks or examples\" : \"is a block or example\"}: pass the folder with --path.`,\n      )\n    }\n    targetDir = await askPath(names)\n  }\n\n  // Destino de cada arquivo publicado, por item (chave do slabui.json).\n  const destinations: Destinations = new Map()\n  for (const { key, item } of plan.items) {\n    destinations.set(key, itemDestinations(item, context, targetDir))\n  }\n\n  // Dependências já instaladas: o destino vem da versão instalada.\n  await addInstalledDependencies(\n    plan.items.map(({ item }) => item),\n    { config, context, destinations, clientFor },\n  )\n\n  // Arquivos que já existem no projeto.\n  const owners = new Map<string, string>()\n  for (const [key, installed] of Object.entries(config.items)) {\n    for (const file of installed.files) {\n      owners.set(file, key)\n    }\n  }\n  const existing: string[] = []\n  for (const { key } of plan.items) {\n    for (const destination of destinations.get(key)?.values() ?? []) {\n      await resolveProjectPath(root, destination)\n      if (await exists(path.join(root, destination))) {\n        const owner = owners.get(destination)\n        existing.push(owner ? `${destination} (from \"${owner}\")` : destination)\n      }\n    }\n  }\n  if (existing.length > 0 && !overwrite) {\n    const list = existing.map((file) => `  ${file}`).join(\"\\n\")\n    const accepted = confirm\n      ? await confirm(\n          `These files already exist and will be overwritten:\\n${list}\\nContinue?`,\n        )\n      : false\n    if (!accepted) {\n      throw new SlabUIError(\n        `These files already exist in the project:\\n${list}\\nUse --overwrite to overwrite them.`,\n      )\n    }\n  }\n\n  const added: AddResult[\"added\"] = []\n  const cssChanges: CssVarChange[] = []\n  const ruleChanges: CssRuleChange[] = []\n  for (const { key, item, registry } of plan.items) {\n    const own = destinations.get(key) as Map<string, string>\n\n    for (const file of item.files) {\n      const destination = own.get(file.path) as string\n      const content = materializeFile(file, {\n        key,\n        item,\n        destination,\n        destinations,\n        context,\n        warnings,\n      })\n\n      const absolute = await resolveProjectPath(root, destination)\n      await mkdir(path.dirname(absolute), { recursive: true })\n      await writeFile(absolute, content)\n    }\n\n    // Variáveis do tema padrão que o item usa e faltam no CSS (só do registry\n    // padrão: os tokens de outro registry são do tema dele).\n    if (registry.namespace === DEFAULT_REGISTRY.namespace) {\n      const tokens = (await clientFor(registry).index()).items[item.name]\n        ?.tokens\n      cssChanges.push(\n        ...(await addThemeTokens(root, context.css, key, tokens, warnings)),\n      )\n    }\n    if (item.cssVars !== undefined) {\n      cssChanges.push(\n        ...(await updateStylesheet(root, context.css, key, item.cssVars, {\n          overwrite,\n          warnings,\n        })),\n      )\n    }\n    if (item.css !== undefined) {\n      ruleChanges.push(\n        ...(await updateCssRules(root, context.css, key, item.css, {\n          overwrite,\n          warnings,\n        })),\n      )\n    }\n\n    const files = [...own.values()]\n    if (!isBlock(item)) {\n      config.items[key] = { version: item.version, files }\n    }\n    added.push({ key, version: item.version, files, block: isBlock(item) })\n  }\n  await writeConfig(root, config)\n\n  const packages = await installPackages(\n    root,\n    {\n      npm: plan.items.flatMap(({ item }) => item.dependencies.npm),\n      npmDev: plan.items.flatMap(({ item }) => item.dependencies.npmDev),\n    },\n    { confirm, skipInstall, warnings },\n  )\n\n  const licenses: AddResult[\"licenses\"] = []\n  const registry = plan.items[0]?.registry\n  if (firstInstall && registry !== undefined) {\n    const url = (await clientFor(registry).index()).license\n    if (url !== undefined) {\n      licenses.push({ namespace: registry.namespace, url })\n    }\n  }\n\n  return {\n    added,\n    installed: plan.installed,\n    packages,\n    cssChanges,\n    ruleChanges,\n    licenses,\n    warnings,\n  }\n}\n","import { readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport semver from \"semver\"\n\nimport type { RegistryClient } from \"../client\"\nimport type { Config } from \"../schemas/config\"\nimport type { Item } from \"../schemas/item\"\nimport type { RegistryEntry } from \"../schemas/registry\"\n\nimport { SlabUIError } from \"../errors\"\nimport {\n  type ItemRef,\n  parseItemRef,\n  type ResolvedRegistry,\n  resolveRegistry,\n  resolveVersion,\n} from \"../resolve\"\nimport {\n  addInstalledDependencies,\n  type Destinations,\n  itemDestinations,\n  type MaterializeContext,\n  materializeFile,\n} from \"./materialize\"\n\n// Um arquivo do item nas três versões, já como o add o gravaria. `undefined`\n// quando o arquivo não existe naquela versão (ou no disco, para `local`).\nexport type FileComparison = {\n  destination: string\n  base?: string\n  remote?: string\n  local?: string\n}\n\nexport type ItemComparison = {\n  key: string\n  registry: ResolvedRegistry\n  base: Item\n  remote: Item\n  files: FileComparison[]\n  // Major mais nova que a escolhida, quando existe e não foi pedida.\n  newerMajor?: string\n  warnings: string[]\n}\n\n// Versão para a qual atualizar: a pedida (exata ou intervalo); sem pedido, a\n// mais recente da major instalada, ou a mais recente de todas com `major`.\nexport function chooseVersion(\n  entry: RegistryEntry,\n  installed: string,\n  ref: ItemRef,\n  major = false,\n): { version: string; newerMajor?: string } {\n  if (ref.range !== undefined) {\n    return { version: resolveVersion(ref, entry) }\n  }\n  if (major) {\n    return { version: entry.latest }\n  }\n  const sameMajor = resolveVersion(\n    { ...ref, range: `${semver.major(installed)}.x` },\n    {\n      ...entry,\n      versions: { ...entry.versions, [installed]: { hash: \"\", path: \"\" } },\n    },\n  )\n  const version = semver.gt(installed, sameMajor) ? installed : sameMajor\n  return {\n    version,\n    newerMajor:\n      semver.major(entry.latest) > semver.major(version)\n        ? entry.latest\n        : undefined,\n  }\n}\n\nexport async function compareItem({\n  key,\n  version,\n  major,\n  config,\n  context,\n  clientFor,\n}: {\n  // Chave do item em `items`, com versão opcional (`button@2`).\n  key: string\n  version?: string\n  major?: boolean\n  config: Pick<Config, \"items\" | \"token\">\n  context: MaterializeContext\n  clientFor: (registry: ResolvedRegistry) => RegistryClient\n}): Promise<ItemComparison> {\n  const ref = parseItemRef(version ? `${key}@${version}` : key)\n  const name = ref.name\n  const installed = config.items[name]\n  if (installed === undefined) {\n    throw new SlabUIError(\n      `\"${name}\" is not installed. Blocks and examples are not updated; for other items, use \"slabui add ${name}\".`,\n    )\n  }\n\n  const registry = resolveRegistry(config.token)\n  const client = clientFor(registry)\n  const entry = (await client.index()).items[ref.name]\n  if (entry === undefined) {\n    throw new SlabUIError(\n      `Item \"${ref.name}\" no longer exists in the \"${registry.namespace}\" registry.`,\n    )\n  }\n  const chosen = chooseVersion(entry, installed.version, ref, major)\n  const base = await client.item(ref.name, installed.version)\n  const remote =\n    chosen.version === installed.version\n      ? base\n      : await client.item(ref.name, chosen.version)\n\n  const warnings: string[] = []\n  const materialize = async (item: Item) => {\n    const destinations: Destinations = new Map([\n      [name, itemDestinations(item, context)],\n    ])\n    await addInstalledDependencies([item], {\n      config,\n      context,\n      destinations,\n      clientFor,\n    })\n    const own = destinations.get(name) as Map<string, string>\n    return new Map(\n      item.files.map((file) => {\n        const destination = own.get(file.path) as string\n        const content = materializeFile(file, {\n          key: name,\n          item,\n          destination,\n          destinations,\n          context,\n          warnings,\n        })\n        return [destination, normalizeNewlines(content)]\n      }),\n    )\n  }\n\n  const baseFiles = await materialize(base)\n  const remoteFiles = await materialize(remote)\n  const destinations = [\n    ...new Set([...baseFiles.keys(), ...remoteFiles.keys()]),\n  ]\n\n  const files = await Promise.all(\n    destinations.map(async (destination) => {\n      const local = await readFile(path.join(context.root, destination), \"utf8\")\n        .then(normalizeNewlines)\n        .catch(() => undefined)\n      return {\n        destination,\n        base: baseFiles.get(destination),\n        remote: remoteFiles.get(destination),\n        local,\n      }\n    }),\n  )\n\n  return {\n    key: name,\n    registry,\n    base,\n    remote,\n    files,\n    newerMajor: chosen.newerMajor,\n    warnings,\n  }\n}\n\nfunction normalizeNewlines(content: string) {\n  return content.replace(/\\r\\n/g, \"\\n\")\n}\n","import { createTwoFilesPatch } from \"diff\"\n\nimport type { ResolvedRegistry } from \"../resolve\"\n\nimport { createRegistryClient, type RegistryClient } from \"../client\"\nimport { loadTsconfig, readConfig, resolveCssFile } from \"../project\"\nimport { compareItem, type ItemComparison } from \"./compare\"\n\nexport type DiffResult = {\n  comparison: ItemComparison\n  patches: string[]\n  changed: boolean\n}\n\n// Sem `local`: o que o update traria (local → remota). Com `local`: o que foi\n// alterado no projeto (base → local).\nexport async function diffItem({\n  root,\n  ref,\n  local = false,\n  major,\n  createClient = (registry) => createRegistryClient(registry),\n}: {\n  root: string\n  ref: string\n  local?: boolean\n  major?: boolean\n  createClient?: (registry: ResolvedRegistry) => RegistryClient\n}): Promise<DiffResult> {\n  const config = await readConfig(root)\n  const tsconfig = await loadTsconfig(root)\n  const context = {\n    root,\n    aliases: config.aliases,\n    tsconfig,\n    css: resolveCssFile(tsconfig, root, config.css),\n  }\n  const [key, version] = splitVersion(ref)\n  const comparison = await compareItem({\n    key,\n    version,\n    major,\n    config,\n    context,\n    clientFor: createClient,\n  })\n\n  const from = local ? \"base\" : \"local\"\n  const to = local ? \"local\" : \"remote\"\n  const patches = comparison.files.flatMap((file) => {\n    const before = file[from] ?? \"\"\n    const after = file[to] ?? \"\"\n    if (before === after) {\n      return []\n    }\n    return [\n      createTwoFilesPatch(\n        `a/${file.destination}`,\n        `b/${file.destination}`,\n        before,\n        after,\n        local ? comparison.base.version : \"local\",\n        local ? \"local\" : comparison.remote.version,\n      ),\n    ]\n  })\n\n  return { comparison, patches, changed: patches.length > 0 }\n}\n\n// `button@2` → [\"button\", \"2\"]; `@acme/table@^1` → [\"@acme/table\", \"^1\"].\nexport function splitVersion(ref: string): [string, string | undefined] {\n  const at = ref.indexOf(\"@\", ref.startsWith(\"@\") ? 1 : 0)\n  return at === -1 ? [ref, undefined] : [ref.slice(0, at), ref.slice(at + 1)]\n}\n","import semver from \"semver\"\n\nimport type { Config } from \"../schemas/config\"\nimport type { Registry } from \"../schemas/registry\"\n\nimport { createRegistryClient, type RegistryClient } from \"../client\"\nimport { CONFIG_FILE, DEFAULT_REGISTRY } from \"../constants\"\nimport { SlabUIError } from \"../errors\"\nimport { readConfig } from \"../project\"\nimport {\n  itemKey,\n  parseItemRef,\n  type ResolvedRegistry,\n  resolveRegistry,\n} from \"../resolve\"\nimport { chooseVersion } from \"./compare\"\n\n// `missing`: o item não existe mais no registry. `unknown-version`: a versão\n// instalada sumiu do índice (Wanted e Latest são calculados mesmo assim).\nexport type OutdatedStatus =\n  | \"outdated\"\n  | \"current\"\n  | \"missing\"\n  | \"unknown-version\"\n\nexport type OutdatedItem = {\n  key: string\n  registry: string\n  current: string\n  // Mais recente dentro da major instalada, como no `update`.\n  wanted?: string\n  latest?: string\n  status: OutdatedStatus\n}\n\nexport type OutdatedOptions = {\n  root: string\n  // Vazio: todos os itens instalados.\n  refs?: string[]\n  createClient?: (registry: ResolvedRegistry) => RegistryClient\n}\n\n// Versões novas dos itens instalados. Lê só os índices, um por registry, em\n// paralelo; um registry inacessível é erro, para o CI não passar sem conferir.\nexport async function outdatedItems({\n  root,\n  refs = [],\n  createClient = (registry) => createRegistryClient(registry),\n}: OutdatedOptions): Promise<OutdatedItem[]> {\n  const config = await readConfig(root)\n  const keys =\n    refs.length > 0\n      ? [...new Set(refs.map((ref) => itemKey(parseItemRef(ref))))]\n      : Object.keys(config.items)\n\n  for (const key of keys) {\n    if (config.items[key] === undefined) {\n      throw new SlabUIError(\n        `\"${key}\" is not installed. Blocks and examples are not tracked in ${CONFIG_FILE}.`,\n      )\n    }\n  }\n\n  if (keys.length === 0) {\n    return []\n  }\n  const index = await createClient(resolveRegistry(config.token)).index()\n\n  return compareInstalled(config, keys, index)\n}\n\n// Compara os itens com o índice já baixado.\nexport function compareInstalled(\n  config: Pick<Config, \"items\">,\n  keys: string[],\n  index: Registry,\n): OutdatedItem[] {\n  return keys.flatMap((key): OutdatedItem[] => {\n    const ref = parseItemRef(key)\n    const installed = config.items[key]\n    if (installed === undefined) {\n      return []\n    }\n    const current = installed.version\n    const entry = index.items[ref.name]\n    if (entry === undefined) {\n      return [\n        {\n          key,\n          registry: index.namespace ?? DEFAULT_REGISTRY.namespace,\n          current,\n          status: \"missing\",\n        },\n      ]\n    }\n\n    const wanted = chooseVersion(entry, current, {\n      ...ref,\n      range: undefined,\n    }).version\n    const latest = entry.latest\n    const status: OutdatedStatus = !(current in entry.versions)\n      ? \"unknown-version\"\n      : semver.gt(wanted, current) || semver.gt(latest, current)\n        ? \"outdated\"\n        : \"current\"\n    return [\n      {\n        key,\n        registry: index.namespace ?? DEFAULT_REGISTRY.namespace,\n        current,\n        wanted,\n        latest,\n        status,\n      },\n    ]\n  })\n}\n","import { mkdir, rm, writeFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport { merge } from \"node-diff3\"\nimport semver from \"semver\"\n\nimport type { CssRuleChange, CssVarChange } from \"../css\"\nimport type { ResolvedRegistry } from \"../resolve\"\nimport type { MaterializeContext } from \"./materialize\"\n\nimport { createRegistryClient, type RegistryClient } from \"../client\"\nimport { DEFAULT_REGISTRY } from \"../constants\"\nimport { resolveProjectPath } from \"../paths\"\nimport {\n  loadTsconfig,\n  readConfig,\n  resolveCssFile,\n  writeConfig,\n} from \"../project\"\nimport { itemKey, parseItemRef } from \"../resolve\"\nimport { addItems } from \"./add\"\nimport { compareItem, type FileComparison } from \"./compare\"\nimport { splitVersion } from \"./diff\"\nimport { installPackages } from \"./npm\"\nimport { addThemeTokens, updateCssRules, updateStylesheet } from \"./styles\"\n\nexport type ConflictResolution = \"markers\" | \"local\" | \"remote\"\n\nexport type FileStatus =\n  | \"unchanged\"\n  | \"updated\"\n  | \"merged\"\n  | \"conflict\"\n  | \"added\"\n  | \"removed\"\n  | \"kept\"\n\nexport type UpdateOptions = {\n  root: string\n  // Vazio: todos os itens instalados.\n  refs: string[]\n  major?: boolean\n  overwrite?: boolean\n  skipInstall?: boolean\n  // Ausentes fora do modo interativo: o update não pergunta.\n  confirm?: (message: string) => Promise<boolean>\n  resolveConflict?: (destination: string) => Promise<ConflictResolution>\n  createClient?: (registry: ResolvedRegistry) => RegistryClient\n}\n\nexport type UpdateResult = {\n  updated: {\n    key: string\n    from: string\n    to: string\n    files: { destination: string; status: FileStatus }[]\n  }[]\n  upToDate: string[]\n  // Arquivos que ficaram com marcadores de conflito.\n  conflicts: string[]\n  added: string[]\n  packages: string[]\n  cssChanges: CssVarChange[]\n  ruleChanges: CssRuleChange[]\n  warnings: string[]\n}\n\nconst LABELS = { a: \"local\", o: \"base\", b: \"remote\" }\n\nexport async function updateItems({\n  root,\n  refs,\n  major = false,\n  overwrite = false,\n  skipInstall = false,\n  confirm,\n  resolveConflict,\n  createClient = (registry) => createRegistryClient(registry),\n}: UpdateOptions): Promise<UpdateResult> {\n  const config = await readConfig(root)\n  const tsconfig = await loadTsconfig(root)\n  const context: MaterializeContext = {\n    root,\n    aliases: config.aliases,\n    tsconfig,\n    css: resolveCssFile(tsconfig, root, config.css),\n  }\n  const clients = new Map<string, RegistryClient>()\n  const clientFor = (registry: ResolvedRegistry) => {\n    let client = clients.get(registry.namespace)\n    if (client === undefined) {\n      client = createClient(registry)\n      clients.set(registry.namespace, client)\n    }\n    return client\n  }\n\n  const result: UpdateResult = {\n    updated: [],\n    upToDate: [],\n    conflicts: [],\n    added: [],\n    packages: [],\n    cssChanges: [],\n    ruleChanges: [],\n    warnings: [],\n  }\n  const queue = (refs.length > 0 ? refs : Object.keys(config.items)).map(\n    (ref) => splitVersion(ref),\n  )\n  const processed = new Set<string>()\n  const missing = new Set<string>()\n  const npm: string[] = []\n  const npmDev: string[] = []\n\n  while (queue.length > 0) {\n    const [key, version] = queue.shift() as [string, string | undefined]\n    if (processed.has(key)) {\n      continue\n    }\n    processed.add(key)\n\n    const comparison = await compareItem({\n      key,\n      version,\n      major,\n      config,\n      context,\n      clientFor,\n    })\n    result.warnings.push(...comparison.warnings)\n    if (comparison.newerMajor) {\n      result.warnings.push(\n        `${comparison.key}@${comparison.newerMajor} is available (new major): slabui update ${comparison.key} --major`,\n      )\n    }\n    const { base, remote } = comparison\n    if (remote.version === base.version) {\n      result.upToDate.push(comparison.key)\n      continue\n    }\n\n    const files: UpdateResult[\"updated\"][number][\"files\"] = []\n    for (const file of comparison.files) {\n      const status = await applyFile(file, {\n        root,\n        overwrite,\n        confirm,\n        resolveConflict,\n        warnings: result.warnings,\n      })\n      files.push({ destination: file.destination, status })\n      if (status === \"conflict\") {\n        result.conflicts.push(file.destination)\n      }\n    }\n\n    if (remote.cssVars !== undefined || base.cssVars !== undefined) {\n      result.cssChanges.push(\n        ...(await updateStylesheet(\n          root,\n          context.css,\n          comparison.key,\n          remote.cssVars ?? {},\n          {\n            base: base.cssVars ?? {},\n            warnings: result.warnings,\n            shouldRemove: overwrite\n              ? async () => true\n              : confirm &&\n                ((group, name) =>\n                  confirm(\n                    `--${name} (${group}) was removed in the new version of \"${comparison.key}\". Remove it from the CSS?`,\n                  )),\n          },\n        )),\n      )\n    }\n\n    if (comparison.registry.namespace === DEFAULT_REGISTRY.namespace) {\n      const tokens = (await clientFor(comparison.registry).index()).items[\n        remote.name\n      ]?.tokens\n      result.cssChanges.push(\n        ...(await addThemeTokens(\n          root,\n          context.css,\n          comparison.key,\n          tokens,\n          result.warnings,\n        )),\n      )\n    }\n\n    if (remote.css !== undefined || base.css !== undefined) {\n      result.ruleChanges.push(\n        ...(await updateCssRules(\n          root,\n          context.css,\n          comparison.key,\n          remote.css ?? {},\n          {\n            base: base.css ?? {},\n            warnings: result.warnings,\n            shouldRemove: overwrite\n              ? async () => true\n              : confirm &&\n                ((kind, name) =>\n                  confirm(\n                    `${kind === \"base\" ? name : `${kind === \"utility\" ? \"@utility\" : \"@custom-variant\"} ${name}`} was removed in the new version of \"${comparison.key}\". Remove it from the CSS?`,\n                  )),\n          },\n        )),\n      )\n    }\n\n    config.items[comparison.key] = {\n      version: remote.version,\n      files: comparison.files\n        .filter((file) => file.remote !== undefined)\n        .map((file) => file.destination),\n    }\n    result.updated.push({\n      key: comparison.key,\n      from: base.version,\n      to: remote.version,\n      files,\n    })\n\n    // Dependências que a versão nova exige: as que faltam são instaladas\n    // com o add; as instaladas fora do intervalo também são atualizadas.\n    for (const dependency of remote.dependencies.registry) {\n      const ref = parseItemRef(dependency)\n      const dependencyKey = itemKey(ref)\n      const installed = config.items[dependencyKey]\n      if (installed === undefined) {\n        missing.add(dependency)\n      } else if (\n        ref.range !== undefined &&\n        !semver.satisfies(installed.version, ref.range)\n      ) {\n        queue.push([dependencyKey, ref.range])\n      }\n    }\n    npm.push(...remote.dependencies.npm)\n    npmDev.push(...remote.dependencies.npmDev)\n  }\n\n  await writeConfig(root, config)\n\n  if (missing.size > 0) {\n    const added = await addItems({\n      root,\n      refs: [...missing],\n      overwrite,\n      skipInstall,\n      confirm,\n      createClient: clientFor,\n    })\n    result.added = added.added.map(({ key }) => key)\n    result.cssChanges.push(...added.cssChanges)\n    result.ruleChanges.push(...added.ruleChanges)\n    result.packages.push(...added.packages)\n    result.warnings.push(...added.warnings)\n  }\n\n  result.packages.push(\n    ...(await installPackages(\n      root,\n      { npm, npmDev },\n      { confirm, skipInstall, warnings: result.warnings },\n    )),\n  )\n  return result\n}\n\nasync function applyFile(\n  { destination, base, remote, local }: FileComparison,\n  {\n    root,\n    overwrite,\n    confirm,\n    resolveConflict,\n    warnings,\n  }: {\n    root: string\n    overwrite: boolean\n    confirm?: (message: string) => Promise<boolean>\n    resolveConflict?: (destination: string) => Promise<ConflictResolution>\n    warnings: string[]\n  },\n): Promise<FileStatus> {\n  const absolute = await resolveProjectPath(root, destination)\n  const write = async (content: string) => {\n    await mkdir(path.dirname(absolute), { recursive: true })\n    await writeFile(absolute, content)\n  }\n\n  // Removido na versão nova.\n  if (remote === undefined) {\n    if (local === undefined) {\n      return \"removed\"\n    }\n    const remove =\n      local === base ||\n      overwrite ||\n      (confirm !== undefined &&\n        (await confirm(\n          `${destination} was removed in the new version, but has local changes. Delete it?`,\n        )))\n    if (remove) {\n      await rm(absolute)\n      return \"removed\"\n    }\n    warnings.push(\n      `${destination} was removed in the new version; kept because it has local changes.`,\n    )\n    return \"kept\"\n  }\n\n  // Novo na versão nova.\n  if (base === undefined) {\n    if (local === remote) {\n      return \"unchanged\"\n    }\n    if (local !== undefined) {\n      const replace =\n        overwrite ||\n        (confirm !== undefined &&\n          (await confirm(\n            `${destination} is new in this version, but already exists in the project. Overwrite it?`,\n          )))\n      if (!replace) {\n        warnings.push(\n          `${destination} already exists in the project and was not overwritten (--overwrite).`,\n        )\n        return \"kept\"\n      }\n    }\n    await write(remote)\n    return \"added\"\n  }\n\n  if (local === remote) {\n    return \"unchanged\"\n  }\n  if (local === undefined || local === base) {\n    if (local === undefined) {\n      warnings.push(\n        `${destination} was missing from the project and was recreated.`,\n      )\n    }\n    await write(remote)\n    return \"updated\"\n  }\n\n  // Alterado no projeto e na versão nova: merge de 3 vias.\n  const merged = merge(\n    local.split(\"\\n\"),\n    base.split(\"\\n\"),\n    remote.split(\"\\n\"),\n    {\n      label: LABELS,\n    },\n  )\n  if (!merged.conflict) {\n    await write(merged.result.join(\"\\n\"))\n    return \"merged\"\n  }\n\n  const resolution = resolveConflict\n    ? await resolveConflict(destination)\n    : \"markers\"\n  if (resolution === \"local\") {\n    return \"kept\"\n  }\n  if (resolution === \"remote\") {\n    await write(remote)\n    return \"updated\"\n  }\n  await write(merged.result.join(\"\\n\"))\n  return \"conflict\"\n}\n","import { spawn } from \"node:child_process\"\nimport { createServer } from \"node:http\"\n\nimport { authorizeUrl, fetchAccount, newState } from \"@slabui/account\"\n\nimport type { AddressInfo } from \"node:net\"\n\nimport { credentialsFile, saveToken } from \"./credentials\"\nimport { SlabUIError } from \"./errors\"\nimport { resolveRegistry } from \"./resolve\"\nimport { telemetryHeaders } from \"./telemetry\"\n\n// Mesmo formato do `Account` de `@slabui/account`, declarado aqui para\n// a API pública (o .d.ts) não depender do pacote de temas.\nexport type Account = {\n  name?: string\n  image?: string\n  plan?: string\n  access: string[]\n}\n\n// Tempo para a pessoa entrar e autorizar no navegador.\nconst BROWSER_TIMEOUT_MS = 5 * 60 * 1000\n\ntype Options = {\n  root: string\n  fetch?: typeof fetch\n  env?: Record<string, string | undefined>\n  file?: string\n}\n\n// Confere o token no `whoami.json` do registry padrão e grava fora do projeto.\nexport async function login({\n  token,\n  fetch = globalThis.fetch,\n  env = process.env,\n  file = credentialsFile(env),\n}: Options & { token: string }): Promise<{\n  account: Account\n  url: string\n  file: string\n}> {\n  const registry = resolveRegistry(undefined, env)\n\n  let account: Account | null\n  try {\n    account = await fetchAccount({\n      registryUrl: registry.url,\n      token,\n      fetch,\n      headers: telemetryHeaders(env, \"login\"),\n    })\n  } catch (error) {\n    if (error instanceof Error && error.message.startsWith(\"Error 404\")) {\n      throw new SlabUIError(`${registry.url} does not support login.`)\n    }\n    throw new SlabUIError(\n      error instanceof Error && error.message.startsWith(\"Error \")\n        ? error.message\n        : `Could not reach ${registry.url}.`,\n    )\n  }\n  if (account === null) {\n    throw new SlabUIError(\"Invalid token. Check it and try again.\")\n  }\n\n  await saveToken(token.trim(), file)\n  return { account, url: registry.url, file }\n}\n\n// Login pelo navegador: abre a página de autorização do site e recebe o\n// token num servidor local temporário (só em 127.0.0.1), conferindo o `state`.\nexport async function loginWithBrowser({\n  root,\n  onUrl,\n  timeout = BROWSER_TIMEOUT_MS,\n  ...options\n}: Options & {\n  // Recebe a URL a abrir (o comando imprime e abre o navegador).\n  onUrl: (url: string) => void\n  timeout?: number\n}) {\n  const registry = resolveRegistry(undefined, options.env)\n  const state = newState()\n\n  const token = await new Promise<string>((resolve, reject) => {\n    const server = createServer((req, res) => {\n      const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\")\n      if (\n        url.pathname !== \"/callback\" ||\n        url.searchParams.get(\"state\") !== state\n      ) {\n        res.writeHead(404).end()\n        return\n      }\n      const value = url.searchParams.get(\"token\")\n      res.writeHead(200, { \"content-type\": \"text/html; charset=utf-8\" })\n      res.end(\n        page(\n          value\n            ? \"Signed in. You can close this tab and go back to the terminal.\"\n            : \"Sign-in cancelled. You can close this tab.\",\n        ),\n      )\n      finish(() =>\n        value\n          ? resolve(value)\n          : reject(new SlabUIError(\"Sign-in was cancelled in the browser.\")),\n      )\n    })\n    const timer = setTimeout(\n      () =>\n        finish(() =>\n          reject(new SlabUIError(\"Timed out waiting for the browser sign-in.\")),\n        ),\n      timeout,\n    )\n    function finish(done: () => void) {\n      clearTimeout(timer)\n      server.close()\n      done()\n    }\n\n    server.once(\"error\", reject)\n    server.listen(0, \"127.0.0.1\", () => {\n      const { port } = server.address() as AddressInfo\n      onUrl(\n        authorizeUrl({\n          registryUrl: registry.url,\n          callback: `http://127.0.0.1:${port}/callback`,\n          state,\n          client: \"SlabUI CLI\",\n        }),\n      )\n    })\n  })\n\n  return login({ root, token, ...options })\n}\n\n// Abre a URL no navegador padrão; se falhar, a pessoa usa a URL impressa.\nexport function openBrowser(url: string) {\n  const [command, args] =\n    process.platform === \"darwin\"\n      ? [\"open\", [url]]\n      : process.platform === \"win32\"\n        ? [\"cmd\", [\"/c\", \"start\", \"\", url]]\n        : [\"xdg-open\", [url]]\n  try {\n    spawn(command, args, { stdio: \"ignore\", detached: true })\n      .on(\"error\", () => {})\n      .unref()\n  } catch {}\n}\n\nfunction page(message: string) {\n  return `<!doctype html><meta charset=\"utf-8\"><title>SlabUI</title><body style=\"font:16px system-ui;display:grid;place-items:center;height:100vh;margin:0\"><p>${message}</p></body>`\n}\n","import MiniSearch from \"minisearch\"\n\nimport type { ItemKind } from \"./constants\"\nimport type { Registry, RegistryEntry } from \"./schemas/registry\"\n\nexport type SearchResult = {\n  // Como o item é instalado: `button` ou `@acme/data-table`.\n  key: string\n  name: string\n  namespace: string\n  entry: RegistryEntry\n  score: number\n}\n\nexport type SearchSource = {\n  namespace: string\n  isDefault: boolean\n  index: Registry\n}\n\ntype Document = {\n  id: string\n  name: string\n  title: string\n  description: string\n  categories: string\n  keywords: string\n  kind: string\n}\n\n// Busca aproximada (erros de digitação e termo parcial) nos índices, com mais\n// peso para o nome, depois título, keywords, categorias e descrição. Usada pelo\n// CLI e, depois, pelo servidor MCP.\nexport function searchRegistries(\n  sources: SearchSource[],\n  term: string,\n  { type }: { type?: ItemKind } = {},\n): SearchResult[] {\n  const results = new Map<string, Omit<SearchResult, \"score\">>()\n  const engine = new MiniSearch<Document>({\n    fields: [\"name\", \"title\", \"description\", \"categories\", \"keywords\", \"kind\"],\n    searchOptions: {\n      boost: { name: 4, title: 3, keywords: 2, categories: 1.5 },\n      fuzzy: 0.2,\n      prefix: true,\n      combineWith: \"AND\",\n    },\n  })\n\n  for (const { namespace, isDefault, index } of sources) {\n    for (const [name, entry] of Object.entries(index.items)) {\n      if (type !== undefined && entry.kind !== type) {\n        continue\n      }\n      const key = isDefault ? name : `${namespace}/${name}`\n      results.set(key, { key, name, namespace, entry })\n      engine.add({\n        id: key,\n        // O nome também entra separado por hífen: \"input-number\" → \"input number\".\n        name: `${name} ${name.replaceAll(\"-\", \" \")}`,\n        title: entry.title ?? \"\",\n        description: entry.description,\n        categories: (entry.categories ?? []).join(\" \"),\n        keywords: (entry.keywords ?? []).join(\" \"),\n        kind: entry.kind,\n      })\n    }\n  }\n\n  return engine.search(term).map(({ id, score }) => ({\n    ...(results.get(id) as Omit<SearchResult, \"score\">),\n    score,\n  }))\n}\n","import path from \"node:path\"\n\nimport type { Config } from \"./schemas/config\"\nimport type { Item } from \"./schemas/item\"\nimport type { RegistryEntry } from \"./schemas/registry\"\n\nimport { createRegistryClient, type RegistryClient } from \"./client\"\nimport { CONFIG_FILE, type ItemKind } from \"./constants\"\nimport { SlabUIError } from \"./errors\"\nimport { destinationOf } from \"./install/destinations\"\nimport { exists, loadTsconfig, readConfig } from \"./project\"\nimport {\n  itemKey,\n  parseItemRef,\n  type ResolvedRegistry,\n  resolveRegistry,\n  resolveVersion,\n} from \"./resolve\"\nimport { type SearchResult, searchRegistries } from \"./search\"\n\ntype Options = {\n  root: string\n  createClient?: (registry: ResolvedRegistry) => RegistryClient\n}\n\nconst defaultClient = (registry: ResolvedRegistry) =>\n  createRegistryClient(registry)\n\n// Sem slabui.json, só o registry padrão (busca e info não exigem o init).\nasync function readConfigIfExists(root: string): Promise<Config | undefined> {\n  return (await exists(path.join(root, CONFIG_FILE)))\n    ? readConfig(root)\n    : undefined\n}\n\nexport async function searchItems({\n  root,\n  term,\n  type,\n  createClient = defaultClient,\n}: Options & { term: string; type?: ItemKind }): Promise<{\n  results: SearchResult[]\n  warnings: string[]\n}> {\n  const config = await readConfigIfExists(root)\n  const registry = resolveRegistry(config?.token)\n  try {\n    const index = await createClient(registry).index()\n    const source = { namespace: registry.namespace, isDefault: true, index }\n    return { results: searchRegistries([source], term, { type }), warnings: [] }\n  } catch (error) {\n    return {\n      results: [],\n      warnings: [`\"${registry.namespace}\": ${(error as Error).message}`],\n    }\n  }\n}\n\nexport type ItemInfo = {\n  key: string\n  registry: ResolvedRegistry\n  entry: RegistryEntry\n  item: Item\n  installed?: string\n  // Destino de cada arquivo no projeto (com slabui.json).\n  destinations?: string[]\n}\n\nexport async function itemInfo({\n  root,\n  ref: raw,\n  createClient = defaultClient,\n}: Options & { ref: string }): Promise<ItemInfo> {\n  const config = await readConfigIfExists(root)\n  const ref = parseItemRef(raw)\n  const registry = resolveRegistry(config?.token)\n  const client = createClient(registry)\n\n  const entry = (await client.index()).items[ref.name]\n  if (entry === undefined) {\n    throw new SlabUIError(\n      `Item \"${ref.name}\" does not exist in the \"${registry.namespace}\" registry.`,\n    )\n  }\n  const item = await client.item(ref.name, resolveVersion(ref, entry))\n  const key = itemKey(ref)\n\n  let destinations: string[] | undefined\n  if (config !== undefined) {\n    const context = {\n      root,\n      aliases: config.aliases,\n      tsconfig: await loadTsconfig(root),\n    }\n    destinations = item.files.map((file) => {\n      try {\n        return destinationOf(file, context)\n      } catch {\n        return file.path\n      }\n    })\n  }\n\n  return {\n    key,\n    registry,\n    entry,\n    item,\n    installed: config?.items[key]?.version,\n    destinations,\n  }\n}\n"],"mappings":"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"}