skalpel 2.0.17 → 2.0.19
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/cli/index.js +95 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/proxy-runner.js +136 -11
- package/dist/cli/proxy-runner.js.map +1 -1
- package/dist/index.cjs +157 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +136 -11
- package/dist/index.js.map +1 -1
- package/dist/proxy/index.cjs +157 -32
- package/dist/proxy/index.cjs.map +1 -1
- package/dist/proxy/index.js +136 -11
- package/dist/proxy/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -4,6 +4,54 @@ var __esm = (fn, res) => function __init() {
|
|
|
4
4
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
+
// src/proxy/codex-oauth.ts
|
|
8
|
+
import { readFileSync } from "fs";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
import { join } from "path";
|
|
11
|
+
function authFilePath() {
|
|
12
|
+
return join(homedir(), ".codex", "auth.json");
|
|
13
|
+
}
|
|
14
|
+
function readCodexAuth() {
|
|
15
|
+
const path17 = authFilePath();
|
|
16
|
+
let raw;
|
|
17
|
+
try {
|
|
18
|
+
raw = readFileSync(path17, "utf-8");
|
|
19
|
+
} catch (err) {
|
|
20
|
+
const code = err?.code;
|
|
21
|
+
if (code !== "ENOENT") {
|
|
22
|
+
process.stderr.write(`skalpel: codex-oauth: cannot read auth file (${code ?? "unknown"})
|
|
23
|
+
`);
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
let parsed;
|
|
28
|
+
try {
|
|
29
|
+
parsed = JSON.parse(raw);
|
|
30
|
+
} catch {
|
|
31
|
+
process.stderr.write("skalpel: codex-oauth: auth file is not valid JSON\n");
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (parsed === null || typeof parsed !== "object" || typeof parsed.access_token !== "string" || typeof parsed.refresh_token !== "string" || typeof parsed.expires_at !== "string") {
|
|
35
|
+
process.stderr.write("skalpel: codex-oauth: auth file missing required fields\n");
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const obj = parsed;
|
|
39
|
+
const auth = {
|
|
40
|
+
access_token: obj.access_token,
|
|
41
|
+
refresh_token: obj.refresh_token,
|
|
42
|
+
expires_at: obj.expires_at
|
|
43
|
+
};
|
|
44
|
+
if (typeof obj.account_id === "string") {
|
|
45
|
+
auth.account_id = obj.account_id;
|
|
46
|
+
}
|
|
47
|
+
return auth;
|
|
48
|
+
}
|
|
49
|
+
var init_codex_oauth = __esm({
|
|
50
|
+
"src/proxy/codex-oauth.ts"() {
|
|
51
|
+
"use strict";
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
7
55
|
// src/proxy/dispatcher.ts
|
|
8
56
|
import { Agent } from "undici";
|
|
9
57
|
var skalpelDispatcher;
|
|
@@ -85,10 +133,19 @@ var init_streaming = __esm({
|
|
|
85
133
|
|
|
86
134
|
// src/proxy/ws-client.ts
|
|
87
135
|
import { EventEmitter } from "events";
|
|
136
|
+
import https from "https";
|
|
137
|
+
import http from "http";
|
|
88
138
|
import WebSocket2 from "ws";
|
|
139
|
+
var H1_HTTPS_AGENT, H1_HTTP_AGENT;
|
|
89
140
|
var init_ws_client = __esm({
|
|
90
141
|
"src/proxy/ws-client.ts"() {
|
|
91
142
|
"use strict";
|
|
143
|
+
init_codex_oauth();
|
|
144
|
+
H1_HTTPS_AGENT = new https.Agent({
|
|
145
|
+
ALPNProtocols: ["http/1.1"],
|
|
146
|
+
keepAlive: true
|
|
147
|
+
});
|
|
148
|
+
H1_HTTP_AGENT = new http.Agent({ keepAlive: true });
|
|
92
149
|
}
|
|
93
150
|
});
|
|
94
151
|
|
|
@@ -100,6 +157,7 @@ var init_handler = __esm({
|
|
|
100
157
|
init_dispatcher();
|
|
101
158
|
init_envelope();
|
|
102
159
|
init_ws_client();
|
|
160
|
+
init_codex_oauth();
|
|
103
161
|
init_recovery();
|
|
104
162
|
init_fetch_error();
|
|
105
163
|
}
|
|
@@ -115,6 +173,7 @@ import * as fs2 from "fs";
|
|
|
115
173
|
import * as path2 from "path";
|
|
116
174
|
|
|
117
175
|
// src/cli/utils.ts
|
|
176
|
+
init_codex_oauth();
|
|
118
177
|
import * as fs from "fs";
|
|
119
178
|
import * as path from "path";
|
|
120
179
|
function detectProjectType() {
|
|
@@ -157,6 +216,25 @@ function detectAiSdks(projectType) {
|
|
|
157
216
|
function validateApiKey(key) {
|
|
158
217
|
return key.startsWith("sk-skalpel-") && key.length >= 20;
|
|
159
218
|
}
|
|
219
|
+
function validateCodexOAuth() {
|
|
220
|
+
try {
|
|
221
|
+
const auth = readCodexAuth();
|
|
222
|
+
if (auth !== null) {
|
|
223
|
+
return { present: true };
|
|
224
|
+
}
|
|
225
|
+
} catch (err) {
|
|
226
|
+
return { present: false, reason: `other: ${err.message}` };
|
|
227
|
+
}
|
|
228
|
+
const candidatePath = path.join(
|
|
229
|
+
process.env.HOME ?? process.env.USERPROFILE ?? "",
|
|
230
|
+
".codex",
|
|
231
|
+
"auth.json"
|
|
232
|
+
);
|
|
233
|
+
if (!fs.existsSync(candidatePath)) {
|
|
234
|
+
return { present: false, reason: "file missing" };
|
|
235
|
+
}
|
|
236
|
+
return { present: false, reason: "malformed JSON" };
|
|
237
|
+
}
|
|
160
238
|
function generateCodeSample(config) {
|
|
161
239
|
if (config.integrationMethod === "wrapper") {
|
|
162
240
|
if (config.providers.includes("openai")) {
|
|
@@ -1525,6 +1603,12 @@ function configureCodex(agent, proxyConfig, direct = false) {
|
|
|
1525
1603
|
content = removeCodexDirectProvider(content);
|
|
1526
1604
|
}
|
|
1527
1605
|
fs9.writeFileSync(configPath, content);
|
|
1606
|
+
const oauth = validateCodexOAuth();
|
|
1607
|
+
if (!oauth.present) {
|
|
1608
|
+
process.stderr.write("OAuth not configured. Run: codex login\n");
|
|
1609
|
+
process.stderr.write(" Then re-run: skalpel configure\n");
|
|
1610
|
+
process.stderr.write(" (Skalpel will fall back to OPENAI_API_KEY env var if OAuth missing.)\n");
|
|
1611
|
+
}
|
|
1528
1612
|
}
|
|
1529
1613
|
function getCursorConfigDir() {
|
|
1530
1614
|
if (process.platform === "darwin") {
|
|
@@ -1817,7 +1901,7 @@ import { execSync as execSync5 } from "child_process";
|
|
|
1817
1901
|
|
|
1818
1902
|
// src/proxy/server.ts
|
|
1819
1903
|
init_handler();
|
|
1820
|
-
import
|
|
1904
|
+
import http2 from "http";
|
|
1821
1905
|
|
|
1822
1906
|
// src/proxy/logger.ts
|
|
1823
1907
|
import fs11 from "fs";
|
|
@@ -1833,6 +1917,7 @@ var wss = new WebSocketServer({
|
|
|
1833
1917
|
});
|
|
1834
1918
|
|
|
1835
1919
|
// src/proxy/server.ts
|
|
1920
|
+
init_codex_oauth();
|
|
1836
1921
|
var proxyStartTime = 0;
|
|
1837
1922
|
function stopProxy(config) {
|
|
1838
1923
|
const pid = readPid(config.pidFile);
|
|
@@ -2240,10 +2325,13 @@ async function runWizard(options) {
|
|
|
2240
2325
|
}
|
|
2241
2326
|
print11("");
|
|
2242
2327
|
const codexConfigured = agentsToConfigure.some((a) => a.name === "codex");
|
|
2243
|
-
if (codexConfigured
|
|
2244
|
-
print11(" [!] Codex
|
|
2245
|
-
print11("
|
|
2246
|
-
print11("
|
|
2328
|
+
if (codexConfigured) {
|
|
2329
|
+
print11(" [!] Codex auth: recommended -> run 'codex login' first to enable ChatGPT plan billing.");
|
|
2330
|
+
print11(" The OPENAI_API_KEY env var (placeholder OK) is still required for Codex startup");
|
|
2331
|
+
print11(" but is ignored by Skalpel when OAuth is present.");
|
|
2332
|
+
if (!process.env.OPENAI_API_KEY) {
|
|
2333
|
+
print11(" example: export OPENAI_API_KEY=sk-codex-placeholder-skalpel");
|
|
2334
|
+
}
|
|
2247
2335
|
print11("");
|
|
2248
2336
|
}
|
|
2249
2337
|
}
|
|
@@ -2462,7 +2550,7 @@ function clearNpxCache() {
|
|
|
2462
2550
|
}
|
|
2463
2551
|
|
|
2464
2552
|
// src/cli/auth/callback-server.ts
|
|
2465
|
-
import * as
|
|
2553
|
+
import * as http3 from "http";
|
|
2466
2554
|
import * as net2 from "net";
|
|
2467
2555
|
|
|
2468
2556
|
// src/cli/auth/session-storage.ts
|
|
@@ -2591,7 +2679,7 @@ async function startCallbackServer(port, timeoutMsOrOptions = DEFAULT_TIMEOUT_MS
|
|
|
2591
2679
|
return new Promise((resolve2, reject) => {
|
|
2592
2680
|
let settled = false;
|
|
2593
2681
|
let timer;
|
|
2594
|
-
const server =
|
|
2682
|
+
const server = http3.createServer((req, res) => {
|
|
2595
2683
|
const origin = req.headers.origin;
|
|
2596
2684
|
const corsHeaders = buildCorsHeaders(origin);
|
|
2597
2685
|
if (req.method === "OPTIONS") {
|