nvicode 0.1.11 → 0.1.13

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
@@ -1,30 +1,115 @@
1
- # NviCode
1
+ # NviCode - Introducing one click Nvidia/OpenRouter keys to Claude Code. Free Claude code.
2
2
 
3
- Connect Claude Code to NVIDIA or OpenRouter.
3
+ [![CI](https://github.com/dineshpotla/nvicode/actions/workflows/ci.yml/badge.svg)](https://github.com/dineshpotla/nvicode/actions/workflows/ci.yml)
4
+ [![npm version](https://img.shields.io/npm/v/nvicode)](https://www.npmjs.com/package/nvicode)
5
+ [![package](https://img.shields.io/badge/package-nvicode-orange)](https://www.npmjs.com/package/nvicode)
6
+ [![node >=20](https://img.shields.io/badge/node-%3E%3D20-339933)](https://nodejs.org/)
7
+ [![license: MIT](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
4
8
 
5
- ## Install
9
+ Internally, `nvicode` sits between Claude Code and the selected provider.
10
+ For NVIDIA, it starts a local Anthropic-compatible proxy that translates Claude Code requests to NVIDIA chat completions.
11
+ For OpenRouter, it points Claude Code directly at OpenRouter's compatible endpoint and applies the selected model configuration.
12
+
13
+ Supported environments:
14
+ - macOS
15
+ - Ubuntu/Linux
16
+ - WSL
17
+ - Native Windows with Claude Code installed and working from PowerShell, CMD, or Git Bash
18
+
19
+ ## Quickstart
20
+
21
+ Install the published package:
6
22
 
7
23
  ```sh
8
24
  npm install -g nvicode
9
25
  ```
10
26
 
11
- ## Setup
27
+ Set up provider, key, and model:
12
28
 
13
29
  ```sh
14
30
  nvicode select model
15
31
  ```
16
32
 
17
- NVIDIA keys: [https://build.nvidia.com/settings/api-keys](https://build.nvidia.com/settings/api-keys)
33
+ The setup flow asks for provider, API key, and model:
34
+
35
+ - NVIDIA: get a free key from [NVIDIA Build API Keys](https://build.nvidia.com/settings/api-keys)
36
+ - OpenRouter: use your OpenRouter API key
18
37
 
19
- ## Launch
38
+ Launch Claude Code through your selected provider:
20
39
 
21
40
  ```sh
22
41
  nvicode launch claude
23
42
  ```
24
43
 
25
- After the first successful launch, plain `claude` continues to use the selected `nvicode` provider and model.
44
+ The first successful `nvicode launch claude` also installs persistent plain-`claude` routing.
45
+ After that, restarting your terminal or PC and running:
46
+
47
+ ```sh
48
+ claude
49
+ ```
50
+
51
+ will continue using your selected `nvicode` provider and model.
52
+
53
+ ## Screenshots
54
+
55
+ ### Save your API key
56
+
57
+ ![nvicode auth](https://raw.githubusercontent.com/dineshpotla/nvicode/main/assets/screenshots/auth.png)
58
+
59
+ ### Choose a model
60
+
61
+ ![nvicode select model](https://raw.githubusercontent.com/dineshpotla/nvicode/main/assets/screenshots/select-model.png)
62
+
63
+ ### Launch Claude Code through your selected provider
64
+
65
+ ![nvicode launch claude](https://raw.githubusercontent.com/dineshpotla/nvicode/main/assets/screenshots/launch.png)
66
+
67
+ ## Commands
68
+
69
+ Useful commands:
70
+
71
+ ```sh
72
+ nvicode dashboard
73
+ nvicode usage
74
+ nvicode activity
75
+ nvicode models
76
+ nvicode config
77
+ nvicode auth
78
+ nvicode launch claude -p "Reply with exactly OK"
79
+ ```
80
+
81
+ Provider behavior:
82
+ - NVIDIA: starts a local proxy on `127.0.0.1:8788`, points Claude Code at it with `ANTHROPIC_BASE_URL`, and forwards requests to NVIDIA `chat/completions`.
83
+ - OpenRouter: points Claude Code directly at `https://openrouter.ai/api` using OpenRouter credentials and Anthropic-compatible model ids.
84
+
85
+ In an interactive terminal, `nvicode usage` refreshes live every 2 seconds. When piped or redirected, it prints a single snapshot.
86
+
87
+ `nvicode select model` now asks for provider, optional API key update, and model choice in one guided flow.
88
+ If no API key is saved for the active provider yet, `nvicode` prompts for one on first use.
89
+ By default, the proxy paces upstream NVIDIA requests at `40 RPM`. Override that with `NVICODE_MAX_RPM` if your account has a different limit.
90
+ The usage dashboard compares your local NVIDIA run cost against Claude Opus 4.6 at `$5 / MTok input` and `$25 / MTok output`, based on Anthropic pricing as of `2026-03-30`.
91
+ If your NVIDIA endpoint is not free, override local cost estimates with `NVICODE_INPUT_USD_PER_MTOK` and `NVICODE_OUTPUT_USD_PER_MTOK`.
92
+ Local `usage`, `activity`, and `dashboard` commands are available for NVIDIA proxy sessions. OpenRouter sessions use OpenRouter's direct connection path instead.
26
93
 
27
94
  ## Requirements
28
95
 
29
- - Claude Code must already be installed
30
- - Node.js 20 or newer
96
+ - Claude Code must already be installed on the machine.
97
+ - Node.js 20 or newer is required to install `nvicode`.
98
+ - On native Windows, Claude Code itself requires Git for Windows. See the [Claude Code setup docs](https://code.claude.com/docs/en/setup).
99
+
100
+ ## Local Development
101
+
102
+ These steps are only for contributors working from a git checkout. End users do not need them.
103
+
104
+ ```sh
105
+ npm install
106
+ npm run build
107
+ npm link
108
+ ```
109
+
110
+ ## Notes
111
+
112
+ - `thinking` is disabled by default because some NVIDIA reasoning models can consume the entire output budget and return no visible answer to Claude Code.
113
+ - The proxy supports basic text, tool calls, tool results, and token count estimation.
114
+ - The proxy includes upstream request pacing and retries on NVIDIA `429` responses.
115
+ - Claude Code remains the frontend; the selected provider/model becomes the backend.
@@ -1,4 +1,5 @@
1
1
  import { spawnSync } from "node:child_process";
2
+ import { promises as fs } from "node:fs";
2
3
  import path from "node:path";
3
4
  import process from "node:process";
4
5
  import { fileURLToPath } from "node:url";
@@ -7,6 +8,48 @@ const isTruthy = (value) => value === "1" || value === "true" || value === "yes"
7
8
  const isGlobalInstall = () => process.env.npm_config_global === "true" ||
8
9
  process.env.npm_config_location === "global";
9
10
  const isInteractive = () => Boolean(process.stdin.isTTY && process.stdout.isTTY);
11
+ const getCliPath = () => path.join(path.dirname(fileURLToPath(import.meta.url)), "cli.js");
12
+ const getGlobalBinDir = () => {
13
+ const prefix = process.env.npm_config_prefix || process.env.PREFIX;
14
+ if (!prefix) {
15
+ return null;
16
+ }
17
+ return process.platform === "win32" ? prefix : path.join(prefix, "bin");
18
+ };
19
+ const createGlobalLauncher = async () => {
20
+ const binDir = getGlobalBinDir();
21
+ if (!binDir) {
22
+ return "skipped";
23
+ }
24
+ const cliPath = getCliPath();
25
+ const launcherPath = process.platform === "win32"
26
+ ? path.join(binDir, "nvicode.cmd")
27
+ : path.join(binDir, "nvicode");
28
+ const launcherContents = process.platform === "win32"
29
+ ? [
30
+ "@echo off",
31
+ `node "${cliPath}" %*`,
32
+ "",
33
+ ].join("\r\n")
34
+ : [
35
+ "#!/bin/sh",
36
+ `exec node "${cliPath}" "$@"`,
37
+ "",
38
+ ].join("\n");
39
+ try {
40
+ await fs.lstat(launcherPath);
41
+ return "skipped";
42
+ }
43
+ catch {
44
+ // create launcher only when npm did not create the command entry
45
+ }
46
+ await fs.mkdir(binDir, { recursive: true });
47
+ await fs.writeFile(launcherPath, launcherContents, "utf8");
48
+ if (process.platform !== "win32") {
49
+ await fs.chmod(launcherPath, 0o755);
50
+ }
51
+ return "created";
52
+ };
10
53
  const main = async () => {
11
54
  if (isTruthy(process.env.NVICODE_SKIP_POSTINSTALL) || isTruthy(process.env.CI)) {
12
55
  return;
@@ -14,6 +57,12 @@ const main = async () => {
14
57
  if (!isGlobalInstall()) {
15
58
  return;
16
59
  }
60
+ try {
61
+ await createGlobalLauncher();
62
+ }
63
+ catch {
64
+ // keep install resilient even if the launcher cannot be created manually
65
+ }
17
66
  if (!isInteractive()) {
18
67
  console.log("nvicode installed. Run `nvicode select model` to finish setup.");
19
68
  return;
@@ -27,7 +76,7 @@ const main = async () => {
27
76
  console.log("nvicode installed. Starting guided setup.");
28
77
  console.log("If you want to skip now, press Ctrl+C and run `nvicode select model` later.");
29
78
  console.log("");
30
- const cliPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "cli.js");
79
+ const cliPath = getCliPath();
31
80
  const result = spawnSync(process.execPath, [cliPath, "select", "model"], {
32
81
  stdio: "inherit",
33
82
  env: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nvicode",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "NviCode - Introducing one click Nvidia/OpenRouter keys to Claude Code. Free Claude code.",
5
5
  "author": "Dinesh Potla",
6
6
  "keywords": [
@@ -17,7 +17,7 @@
17
17
  "nvicode": "dist/cli.js"
18
18
  },
19
19
  "scripts": {
20
- "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true,maxRetries:10,retryDelay:100})\" && tsc -p tsconfig.json",
20
+ "build": "tsc -p tsconfig.json",
21
21
  "prepack": "npm run build",
22
22
  "postinstall": "node dist/postinstall.js",
23
23
  "typecheck": "tsc --noEmit",