@victor-software-house/pi-openai-proxy 4.9.4 → 4.9.5

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
@@ -20,10 +20,10 @@ A local OpenAI-compatible HTTP proxy built on [pi](https://github.com/badlogic/p
20
20
 
21
21
  ```bash
22
22
  # Install globally
23
- npm install -g @victor-software-house/pi-openai-proxy
23
+ pnpm add -g @victor-software-house/pi-openai-proxy
24
24
 
25
- # Or run directly with npx
26
- npx @victor-software-house/pi-openai-proxy
25
+ # Or run directly
26
+ pnpm dlx @victor-software-house/pi-openai-proxy
27
27
  ```
28
28
 
29
29
  ## Quickstart
@@ -339,17 +339,18 @@ The extension detects externally running instances and shows their status via `/
339
339
  ## Dev Workflow
340
340
 
341
341
  ```bash
342
- bun install # Install dependencies
343
- bun run dev # Run in development
344
- bun run build # Build for npm (tsdown)
345
- bun run typecheck # TypeScript strict check
346
- bun run lint # Biome + oxlint (strict)
347
- bun test # Run all tests
342
+ pnpm install # Install dependencies
343
+ pnpm run dev # Run in development
344
+ pnpm run build # Build for npm (tsdown)
345
+ pnpm run typecheck # TypeScript strict check
346
+ pnpm run lint # Biome + oxlint (strict)
347
+ pnpm test # Run all tests
348
348
  ```
349
349
 
350
350
  ### Tooling
351
351
 
352
- - **Bun** — runtime, test runner, package manager
352
+ - **pnpm** — package manager and script runner
353
+ - **Bun** — runtime and test runner
353
354
  - **tsdown** — npm build (ESM + .d.ts)
354
355
  - **Biome** — format + lint
355
356
  - **oxlint** — type-aware lint with strict rules (`.oxlintrc.json`)
package/dist/index.mjs CHANGED
@@ -761,7 +761,7 @@ async function* streamToSSE(events, requestId, model, includeUsage) {
761
761
  yield encodeDone();
762
762
  }
763
763
  //#endregion
764
- //#region node_modules/typebox/build/system/memory/metrics.mjs
764
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/system/memory/metrics.mjs
765
765
  /** TypeBox instantiation metrics */
766
766
  const Metrics = {
767
767
  assign: 0,
@@ -771,7 +771,7 @@ const Metrics = {
771
771
  update: 0
772
772
  };
773
773
  //#endregion
774
- //#region node_modules/typebox/build/guard/guard.mjs
774
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/guard/guard.mjs
775
775
  /** Returns true if this value is an array */
776
776
  function IsArray(value) {
777
777
  return Array.isArray(value);
@@ -816,7 +816,7 @@ function Keys(value) {
816
816
  return Object.getOwnPropertyNames(value);
817
817
  }
818
818
  //#endregion
819
- //#region node_modules/typebox/build/system/memory/clone.mjs
819
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/system/memory/clone.mjs
820
820
  function IsGuard(value) {
821
821
  return IsObject(value) && HasPropertyKey(value, "~guard");
822
822
  }
@@ -857,7 +857,7 @@ function Clone(value) {
857
857
  return FromValue(value);
858
858
  }
859
859
  //#endregion
860
- //#region node_modules/typebox/build/system/settings/settings.mjs
860
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/system/settings/settings.mjs
861
861
  const settings = {
862
862
  immutableTypes: false,
863
863
  maxErrors: 8,
@@ -871,7 +871,7 @@ function Get() {
871
871
  return settings;
872
872
  }
873
873
  //#endregion
874
- //#region node_modules/typebox/build/system/memory/create.mjs
874
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/system/memory/create.mjs
875
875
  function MergeHidden(left, right) {
876
876
  for (const key of Object.keys(right)) Object.defineProperty(left, key, {
877
877
  configurable: true,
@@ -900,7 +900,7 @@ function Create(hidden, enumerable, options = {}) {
900
900
  return settings.immutableTypes ? Object.freeze(withHidden) : withHidden;
901
901
  }
902
902
  //#endregion
903
- //#region node_modules/typebox/build/system/memory/update.mjs
903
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/system/memory/update.mjs
904
904
  /**
905
905
  * Updates a value with new properties while preserving property enumerability. Use this function to modify
906
906
  * existing types without altering their configuration.
@@ -924,12 +924,12 @@ function Update(current, hidden, enumerable) {
924
924
  return result;
925
925
  }
926
926
  //#endregion
927
- //#region node_modules/typebox/build/type/types/schema.mjs
927
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/schema.mjs
928
928
  function IsSchema(value) {
929
929
  return IsObject(value);
930
930
  }
931
931
  //#endregion
932
- //#region node_modules/typebox/build/type/types/_optional.mjs
932
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/_optional.mjs
933
933
  /** Adds Optional to the given type. */
934
934
  function OptionalAdd(type) {
935
935
  return Update(type, { "~optional": true }, {});
@@ -943,7 +943,7 @@ function IsOptional(value) {
943
943
  return IsSchema(value) && HasPropertyKey(value, "~optional");
944
944
  }
945
945
  //#endregion
946
- //#region node_modules/typebox/build/type/types/array.mjs
946
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/array.mjs
947
947
  /** Creates an Array type. */
948
948
  function _Array_(items, options) {
949
949
  return Create({ "~kind": "Array" }, {
@@ -952,37 +952,36 @@ function _Array_(items, options) {
952
952
  }, options);
953
953
  }
954
954
  //#endregion
955
- //#region node_modules/typebox/build/type/types/properties.mjs
955
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/properties.mjs
956
956
  /** Creates a RequiredArray derived from the given TProperties value. */
957
957
  function RequiredArray(properties) {
958
958
  return Keys(properties).filter((key) => !IsOptional(properties[key]));
959
959
  }
960
960
  //#endregion
961
- //#region node_modules/typebox/build/type/types/object.mjs
961
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/object.mjs
962
962
  /** Creates an Object type. */
963
963
  function _Object_(properties, options = {}) {
964
964
  const requiredKeys = RequiredArray(properties);
965
- const required = requiredKeys.length > 0 ? { required: requiredKeys } : {};
966
965
  return Create({ "~kind": "Object" }, {
967
966
  type: "object",
968
- ...required,
967
+ ...requiredKeys.length > 0 ? { required: requiredKeys } : {},
969
968
  properties
970
969
  }, options);
971
970
  }
972
971
  //#endregion
973
- //#region node_modules/typebox/build/type/types/union.mjs
972
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/union.mjs
974
973
  /** Creates a Union type. */
975
974
  function Union(anyOf, options = {}) {
976
975
  return Create({ "~kind": "Union" }, { anyOf }, options);
977
976
  }
978
977
  //#endregion
979
- //#region node_modules/typebox/build/type/types/unknown.mjs
978
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/unknown.mjs
980
979
  /** Creates an Unknown type. */
981
980
  function Unknown(options) {
982
981
  return Create({ ["~kind"]: "Unknown" }, {}, options);
983
982
  }
984
983
  //#endregion
985
- //#region node_modules/typebox/build/system/hashing/hash.mjs
984
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/system/hashing/hash.mjs
986
985
  var ByteMarker;
987
986
  (function(ByteMarker) {
988
987
  ByteMarker[ByteMarker["Array"] = 0] = "Array";
@@ -1000,27 +999,26 @@ var ByteMarker;
1000
999
  ByteMarker[ByteMarker["TypeArray"] = 12] = "TypeArray";
1001
1000
  ByteMarker[ByteMarker["Undefined"] = 13] = "Undefined";
1002
1001
  })(ByteMarker || (ByteMarker = {}));
1003
- const [Prime, Size] = [BigInt("1099511628211"), BigInt("18446744073709551616")];
1004
1002
  Array.from({ length: 256 }).map((_, i) => BigInt(i));
1005
1003
  const F64 = new Float64Array(1);
1006
1004
  new DataView(F64.buffer);
1007
1005
  new Uint8Array(F64.buffer);
1008
1006
  new TextEncoder();
1009
1007
  //#endregion
1010
- //#region node_modules/typebox/build/type/types/boolean.mjs
1008
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/boolean.mjs
1011
1009
  /** Creates a Boolean type. */
1012
1010
  function Boolean(options) {
1013
1011
  return Create({ "~kind": "Boolean" }, { type: "boolean" }, options);
1014
1012
  }
1015
1013
  //#endregion
1016
- //#region node_modules/typebox/build/type/types/integer.mjs
1014
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/integer.mjs
1017
1015
  const IntegerPattern = "-?(?:0|[1-9][0-9]*)";
1018
1016
  /** Creates a Integer type. */
1019
1017
  function Integer(options) {
1020
1018
  return Create({ "~kind": "Integer" }, { type: "integer" }, options);
1021
1019
  }
1022
1020
  //#endregion
1023
- //#region node_modules/typebox/build/type/types/literal.mjs
1021
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/literal.mjs
1024
1022
  var InvalidLiteralValue = class extends Error {
1025
1023
  constructor(value) {
1026
1024
  super(`Invalid Literal value`);
@@ -1045,30 +1043,30 @@ function Literal(value, options) {
1045
1043
  }, options);
1046
1044
  }
1047
1045
  //#endregion
1048
- //#region node_modules/typebox/build/type/types/null.mjs
1046
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/null.mjs
1049
1047
  /** Creates a Null type. */
1050
1048
  function Null(options) {
1051
1049
  return Create({ "~kind": "Null" }, { type: "null" }, options);
1052
1050
  }
1053
1051
  //#endregion
1054
- //#region node_modules/typebox/build/type/types/number.mjs
1052
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/number.mjs
1055
1053
  const NumberPattern = "-?(?:0|[1-9][0-9]*)(?:.[0-9]+)?";
1056
1054
  /** Creates a Number type. */
1057
1055
  function Number$1(options) {
1058
1056
  return Create({ "~kind": "Number" }, { type: "number" }, options);
1059
1057
  }
1060
1058
  //#endregion
1061
- //#region node_modules/typebox/build/type/types/string.mjs
1059
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/string.mjs
1062
1060
  /** Creates a String type. */
1063
1061
  function String$1(options) {
1064
1062
  return Create({ "~kind": "String" }, { type: "string" }, options);
1065
1063
  }
1066
1064
  //#endregion
1067
- //#region node_modules/typebox/build/type/types/record.mjs
1065
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/types/record.mjs
1068
1066
  const IntegerKey = `^${IntegerPattern}$`;
1069
1067
  `${NumberPattern}`;
1070
1068
  //#endregion
1071
- //#region node_modules/typebox/build/type/script/token/internal/char.mjs
1069
+ //#region node_modules/.pnpm/typebox@1.1.38/node_modules/typebox/build/type/script/token/internal/char.mjs
1072
1070
  function Range(start, end) {
1073
1071
  return Array.from({ length: end - start + 1 }, (_, i) => String.fromCharCode(start + i));
1074
1072
  }
@@ -20,8 +20,10 @@
20
20
  */
21
21
 
22
22
  import { type ChildProcess, spawn } from "node:child_process";
23
- import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
24
- import { dirname, resolve } from "node:path";
23
+ import { constants, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
24
+ import { access } from "node:fs/promises";
25
+ import { homedir } from "node:os";
26
+ import { delimiter, dirname, join, resolve } from "node:path";
25
27
  import { fileURLToPath } from "node:url";
26
28
  import type { Api, Model } from "@mariozechner/pi-ai";
27
29
  import {
@@ -129,6 +131,41 @@ export default function proxyExtension(pi: ExtensionAPI): void {
129
131
  return "pi-proxy";
130
132
  }
131
133
 
134
+ async function isExecutable(path: string): Promise<boolean> {
135
+ try {
136
+ await access(path, constants.X_OK);
137
+ return true;
138
+ } catch {
139
+ return false;
140
+ }
141
+ }
142
+
143
+ async function resolveBunExecutable(): Promise<string> {
144
+ if ("bun" in process.versions) return process.execPath;
145
+
146
+ const bunInstall = process.env["BUN_INSTALL"];
147
+ const pathEntries = (process.env["PATH"] ?? "")
148
+ .split(delimiter)
149
+ .filter((entry) => entry.length > 0);
150
+ const candidates = [
151
+ process.env["PI_OPENAI_PROXY_BUN"],
152
+ bunInstall === undefined ? undefined : join(bunInstall, "bin", "bun"),
153
+ ...pathEntries.map((entry) => join(entry, "bun")),
154
+ join(homedir(), ".bun", "bin", "bun"),
155
+ join(homedir(), ".local", "share", "mise", "installs", "bun", "latest", "bin", "bun"),
156
+ "/opt/homebrew/bin/bun",
157
+ "/usr/local/bin/bun",
158
+ ];
159
+
160
+ for (const candidate of candidates) {
161
+ if (candidate !== undefined && (await isExecutable(candidate))) return candidate;
162
+ }
163
+
164
+ throw new Error(
165
+ "Bun runtime not found. Install Bun or set PI_OPENAI_PROXY_BUN to the Bun executable path.",
166
+ );
167
+ }
168
+
132
169
  function proxyUrl(): string {
133
170
  return `http://${config.host}:${String(config.port)}`;
134
171
  }
@@ -343,9 +380,9 @@ export default function proxyExtension(pi: ExtensionAPI): void {
343
380
  const bin = findProxyBinary();
344
381
 
345
382
  if (config.lifetime === "detached") {
346
- startDetached(bin, proxyEnv);
383
+ await startDetached(bin, proxyEnv);
347
384
  } else {
348
- startSessionTied(ctx, bin, proxyEnv);
385
+ await startSessionTied(ctx, bin, proxyEnv);
349
386
  }
350
387
 
351
388
  const ready = await waitForReady(3000);
@@ -366,9 +403,9 @@ export default function proxyExtension(pi: ExtensionAPI): void {
366
403
  }
367
404
  }
368
405
 
369
- function startDetached(bin: string, env: Record<string, string>): void {
406
+ async function startDetached(bin: string, env: Record<string, string>): Promise<void> {
370
407
  const usesBun = bin.endsWith(".mjs");
371
- const cmd = usesBun ? "bun" : bin;
408
+ const cmd = usesBun ? await resolveBunExecutable() : bin;
372
409
  const cmdArgs = usesBun ? ["run", bin] : [];
373
410
 
374
411
  const child = spawn(cmd, cmdArgs, {
@@ -377,6 +414,10 @@ export default function proxyExtension(pi: ExtensionAPI): void {
377
414
  env: { ...process.env, ...env },
378
415
  });
379
416
 
417
+ child.once("error", () => {
418
+ if (child.pid !== undefined) removePid();
419
+ });
420
+
380
421
  if (child.pid === undefined) {
381
422
  throw new Error("No PID returned from spawn");
382
423
  }
@@ -385,14 +426,18 @@ export default function proxyExtension(pi: ExtensionAPI): void {
385
426
  writePid(child.pid);
386
427
  }
387
428
 
388
- function startSessionTied(ctx: ExtensionContext, bin: string, env: Record<string, string>): void {
429
+ async function startSessionTied(
430
+ ctx: ExtensionContext,
431
+ bin: string,
432
+ env: Record<string, string>,
433
+ ): Promise<void> {
389
434
  if (sessionProcess !== undefined) {
390
435
  ctx.ui.notify("Session proxy already running", "info");
391
436
  return;
392
437
  }
393
438
 
394
439
  const usesBun = bin.endsWith(".mjs");
395
- const cmd = usesBun ? "bun" : bin;
440
+ const cmd = usesBun ? await resolveBunExecutable() : bin;
396
441
  const cmdArgs = usesBun ? ["run", bin] : [];
397
442
 
398
443
  sessionProcess = spawn(cmd, cmdArgs, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@victor-software-house/pi-openai-proxy",
3
- "version": "4.9.4",
3
+ "version": "4.9.5",
4
4
  "description": "OpenAI-compatible HTTP proxy for pi's multi-provider model registry",
5
5
  "license": "MIT",
6
6
  "author": "Victor Software House",
@@ -28,6 +28,7 @@
28
28
  "engines": {
29
29
  "node": ">=20"
30
30
  },
31
+ "packageManager": "pnpm@11.0.0-dev.1005",
31
32
  "type": "module",
32
33
  "exports": {
33
34
  ".": {
@@ -60,7 +61,7 @@
60
61
  "build": "tsdown",
61
62
  "start": "bun dist/index.mjs",
62
63
  "typecheck": "tsc --noEmit",
63
- "lint": "bun run lint:biome && bun run lint:oxlint",
64
+ "lint": "pnpm run lint:biome && pnpm run lint:oxlint",
64
65
  "lint:biome": "biome check .",
65
66
  "lint:oxlint": "oxlint --import-plugin --type-aware --tsconfig=./tsconfig.json .",
66
67
  "lint:fix": "biome check --write .",
@@ -68,36 +69,37 @@
68
69
  "test": "bun test",
69
70
  "test:ci": "bun test test/unit/ test/integration/",
70
71
  "prepare": "tsdown",
71
- "prepack": "bun run build",
72
- "prepublishOnly": "bun test && bun run build"
72
+ "prepack": "pnpm run build",
73
+ "prepublishOnly": "pnpm test && pnpm run build"
73
74
  },
74
75
  "dependencies": {
75
76
  "@mariozechner/pi-ai": "^0.73.0",
76
77
  "@mariozechner/pi-coding-agent": "^0.73.0",
77
- "citty": "^0.1.6",
78
- "hono": "^4.12.8",
78
+ "@mariozechner/pi-tui": "^0.73.0",
79
+ "citty": "^0.2.2",
80
+ "hono": "^4.12.18",
79
81
  "jsonc-parser": "^3.3.1",
80
- "zod": "^4.3.6"
82
+ "zod": "^4.4.3"
81
83
  },
82
84
  "devDependencies": {
83
- "@biomejs/biome": "^2.4.8",
84
- "@commitlint/cli": "^20.5.0",
85
- "@commitlint/config-conventional": "^20.5.0",
85
+ "@biomejs/biome": "^2.4.14",
86
+ "@commitlint/cli": "^20.5.3",
87
+ "@commitlint/config-conventional": "^20.5.3",
86
88
  "@limegrass/eslint-plugin-import-alias": "^1.6.1",
87
89
  "@semantic-release/changelog": "^6.0.3",
88
90
  "@semantic-release/git": "^10.0.1",
89
91
  "@semantic-release/github": "^12.0.6",
90
92
  "@semantic-release/npm": "^13.1.5",
91
- "@types/bun": "^1.3.11",
92
- "@types/node": "^25.5.0",
93
- "eslint-plugin-zod": "^3.5.0",
94
- "lefthook": "^2.1.4",
95
- "openai": "^6.26.0",
96
- "oxlint": "^1.56.0",
97
- "oxlint-tsgolint": "^0.17.1",
93
+ "@types/bun": "^1.3.13",
94
+ "@types/node": "^25.6.0",
95
+ "eslint-plugin-zod": "^3.12.0",
96
+ "lefthook": "^2.1.6",
97
+ "openai": "^6.36.0",
98
+ "oxlint": "^1.63.0",
99
+ "oxlint-tsgolint": "^0.22.1",
98
100
  "semantic-release": "^25.0.3",
99
- "tsdown": "^0.21.4",
101
+ "tsdown": "^0.21.10",
100
102
  "typebox": "^1.1.38",
101
- "typescript": "^5.9.3"
103
+ "typescript": "^6.0.3"
102
104
  }
103
105
  }