@victor-software-house/pi-openai-proxy 0.3.1 → 2.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/README.md +53 -19
- package/dist/config.d.mts +59 -0
- package/dist/config.mjs +118 -0
- package/dist/index.d.mts +1 -10
- package/dist/index.mjs +490 -3029
- package/extensions/proxy.ts +64 -152
- package/package.json +19 -7
package/extensions/proxy.ts
CHANGED
|
@@ -4,153 +4,66 @@
|
|
|
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
46
|
}
|
|
54
47
|
|
|
55
|
-
// ---------------------------------------------------------------------------
|
|
56
|
-
// Defaults and normalization
|
|
57
|
-
// ---------------------------------------------------------------------------
|
|
58
|
-
|
|
59
|
-
const DEFAULT_CONFIG: ProxyConfig = {
|
|
60
|
-
host: "127.0.0.1",
|
|
61
|
-
port: 4141,
|
|
62
|
-
authToken: "",
|
|
63
|
-
remoteImages: false,
|
|
64
|
-
maxBodySizeMb: 50,
|
|
65
|
-
upstreamTimeoutSec: 120,
|
|
66
|
-
lifetime: "detached",
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
function toObject(value: unknown): Record<string, unknown> {
|
|
70
|
-
if (value === null || value === undefined || typeof value !== "object" || Array.isArray(value)) {
|
|
71
|
-
return {};
|
|
72
|
-
}
|
|
73
|
-
return value as Record<string, unknown>;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function clampInt(raw: unknown, min: number, max: number, fallback: number): number {
|
|
77
|
-
if (typeof raw !== "number" || !Number.isFinite(raw)) return fallback;
|
|
78
|
-
return Math.max(min, Math.min(max, Math.round(raw)));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function normalizeConfig(raw: unknown): ProxyConfig {
|
|
82
|
-
const v = toObject(raw);
|
|
83
|
-
return {
|
|
84
|
-
host: typeof v["host"] === "string" && v["host"].length > 0 ? (v["host"] as string) : DEFAULT_CONFIG.host,
|
|
85
|
-
port: clampInt(v["port"], 1, 65535, DEFAULT_CONFIG.port),
|
|
86
|
-
authToken: typeof v["authToken"] === "string" ? (v["authToken"] as string) : DEFAULT_CONFIG.authToken,
|
|
87
|
-
remoteImages: typeof v["remoteImages"] === "boolean" ? (v["remoteImages"] as boolean) : DEFAULT_CONFIG.remoteImages,
|
|
88
|
-
maxBodySizeMb: clampInt(v["maxBodySizeMb"], 1, 500, DEFAULT_CONFIG.maxBodySizeMb),
|
|
89
|
-
upstreamTimeoutSec: clampInt(v["upstreamTimeoutSec"], 5, 600, DEFAULT_CONFIG.upstreamTimeoutSec),
|
|
90
|
-
lifetime: v["lifetime"] === "session" ? "session" : "detached",
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// ---------------------------------------------------------------------------
|
|
95
|
-
// Config persistence
|
|
96
|
-
// ---------------------------------------------------------------------------
|
|
97
|
-
|
|
98
|
-
function getConfigPath(): string {
|
|
99
|
-
const piDir = process.env["PI_CODING_AGENT_DIR"] ?? resolve(process.env["HOME"] ?? "~", ".pi", "agent");
|
|
100
|
-
return resolve(piDir, "proxy-config.json");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function loadConfig(): ProxyConfig {
|
|
104
|
-
const p = getConfigPath();
|
|
105
|
-
if (!existsSync(p)) return { ...DEFAULT_CONFIG };
|
|
106
|
-
try {
|
|
107
|
-
return normalizeConfig(JSON.parse(readFileSync(p, "utf-8")));
|
|
108
|
-
} catch {
|
|
109
|
-
return { ...DEFAULT_CONFIG };
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function saveConfig(config: ProxyConfig): void {
|
|
114
|
-
const p = getConfigPath();
|
|
115
|
-
const normalized = normalizeConfig(config);
|
|
116
|
-
const tmp = `${p}.tmp`;
|
|
117
|
-
try {
|
|
118
|
-
mkdirSync(dirname(p), { recursive: true });
|
|
119
|
-
writeFileSync(tmp, `${JSON.stringify(normalized, null, "\t")}\n`, "utf-8");
|
|
120
|
-
renameSync(tmp, p);
|
|
121
|
-
} catch {
|
|
122
|
-
if (existsSync(tmp)) unlinkSync(tmp);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// ---------------------------------------------------------------------------
|
|
127
|
-
// Config -> env vars
|
|
128
|
-
// ---------------------------------------------------------------------------
|
|
129
|
-
|
|
130
|
-
function configToEnv(config: ProxyConfig): Record<string, string> {
|
|
131
|
-
const env: Record<string, string> = {};
|
|
132
|
-
env["PI_PROXY_HOST"] = config.host;
|
|
133
|
-
env["PI_PROXY_PORT"] = String(config.port);
|
|
134
|
-
if (config.authToken.length > 0) {
|
|
135
|
-
env["PI_PROXY_AUTH_TOKEN"] = config.authToken;
|
|
136
|
-
}
|
|
137
|
-
env["PI_PROXY_REMOTE_IMAGES"] = String(config.remoteImages);
|
|
138
|
-
env["PI_PROXY_MAX_BODY_SIZE"] = String(config.maxBodySizeMb * 1024 * 1024);
|
|
139
|
-
env["PI_PROXY_UPSTREAM_TIMEOUT_MS"] = String(config.upstreamTimeoutSec * 1000);
|
|
140
|
-
return env;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
48
|
// ---------------------------------------------------------------------------
|
|
144
49
|
// Extension
|
|
145
50
|
// ---------------------------------------------------------------------------
|
|
146
51
|
|
|
147
52
|
export default function proxyExtension(pi: ExtensionAPI): void {
|
|
148
|
-
let config =
|
|
53
|
+
let config = loadConfigFromFile();
|
|
149
54
|
let sessionProcess: ChildProcess | undefined;
|
|
150
55
|
|
|
151
56
|
const extensionDir = dirname(fileURLToPath(import.meta.url));
|
|
152
57
|
const packageRoot = resolve(extensionDir, "..");
|
|
153
|
-
|
|
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
|
+
}
|
|
154
67
|
|
|
155
68
|
function proxyUrl(): string {
|
|
156
69
|
return `http://${config.host}:${String(config.port)}`;
|
|
@@ -159,12 +72,11 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
159
72
|
// --- Lifecycle ---
|
|
160
73
|
|
|
161
74
|
pi.on("session_start", async (_event, ctx) => {
|
|
162
|
-
config =
|
|
75
|
+
config = loadConfigFromFile();
|
|
163
76
|
await refreshStatus(ctx);
|
|
164
77
|
});
|
|
165
78
|
|
|
166
79
|
pi.on("session_shutdown", async () => {
|
|
167
|
-
// Only kill session-tied processes
|
|
168
80
|
if (sessionProcess !== undefined) {
|
|
169
81
|
sessionProcess.kill("SIGTERM");
|
|
170
82
|
sessionProcess = undefined;
|
|
@@ -204,7 +116,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
204
116
|
return;
|
|
205
117
|
case "reset":
|
|
206
118
|
config = { ...DEFAULT_CONFIG };
|
|
207
|
-
|
|
119
|
+
saveConfigToFile(config);
|
|
208
120
|
ctx.ui.notify("Proxy settings reset to defaults", "info");
|
|
209
121
|
return;
|
|
210
122
|
case "help":
|
|
@@ -218,7 +130,6 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
218
130
|
return;
|
|
219
131
|
}
|
|
220
132
|
|
|
221
|
-
// Default: open settings panel
|
|
222
133
|
if (!ctx.hasUI) {
|
|
223
134
|
ctx.ui.notify("/proxy requires interactive mode. Use /proxy show instead.", "warning");
|
|
224
135
|
return;
|
|
@@ -230,7 +141,8 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
230
141
|
// --- PID file ---
|
|
231
142
|
|
|
232
143
|
function getPidPath(): string {
|
|
233
|
-
const piDir =
|
|
144
|
+
const piDir =
|
|
145
|
+
process.env["PI_CODING_AGENT_DIR"] ?? resolve(process.env["HOME"] ?? "~", ".pi", "agent");
|
|
234
146
|
return resolve(piDir, "proxy.pid");
|
|
235
147
|
}
|
|
236
148
|
|
|
@@ -241,12 +153,10 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
241
153
|
const raw = readFileSync(p, "utf-8").trim();
|
|
242
154
|
const pid = Number.parseInt(raw, 10);
|
|
243
155
|
if (!Number.isFinite(pid) || pid <= 0) return undefined;
|
|
244
|
-
// Check if process is alive
|
|
245
156
|
try {
|
|
246
157
|
process.kill(pid, 0);
|
|
247
158
|
return pid;
|
|
248
159
|
} catch {
|
|
249
|
-
// Process is dead, clean up stale PID file
|
|
250
160
|
unlinkSync(p);
|
|
251
161
|
return undefined;
|
|
252
162
|
}
|
|
@@ -299,9 +209,8 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
299
209
|
}
|
|
300
210
|
|
|
301
211
|
async function startProxy(ctx: ExtensionContext): Promise<void> {
|
|
302
|
-
config =
|
|
212
|
+
config = loadConfigFromFile();
|
|
303
213
|
|
|
304
|
-
// Already running?
|
|
305
214
|
const status = await probe();
|
|
306
215
|
if (status.reachable) {
|
|
307
216
|
ctx.ui.notify(
|
|
@@ -312,7 +221,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
312
221
|
return;
|
|
313
222
|
}
|
|
314
223
|
|
|
315
|
-
//
|
|
224
|
+
// Clean up stale PID
|
|
316
225
|
const existingPid = readPid();
|
|
317
226
|
if (existingPid !== undefined) {
|
|
318
227
|
ctx.ui.notify(`Stale proxy process ${String(existingPid)} -- killing`, "warning");
|
|
@@ -329,11 +238,12 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
329
238
|
|
|
330
239
|
try {
|
|
331
240
|
const proxyEnv = configToEnv(config);
|
|
241
|
+
const bin = findProxyBinary();
|
|
332
242
|
|
|
333
243
|
if (config.lifetime === "detached") {
|
|
334
|
-
|
|
244
|
+
startDetached(bin, proxyEnv);
|
|
335
245
|
} else {
|
|
336
|
-
startSessionTied(ctx, proxyEnv);
|
|
246
|
+
startSessionTied(ctx, bin, proxyEnv);
|
|
337
247
|
}
|
|
338
248
|
|
|
339
249
|
const ready = await waitForReady(3000);
|
|
@@ -354,8 +264,12 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
354
264
|
}
|
|
355
265
|
}
|
|
356
266
|
|
|
357
|
-
|
|
358
|
-
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, {
|
|
359
273
|
stdio: ["ignore", "ignore", "ignore"],
|
|
360
274
|
detached: true,
|
|
361
275
|
env: { ...process.env, ...env },
|
|
@@ -369,13 +283,17 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
369
283
|
writePid(child.pid);
|
|
370
284
|
}
|
|
371
285
|
|
|
372
|
-
function startSessionTied(ctx: ExtensionContext, env: Record<string, string>): void {
|
|
286
|
+
function startSessionTied(ctx: ExtensionContext, bin: string, env: Record<string, string>): void {
|
|
373
287
|
if (sessionProcess !== undefined) {
|
|
374
288
|
ctx.ui.notify("Session proxy already running", "info");
|
|
375
289
|
return;
|
|
376
290
|
}
|
|
377
291
|
|
|
378
|
-
|
|
292
|
+
const usesBun = bin.endsWith(".mjs");
|
|
293
|
+
const cmd = usesBun ? "bun" : bin;
|
|
294
|
+
const cmdArgs = usesBun ? ["run", bin] : [];
|
|
295
|
+
|
|
296
|
+
sessionProcess = spawn(cmd, cmdArgs, {
|
|
379
297
|
stdio: ["ignore", "pipe", "pipe"],
|
|
380
298
|
detached: false,
|
|
381
299
|
env: { ...process.env, ...env },
|
|
@@ -397,7 +315,6 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
397
315
|
}
|
|
398
316
|
|
|
399
317
|
async function stopProxy(ctx: ExtensionContext): Promise<void> {
|
|
400
|
-
// Session-tied process?
|
|
401
318
|
if (sessionProcess !== undefined) {
|
|
402
319
|
sessionProcess.kill("SIGTERM");
|
|
403
320
|
sessionProcess = undefined;
|
|
@@ -406,7 +323,6 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
406
323
|
return;
|
|
407
324
|
}
|
|
408
325
|
|
|
409
|
-
// Detached process via PID file?
|
|
410
326
|
const pid = readPid();
|
|
411
327
|
if (pid !== undefined) {
|
|
412
328
|
try {
|
|
@@ -420,13 +336,9 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
420
336
|
}
|
|
421
337
|
}
|
|
422
338
|
|
|
423
|
-
// Something else listening?
|
|
424
339
|
const status = await probe();
|
|
425
340
|
if (status.reachable) {
|
|
426
|
-
ctx.ui.notify(
|
|
427
|
-
`Proxy at ${proxyUrl()} was not started by /proxy -- stop it manually`,
|
|
428
|
-
"info",
|
|
429
|
-
);
|
|
341
|
+
ctx.ui.notify(`Proxy at ${proxyUrl()} was not started by /proxy -- stop it manually`, "info");
|
|
430
342
|
} else {
|
|
431
343
|
ctx.ui.notify("Proxy is not running", "info");
|
|
432
344
|
ctx.ui.setStatus("proxy", undefined);
|
|
@@ -439,10 +351,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
439
351
|
const pidTag = pid !== undefined ? ` [pid ${String(pid)}]` : "";
|
|
440
352
|
|
|
441
353
|
if (status.reachable) {
|
|
442
|
-
ctx.ui.notify(
|
|
443
|
-
`${proxyUrl()} -- ${String(status.models)} models available${pidTag}`,
|
|
444
|
-
"info",
|
|
445
|
-
);
|
|
354
|
+
ctx.ui.notify(`${proxyUrl()} -- ${String(status.models)} models available${pidTag}`, "info");
|
|
446
355
|
} else {
|
|
447
356
|
ctx.ui.notify("Proxy not running. Use /proxy start", "info");
|
|
448
357
|
}
|
|
@@ -450,7 +359,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
450
359
|
}
|
|
451
360
|
|
|
452
361
|
async function showConfig(ctx: ExtensionContext): Promise<void> {
|
|
453
|
-
config =
|
|
362
|
+
config = loadConfigFromFile();
|
|
454
363
|
const authDisplay =
|
|
455
364
|
config.authToken.length > 0 ? `enabled (token: ${config.authToken})` : "disabled";
|
|
456
365
|
const lines = [
|
|
@@ -493,7 +402,7 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
493
402
|
{
|
|
494
403
|
id: "host",
|
|
495
404
|
label: "Bind address",
|
|
496
|
-
description: "Network interface
|
|
405
|
+
description: "Network interface (127.0.0.1 = local only, 0.0.0.0 = all)",
|
|
497
406
|
currentValue: config.host,
|
|
498
407
|
values: ["127.0.0.1", "0.0.0.0"],
|
|
499
408
|
},
|
|
@@ -547,14 +456,15 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
547
456
|
config = { ...config, host: value };
|
|
548
457
|
break;
|
|
549
458
|
case "port":
|
|
550
|
-
config = {
|
|
459
|
+
config = {
|
|
460
|
+
...config,
|
|
461
|
+
port: Math.max(1, Math.min(65535, Number.parseInt(value, 10) || config.port)),
|
|
462
|
+
};
|
|
551
463
|
break;
|
|
552
464
|
case "authToken":
|
|
553
|
-
// Toggle: "enabled" keeps current token or generates one; "disabled" clears
|
|
554
465
|
if (value === "disabled") {
|
|
555
466
|
config = { ...config, authToken: "" };
|
|
556
467
|
} else if (config.authToken.length === 0) {
|
|
557
|
-
// Generate a random token on first enable
|
|
558
468
|
const bytes = new Uint8Array(16);
|
|
559
469
|
crypto.getRandomValues(bytes);
|
|
560
470
|
config = {
|
|
@@ -563,7 +473,6 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
563
473
|
.map((b) => b.toString(16).padStart(2, "0"))
|
|
564
474
|
.join(""),
|
|
565
475
|
};
|
|
566
|
-
// Stash token so the caller can notify the user
|
|
567
476
|
lastGeneratedToken = config.authToken;
|
|
568
477
|
}
|
|
569
478
|
break;
|
|
@@ -581,12 +490,12 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
581
490
|
break;
|
|
582
491
|
}
|
|
583
492
|
}
|
|
584
|
-
|
|
585
|
-
config =
|
|
493
|
+
saveConfigToFile(config);
|
|
494
|
+
config = loadConfigFromFile();
|
|
586
495
|
}
|
|
587
496
|
|
|
588
497
|
async function openSettingsPanel(ctx: ExtensionCommandContext): Promise<void> {
|
|
589
|
-
config =
|
|
498
|
+
config = loadConfigFromFile();
|
|
590
499
|
|
|
591
500
|
await ctx.ui.custom<void>(
|
|
592
501
|
(tui, theme, _kb, done) => {
|
|
@@ -615,7 +524,10 @@ export default function proxyExtension(pi: ExtensionAPI): void {
|
|
|
615
524
|
container.addChild(settingsList);
|
|
616
525
|
container.addChild(
|
|
617
526
|
new Text(
|
|
618
|
-
theme.fg(
|
|
527
|
+
theme.fg(
|
|
528
|
+
"dim",
|
|
529
|
+
"Esc: close | Arrow keys: navigate | Space: toggle | Restart proxy to apply",
|
|
530
|
+
),
|
|
619
531
|
1,
|
|
620
532
|
0,
|
|
621
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": "2.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
|
}
|