skalpel 2.0.6 → 2.0.7

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 CHANGED
@@ -1028,6 +1028,23 @@ async function runStart() {
1028
1028
  // src/proxy/server.ts
1029
1029
  import http from "http";
1030
1030
 
1031
+ // src/proxy/streaming.ts
1032
+ var HOP_BY_HOP = /* @__PURE__ */ new Set([
1033
+ "connection",
1034
+ "keep-alive",
1035
+ "proxy-authenticate",
1036
+ "proxy-authorization",
1037
+ "te",
1038
+ "trailer",
1039
+ "transfer-encoding",
1040
+ "upgrade"
1041
+ ]);
1042
+ var STRIP_HEADERS = /* @__PURE__ */ new Set([
1043
+ ...HOP_BY_HOP,
1044
+ "content-encoding",
1045
+ "content-length"
1046
+ ]);
1047
+
1031
1048
  // src/proxy/logger.ts
1032
1049
  import fs9 from "fs";
1033
1050
  import path11 from "path";
@@ -1246,7 +1263,7 @@ function readJsonFile(filePath) {
1246
1263
  try {
1247
1264
  return JSON.parse(fs11.readFileSync(filePath, "utf-8"));
1248
1265
  } catch {
1249
- return {};
1266
+ return null;
1250
1267
  }
1251
1268
  }
1252
1269
  function configureClaudeCode(agent, proxyConfig) {
@@ -1254,7 +1271,7 @@ function configureClaudeCode(agent, proxyConfig) {
1254
1271
  const configDir = path12.dirname(configPath);
1255
1272
  ensureDir(configDir);
1256
1273
  createBackup(configPath);
1257
- const config = readJsonFile(configPath);
1274
+ const config = readJsonFile(configPath) ?? {};
1258
1275
  if (!config.env || typeof config.env !== "object") {
1259
1276
  config.env = {};
1260
1277
  }
@@ -1306,14 +1323,12 @@ function configureAgent(agent, proxyConfig) {
1306
1323
  }
1307
1324
  function unconfigureClaudeCode(agent) {
1308
1325
  const configPath = agent.configPath ?? path12.join(os7.homedir(), ".claude", "settings.json");
1309
- const backupPath = `${configPath}.skalpel-backup`;
1310
- if (fs11.existsSync(backupPath)) {
1311
- fs11.copyFileSync(backupPath, configPath);
1312
- fs11.unlinkSync(backupPath);
1313
- return;
1314
- }
1315
1326
  if (!fs11.existsSync(configPath)) return;
1316
1327
  const config = readJsonFile(configPath);
1328
+ if (config === null) {
1329
+ console.warn(` [!] Could not parse ${configPath} \u2014 skipping to avoid data loss. Remove ANTHROPIC_BASE_URL manually if needed.`);
1330
+ return;
1331
+ }
1317
1332
  if (config.env && typeof config.env === "object") {
1318
1333
  delete config.env.ANTHROPIC_BASE_URL;
1319
1334
  if (Object.keys(config.env).length === 0) {
@@ -1321,20 +1336,23 @@ function unconfigureClaudeCode(agent) {
1321
1336
  }
1322
1337
  }
1323
1338
  fs11.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
1339
+ const backupPath = `${configPath}.skalpel-backup`;
1340
+ if (fs11.existsSync(backupPath)) {
1341
+ fs11.unlinkSync(backupPath);
1342
+ }
1324
1343
  }
1325
1344
  function unconfigureCodex(agent) {
1326
1345
  const configDir = process.platform === "win32" ? path12.join(os7.homedir(), "AppData", "Roaming", "codex") : path12.join(os7.homedir(), ".codex");
1327
1346
  const configPath = agent.configPath ?? path12.join(configDir, "config.toml");
1347
+ if (fs11.existsSync(configPath)) {
1348
+ let content = readTomlFile(configPath);
1349
+ content = removeTomlKey(content, "openai_base_url");
1350
+ fs11.writeFileSync(configPath, content);
1351
+ }
1328
1352
  const backupPath = `${configPath}.skalpel-backup`;
1329
1353
  if (fs11.existsSync(backupPath)) {
1330
- fs11.copyFileSync(backupPath, configPath);
1331
1354
  fs11.unlinkSync(backupPath);
1332
- return;
1333
1355
  }
1334
- if (!fs11.existsSync(configPath)) return;
1335
- let content = readTomlFile(configPath);
1336
- content = removeTomlKey(content, "openai_base_url");
1337
- fs11.writeFileSync(configPath, content);
1338
1356
  }
1339
1357
  function unconfigureAgent(agent) {
1340
1358
  switch (agent.name) {
@@ -1570,15 +1588,13 @@ function removeShellEnvVars() {
1570
1588
  const beginIdx = content.indexOf(BEGIN_MARKER);
1571
1589
  const endIdx = content.indexOf(END_MARKER);
1572
1590
  if (beginIdx === -1 || endIdx === -1) continue;
1591
+ const before = content.slice(0, beginIdx);
1592
+ const after = content.slice(endIdx + END_MARKER.length);
1593
+ const cleaned = (before.replace(/\n+$/, "") + after.replace(/^\n+/, "\n")).trimEnd() + "\n";
1594
+ fs13.writeFileSync(profilePath, cleaned);
1573
1595
  const backupPath = `${profilePath}.skalpel-backup`;
1574
1596
  if (fs13.existsSync(backupPath)) {
1575
- fs13.copyFileSync(backupPath, profilePath);
1576
1597
  fs13.unlinkSync(backupPath);
1577
- } else {
1578
- const before = content.slice(0, beginIdx);
1579
- const after = content.slice(endIdx + END_MARKER.length);
1580
- const cleaned = (before.replace(/\n+$/, "") + after.replace(/^\n+/, "\n")).trimEnd() + "\n";
1581
- fs13.writeFileSync(profilePath, cleaned);
1582
1598
  }
1583
1599
  restored.push(profilePath);
1584
1600
  }
@@ -1589,7 +1605,8 @@ function removeShellEnvVars() {
1589
1605
  function print12(msg) {
1590
1606
  console.log(msg);
1591
1607
  }
1592
- async function runUninstall() {
1608
+ async function runUninstall(options) {
1609
+ const force = options?.force ?? false;
1593
1610
  const rl = readline3.createInterface({
1594
1611
  input: process.stdin,
1595
1612
  output: process.stdout
@@ -1604,23 +1621,17 @@ async function runUninstall() {
1604
1621
  print12(" Skalpel Uninstall");
1605
1622
  print12(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
1606
1623
  print12("");
1607
- const confirm = await ask(" This will remove Skalpel proxy, service, and agent configurations. Continue? (y/N): ");
1608
- if (confirm.toLowerCase() !== "y") {
1609
- print12(" Aborted.");
1610
- rl.close();
1611
- return;
1624
+ if (!force) {
1625
+ const confirm = await ask(" This will remove Skalpel proxy, service, and agent configurations. Continue? (y/N): ");
1626
+ if (confirm.toLowerCase() !== "y") {
1627
+ print12(" Aborted.");
1628
+ rl.close();
1629
+ return;
1630
+ }
1631
+ print12("");
1612
1632
  }
1613
- print12("");
1614
1633
  const config = loadConfig();
1615
1634
  const removed = [];
1616
- print12(" Stopping proxy...");
1617
- const stopped = stopProxy(config);
1618
- if (stopped) {
1619
- print12(" [+] Proxy stopped");
1620
- removed.push("proxy process");
1621
- } else {
1622
- print12(" [ ] Proxy was not running");
1623
- }
1624
1635
  print12(" Removing system service...");
1625
1636
  try {
1626
1637
  uninstallService();
@@ -1630,6 +1641,14 @@ async function runUninstall() {
1630
1641
  const msg = err instanceof Error ? err.message : String(err);
1631
1642
  print12(` [!] Could not remove service: ${msg}`);
1632
1643
  }
1644
+ print12(" Stopping proxy...");
1645
+ const stopped = stopProxy(config);
1646
+ if (stopped) {
1647
+ print12(" [+] Proxy stopped");
1648
+ removed.push("proxy process");
1649
+ } else {
1650
+ print12(" [ ] Proxy was not running");
1651
+ }
1633
1652
  print12(" Removing shell environment variables...");
1634
1653
  const restoredProfiles = removeShellEnvVars();
1635
1654
  if (restoredProfiles.length > 0) {
@@ -1657,13 +1676,25 @@ async function runUninstall() {
1657
1676
  print12("");
1658
1677
  const skalpelDir = path15.join(os10.homedir(), ".skalpel");
1659
1678
  if (fs14.existsSync(skalpelDir)) {
1660
- const removeDir = await ask(" Remove ~/.skalpel/ directory (contains config and logs)? (y/N): ");
1661
- if (removeDir.toLowerCase() === "y") {
1679
+ let shouldRemove = force;
1680
+ if (!force) {
1681
+ const removeDir = await ask(" Remove ~/.skalpel/ directory (contains config and logs)? (y/N): ");
1682
+ shouldRemove = removeDir.toLowerCase() === "y";
1683
+ }
1684
+ if (shouldRemove) {
1662
1685
  fs14.rmSync(skalpelDir, { recursive: true, force: true });
1663
1686
  print12(" [+] Removed ~/.skalpel/");
1664
1687
  removed.push("~/.skalpel/ directory");
1665
1688
  }
1666
1689
  }
1690
+ print12(" Clearing npx cache...");
1691
+ try {
1692
+ clearNpxCache();
1693
+ print12(" [+] npx cache cleared");
1694
+ removed.push("npx cache");
1695
+ } catch {
1696
+ print12(" [ ] Could not clear npx cache (not critical)");
1697
+ }
1667
1698
  print12("");
1668
1699
  print12(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
1669
1700
  if (removed.length > 0) {
@@ -1682,6 +1713,28 @@ async function runUninstall() {
1682
1713
  throw err;
1683
1714
  }
1684
1715
  }
1716
+ function clearNpxCache() {
1717
+ const npxCacheDir = path15.join(os10.homedir(), ".npm", "_npx");
1718
+ if (!fs14.existsSync(npxCacheDir)) return;
1719
+ const entries = fs14.readdirSync(npxCacheDir);
1720
+ for (const entry of entries) {
1721
+ const pkgJsonPath = path15.join(npxCacheDir, entry, "node_modules", "skalpel", "package.json");
1722
+ const pkgJsonAlt = path15.join(npxCacheDir, entry, "node_modules", ".package-lock.json");
1723
+ if (fs14.existsSync(pkgJsonPath)) {
1724
+ fs14.rmSync(path15.join(npxCacheDir, entry), { recursive: true, force: true });
1725
+ continue;
1726
+ }
1727
+ if (fs14.existsSync(pkgJsonAlt)) {
1728
+ try {
1729
+ const content = fs14.readFileSync(pkgJsonAlt, "utf-8");
1730
+ if (content.includes('"skalpel"')) {
1731
+ fs14.rmSync(path15.join(npxCacheDir, entry), { recursive: true, force: true });
1732
+ }
1733
+ } catch {
1734
+ }
1735
+ }
1736
+ }
1737
+ }
1685
1738
 
1686
1739
  // src/cli/index.ts
1687
1740
  var require3 = createRequire2(import.meta.url);
@@ -1699,6 +1752,6 @@ program.command("logs").description("View proxy logs").option("-n, --lines <coun
1699
1752
  program.command("config").description("View or edit proxy configuration").argument("[subcommand]", "path | set").argument("[args...]", "Arguments for subcommand").action(runConfig);
1700
1753
  program.command("update").description("Update Skalpel to the latest version").action(runUpdate);
1701
1754
  program.command("setup").description("Run the Skalpel setup wizard").action(runWizard);
1702
- program.command("uninstall").description("Remove Skalpel proxy and configurations").action(runUninstall);
1755
+ program.command("uninstall").description("Remove Skalpel proxy and configurations").option("--force", "Skip confirmation prompts and remove everything").action(runUninstall);
1703
1756
  program.parse(process.argv);
1704
1757
  //# sourceMappingURL=index.js.map