@vocoder/cli 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -100,13 +100,13 @@ When running `vocoder init` from a subdirectory of a git repository, the CLI aut
100
100
 
101
101
  **Stored credentials:**
102
102
 
103
- After first sign-in, the CLI stores credentials at `~/.config/vocoder/auth.json` (mode `0600`). Tokens do not expire. Use `vocoder logout` to revoke.
103
+ After first sign-in, the CLI stores credentials at `~/.vocoder/auth.json` (mode `0600`). Tokens do not expire. Use `vocoder logout` to revoke.
104
104
 
105
105
  **Token resolution:**
106
106
 
107
107
  | Command | Source |
108
108
  |---|---|
109
- | `vocoder init` | `VOCODER_AUTH_TOKEN` env var → `~/.config/vocoder/auth.json` |
109
+ | `vocoder init` | `VOCODER_AUTH_TOKEN` env var → `~/.vocoder/auth.json` |
110
110
  | `vocoder sync` | `VOCODER_API_KEY` env var → `.env` file |
111
111
  | MCP tools | `VOCODER_API_KEY` env var |
112
112
 
@@ -274,7 +274,7 @@ Git repository is auto-detected from the current directory's git remote. Use `--
274
274
 
275
275
  ### `vocoder logout`
276
276
 
277
- Revoke the stored credentials and clear `~/.config/vocoder/auth.json`.
277
+ Revoke the stored credentials and clear `~/.vocoder/auth.json`.
278
278
 
279
279
  ```bash
280
280
  vocoder logout
package/dist/bin.mjs CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  readAuthData,
14
14
  verifyStoredAuth,
15
15
  writeAuthData
16
- } from "./chunk-XUCVAFBG.mjs";
16
+ } from "./chunk-SR6SDGUI.mjs";
17
17
 
18
18
  // src/bin.ts
19
19
  import { Command } from "commander";
@@ -41,17 +41,21 @@ function writeVocoderConfig(options) {
41
41
  const {
42
42
  targetBranches = ["main"],
43
43
  useTypeScript = true,
44
- cwd = process.cwd()
44
+ cwd = process.cwd(),
45
+ appDir
45
46
  } = options;
46
47
  if (findExistingConfig(cwd)) return null;
47
48
  const ext = useTypeScript ? "ts" : "js";
48
49
  const configPath = join(cwd, `vocoder.config.${ext}`);
49
50
  const branchesStr = targetBranches.map((b) => `'${b}'`).join(", ");
51
+ const defaultIncludes = ["**/*.{tsx,jsx,ts,js}"];
52
+ const includes = appDir ? defaultIncludes.map((p14) => `${appDir}/${p14}`) : defaultIncludes;
53
+ const includesStr = includes.map((p14) => `'${p14}'`).join(", ");
50
54
  const content = `import { defineConfig } from '@vocoder/config'
51
55
 
52
56
  export default defineConfig({
53
57
  targetBranches: [${branchesStr}],
54
- include: ['**/*.{tsx,jsx,ts,js}'],
58
+ include: [${includesStr}],
55
59
  exclude: [
56
60
  '**/node_modules/**',
57
61
  '**/.next/**',
@@ -878,25 +882,9 @@ async function runProjectCreate(params) {
878
882
  return null;
879
883
  }
880
884
  const languageOptions = buildLanguageOptions(sourceLocales);
881
- let appDir;
882
- if (params.defaultAppDir) {
883
- appDir = params.defaultAppDir;
885
+ const appDir = params.defaultAppDir ?? "";
886
+ if (appDir) {
884
887
  p3.log.success(`App directory: ${chalk4.bold(appDir)}`);
885
- } else {
886
- const rawScope = await p3.text({
887
- message: "App directory (leave blank for the entire repo)",
888
- placeholder: "e.g. apps/web, packages/frontend",
889
- initialValue: "",
890
- validate(value) {
891
- const v = value.trim();
892
- if (!v) return;
893
- if (v.startsWith("/"))
894
- return "Use a relative path, not an absolute path";
895
- if (v.includes("..")) return 'Path must not contain ".."';
896
- }
897
- });
898
- if (p3.isCancel(rawScope)) return null;
899
- appDir = (rawScope ?? "").trim();
900
888
  }
901
889
  const sourceLocale = await searchSelectLocale(
902
890
  languageOptions,
@@ -969,7 +957,7 @@ async function runProjectCreate(params) {
969
957
  return null;
970
958
  }
971
959
  }
972
- async function runProjectAppCreate(params) {
960
+ async function runAppCreate(params) {
973
961
  const { api, userToken, projectId, projectName, repoCanonical } = params;
974
962
  const existingScopes = new Set(params.existingApps.map((a) => a.appDir));
975
963
  let sourceLocales;
@@ -982,35 +970,13 @@ async function runProjectAppCreate(params) {
982
970
  return null;
983
971
  }
984
972
  const languageOptions = buildLanguageOptions(sourceLocales);
985
- let appDir;
986
- if (params.defaultAppDir && !existingScopes.has(params.defaultAppDir)) {
987
- appDir = params.defaultAppDir;
973
+ const appDir = params.defaultAppDir ?? "";
974
+ if (existingScopes.has(appDir)) {
975
+ p3.log.error(`App directory "${appDir}" is already configured for this project.`);
976
+ return null;
977
+ }
978
+ if (appDir) {
988
979
  p3.log.success(`App directory: ${chalk4.bold(appDir)}`);
989
- } else {
990
- if (params.existingApps.length > 0) {
991
- const configuredList = params.existingApps.map((a) => chalk4.dim(a.appDir || "(entire repo)")).join(", ");
992
- p3.log.info(`Already configured: ${configuredList}`);
993
- }
994
- const hasWholeRepoApp = existingScopes.has("");
995
- const rawScope = await p3.text({
996
- message: "App directory for this new app",
997
- placeholder: "e.g. apps/backend",
998
- initialValue: params.defaultAppDir ?? "",
999
- validate(value) {
1000
- const v = value.trim();
1001
- if (!v && hasWholeRepoApp)
1002
- return "This project already covers the entire repo.";
1003
- if (!v)
1004
- return "App directory is required when other apps already exist.";
1005
- if (v.startsWith("/"))
1006
- return "Use a relative path, not an absolute path.";
1007
- if (v.includes("..")) return 'Path must not contain "..".';
1008
- if (existingScopes.has(v))
1009
- return `"${v}" is already configured. Choose a different directory.`;
1010
- }
1011
- });
1012
- if (p3.isCancel(rawScope)) return null;
1013
- appDir = (rawScope ?? "").trim();
1014
980
  }
1015
981
  const sourceLocale = await searchSelectLocale(
1016
982
  languageOptions,
@@ -1062,7 +1028,7 @@ async function runProjectAppCreate(params) {
1062
1028
  }
1063
1029
  const targetBranches = appPushBranches;
1064
1030
  try {
1065
- const result = await api.createProjectApp(userToken, {
1031
+ const result = await api.createApp(userToken, {
1066
1032
  projectId,
1067
1033
  appDir,
1068
1034
  sourceLocale,
@@ -1302,7 +1268,7 @@ function printPlanLimitMessage(apiUrl, message) {
1302
1268
  p5.log.info(`Manage subscription: ${getSubscriptionSettingsUrl(apiUrl)}`);
1303
1269
  }
1304
1270
  function runScaffold(params) {
1305
- const { sourceLocale, targetBranches } = params;
1271
+ const { sourceLocale, targetBranches, appDir } = params;
1306
1272
  const detection = detectLocalEcosystem();
1307
1273
  const useTypeScript = detection.isTypeScript;
1308
1274
  if (detection.ecosystem) {
@@ -1345,7 +1311,8 @@ function runScaffold(params) {
1345
1311
  framework: detection.framework,
1346
1312
  ecosystem: detection.ecosystem,
1347
1313
  sourceLocale,
1348
- targetBranches
1314
+ targetBranches,
1315
+ appDir
1349
1316
  });
1350
1317
  const steps = [];
1351
1318
  if (snippets.pluginStep) {
@@ -1378,7 +1345,7 @@ function runScaffold(params) {
1378
1345
  printCodeBlock(step.code);
1379
1346
  if (i < steps.length - 1) p5.log.message("");
1380
1347
  }
1381
- const written = writeVocoderConfig({ targetBranches, useTypeScript });
1348
+ const written = writeVocoderConfig({ targetBranches, useTypeScript, appDir });
1382
1349
  if (written) {
1383
1350
  p5.log.success(`Created ${chalk6.cyan(written)}`);
1384
1351
  } else if (!findExistingConfig(process.cwd())) {
@@ -1476,8 +1443,9 @@ async function runAuthFlow(api, options, reauth = false, repoCanonical) {
1476
1443
  return null;
1477
1444
  }
1478
1445
  if (!shouldOpen) {
1479
- p5.note(browserUrl, "Sign In");
1480
- p5.log.info("Open the URL above manually in your browser to continue.");
1446
+ server?.close();
1447
+ p5.cancel("Setup cancelled.");
1448
+ return null;
1481
1449
  } else {
1482
1450
  const opened = await tryOpenBrowser2(browserUrl);
1483
1451
  if (!opened) {
@@ -1966,7 +1934,7 @@ async function init(options = {}) {
1966
1934
  `${chalk6.bold(repoProjectName)} is already set up for this repo.
1967
1935
  Configured apps: ${existingAppsForRepo.map((a) => chalk6.cyan(a.appDir || "(entire repo)")).join(", ")}`
1968
1936
  );
1969
- const appResult = await runProjectAppCreate({
1937
+ const appResult = await runAppCreate({
1970
1938
  api,
1971
1939
  userToken,
1972
1940
  projectId: repoProjectId,
@@ -1982,7 +1950,8 @@ async function init(options = {}) {
1982
1950
  }
1983
1951
  runScaffold({
1984
1952
  sourceLocale: appResult.sourceLocale,
1985
- targetBranches: appResult.targetBranches
1953
+ targetBranches: appResult.targetBranches,
1954
+ appDir: identity?.repoAppDir
1986
1955
  });
1987
1956
  p5.outro("You're all set.");
1988
1957
  return 0;
@@ -2039,7 +2008,7 @@ async function init(options = {}) {
2039
2008
  return 1;
2040
2009
  }
2041
2010
  const chosen = existingProjects.find((proj) => proj.id === chosenId);
2042
- const appResult = await runProjectAppCreate({
2011
+ const appResult = await runAppCreate({
2043
2012
  api,
2044
2013
  userToken,
2045
2014
  projectId: chosen.id,
@@ -2055,7 +2024,8 @@ async function init(options = {}) {
2055
2024
  }
2056
2025
  runScaffold({
2057
2026
  sourceLocale: appResult.sourceLocale,
2058
- targetBranches: appResult.targetBranches
2027
+ targetBranches: appResult.targetBranches,
2028
+ appDir: identity?.repoAppDir
2059
2029
  });
2060
2030
  p5.outro("You're all set.");
2061
2031
  return 0;
@@ -2090,7 +2060,8 @@ Translations won't run automatically until you grant access.
2090
2060
  }
2091
2061
  runScaffold({
2092
2062
  sourceLocale: projectResult.sourceLocale,
2093
- targetBranches: projectResult.targetBranches
2063
+ targetBranches: projectResult.targetBranches,
2064
+ appDir: identity?.repoAppDir
2094
2065
  });
2095
2066
  printApiKey(projectResult.apiKey);
2096
2067
  p5.outro("You're all set.");
@@ -2405,8 +2376,8 @@ function buildTranslationData(params) {
2405
2376
  const hashKeyed = {};
2406
2377
  for (const [locale, localeMap] of Object.entries(params.translations)) {
2407
2378
  hashKeyed[locale] = {};
2408
- for (const [text2, translation] of Object.entries(localeMap)) {
2409
- const hash = textToHash.get(text2);
2379
+ for (const [text, translation] of Object.entries(localeMap)) {
2380
+ const hash = textToHash.get(text);
2410
2381
  if (hash) hashKeyed[locale][hash] = translation;
2411
2382
  }
2412
2383
  }
@@ -2733,7 +2704,7 @@ async function sync(options = {}) {
2733
2704
  requestedMaxWaitMs: waitTimeoutMs,
2734
2705
  clientRunId: randomUUID(),
2735
2706
  force: options.force,
2736
- // Sync appIndustry from vocoder.config.ts to ProjectApp on every push
2707
+ // Sync appIndustry from vocoder.config.ts to App on every push
2737
2708
  ...config.appIndustry ? { appIndustry: config.appIndustry } : {}
2738
2709
  },
2739
2710
  repoIdentity ? { ...repoIdentity, commitSha } : { commitSha }