@victor-software-house/pi-openai-proxy 0.3.0 → 1.0.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/dist/config.d.mts +33 -0
- package/dist/config.mjs +78 -0
- package/dist/index.d.mts +1 -10
- package/dist/index.mjs +331 -3020
- package/extensions/proxy.ts +67 -156
- package/package.json +19 -7
package/extensions/proxy.ts
CHANGED
|
@@ -4,141 +4,45 @@
|
|
|
4
4
|
* Command family:
|
|
5
5
|
* /proxy Open settings panel
|
|
6
6
|
* /proxy start Start the proxy server
|
|
7
|
-
* /proxy stop Stop the proxy server
|
|
7
|
+
* /proxy stop Stop the proxy server
|
|
8
8
|
* /proxy status Show proxy status
|
|
9
9
|
* /proxy config Open settings panel (alias)
|
|
10
10
|
* /proxy show Summarize current config
|
|
11
11
|
* /proxy path Show config file location
|
|
12
12
|
* /proxy reset Restore default settings
|
|
13
13
|
* /proxy help Usage line
|
|
14
|
+
*
|
|
15
|
+
* Config schema imported from @victor-software-house/pi-openai-proxy/config (SSOT).
|
|
14
16
|
*/
|
|
15
17
|
|
|
18
|
+
import { type ChildProcess, spawn } from "node:child_process";
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
20
|
+
import { dirname, resolve } from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
16
22
|
import {
|
|
17
|
-
getSettingsListTheme,
|
|
18
23
|
type ExtensionAPI,
|
|
19
24
|
type ExtensionCommandContext,
|
|
20
25
|
type ExtensionContext,
|
|
26
|
+
getSettingsListTheme,
|
|
21
27
|
} from "@mariozechner/pi-coding-agent";
|
|
22
|
-
import { Container, SettingsList, Text
|
|
23
|
-
|
|
28
|
+
import { Container, type SettingItem, SettingsList, Text } from "@mariozechner/pi-tui";
|
|
29
|
+
|
|
30
|
+
// Config schema -- single source of truth
|
|
24
31
|
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} from "node:fs";
|
|
32
|
-
import { dirname, resolve } from "node:path";
|
|
33
|
-
import { fileURLToPath } from "node:url";
|
|
32
|
+
configToEnv,
|
|
33
|
+
DEFAULT_CONFIG,
|
|
34
|
+
getConfigPath,
|
|
35
|
+
loadConfigFromFile,
|
|
36
|
+
saveConfigToFile,
|
|
37
|
+
} from "@victor-software-house/pi-openai-proxy/config";
|
|
34
38
|
|
|
35
39
|
// ---------------------------------------------------------------------------
|
|
36
|
-
//
|
|
40
|
+
// Runtime status
|
|
37
41
|
// ---------------------------------------------------------------------------
|
|
38
42
|
|
|
39
|
-
interface ProxyConfig {
|
|
40
|
-
host: string;
|
|
41
|
-
port: number;
|
|
42
|
-
authToken: string;
|
|
43
|
-
remoteImages: boolean;
|
|
44
|
-
maxBodySizeMb: number;
|
|
45
|
-
upstreamTimeoutSec: number;
|
|
46
|
-
/** "detached" = daemon that outlives the session, "session" = dies with the session */
|
|
47
|
-
lifetime: "detached" | "session";
|
|
48
|
-
}
|
|
49
|
-
|
|
50
43
|
interface RuntimeStatus {
|
|
51
44
|
reachable: boolean;
|
|
52
45
|
models: number;
|
|
53
|
-
managed: boolean;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// ---------------------------------------------------------------------------
|
|
57
|
-
// Defaults and normalization
|
|
58
|
-
// ---------------------------------------------------------------------------
|
|
59
|
-
|
|
60
|
-
const DEFAULT_CONFIG: ProxyConfig = {
|
|
61
|
-
host: "127.0.0.1",
|
|
62
|
-
port: 4141,
|
|
63
|
-
authToken: "",
|
|
64
|
-
remoteImages: false,
|
|
65
|
-
maxBodySizeMb: 50,
|
|
66
|
-
upstreamTimeoutSec: 120,
|
|
67
|
-
lifetime: "detached",
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
function toObject(value: unknown): Record<string, unknown> {
|
|
71
|
-
if (value === null || value === undefined || typeof value !== "object" || Array.isArray(value)) {
|
|
72
|
-
return {};
|
|
73
|
-
}
|
|
74
|
-
return value as Record<string, unknown>;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function clampInt(raw: unknown, min: number, max: number, fallback: number): number {
|
|
78
|
-
if (typeof raw !== "number" || !Number.isFinite(raw)) return fallback;
|
|
79
|
-
return Math.max(min, Math.min(max, Math.round(raw)));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function normalizeConfig(raw: unknown): ProxyConfig {
|
|
83
|
-
const v = toObject(raw);
|
|
84
|
-
return {
|
|
85
|
-
host: typeof v["host"] === "string" && v["host"].length > 0 ? (v["host"] as string) : DEFAULT_CONFIG.host,
|
|
86
|
-
port: clampInt(v["port"], 1, 65535, DEFAULT_CONFIG.port),
|
|
87
|
-
authToken: typeof v["authToken"] === "string" ? (v["authToken"] as string) : DEFAULT_CONFIG.authToken,
|
|
88
|
-
remoteImages: typeof v["remoteImages"] === "boolean" ? (v["remoteImages"] as boolean) : DEFAULT_CONFIG.remoteImages,
|
|
89
|
-
maxBodySizeMb: clampInt(v["maxBodySizeMb"], 1, 500, DEFAULT_CONFIG.maxBodySizeMb),
|
|
90
|
-
upstreamTimeoutSec: clampInt(v["upstreamTimeoutSec"], 5, 600, DEFAULT_CONFIG.upstreamTimeoutSec),
|
|
91
|
-
lifetime: v["lifetime"] === "session" ? "session" : "detached",
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// ---------------------------------------------------------------------------
|
|
96
|
-
// Config persistence
|
|
97
|
-
// ---------------------------------------------------------------------------
|
|
98
|
-
|
|
99
|
-
function getConfigPath(): string {
|
|
100
|
-
const piDir = process.env["PI_CODING_AGENT_DIR"] ?? resolve(process.env["HOME"] ?? "~", ".pi", "agent");
|
|
101
|
-
return resolve(piDir, "proxy-config.json");
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function loadConfig(): ProxyConfig {
|
|
105
|
-
const p = getConfigPath();
|
|
106
|
-
if (!existsSync(p)) return { ...DEFAULT_CONFIG };
|
|
107
|
-
try {
|
|
108
|
-
return normalizeConfig(JSON.parse(readFileSync(p, "utf-8")));
|
|
109
|
-
} catch {
|
|
110
|
-
return { ...DEFAULT_CONFIG };
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function saveConfig(config: ProxyConfig): void {
|
|
115
|
-
const p = getConfigPath();
|
|
116
|
-
const normalized = normalizeConfig(config);
|
|
117
|
-
const tmp = `${p}.tmp`;
|
|
118
|
-
try {
|
|
119
|
-
mkdirSync(dirname(p), { recursive: true });
|
|
120
|
-
writeFileSync(tmp, `${JSON.stringify(normalized, null, "\t")}\n`, "utf-8");
|
|
121
|
-
renameSync(tmp, p);
|
|
122
|
-
} catch {
|
|
123
|
-
if (existsSync(tmp)) unlinkSync(tmp);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// ---------------------------------------------------------------------------
|
|
128
|
-
// Config -> env vars
|
|
129
|
-
// ---------------------------------------------------------------------------
|
|
130
|
-
|
|
131
|
-
function configToEnv(config: ProxyConfig): Record<string, string> {
|
|
132
|
-
const env: Record<string, string> = {};
|
|
133
|
-
env["PI_PROXY_HOST"] = config.host;
|
|
134
|
-
env["PI_PROXY_PORT"] = String(config.port);
|
|
135
|
-
if (config.authToken.length > 0) {
|
|
136
|
-
env["PI_PROXY_AUTH_TOKEN"] = config.authToken;
|
|
137
|
-
}
|
|
138
|
-
env["PI_PROXY_REMOTE_IMAGES"] = String(config.remoteImages);
|
|
139
|
-
env["PI_PROXY_MAX_BODY_SIZE"] = String(config.maxBodySizeMb * 1024 * 1024);
|
|
140
|
-
env["PI_PROXY_UPSTREAM_TIMEOUT_MS"] = String(config.upstreamTimeoutSec * 1000);
|
|
141
|
-
return env;
|
|
142
46
|
}
|
|
143
47
|
|
|
144
48
|
// ---------------------------------------------------------------------------
|
|
@@ -146,12 +50,20 @@ function configToEnv(config: ProxyConfig): Record<string, string> {
|
|
|
146
50
|
// ---------------------------------------------------------------------------
|
|
147
51
|
|
|
148
52
|
export default function proxyExtension(pi: ExtensionAPI): void {
|
|
149
|
-
let config =
|
|
53
|
+
let config = loadConfigFromFile();
|
|
150
54
|
let sessionProcess: ChildProcess | undefined;
|
|
151
55
|
|
|
152
56
|
const extensionDir = dirname(fileURLToPath(import.meta.url));
|
|
153
57
|
const packageRoot = resolve(extensionDir, "..");
|
|
154
|
-
|
|
58
|
+
|
|
59
|
+
// Resolve pi-proxy binary: try workspace node_modules, then global
|
|
60
|
+
function findProxyBinary(): string {
|
|
61
|
+
// In workspace: node_modules/pi-proxy/dist/index.mjs
|
|
62
|
+
const workspaceBin = resolve(packageRoot, "node_modules", "pi-proxy", "dist", "index.mjs");
|
|
63
|
+
if (existsSync(workspaceBin)) return workspaceBin;
|
|
64
|
+
// Fallback: assume pi-proxy is in PATH
|
|
65
|
+
return "pi-proxy";
|
|
66
|
+
}
|
|
155
67
|
|
|
156
68
|
function proxyUrl(): string {
|
|
157
69
|
return `http://${config.host}:${String(config.port)}`;
|
|
@@ -160,12 +72,11 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
160
72
|
// --- Lifecycle ---
|
|
161
73
|
|
|
162
74
|
pi.on("session_start", async (_event, ctx) => {
|
|
163
|
-
config =
|
|
75
|
+
config = loadConfigFromFile();
|
|
164
76
|
await refreshStatus(ctx);
|
|
165
77
|
});
|
|
166
78
|
|
|
167
79
|
pi.on("session_shutdown", async () => {
|
|
168
|
-
// Only kill session-tied processes
|
|
169
80
|
if (sessionProcess !== undefined) {
|
|
170
81
|
sessionProcess.kill("SIGTERM");
|
|
171
82
|
sessionProcess = undefined;
|
|
@@ -205,7 +116,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
205
116
|
return;
|
|
206
117
|
case "reset":
|
|
207
118
|
config = { ...DEFAULT_CONFIG };
|
|
208
|
-
|
|
119
|
+
saveConfigToFile(config);
|
|
209
120
|
ctx.ui.notify("Proxy settings reset to defaults", "info");
|
|
210
121
|
return;
|
|
211
122
|
case "help":
|
|
@@ -219,7 +130,6 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
219
130
|
return;
|
|
220
131
|
}
|
|
221
132
|
|
|
222
|
-
// Default: open settings panel
|
|
223
133
|
if (!ctx.hasUI) {
|
|
224
134
|
ctx.ui.notify("/proxy requires interactive mode. Use /proxy show instead.", "warning");
|
|
225
135
|
return;
|
|
@@ -231,7 +141,8 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
231
141
|
// --- PID file ---
|
|
232
142
|
|
|
233
143
|
function getPidPath(): string {
|
|
234
|
-
const piDir =
|
|
144
|
+
const piDir =
|
|
145
|
+
process.env["PI_CODING_AGENT_DIR"] ?? resolve(process.env["HOME"] ?? "~", ".pi", "agent");
|
|
235
146
|
return resolve(piDir, "proxy.pid");
|
|
236
147
|
}
|
|
237
148
|
|
|
@@ -242,12 +153,10 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
242
153
|
const raw = readFileSync(p, "utf-8").trim();
|
|
243
154
|
const pid = Number.parseInt(raw, 10);
|
|
244
155
|
if (!Number.isFinite(pid) || pid <= 0) return undefined;
|
|
245
|
-
// Check if process is alive
|
|
246
156
|
try {
|
|
247
157
|
process.kill(pid, 0);
|
|
248
158
|
return pid;
|
|
249
159
|
} catch {
|
|
250
|
-
// Process is dead, clean up stale PID file
|
|
251
160
|
unlinkSync(p);
|
|
252
161
|
return undefined;
|
|
253
162
|
}
|
|
@@ -300,9 +209,8 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
300
209
|
}
|
|
301
210
|
|
|
302
211
|
async function startProxy(ctx: ExtensionContext): Promise<void> {
|
|
303
|
-
config =
|
|
212
|
+
config = loadConfigFromFile();
|
|
304
213
|
|
|
305
|
-
// Already running?
|
|
306
214
|
const status = await probe();
|
|
307
215
|
if (status.reachable) {
|
|
308
216
|
ctx.ui.notify(
|
|
@@ -313,7 +221,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
313
221
|
return;
|
|
314
222
|
}
|
|
315
223
|
|
|
316
|
-
//
|
|
224
|
+
// Clean up stale PID
|
|
317
225
|
const existingPid = readPid();
|
|
318
226
|
if (existingPid !== undefined) {
|
|
319
227
|
ctx.ui.notify(`Stale proxy process ${String(existingPid)} -- killing`, "warning");
|
|
@@ -329,12 +237,13 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
329
237
|
ctx.ui.setStatus("proxy", "proxy: starting...");
|
|
330
238
|
|
|
331
239
|
try {
|
|
332
|
-
const proxyEnv =
|
|
240
|
+
const proxyEnv = configToEnv(config);
|
|
241
|
+
const bin = findProxyBinary();
|
|
333
242
|
|
|
334
243
|
if (config.lifetime === "detached") {
|
|
335
|
-
|
|
244
|
+
startDetached(bin, proxyEnv);
|
|
336
245
|
} else {
|
|
337
|
-
startSessionTied(ctx, proxyEnv);
|
|
246
|
+
startSessionTied(ctx, bin, proxyEnv);
|
|
338
247
|
}
|
|
339
248
|
|
|
340
249
|
const ready = await waitForReady(3000);
|
|
@@ -355,11 +264,15 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
355
264
|
}
|
|
356
265
|
}
|
|
357
266
|
|
|
358
|
-
|
|
359
|
-
const
|
|
267
|
+
function startDetached(bin: string, env: Record<string, string>): void {
|
|
268
|
+
const usesBun = bin.endsWith(".mjs");
|
|
269
|
+
const cmd = usesBun ? "bun" : bin;
|
|
270
|
+
const cmdArgs = usesBun ? ["run", bin] : [];
|
|
271
|
+
|
|
272
|
+
const child = spawn(cmd, cmdArgs, {
|
|
360
273
|
stdio: ["ignore", "ignore", "ignore"],
|
|
361
274
|
detached: true,
|
|
362
|
-
env,
|
|
275
|
+
env: { ...process.env, ...env },
|
|
363
276
|
});
|
|
364
277
|
|
|
365
278
|
if (child.pid === undefined) {
|
|
@@ -370,16 +283,20 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
370
283
|
writePid(child.pid);
|
|
371
284
|
}
|
|
372
285
|
|
|
373
|
-
function startSessionTied(ctx: ExtensionContext, env: Record<string, string>): void {
|
|
286
|
+
function startSessionTied(ctx: ExtensionContext, bin: string, env: Record<string, string>): void {
|
|
374
287
|
if (sessionProcess !== undefined) {
|
|
375
288
|
ctx.ui.notify("Session proxy already running", "info");
|
|
376
289
|
return;
|
|
377
290
|
}
|
|
378
291
|
|
|
379
|
-
|
|
292
|
+
const usesBun = bin.endsWith(".mjs");
|
|
293
|
+
const cmd = usesBun ? "bun" : bin;
|
|
294
|
+
const cmdArgs = usesBun ? ["run", bin] : [];
|
|
295
|
+
|
|
296
|
+
sessionProcess = spawn(cmd, cmdArgs, {
|
|
380
297
|
stdio: ["ignore", "pipe", "pipe"],
|
|
381
298
|
detached: false,
|
|
382
|
-
env,
|
|
299
|
+
env: { ...process.env, ...env },
|
|
383
300
|
});
|
|
384
301
|
|
|
385
302
|
sessionProcess.on("exit", (code) => {
|
|
@@ -398,7 +315,6 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
398
315
|
}
|
|
399
316
|
|
|
400
317
|
async function stopProxy(ctx: ExtensionContext): Promise<void> {
|
|
401
|
-
// Session-tied process?
|
|
402
318
|
if (sessionProcess !== undefined) {
|
|
403
319
|
sessionProcess.kill("SIGTERM");
|
|
404
320
|
sessionProcess = undefined;
|
|
@@ -407,7 +323,6 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
407
323
|
return;
|
|
408
324
|
}
|
|
409
325
|
|
|
410
|
-
// Detached process via PID file?
|
|
411
326
|
const pid = readPid();
|
|
412
327
|
if (pid !== undefined) {
|
|
413
328
|
try {
|
|
@@ -421,13 +336,9 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
421
336
|
}
|
|
422
337
|
}
|
|
423
338
|
|
|
424
|
-
// Something else listening?
|
|
425
339
|
const status = await probe();
|
|
426
340
|
if (status.reachable) {
|
|
427
|
-
ctx.ui.notify(
|
|
428
|
-
`Proxy at ${proxyUrl()} was not started by /proxy -- stop it manually`,
|
|
429
|
-
"info",
|
|
430
|
-
);
|
|
341
|
+
ctx.ui.notify(`Proxy at ${proxyUrl()} was not started by /proxy -- stop it manually`, "info");
|
|
431
342
|
} else {
|
|
432
343
|
ctx.ui.notify("Proxy is not running", "info");
|
|
433
344
|
ctx.ui.setStatus("proxy", undefined);
|
|
@@ -440,10 +351,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
440
351
|
const pidTag = pid !== undefined ? ` [pid ${String(pid)}]` : "";
|
|
441
352
|
|
|
442
353
|
if (status.reachable) {
|
|
443
|
-
ctx.ui.notify(
|
|
444
|
-
`${proxyUrl()} -- ${String(status.models)} models available${pidTag}`,
|
|
445
|
-
"info",
|
|
446
|
-
);
|
|
354
|
+
ctx.ui.notify(`${proxyUrl()} -- ${String(status.models)} models available${pidTag}`, "info");
|
|
447
355
|
} else {
|
|
448
356
|
ctx.ui.notify("Proxy not running. Use /proxy start", "info");
|
|
449
357
|
}
|
|
@@ -451,7 +359,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
451
359
|
}
|
|
452
360
|
|
|
453
361
|
async function showConfig(ctx: ExtensionContext): Promise<void> {
|
|
454
|
-
config =
|
|
362
|
+
config = loadConfigFromFile();
|
|
455
363
|
const authDisplay =
|
|
456
364
|
config.authToken.length > 0 ? `enabled (token: ${config.authToken})` : "disabled";
|
|
457
365
|
const lines = [
|
|
@@ -494,7 +402,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
494
402
|
{
|
|
495
403
|
id: "host",
|
|
496
404
|
label: "Bind address",
|
|
497
|
-
description: "Network interface
|
|
405
|
+
description: "Network interface (127.0.0.1 = local only, 0.0.0.0 = all)",
|
|
498
406
|
currentValue: config.host,
|
|
499
407
|
values: ["127.0.0.1", "0.0.0.0"],
|
|
500
408
|
},
|
|
@@ -548,14 +456,15 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
548
456
|
config = { ...config, host: value };
|
|
549
457
|
break;
|
|
550
458
|
case "port":
|
|
551
|
-
config = {
|
|
459
|
+
config = {
|
|
460
|
+
...config,
|
|
461
|
+
port: Math.max(1, Math.min(65535, Number.parseInt(value, 10) || config.port)),
|
|
462
|
+
};
|
|
552
463
|
break;
|
|
553
464
|
case "authToken":
|
|
554
|
-
// Toggle: "enabled" keeps current token or generates one; "disabled" clears
|
|
555
465
|
if (value === "disabled") {
|
|
556
466
|
config = { ...config, authToken: "" };
|
|
557
467
|
} else if (config.authToken.length === 0) {
|
|
558
|
-
// Generate a random token on first enable
|
|
559
468
|
const bytes = new Uint8Array(16);
|
|
560
469
|
crypto.getRandomValues(bytes);
|
|
561
470
|
config = {
|
|
@@ -564,7 +473,6 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
564
473
|
.map((b) => b.toString(16).padStart(2, "0"))
|
|
565
474
|
.join(""),
|
|
566
475
|
};
|
|
567
|
-
// Stash token so the caller can notify the user
|
|
568
476
|
lastGeneratedToken = config.authToken;
|
|
569
477
|
}
|
|
570
478
|
break;
|
|
@@ -582,12 +490,12 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
582
490
|
break;
|
|
583
491
|
}
|
|
584
492
|
}
|
|
585
|
-
|
|
586
|
-
config =
|
|
493
|
+
saveConfigToFile(config);
|
|
494
|
+
config = loadConfigFromFile();
|
|
587
495
|
}
|
|
588
496
|
|
|
589
497
|
async function openSettingsPanel(ctx: ExtensionCommandContext): Promise<void> {
|
|
590
|
-
config =
|
|
498
|
+
config = loadConfigFromFile();
|
|
591
499
|
|
|
592
500
|
await ctx.ui.custom<void>(
|
|
593
501
|
(tui, theme, _kb, done) => {
|
|
@@ -616,7 +524,10 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
616
524
|
container.addChild(settingsList);
|
|
617
525
|
container.addChild(
|
|
618
526
|
new Text(
|
|
619
|
-
theme.fg(
|
|
527
|
+
theme.fg(
|
|
528
|
+
"dim",
|
|
529
|
+
"Esc: close | Arrow keys: navigate | Space: toggle | Restart proxy to apply",
|
|
530
|
+
),
|
|
620
531
|
1,
|
|
621
532
|
0,
|
|
622
533
|
),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@victor-software-house/pi-openai-proxy",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenAI-compatible HTTP proxy for pi's multi-provider model registry",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Victor Software House",
|
|
7
7
|
"repository": {
|
|
@@ -29,6 +29,16 @@
|
|
|
29
29
|
"node": ">=20"
|
|
30
30
|
},
|
|
31
31
|
"type": "module",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"import": "./dist/index.mjs",
|
|
35
|
+
"types": "./dist/index.d.mts"
|
|
36
|
+
},
|
|
37
|
+
"./config": {
|
|
38
|
+
"import": "./dist/config.mjs",
|
|
39
|
+
"types": "./dist/config.d.mts"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
32
42
|
"main": "dist/index.mjs",
|
|
33
43
|
"bin": {
|
|
34
44
|
"pi-openai-proxy": "dist/index.mjs"
|
|
@@ -40,7 +50,7 @@
|
|
|
40
50
|
"scripts": {
|
|
41
51
|
"dev": "bun src/index.ts",
|
|
42
52
|
"build": "tsdown",
|
|
43
|
-
"start": "
|
|
53
|
+
"start": "bun dist/index.mjs",
|
|
44
54
|
"typecheck": "tsc --noEmit",
|
|
45
55
|
"lint": "bun run lint:biome && bun run lint:oxlint",
|
|
46
56
|
"lint:biome": "biome check .",
|
|
@@ -54,6 +64,8 @@
|
|
|
54
64
|
"dependencies": {
|
|
55
65
|
"@mariozechner/pi-ai": "^0.62.0",
|
|
56
66
|
"@mariozechner/pi-coding-agent": "^0.62.0",
|
|
67
|
+
"@sinclair/typebox": "^0.34.0",
|
|
68
|
+
"citty": "^0.1.6",
|
|
57
69
|
"hono": "^4.12.8",
|
|
58
70
|
"zod": "^4.3.6"
|
|
59
71
|
},
|
|
@@ -62,10 +74,6 @@
|
|
|
62
74
|
"@commitlint/cli": "^20.5.0",
|
|
63
75
|
"@commitlint/config-conventional": "^20.5.0",
|
|
64
76
|
"@limegrass/eslint-plugin-import-alias": "^1.6.1",
|
|
65
|
-
"@semantic-release/changelog": "^6.0.3",
|
|
66
|
-
"@semantic-release/git": "^10.0.1",
|
|
67
|
-
"@semantic-release/github": "^12.0.6",
|
|
68
|
-
"@semantic-release/npm": "^13.1.5",
|
|
69
77
|
"@types/bun": "^1.3.11",
|
|
70
78
|
"@types/node": "^25.5.0",
|
|
71
79
|
"eslint-plugin-zod": "^3.5.0",
|
|
@@ -73,6 +81,10 @@
|
|
|
73
81
|
"oxlint": "^1.56.0",
|
|
74
82
|
"oxlint-tsgolint": "^0.17.1",
|
|
75
83
|
"semantic-release": "^25.0.3",
|
|
84
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
85
|
+
"@semantic-release/git": "^10.0.1",
|
|
86
|
+
"@semantic-release/github": "^12.0.6",
|
|
87
|
+
"@semantic-release/npm": "^13.1.5",
|
|
76
88
|
"tsdown": "^0.21.4",
|
|
77
89
|
"typescript": "^5.9.3"
|
|
78
90
|
}
|