@thejeetsingh/kalcode 2.0.0 → 2.1.0

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
@@ -62,7 +62,6 @@ Run the backend proxy with your NVIDIA key on a server you control:
62
62
 
63
63
  ```bash
64
64
  export NVIDIA_NIM_KEY="your-real-provider-key"
65
- export KALCODE_PROXY_TOKEN="choose-a-long-random-token"
66
65
  export PORT=8787
67
66
  bun run proxy
68
67
  ```
@@ -71,7 +70,6 @@ Client users run `kalcode` with proxy settings (no NVIDIA key needed on client):
71
70
 
72
71
  ```bash
73
72
  export KALCODE_PROXY_URL="https://your-proxy-domain"
74
- export KALCODE_PROXY_TOKEN="same-token-as-server"
75
73
  kalcode
76
74
  ```
77
75
 
@@ -103,13 +101,11 @@ This repo now includes Vercel serverless endpoints:
103
101
  ### 2) Set Vercel environment variables
104
102
 
105
103
  - `NVIDIA_NIM_KEY` = your provider key (server-only)
106
- - `KALCODE_PROXY_TOKEN` = long random token for client auth
107
104
 
108
105
  ### 3) Configure clients
109
106
 
110
107
  ```bash
111
108
  export KALCODE_PROXY_URL="https://<your-vercel-project>.vercel.app"
112
- export KALCODE_PROXY_TOKEN="<same-token-as-vercel-env>"
113
109
  kalcode
114
110
  ```
115
111
 
package/api/health.ts CHANGED
@@ -1,10 +1,8 @@
1
- export const runtime = "edge";
1
+ export const config = { runtime: "edge" };
2
2
 
3
- export default async function handler(): Promise<Response> {
3
+ export default function handler(_req: Request): Response {
4
4
  return new Response(JSON.stringify({ ok: true }), {
5
5
  status: 200,
6
- headers: {
7
- "Content-Type": "application/json",
8
- },
6
+ headers: { "Content-Type": "application/json" },
9
7
  });
10
8
  }
@@ -1,41 +1,25 @@
1
1
  const API_URL = "https://integrate.api.nvidia.com/v1/chat/completions";
2
2
 
3
- export const runtime = "edge";
3
+ export const config = { runtime: "edge" };
4
4
 
5
5
  function json(status: number, payload: Record<string, unknown>): Response {
6
6
  return new Response(JSON.stringify(payload), {
7
7
  status,
8
- headers: {
9
- "Content-Type": "application/json",
10
- },
8
+ headers: { "Content-Type": "application/json" },
11
9
  });
12
10
  }
13
11
 
14
- function getBearerToken(req: Request): string {
15
- const auth = req.headers.get("authorization") || "";
16
- const m = auth.match(/^Bearer\s+(.+)$/i);
17
- return m?.[1]?.trim() || "";
18
- }
19
-
20
12
  export default async function handler(req: Request): Promise<Response> {
21
13
  if (req.method !== "POST") {
22
14
  return json(405, { error: { message: "Method not allowed." } });
23
15
  }
24
16
 
25
17
  const serverNimKey = process.env.NVIDIA_NIM_KEY || "";
26
- const requiredProxyToken = process.env.KALCODE_PROXY_TOKEN || "";
27
18
 
28
19
  if (!serverNimKey) {
29
20
  return json(500, { error: { message: "Server missing NVIDIA_NIM_KEY." } });
30
21
  }
31
22
 
32
- if (requiredProxyToken) {
33
- const incoming = getBearerToken(req);
34
- if (!incoming || incoming !== requiredProxyToken) {
35
- return json(401, { error: { message: "Unauthorized." } });
36
- }
37
- }
38
-
39
23
  const body = await req.text();
40
24
  const upstream = await fetch(API_URL, {
41
25
  method: "POST",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thejeetsingh/kalcode",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "CLI coding agent powered by NVIDIA NIM",
5
5
  "author": "Jeet Singh",
6
6
  "license": "MIT",
package/src/api/client.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { API_URL, RATE_LIMIT_MAX, RATE_LIMIT_WINDOW, MAX_RETRIES, RETRY_BASE_DELAY } from "../constants.js";
1
+ import { API_URL, DEFAULT_PROXY_URL, RATE_LIMIT_MAX, RATE_LIMIT_WINDOW, MAX_RETRIES, RETRY_BASE_DELAY } from "../constants.js";
2
2
  import type { Message, StreamDelta, ToolDefinition } from "../types.js";
3
3
  import { parseSSEStream } from "./stream-parser.js";
4
4
 
@@ -28,27 +28,18 @@ export async function* streamChat(
28
28
  tools?: ToolDefinition[],
29
29
  onRetry?: (attempt: number, waitSec: number) => void
30
30
  ): AsyncGenerator<StreamDelta> {
31
- const proxyUrl = (process.env.KALCODE_PROXY_URL || "").trim();
32
- const proxyToken = (process.env.KALCODE_PROXY_TOKEN || "").trim();
31
+ const explicitProxy = (process.env.KALCODE_PROXY_URL || "").trim();
32
+ // If no API key and no explicit proxy, auto-use the public Vercel proxy
33
+ const proxyUrl = explicitProxy || (!apiKey ? DEFAULT_PROXY_URL : "");
33
34
  const targetUrl = proxyUrl
34
35
  ? `${proxyUrl.replace(/\/+$/, "")}/v1/chat/completions`
35
36
  : API_URL;
36
- const authToken = proxyUrl ? proxyToken : apiKey;
37
+ const authToken = apiKey;
37
38
 
38
- if (proxyUrl && !proxyToken) {
39
+ if (!proxyUrl && !authToken) {
39
40
  yield {
40
41
  type: "error",
41
- error: "KALCODE_PROXY_URL is set but KALCODE_PROXY_TOKEN is missing.",
42
- };
43
- return;
44
- }
45
-
46
- if (!authToken) {
47
- yield {
48
- type: "error",
49
- error: proxyUrl
50
- ? "Missing proxy auth token."
51
- : "Missing NVIDIA API key.",
42
+ error: "Missing NVIDIA API key.",
52
43
  };
53
44
  return;
54
45
  }
@@ -71,10 +62,14 @@ export async function* streamChat(
71
62
 
72
63
  const response = await fetch(targetUrl, {
73
64
  method: "POST",
74
- headers: {
75
- "Content-Type": "application/json",
76
- Authorization: `Bearer ${authToken}`,
77
- },
65
+ headers: proxyUrl
66
+ ? {
67
+ "Content-Type": "application/json",
68
+ }
69
+ : {
70
+ "Content-Type": "application/json",
71
+ Authorization: `Bearer ${authToken}`,
72
+ },
78
73
  body: JSON.stringify(body),
79
74
  });
80
75
 
package/src/constants.ts CHANGED
@@ -1,7 +1,10 @@
1
- export const VERSION = "2.0.0";
1
+ export const VERSION = "2.1.0";
2
2
 
3
3
  export const API_URL = "https://integrate.api.nvidia.com/v1/chat/completions";
4
4
 
5
+ /** Public proxy — used automatically when no API key is set */
6
+ export const DEFAULT_PROXY_URL = "https://kalcode.vercel.app";
7
+
5
8
  export const DEFAULT_MODEL = "qwen/qwen3-coder-480b-a35b-instruct";
6
9
 
7
10
  export const AVAILABLE_MODELS: { id: string; name: string; params: string }[] = [
package/src/index.ts CHANGED
@@ -41,7 +41,7 @@ const REPL_COMMANDS: { cmd: string; desc: string }[] = [
41
41
 
42
42
  export async function main(): Promise<void> {
43
43
  const { values, positionals } = parseArgs({
44
- args: Bun.argv.slice(2),
44
+ args: process.argv.slice(2),
45
45
  options: {
46
46
  help: { type: "boolean", short: "h" },
47
47
  version: { type: "boolean", short: "v" },
@@ -88,9 +88,9 @@ export async function main(): Promise<void> {
88
88
  if (values["auto-accept"]) setPermissionLevel("auto");
89
89
  if (values.ask) setAskMode(true);
90
90
  const proxyUrl = (process.env.KALCODE_PROXY_URL || "").trim();
91
- const proxyMode = proxyUrl.length > 0;
91
+ const proxyMode = proxyUrl.length > 0 || !config.apiKey; // auto-proxy when no key
92
92
 
93
- // API key check (skip when using proxy mode)
93
+ // API key check skip when proxy will be used (explicit or auto-fallback)
94
94
  if (!proxyMode && !config.apiKey) {
95
95
  console.log("");
96
96
  console.log(chalk.yellow(" No API key found."));
@@ -2,7 +2,6 @@ import { API_URL } from "../constants.js";
2
2
 
3
3
  const PORT = parseInt(process.env.PORT || "8787", 10);
4
4
  const HOST = process.env.HOST || "0.0.0.0";
5
- const PROXY_TOKEN = process.env.KALCODE_PROXY_TOKEN || "";
6
5
  const NVIDIA_NIM_KEY = process.env.NVIDIA_NIM_KEY || "";
7
6
  const RATE_LIMIT_PER_MIN = Math.max(
8
7
  1,
@@ -42,12 +41,6 @@ function isRateLimited(clientId: string): boolean {
42
41
  return false;
43
42
  }
44
43
 
45
- function getBearerToken(req: Request): string {
46
- const auth = req.headers.get("authorization") || "";
47
- const m = auth.match(/^Bearer\s+(.+)$/i);
48
- return m?.[1]?.trim() || "";
49
- }
50
-
51
44
  async function proxyCompletions(req: Request): Promise<Response> {
52
45
  if (!NVIDIA_NIM_KEY) {
53
46
  return json(500, {
@@ -57,17 +50,6 @@ async function proxyCompletions(req: Request): Promise<Response> {
57
50
  });
58
51
  }
59
52
 
60
- if (PROXY_TOKEN) {
61
- const incomingToken = getBearerToken(req);
62
- if (!incomingToken || incomingToken !== PROXY_TOKEN) {
63
- return json(401, {
64
- error: {
65
- message: "Unauthorized. Invalid proxy token.",
66
- },
67
- });
68
- }
69
- }
70
-
71
53
  const clientId = getClientId(req);
72
54
  if (isRateLimited(clientId)) {
73
55
  return json(429, {
package/tsconfig.json CHANGED
@@ -11,5 +11,6 @@
11
11
  "rootDir": ".",
12
12
  "types": ["bun"]
13
13
  },
14
- "include": ["src/**/*", "bin/**/*", "api/**/*"]
14
+ "include": ["src/**/*", "bin/**/*"],
15
+ "exclude": ["api"]
15
16
  }
package/vercel.json CHANGED
@@ -1,4 +1,5 @@
1
1
  {
2
+ "framework": null,
2
3
  "rewrites": [
3
4
  {
4
5
  "source": "/v1/chat/completions",