{"version":3,"file":"index.mjs","names":["WHOAMI_PATH","pkg.version","applyCssVars","same","applyCssRules","merge","applyBaseRules","importPath","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","aliasFolder","isRelativeAlias","alias","createPathsMatcher","detectCss","candidate","readConfig","writeConfig","config","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","isTypographyToken","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$1","sameImport","imports","addImport$1","applyCssVars","applyCssRules","applyBaseRules","addImport","FONTS_FILE","BASE_FILE","UTILITIES_FILE","CSS_TEMPLATE_VARS","themeSubset","splitTypography","typography","_","mode","tokens","pick","themeVars","uses","applyCssTemplate","backup","backupFile","fontsPath","sideFile","fontsFile","fontsCss","useFonts","globals","fontsResult","fonts","ensureSideFile","updateStylesheet","readGlobals","hasFonts","split","warning","addThemeTokens","action","updateCssRules","merge","rules","hasRules","hasBase","apply","run","beside","posix","legacy","globalsFile","importPath","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 de um alias (`@/styles` ou `./styles`), relativa à raiz e com `/`.\n// Sem correspondência nos `paths`, `undefined`.\nexport function aliasFolder(\n  tsconfig: TsConfigResult,\n  root: string,\n  alias: string,\n): string | undefined {\n  const absolute = isRelativeAlias(alias)\n    ? path.resolve(root, alias)\n    : aliasToPath(tsconfig, alias)\n  return absolute === undefined\n    ? undefined\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    // Tamanhos de texto proporcionais ao `--font-size` (o `text-base`): mudar\n    // ele muda todas as classes `text-*`. A altura de linha de cada tamanho é\n    // uma proporção sem unidade, então acompanha sozinha.\n    \"text-xxs\": \"calc(var(--font-size) * 0.625)\",\n    \"text-2xxs\": \"calc(var(--font-size) * 0.688)\",\n    \"text-xs\": \"calc(var(--font-size) * 0.75)\",\n    \"text-xs--line-height\": \"calc(1 / 0.75)\",\n    \"text-2xs\": \"calc(var(--font-size) * 0.813)\",\n    \"text-2xs--line-height\": \"calc(1.125 / 0.813)\",\n    \"text-sm\": \"calc(var(--font-size) * 0.875)\",\n    \"text-sm--line-height\": \"calc(1.25 / 0.875)\",\n    \"text-2sm\": \"calc(var(--font-size) * 0.938)\",\n    \"text-2sm--line-height\": \"calc(1.625 / 0.938)\",\n    \"text-base\": \"var(--font-size)\",\n    \"text-base--line-height\": \"calc(1.5 / 1)\",\n    \"text-lg\": \"calc(var(--font-size) * 1.125)\",\n    \"text-lg--line-height\": \"calc(1.75 / 1.125)\",\n    \"text-xl\": \"calc(var(--font-size) * 1.25)\",\n    \"text-xl--line-height\": \"calc(1.75 / 1.25)\",\n    \"text-2xl\": \"calc(var(--font-size) * 1.5)\",\n    \"text-2xl--line-height\": \"calc(2 / 1.5)\",\n    \"text-3xl\": \"calc(var(--font-size) * 1.875)\",\n    \"text-3xl--line-height\": \"calc(2.25 / 1.875)\",\n    \"text-4xl\": \"calc(var(--font-size) * 2.25)\",\n    \"text-4xl--line-height\": \"calc(2.5 / 2.25)\",\n    \"text-5xl\": \"calc(var(--font-size) * 3)\",\n    \"text-5xl--line-height\": \"1\",\n    \"text-6xl\": \"calc(var(--font-size) * 3.75)\",\n    \"text-6xl--line-height\": \"1\",\n    \"text-7xl\": \"calc(var(--font-size) * 4.5)\",\n    \"text-7xl--line-height\": \"1\",\n    \"text-8xl\": \"calc(var(--font-size) * 6)\",\n    \"text-8xl--line-height\": \"1\",\n    \"text-9xl\": \"calc(var(--font-size) * 8)\",\n    \"text-9xl--line-height\": \"1\",\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    // Tamanho base do texto. Em `rem`, respeita o tamanho de fonte do\n    // navegador; o usuário pode aumentar ou diminuir em produção.\n    \"font-size\": \"1rem\",\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    // Cor da marca (logo, destaques), com o texto por cima. Começa igual ao\n    // `primary`, que é a cor das ações dos componentes: quando a marca não tem\n    // contraste para um botão, o `primary` muda e a marca fica.\n    brand: \"oklch(70% 0.1435 227.76)\",\n    \"brand-foreground\": \"oklch(0.985 0 0)\",\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    brand: \"oklch(66% 0.1435 227.76)\",\n    \"brand-foreground\": \"oklch(0.985 0 0)\",\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\n// Entradas de tipografia do `@theme inline` (famílias `--font-*` e a escala\n// `--text-*`): no projeto, ficam no `fonts.css`, ao lado do CSS global.\nexport function isTypographyToken(name: string): boolean {\n  return /^(?:font|text)-/.test(name)\n}\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, isTypographyToken } 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 quatro arquivos: o global, onde\n// o `css` do slabui.json aponta, e os outros três em `core/`, na pasta do\n// alias `styles` (ou onde já estão, num projeto de antes):\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// - `fonts.css`: a tipografia, no `@theme inline` (famílias `--font-*` e a\n//   escala `--text-*`, proporcional ao `--font-size` do CSS global).\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 três, pelo caminho relativo a ele. Cada `slabui add` acrescenta o que o\n// item usa: as variáveis no global (a tipografia no `fonts.css`), as\n// utilities e as variantes no `utilities.css` e as declarações de base no\n// `base.css`.\n\n// Subpasta da pasta de estilos com os arquivos que o CLI mantém\n// (`styles/core/fonts.css`, `base.css`, `utilities.css`).\nexport const CORE_FOLDER = \"core\"\nexport const FONTS_FILE = \"fonts.css\"\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, e os `@import` dos\n// outros arquivos, com o caminho da pasta de estilos até o CSS global.\nexport const CSS_GLOBALS = `@import \"tailwindcss\";\n`\n\nexport const FONTS_HEADER = `/* Typography: font families and the text-* scale, imported by the global CSS.\n   Every text-* class is proportional to --font-size (set in :root in the\n   global CSS): change it to make all text larger or smaller. Line heights are\n   unitless ratios, so they follow the font size on their own. */\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, as cores que o\n// `base.css` usa e as das ações e dos estados (marca, primary, secondary,\n// danger, success, warning e inverted, com os foregrounds), 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  // As cores que quase todo componente usa, com o texto por cima.\n  \"brand\",\n  \"brand-foreground\",\n  \"primary\",\n  \"primary-foreground\",\n  \"secondary\",\n  \"secondary-foreground\",\n  \"danger\",\n  \"danger-foreground\",\n  \"success\",\n  \"success-foreground\",\n  \"warning\",\n  \"warning-foreground\",\n  \"inverted\",\n  \"inverted-foreground\",\n  \"radius\",\n  \"spacing\",\n  \"font-size\",\n  \"scrollbar-thumb\",\n] as const\n\nexport const CSS_TEMPLATE_VARS: CssVars = themeSubset(TEMPLATE_TOKENS)\n\n// O tema dividido entre o CSS global e o `fonts.css`: a tipografia do\n// `@theme inline` vai para o `fonts.css`; o resto fica no global.\nexport function splitTypography(vars: CssVars): {\n  globals: CssVars\n  fonts: CssVars\n} {\n  const typography: Record<string, string> = {}\n  const theme: Record<string, string> = {}\n  for (const [name, value] of Object.entries(vars.theme ?? {})) {\n    ;(isTypographyToken(name) ? typography : theme)[name] = value\n  }\n  const { theme: _, ...rest } = vars\n  return {\n    globals: { ...rest, ...(Object.keys(theme).length > 0 && { theme }) },\n    fonts: Object.keys(typography).length > 0 ? { theme: typography } : {},\n  }\n}\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  CORE_FOLDER,\n  CSS_BASE,\n  CSS_GLOBALS,\n  CSS_TEMPLATE_VARS,\n  CSS_UTILITIES,\n  FONTS_FILE,\n  FONTS_HEADER,\n  splitTypography,\n  themeSubset,\n  UTILITIES_FILE,\n  UTILITIES_HEADER,\n} from \"../css-template\"\nimport { resolveProjectPath } from \"../paths\"\n\nexport type TemplateResult = {\n  created: boolean\n  // Cópia do CSS global substituído (`replace`), relativa à raiz.\n  backup?: string\n  changes: CssVarChange[]\n  // `fonts.css`, `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 `fonts.css` (a tipografia) e o\n// `base.css`, na pasta de estilos (`styles`, relativa à raiz; sem ela, ao\n// lado do CSS global). Um CSS que já existe e não tem `fonts.css` continua\n// com a tipografia nele.\n//\n// Com `replace`, um CSS global que já existe é substituído pelo template, como\n// se fosse novo; o original fica numa cópia `<arquivo>.bak` ao lado dele.\nexport async function applyCssTemplate(\n  root: string,\n  file: string,\n  styles?: string,\n  { replace = false }: { replace?: boolean } = {},\n): Promise<TemplateResult> {\n  const absolute = await resolveProjectPath(root, file)\n  const existing = await readFile(absolute, \"utf8\").catch(() => undefined)\n  let backup: string | undefined\n  if (replace && existing !== undefined) {\n    backup = await backupFile(root, file, existing)\n  }\n  const current = replace ? undefined : existing\n  const fontsPath = await sideFile(root, file, styles, FONTS_FILE)\n  const fontsFile = await resolveProjectPath(root, fontsPath)\n  const fontsCss = await readFile(fontsFile, \"utf8\").catch(() => undefined)\n  const useFonts = current === undefined || fontsCss !== undefined\n  const { globals, fonts } = splitTypography(CSS_TEMPLATE_VARS)\n\n  const result = await applyCssVars(\n    current ?? CSS_GLOBALS,\n    useFonts ? globals : CSS_TEMPLATE_VARS,\n  )\n  if (current === undefined || result.css !== current) {\n    await mkdir(path.dirname(absolute), { recursive: true })\n    await writeFile(absolute, result.css)\n  }\n  const changes = [...result.changes]\n\n  // Na ordem dos `@import`: tipografia, base e utilities.\n  const files: string[] = []\n  if (useFonts) {\n    const fontsResult = await applyCssVars(fontsCss ?? FONTS_HEADER, fonts)\n    changes.push(...fontsResult.changes)\n    if (fontsCss === undefined) {\n      await ensureSideFile(root, file, styles, FONTS_FILE, fontsResult.css)\n      files.push(fontsPath)\n    } else if (fontsResult.css !== fontsCss) {\n      await writeFile(fontsFile, fontsResult.css)\n    }\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, styles, BASE_FILE, CSS_BASE))\n  ) {\n    files.push(await sideFile(root, file, styles, BASE_FILE))\n  }\n  if (await ensureSideFile(root, file, styles, UTILITIES_FILE, CSS_UTILITIES)) {\n    files.push(await sideFile(root, file, styles, UTILITIES_FILE))\n  }\n  return {\n    created: existing === undefined,\n    ...(backup && { backup }),\n    changes,\n    files,\n  }\n}\n\n// Copia o CSS global para `<arquivo>.bak` (ou `.bak.1`, `.bak.2`… se já\n// existe) e devolve o caminho da cópia, relativo à raiz.\nasync function backupFile(\n  root: string,\n  file: string,\n  content: string,\n): Promise<string> {\n  for (let index = 0; ; index++) {\n    const candidate = index === 0 ? `${file}.bak` : `${file}.bak.${index}`\n    const absolute = await resolveProjectPath(root, candidate)\n    const taken = await readFile(absolute)\n      .then(() => true)\n      .catch(() => false)\n    if (!taken) {\n      await writeFile(absolute, content)\n      return candidate\n    }\n  }\n}\n\n// Aplica as variáveis CSS de um item no `css` do slabui.json (a tipografia\n// do `@theme inline` no `fonts.css`, quando ele existe). Se o CSS global não\n// existe, cria com o template antes.\nexport async function updateStylesheet(\n  root: string,\n  file: string | undefined,\n  key: string,\n  vars: CssVars,\n  {\n    styles,\n    ...options\n  }: Parameters<typeof applyCssVars>[2] & {\n    warnings: string[]\n    // Pasta de estilos, relativa à raiz (o alias `styles`).\n    styles?: string\n  },\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  await readGlobals(root, file, styles, options.warnings)\n\n  const fontsFile = await sideFile(root, file, styles, FONTS_FILE)\n  const hasFonts = await readFile(await resolveProjectPath(root, fontsFile))\n    .then(() => true)\n    .catch(() => false)\n  const split = (tokens: CssVars) =>\n    hasFonts ? splitTypography(tokens) : { globals: tokens, fonts: {} }\n  const wanted = split(vars)\n  const base = options.base ? split(options.base) : undefined\n\n  const changes: CssVarChange[] = []\n  for (const [target, group] of [\n    [file, \"globals\"],\n    [fontsFile, \"fonts\"],\n  ] as const) {\n    const remote = wanted[group]\n    const previous = base?.[group]\n    if (\n      group === \"fonts\" &&\n      Object.keys(remote).length === 0 &&\n      Object.keys(previous ?? {}).length === 0\n    ) {\n      continue\n    }\n    const absolute = await resolveProjectPath(root, target)\n    const current = await readFile(absolute, \"utf8\")\n    const result = await applyCssVars(current, remote, {\n      ...options,\n      base: previous,\n    })\n    options.warnings.push(\n      ...result.warnings.map((warning) => `\"${key}\": ${warning}`),\n    )\n    if (result.css !== current) {\n      await writeFile(absolute, result.css)\n    }\n    changes.push(...result.changes)\n  }\n  return 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  styles?: 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    styles,\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    // Pasta de estilos, relativa à raiz (o alias `styles`).\n    styles?: string\n  },\n): Promise<CssRuleChange[]> {\n  const { warnings, styles, ...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, styles, 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, styles, name, header)\n    const absolute = await resolveProjectPath(\n      root,\n      await sideFile(root, file, styles, name),\n    )\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(\n  root: string,\n  file: string,\n  styles: string | undefined,\n  warnings: string[],\n) {\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, styles)\n  warnings.push(\n    `${file} did not exist; it was created with the default template.`,\n  )\n  return readFile(absolute, \"utf8\")\n}\n\n// Onde fica `name` (`fonts.css`, `base.css`, `utilities.css`), relativo à\n// raiz: na subpasta `core` da pasta de estilos (`styles/core/utilities.css`).\n// Num projeto de antes que já tem o arquivo ao lado do CSS global ou direto\n// na pasta de estilos, usa o que está lá.\nasync function sideFile(\n  root: string,\n  globals: string,\n  styles: string | undefined,\n  name: string,\n): Promise<string> {\n  const beside = path.posix.join(path.posix.dirname(posix(globals)), name)\n  if (styles === undefined) {\n    return beside\n  }\n  for (const legacy of [beside, path.posix.join(posix(styles), name)]) {\n    const found = await readFile(await resolveProjectPath(root, legacy))\n      .then(() => true)\n      .catch(() => false)\n    if (found) {\n      return legacy\n    }\n  }\n  return path.posix.join(posix(styles), CORE_FOLDER, name)\n}\n\n// Cria `name` na pasta de estilos com `content`, se não existe, e garante o\n// `@import` dele no CSS global, com o caminho relativo ao CSS global (o CSS\n// não entende os aliases do tsconfig). Devolve se o arquivo foi criado.\nasync function ensureSideFile(\n  root: string,\n  globals: string,\n  styles: string | undefined,\n  name: string,\n  content: string,\n): Promise<boolean> {\n  const target = await sideFile(root, globals, styles, name)\n  const absolute = await resolveProjectPath(root, target)\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, importPath(globals, target))\n  if (next !== css) {\n    await writeFile(globalsFile, next)\n  }\n  return !exists\n}\n\n// `@import` de `target` dentro de `globals` (`./base.css`,\n// `../styles/base.css`).\nfunction importPath(globals: string, target: string) {\n  const relative = path.posix.relative(\n    path.posix.dirname(posix(globals)),\n    posix(target),\n  )\n  return relative.startsWith(\".\") ? relative : `./${relative}`\n}\n\nconst posix = (file: string) => file.replaceAll(\"\\\\\", \"/\")\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  aliasFolder,\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  // Onde ficam o fonts.css, o base.css e o utilities.css.\n  const styles = aliasFolder(tsconfig, root, config.aliases.styles)\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(\n          root,\n          context.css,\n          key,\n          tokens,\n          warnings,\n          styles,\n        )),\n      )\n    }\n    if (item.cssVars !== undefined) {\n      cssChanges.push(\n        ...(await updateStylesheet(root, context.css, key, item.cssVars, {\n          overwrite,\n          warnings,\n          styles,\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          styles,\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  aliasFolder,\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  // Onde ficam o fonts.css, o base.css e o utilities.css.\n  const styles = aliasFolder(tsconfig, root, config.aliases.styles)\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            styles,\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          styles,\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            styles,\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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"}