@verboo/code 0.7.5 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -17082,7 +17082,7 @@ function getOauthConfig() {
17082
17082
  }
17083
17083
  return config;
17084
17084
  }
17085
- var CLAUDE_AI_INFERENCE_SCOPE = "user:inference", CLAUDE_AI_PROFILE_SCOPE = "user:profile", CONSOLE_SCOPE = "org:create_api_key", OAUTH_BETA_HEADER = "oauth-2025-04-20", CONSOLE_OAUTH_SCOPES, CLAUDE_AI_OAUTH_SCOPES, ALL_OAUTH_SCOPES, VERBOO_API_BASE_URL = "https://code.verboo.ai", VERBOO_FRONT_BASE_URL = "https://code.verboo.ai", VERBOO_ROUTER_URL = "https://code.verboo.ai/router", VERBOO_OAUTH_SCOPES, PROD_OAUTH_CONFIG, MCP_CLIENT_METADATA_URL = "https://claude.ai/oauth/claude-code-client-metadata", STAGING_OAUTH_CONFIG, ALLOWED_OAUTH_BASE_URLS;
17085
+ var CLAUDE_AI_INFERENCE_SCOPE = "user:inference", CLAUDE_AI_PROFILE_SCOPE = "user:profile", CONSOLE_SCOPE = "org:create_api_key", OAUTH_BETA_HEADER = "oauth-2025-04-20", CONSOLE_OAUTH_SCOPES, CLAUDE_AI_OAUTH_SCOPES, ALL_OAUTH_SCOPES, VERBOO_API_BASE_URL = "https://code.verboo.ai", VERBOO_FRONT_BASE_URL = "https://code.verboo.ai", VERBOO_ROUTER_URL = "https://code.verboo.ai/router/v1", VERBOO_OAUTH_SCOPES, PROD_OAUTH_CONFIG, MCP_CLIENT_METADATA_URL = "https://claude.ai/oauth/claude-code-client-metadata", STAGING_OAUTH_CONFIG, ALLOWED_OAUTH_BASE_URLS;
17086
17086
  var init_oauth = __esm(() => {
17087
17087
  init_envUtils();
17088
17088
  CONSOLE_OAUTH_SCOPES = [
@@ -110603,7 +110603,7 @@ async function fetchVerbooModels(accessToken, opts = {}) {
110603
110603
  }
110604
110604
  if (inflight)
110605
110605
  return inflight;
110606
- const endpoint = `${VERBOO_ROUTER_URL}/v1/models`;
110606
+ const endpoint = `${VERBOO_ROUTER_URL}/models`;
110607
110607
  inflight = (async () => {
110608
110608
  try {
110609
110609
  const response = await axios_default.get(endpoint, {
@@ -115487,7 +115487,7 @@ function printStartupScreen(modelOverride) {
115487
115487
  const home = process.env.HOME || process.env.USERPROFILE || "";
115488
115488
  const cwd2 = process.cwd();
115489
115489
  const displayCwd = home && cwd2.startsWith(home) ? `~${cwd2.slice(home.length)}` : cwd2;
115490
- const version2 = "0.7.5";
115490
+ const version2 = "0.7.7";
115491
115491
  const bold2 = `${ESC}1m`;
115492
115492
  const PURPLE = rgb(...ACCENT);
115493
115493
  const SOFT = rgb(...CREAM);
@@ -201070,7 +201070,8 @@ async function getAnthropicClient({
201070
201070
  return createOpenAIShimClient2({
201071
201071
  defaultHeaders,
201072
201072
  maxRetries,
201073
- timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10)
201073
+ timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10),
201074
+ providerOverride
201074
201075
  });
201075
201076
  }
201076
201077
  if (isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK)) {
@@ -201150,14 +201151,26 @@ async function getAnthropicClient({
201150
201151
  return new AnthropicVertex(vertexArgs);
201151
201152
  }
201152
201153
  const useOAuthToken = isClaudeAISubscriber() || isVerbooMode();
201153
- const verbooAccessToken = useOAuthToken ? getClaudeAIOAuthTokens()?.accessToken : undefined;
201154
- if (isVerbooMode() && !verbooAccessToken) {
201155
- process.stderr.write("[Verboo] ERRO: token de acesso não encontrado. Execute `verboo /login`.\n");
201154
+ const accessToken = useOAuthToken ? getClaudeAIOAuthTokens()?.accessToken : undefined;
201155
+ if (isVerbooMode()) {
201156
+ if (!accessToken) {
201157
+ process.stderr.write("[Verboo] ERRO: token de acesso não encontrado. Execute `verboo /login`.\n");
201158
+ }
201159
+ const { createOpenAIShimClient: createOpenAIShimClient2 } = await Promise.resolve().then(() => (init_openaiShim(), exports_openaiShim));
201160
+ return createOpenAIShimClient2({
201161
+ defaultHeaders,
201162
+ maxRetries,
201163
+ timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10),
201164
+ providerOverride: {
201165
+ model: model ?? "",
201166
+ baseURL: VERBOO_ROUTER_URL,
201167
+ apiKey: accessToken ?? ""
201168
+ }
201169
+ });
201156
201170
  }
201157
201171
  const clientConfig = {
201158
201172
  apiKey: useOAuthToken ? null : apiKey || getAnthropicApiKey(),
201159
- authToken: verbooAccessToken,
201160
- baseURL: process.env.USER_TYPE === "ant" && isEnvTruthy(process.env.USE_STAGING_OAUTH) ? getOauthConfig().BASE_API_URL : VERBOO_ROUTER_URL,
201173
+ authToken: accessToken,
201161
201174
  ...ARGS,
201162
201175
  ...isDebugToStdErr() && { logger: createStderrLogger() }
201163
201176
  };
@@ -271137,16 +271150,26 @@ async function checkInstall(force = false) {
271137
271150
  });
271138
271151
  } else {
271139
271152
  const shellType = getShellType();
271140
- const configPaths = getShellConfigPaths();
271141
- const configFile = configPaths[shellType];
271142
- const displayPath = configFile ? configFile.replace(homedir21(), "~") : "your shell config file";
271143
- messages.push({
271144
- message: `Native installation exists but ~/.local/bin is not in your PATH. Run:
271153
+ if (shellType === "fish") {
271154
+ messages.push({
271155
+ message: `Native installation exists but ~/.local/bin is not in your PATH. Run:
271156
+
271157
+ fish_add_path ~/.local/bin`,
271158
+ userActionRequired: true,
271159
+ type: "path"
271160
+ });
271161
+ } else {
271162
+ const configPaths = getShellConfigPaths();
271163
+ const configFile = configPaths[shellType];
271164
+ const displayPath = configFile ? configFile.replace(homedir21(), "~") : "your shell config file";
271165
+ messages.push({
271166
+ message: `Native installation exists but ~/.local/bin is not in your PATH. Run:
271145
271167
 
271146
271168
  echo 'export PATH="$HOME/.local/bin:$PATH"' >> ${displayPath} && source ${displayPath}`,
271147
- userActionRequired: true,
271148
- type: "path"
271149
- });
271169
+ userActionRequired: true,
271170
+ type: "path"
271171
+ });
271172
+ }
271150
271173
  }
271151
271174
  }
271152
271175
  return messages;
@@ -376693,7 +376716,7 @@ function getAnthropicEnvMetadata() {
376693
376716
  function getBuildAgeMinutes() {
376694
376717
  if (false)
376695
376718
  ;
376696
- const buildTime = new Date("2026-04-29T16:44:33.074Z").getTime();
376719
+ const buildTime = new Date("2026-04-29T17:32:40.324Z").getTime();
376697
376720
  if (isNaN(buildTime))
376698
376721
  return;
376699
376722
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -405044,10 +405067,7 @@ ${deferredToolList}
405044
405067
  ...Object.keys(outputConfig).length > 0 && {
405045
405068
  output_config: outputConfig
405046
405069
  },
405047
- ...speed !== undefined && { speed },
405048
- ...isVerbooMode() && !modelSupportsThinking(options2.model) && {
405049
- enable_thinking: false
405050
- }
405070
+ ...speed !== undefined && { speed }
405051
405071
  };
405052
405072
  };
405053
405073
  {
@@ -405325,8 +405345,6 @@ ${deferredToolList}
405325
405345
  expected_type: "thinking",
405326
405346
  actual_type: contentBlock.type
405327
405347
  });
405328
- if (isVerbooMode())
405329
- break;
405330
405348
  throw new Error("Content block is not a thinking block");
405331
405349
  }
405332
405350
  contentBlock.signature = delta.signature;
@@ -405338,8 +405356,6 @@ ${deferredToolList}
405338
405356
  expected_type: "thinking",
405339
405357
  actual_type: contentBlock.type
405340
405358
  });
405341
- if (isVerbooMode())
405342
- break;
405343
405359
  throw new Error("Content block is not a thinking block");
405344
405360
  }
405345
405361
  contentBlock.thinking += delta.thinking;
@@ -406030,7 +406046,6 @@ function getMaxOutputTokensForModel(model) {
406030
406046
  var autoModeStateModule3, MAX_NON_STREAMING_TOKENS = 64000;
406031
406047
  var init_claude = __esm(() => {
406032
406048
  init_providers();
406033
- init_oauth();
406034
406049
  init_system();
406035
406050
  init_Tool();
406036
406051
  init_api3();
@@ -417228,7 +417243,7 @@ function buildPrimarySection() {
417228
417243
  }, undefined, false, undefined, this);
417229
417244
  return [{
417230
417245
  label: "Version",
417231
- value: "0.7.5"
417246
+ value: "0.7.7"
417232
417247
  }, {
417233
417248
  label: "Session name",
417234
417249
  value: nameValue
@@ -485178,7 +485193,7 @@ var init_bridge_kick = __esm(() => {
485178
485193
  var call60 = async () => {
485179
485194
  return {
485180
485195
  type: "text",
485181
- value: `${"99.0.0"} (built ${"2026-04-29T16:44:33.074Z"})`
485196
+ value: `${"99.0.0"} (built ${"2026-04-29T17:32:40.324Z"})`
485182
485197
  };
485183
485198
  }, version2, version_default;
485184
485199
  var init_version = __esm(() => {
@@ -487671,6 +487686,26 @@ async function validateModel(model) {
487671
487686
  if (!normalizedModel) {
487672
487687
  return { valid: false, error: "Model name cannot be empty" };
487673
487688
  }
487689
+ if (isVerbooMode()) {
487690
+ const verbooModels = getCachedVerbooModels();
487691
+ if (verbooModels && verbooModels.length > 0) {
487692
+ const found = verbooModels.some((m) => m.id === normalizedModel);
487693
+ if (found) {
487694
+ validModelCache.set(normalizedModel, true);
487695
+ return { valid: true };
487696
+ }
487697
+ const MAX_SHOWN = 5;
487698
+ const names = verbooModels.map((m) => m.id);
487699
+ const shown = names.slice(0, MAX_SHOWN).join(", ");
487700
+ const suffix = names.length > MAX_SHOWN ? ` e mais ${names.length - MAX_SHOWN}` : "";
487701
+ return {
487702
+ valid: false,
487703
+ error: `Modelo '${normalizedModel}' não disponível. Disponíveis: ${shown}${suffix}`
487704
+ };
487705
+ }
487706
+ validModelCache.set(normalizedModel, true);
487707
+ return { valid: true };
487708
+ }
487674
487709
  if (getAPIProvider() === "openai" && isOllamaProvider()) {
487675
487710
  const ollamaModels = getCachedOllamaModelOptions();
487676
487711
  const found = ollamaModels.some((m) => m.value === normalizedModel);
@@ -487818,6 +487853,8 @@ var init_validateModel = __esm(() => {
487818
487853
  init_ollamaModels();
487819
487854
  init_nvidiaNimModels();
487820
487855
  init_minimaxModels();
487856
+ init_oauth();
487857
+ init_verbooModels();
487821
487858
  validModelCache = new Map;
487822
487859
  });
487823
487860
 
@@ -509876,7 +509913,7 @@ function preconnectAnthropicApi() {
509876
509913
  if (process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || process.env.ANTHROPIC_UNIX_SOCKET || process.env.CLAUDE_CODE_CLIENT_CERT || process.env.CLAUDE_CODE_CLIENT_KEY) {
509877
509914
  return;
509878
509915
  }
509879
- const baseUrl = process.env.ANTHROPIC_BASE_URL || getOauthConfig().BASE_API_URL;
509916
+ const baseUrl = isVerbooMode() ? getOauthConfig().BASE_API_URL : process.env.ANTHROPIC_BASE_URL || getOauthConfig().BASE_API_URL;
509880
509917
  fetch(baseUrl, {
509881
509918
  method: "HEAD",
509882
509919
  signal: AbortSignal.timeout(1e4)
@@ -560814,7 +560851,7 @@ function WelcomeV2() {
560814
560851
  dimColor: true,
560815
560852
  children: [
560816
560853
  "v",
560817
- "0.7.5",
560854
+ "0.7.7",
560818
560855
  " "
560819
560856
  ]
560820
560857
  }, undefined, true, undefined, this)
@@ -561001,7 +561038,7 @@ function WelcomeV2() {
561001
561038
  dimColor: true,
561002
561039
  children: [
561003
561040
  "v",
561004
- "0.7.5",
561041
+ "0.7.7",
561005
561042
  " "
561006
561043
  ]
561007
561044
  }, undefined, true, undefined, this)
@@ -561217,7 +561254,7 @@ function AppleTerminalWelcomeV2(t0) {
561217
561254
  dimColor: true,
561218
561255
  children: [
561219
561256
  "v",
561220
- "0.7.5",
561257
+ "0.7.7",
561221
561258
  " "
561222
561259
  ]
561223
561260
  }, undefined, true, undefined, this);
@@ -561426,7 +561463,7 @@ function AppleTerminalWelcomeV2(t0) {
561426
561463
  dimColor: true,
561427
561464
  children: [
561428
561465
  "v",
561429
- "0.7.5",
561466
+ "0.7.7",
561430
561467
  " "
561431
561468
  ]
561432
561469
  }, undefined, true, undefined, this);
@@ -578962,11 +578999,11 @@ function Install({
578962
578999
  }, [force, target]);
578963
579000
  import_react332.useEffect(() => {
578964
579001
  if (state3.type === "success") {
578965
- setTimeout(onDone, 2000, "OpenClaude installation completed successfully", {
579002
+ setTimeout(onDone, 2000, "Verboo installation completed successfully", {
578966
579003
  display: "system"
578967
579004
  });
578968
579005
  } else if (state3.type === "error") {
578969
- setTimeout(onDone, 3000, "OpenClaude installation failed", {
579006
+ setTimeout(onDone, 3000, "Verboo installation failed", {
578970
579007
  display: "system"
578971
579008
  });
578972
579009
  }
@@ -578986,7 +579023,7 @@ function Install({
578986
579023
  state3.type === "installing" && /* @__PURE__ */ jsx_dev_runtime489.jsxDEV(ThemedText, {
578987
579024
  color: "claude",
578988
579025
  children: [
578989
- "Installing OpenClaude native build ",
579026
+ "Installing Verboo native build ",
578990
579027
  state3.version,
578991
579028
  "..."
578992
579029
  ]
@@ -579011,7 +579048,7 @@ function Install({
579011
579048
  /* @__PURE__ */ jsx_dev_runtime489.jsxDEV(ThemedText, {
579012
579049
  color: "success",
579013
579050
  bold: true,
579014
- children: "OpenClaude successfully installed!"
579051
+ children: "Verboo successfully installed!"
579015
579052
  }, undefined, false, undefined, this)
579016
579053
  ]
579017
579054
  }, undefined, true, undefined, this),
@@ -579121,7 +579158,7 @@ var init_install = __esm(() => {
579121
579158
  install = {
579122
579159
  type: "local-jsx",
579123
579160
  name: "install",
579124
- description: "Install OpenClaude native build",
579161
+ description: "Install Verboo native build",
579125
579162
  argumentHint: "[options]",
579126
579163
  async call(onDone, _context, args) {
579127
579164
  const force = args.includes("--force");
@@ -579454,7 +579491,7 @@ __export(exports_update, {
579454
579491
  async function update() {
579455
579492
  if (getAPIProvider() !== "firstParty") {
579456
579493
  writeToStdout(source_default.yellow(`Auto-update is not available for third-party provider builds.
579457
- `) + `Current version: ${"0.7.5"}
579494
+ `) + `Current version: ${"0.7.7"}
579458
579495
 
579459
579496
  ` + `To update, reinstall from npm:
579460
579497
  ` + source_default.bold(` npm install -g ${"@verboo/code"}@latest`) + `
@@ -579465,7 +579502,7 @@ async function update() {
579465
579502
  await gracefulShutdown(0);
579466
579503
  }
579467
579504
  logEvent("tengu_update_check", {});
579468
- writeToStdout(`Current version: ${"0.7.5"}
579505
+ writeToStdout(`Current version: ${"0.7.7"}
579469
579506
  `);
579470
579507
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
579471
579508
  writeToStdout(`Checking for updates to ${channel} version...
@@ -579550,8 +579587,8 @@ async function update() {
579550
579587
  writeToStdout(`Claude is managed by Homebrew.
579551
579588
  `);
579552
579589
  const latest = await getLatestVersion(channel);
579553
- if (latest && !gte("0.7.5", latest)) {
579554
- writeToStdout(`Update available: ${"0.7.5"} → ${latest}
579590
+ if (latest && !gte("0.7.7", latest)) {
579591
+ writeToStdout(`Update available: ${"0.7.7"} → ${latest}
579555
579592
  `);
579556
579593
  writeToStdout(`
579557
579594
  `);
@@ -579567,8 +579604,8 @@ async function update() {
579567
579604
  writeToStdout(`Claude is managed by winget.
579568
579605
  `);
579569
579606
  const latest = await getLatestVersion(channel);
579570
- if (latest && !gte("0.7.5", latest)) {
579571
- writeToStdout(`Update available: ${"0.7.5"} → ${latest}
579607
+ if (latest && !gte("0.7.7", latest)) {
579608
+ writeToStdout(`Update available: ${"0.7.7"} → ${latest}
579572
579609
  `);
579573
579610
  writeToStdout(`
579574
579611
  `);
@@ -579584,8 +579621,8 @@ async function update() {
579584
579621
  writeToStdout(`Claude is managed by apk.
579585
579622
  `);
579586
579623
  const latest = await getLatestVersion(channel);
579587
- if (latest && !gte("0.7.5", latest)) {
579588
- writeToStdout(`Update available: ${"0.7.5"} → ${latest}
579624
+ if (latest && !gte("0.7.7", latest)) {
579625
+ writeToStdout(`Update available: ${"0.7.7"} → ${latest}
579589
579626
  `);
579590
579627
  writeToStdout(`
579591
579628
  `);
@@ -579650,11 +579687,11 @@ async function update() {
579650
579687
  `);
579651
579688
  await gracefulShutdown(1);
579652
579689
  }
579653
- if (result.latestVersion === "0.7.5") {
579654
- writeToStdout(source_default.green(`Verboo Code is up to date (${"0.7.5"})`) + `
579690
+ if (result.latestVersion === "0.7.7") {
579691
+ writeToStdout(source_default.green(`Verboo Code is up to date (${"0.7.7"})`) + `
579655
579692
  `);
579656
579693
  } else {
579657
- writeToStdout(source_default.green(`Successfully updated from ${"0.7.5"} to version ${result.latestVersion}`) + `
579694
+ writeToStdout(source_default.green(`Successfully updated from ${"0.7.7"} to version ${result.latestVersion}`) + `
579658
579695
  `);
579659
579696
  await regenerateCompletionCache();
579660
579697
  }
@@ -579714,12 +579751,12 @@ async function update() {
579714
579751
  `);
579715
579752
  await gracefulShutdown(1);
579716
579753
  }
579717
- if (latestVersion === "0.7.5") {
579718
- writeToStdout(source_default.green(`Verboo Code is up to date (${"0.7.5"})`) + `
579754
+ if (latestVersion === "0.7.7") {
579755
+ writeToStdout(source_default.green(`Verboo Code is up to date (${"0.7.7"})`) + `
579719
579756
  `);
579720
579757
  await gracefulShutdown(0);
579721
579758
  }
579722
- writeToStdout(`New version available: ${latestVersion} (current: ${"0.7.5"})
579759
+ writeToStdout(`New version available: ${latestVersion} (current: ${"0.7.7"})
579723
579760
  `);
579724
579761
  writeToStdout(`Installing update...
579725
579762
  `);
@@ -579764,7 +579801,7 @@ async function update() {
579764
579801
  logForDebugging2(`update: Installation status: ${status2}`);
579765
579802
  switch (status2) {
579766
579803
  case "success":
579767
- writeToStdout(source_default.green(`Successfully updated from ${"0.7.5"} to version ${latestVersion}`) + `
579804
+ writeToStdout(source_default.green(`Successfully updated from ${"0.7.7"} to version ${latestVersion}`) + `
579768
579805
  `);
579769
579806
  await regenerateCompletionCache();
579770
579807
  break;
@@ -580369,7 +580406,7 @@ ${getTmuxInstallInstructions2()}
580369
580406
  const files2 = parseFileSpecs(fileSpecs);
580370
580407
  if (files2.length > 0) {
580371
580408
  const config3 = {
580372
- baseUrl: process.env.ANTHROPIC_BASE_URL || getOauthConfig().BASE_API_URL,
580409
+ baseUrl: isVerbooMode() ? getOauthConfig().BASE_API_URL : process.env.ANTHROPIC_BASE_URL || getOauthConfig().BASE_API_URL,
580373
580410
  oauthToken: sessionToken,
580374
580411
  sessionId: fileSessionId
580375
580412
  };
@@ -581817,7 +581854,7 @@ Usage: verboo --remote "your task description"`, () => gracefulShutdown(1));
581817
581854
  pendingHookMessages
581818
581855
  }, renderAndRun);
581819
581856
  }
581820
- }).version(`0.7.5 (${cliDesc})`, "-v, --version", "Output the version number");
581857
+ }).version(`0.7.7 (${cliDesc})`, "-v, --version", "Output the version number");
581821
581858
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
581822
581859
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
581823
581860
  if (canUserConfigureAdvisor()) {
@@ -582373,7 +582410,7 @@ if (false) {}
582373
582410
  async function main2() {
582374
582411
  const args = process.argv.slice(2);
582375
582412
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
582376
- console.log(`${"0.7.5"} (Verboo Code)`);
582413
+ console.log(`${"0.7.7"} (Verboo Code)`);
582377
582414
  return;
582378
582415
  }
582379
582416
  if (args.includes("--provider")) {
@@ -582528,4 +582565,4 @@ async function main2() {
582528
582565
  }
582529
582566
  main2();
582530
582567
 
582531
- //# debugId=502A51FF8BE4AE2164756E2164756E21
582568
+ //# debugId=2A7860A73BFAD4B264756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verboo/code",
3
- "version": "0.7.5",
3
+ "version": "0.7.7",
4
4
  "description": "Verboo Code — coding agent for the Verboo platform",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,10 +10,12 @@
10
10
  "bin/verboo",
11
11
  "bin/import-specifier.mjs",
12
12
  "dist/cli.mjs",
13
+ "scripts/postinstall.mjs",
13
14
  "README.md"
14
15
  ],
15
16
  "scripts": {
16
17
  "build": "bun run scripts/build.ts",
18
+ "postinstall": "node scripts/postinstall.mjs || true",
17
19
  "dev": "bun run build && node dist/cli.mjs",
18
20
  "dev:profile": "bun run scripts/provider-launch.ts",
19
21
  "dev:profile:fast": "bun run scripts/provider-launch.ts auto --fast --bare",
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Postinstall: garante que o binário `verboo` fique disponível no fish shell.
4
+ *
5
+ * O npm instala globalmente no prefixo retornado por `npm prefix -g` (ex:
6
+ * /usr/local ou ~/.npm-global). Shells bash/zsh geralmente já têm esse bin no
7
+ * PATH via .bashrc/.zshrc, mas o fish não herda essas configs — é preciso
8
+ * chamar `fish_add_path` explicitamente.
9
+ */
10
+
11
+ import { execFileSync, spawnSync } from 'node:child_process'
12
+ import { existsSync } from 'node:fs'
13
+ import { join } from 'node:path'
14
+
15
+ function isFishShell() {
16
+ const shell = process.env.SHELL ?? ''
17
+ const parent = process.env.FISH_VERSION // set by fish itself
18
+ return shell.endsWith('/fish') || parent !== undefined
19
+ }
20
+
21
+ function getNpmGlobalBin() {
22
+ try {
23
+ const prefix = execFileSync('npm', ['prefix', '-g'], { encoding: 'utf8' }).trim()
24
+ return join(prefix, 'bin')
25
+ } catch {
26
+ return null
27
+ }
28
+ }
29
+
30
+ function fishAddPath(dir) {
31
+ const result = spawnSync('fish', ['-c', `fish_add_path ${dir}`], {
32
+ stdio: 'inherit',
33
+ timeout: 5000,
34
+ })
35
+ return result.status === 0
36
+ }
37
+
38
+ if (isFishShell()) {
39
+ const binDir = getNpmGlobalBin()
40
+ if (binDir && existsSync(binDir)) {
41
+ const ok = fishAddPath(binDir)
42
+ if (ok) {
43
+ process.stdout.write(`[verboo] fish_add_path ${binDir} — feito.\n`)
44
+ } else {
45
+ process.stdout.write(
46
+ `[verboo] Não foi possível adicionar ${binDir} ao fish automaticamente.\n` +
47
+ ` Execute manualmente: fish_add_path ${binDir}\n`,
48
+ )
49
+ }
50
+ }
51
+ }