droid-patch 0.13.4 → 0.14.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/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as removeAlias, d as listAllMetadata, f as loadAliasMetadata, i as listAliases, l as createMetadata, m as patchDroid, n as createAlias, o as removeAliasesByFilter, p as saveAliasMetadata, r as createAliasForWrapper, t as clearAllAliases, u as formatPatches } from "./alias-DTf8YAYU.mjs";
2
+ import { a as removeAlias, d as listAllMetadata, f as loadAliasMetadata, i as listAliases, l as createMetadata, m as patchDroid, n as createAlias, o as removeAliasesByFilter, p as saveAliasMetadata, r as createAliasForWrapper, t as clearAllAliases, u as formatPatches } from "./alias-jucBZXia.mjs";
3
3
  import bin from "tiny-bin";
4
4
  import { styleText } from "node:util";
5
5
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
@@ -624,6 +624,7 @@ ACTUAL_PORT=$(cat "$PORT_FILE")
624
624
  rm -f "$PORT_FILE"
625
625
 
626
626
  export FACTORY_API_BASE_URL_OVERRIDE="http://127.0.0.1:$ACTUAL_PORT"
627
+ export FACTORY_API_BASE_URL="http://127.0.0.1:$ACTUAL_PORT"
627
628
  "$DROID_BIN" "$@"
628
629
  DROID_EXIT_CODE=$?
629
630
  exit $DROID_EXIT_CODE
@@ -706,6 +707,7 @@ if defined DROID_SEARCH_DEBUG echo [websearch] Proxy ready on port %ACTUAL_PORT%
706
707
  del "%PORT_FILE%" 2>nul
707
708
 
708
709
  set "FACTORY_API_BASE_URL_OVERRIDE=http://127.0.0.1:%ACTUAL_PORT%"
710
+ set "FACTORY_API_BASE_URL=http://127.0.0.1:%ACTUAL_PORT%"
709
711
  "%DROID_BIN%" %*
710
712
  set "DROID_EXIT_CODE=%ERRORLEVEL%"
711
713
 
@@ -1084,18 +1086,18 @@ function findDefaultDroidPath() {
1084
1086
  for (const p of paths) if (existsSync(p)) return p;
1085
1087
  return join(home, ".droid", "bin", "droid");
1086
1088
  }
1087
- bin("droid-patch", "CLI tool to patch droid binary with various modifications").package("droid-patch", version).option("--is-custom", "Patch isCustom:!0 to isCustom:!1 (enable context compression for custom models)").option("--skip-login", "Inject a fake FACTORY_API_KEY to bypass login requirement (no real key needed)").option("--api-base <url>", "Replace API URL (standalone: binary patch, max 22 chars; with --websearch: proxy forward target, no limit)").option("--websearch", "Enable local WebSearch proxy with external providers (Smithery, Google PSE, etc.)").option("--websearch-proxy", "Enable native provider websearch (requires proxy plugin, reads ~/.factory/settings.json)").option("--standalone", "Standalone mode: mock non-LLM Factory APIs (use with --websearch)").option("--reasoning-effort", "Enable reasoning effort for custom models (set to high, enable UI selector)").option("--disable-telemetry", "Disable telemetry and Sentry error reporting (block data uploads)").option("--dry-run", "Verify patches without actually modifying the binary").option("-p, --path <path>", "Path to the droid binary").option("-o, --output <dir>", "Output directory for patched binary").option("--no-backup", "Do not create backup of original binary").option("-v, --verbose", "Enable verbose output").argument("[alias]", "Alias name for the patched binary").action(async (options, args) => {
1089
+ bin("droid-patch", "CLI tool to patch droid binary with various modifications").option("--is-custom", "Patch isCustom:!0 to isCustom:!1 (enable context compression for custom models)").option("--skip-login", "Inject a fake FACTORY_API_KEY to bypass login requirement (no real key needed)").option("--api-base <url>", "Replace API URL (standalone: binary patch, max 22 chars; with --websearch: proxy forward target, no limit)").option("--websearch", "Enable local WebSearch proxy with external providers (Smithery, Google PSE, etc.)").option("--websearch-proxy", "Enable native provider websearch (requires proxy plugin, reads ~/.factory/settings.json)").option("--standalone", "Standalone mode: mock non-LLM Factory APIs (use with --websearch)").option("--reasoning-effort", "Enable reasoning effort for custom models (default high; UI options: \"high\",\"max\",\"xhigh\")").option("--disable-telemetry", "Disable telemetry and Sentry error reporting (block data uploads)").option("--dry-run", "Verify patches without actually modifying the binary").option("-p, --path <path>", "Path to the droid binary").option("-o, --output <dir>", "Output directory for patched binary").option("--no-backup", "Do not create backup of original binary").option("-v, --verbose", "Enable verbose output").argument("[alias]", "Alias name for the patched binary").action(async (options, args) => {
1088
1090
  const alias = args?.[0];
1089
- const isCustom = options["is-custom"];
1090
- const skipLogin = options["skip-login"];
1091
- const apiBase = options["api-base"];
1092
- const websearch = options["websearch"];
1093
- const websearchProxy = options["websearch-proxy"];
1094
- const standalone = options["standalone"];
1091
+ const isCustom = !!options.isCustom;
1092
+ const skipLogin = !!options.skipLogin;
1093
+ const apiBase = options.apiBase;
1094
+ const websearch = !!options.websearch;
1095
+ const websearchProxy = !!options.websearchProxy;
1096
+ const standalone = !!options.standalone;
1095
1097
  const websearchTarget = websearch ? apiBase || "https://api.factory.ai" : void 0;
1096
- const reasoningEffort = options["reasoning-effort"];
1097
- const noTelemetry = options["disable-telemetry"];
1098
- const dryRun = options["dry-run"];
1098
+ const reasoningEffort = !!options.reasoningEffort;
1099
+ const noTelemetry = !!options.disableTelemetry;
1100
+ const dryRun = !!options.dryRun;
1099
1101
  const path = options.path || findDefaultDroidPath();
1100
1102
  const outputDir = options.output;
1101
1103
  const backup = options.backup !== false;
@@ -1237,7 +1239,7 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1237
1239
  if (apiBase && !websearch) {
1238
1240
  const originalUrl = "https://api.factory.ai";
1239
1241
  const originalLength = 22;
1240
- let normalizedUrl = apiBase.replace(/\/+$/, "");
1242
+ const normalizedUrl = apiBase.replace(/\/+$/, "");
1241
1243
  if (normalizedUrl.length > originalLength) {
1242
1244
  console.log(styleText("red", `Error: API base URL must be ${originalLength} characters or less`));
1243
1245
  console.log(styleText("gray", ` Your URL: "${normalizedUrl}" (${normalizedUrl.length} chars)`));
@@ -1260,21 +1262,21 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1260
1262
  if (reasoningEffort) {
1261
1263
  patches.push({
1262
1264
  name: "reasoningEffortSupportedXHighList",
1263
- description: "Enable [\"low\",\"high\",\"xhigh\"] in UI for custom model list",
1265
+ description: "Enable [\"high\",\"max\",\"xhigh\"] in UI for custom model list",
1264
1266
  pattern: Buffer.from(""),
1265
1267
  replacement: Buffer.from(""),
1266
- regexPattern: /id:([A-Za-z$_])\.id,displayName:\1\.displayName,shortDisplayName:\1\.(?:displayName|id),modelProvider:\1\.provider\s*,supportedReasoningEfforts:\["(?:none|high)"(?:,"xhigh")?\],defaultReasoningEffort:"(?:none|high)",isCustom:!([01]),noImageSupport:(?:\1\.noImageSupport|!1)/g,
1267
- regexReplacement: "id:$1.id,displayName:$1.displayName,shortDisplayName:$1.displayName,modelProvider:$1.provider,supportedReasoningEfforts:[\"low\",\"high\",\"xhigh\"],defaultReasoningEffort:\"high\",isCustom:!$2,noImageSupport:!1",
1268
- alreadyPatchedRegexPattern: /id:([A-Za-z$_])\.id,displayName:\1\.displayName,shortDisplayName:\1\.displayName,modelProvider:\1\.provider,supportedReasoningEfforts:\["low","high","xhigh"\],defaultReasoningEffort:"high",isCustom:!([01]),noImageSupport:!1/g
1268
+ regexPattern: /id:([A-Za-z$_])\.id,displayName:\1\.displayName,shortDisplayName:\1\.(?:displayName|id),modelProvider:\1\.provider\s*,supportedReasoningEfforts:\[(?:"(?:none|high)"(?:,"xhigh")?|"low","high","xhigh")\],defaultReasoningEffort:"(?:none|high)",isCustom:!([01]),noImageSupport:(?:\1\.noImageSupport|!1)/g,
1269
+ regexReplacement: "id:$1.id,displayName:$1.displayName,shortDisplayName:$1.displayName,modelProvider:$1.provider,supportedReasoningEfforts:[\"high\",\"max\",\"xhigh\"],defaultReasoningEffort:\"high\",isCustom:!$2,noImageSupport:!1",
1270
+ alreadyPatchedRegexPattern: /id:([A-Za-z$_])\.id,displayName:\1\.displayName,shortDisplayName:\1\.displayName,modelProvider:\1\.provider,supportedReasoningEfforts:\["high","max","xhigh"\],defaultReasoningEffort:"high",isCustom:!([01]),noImageSupport:!1/g
1269
1271
  });
1270
1272
  patches.push({
1271
1273
  name: "reasoningEffortSupportedXHighResolver",
1272
- description: "Enable [\"low\",\"high\",\"xhigh\"] in UI for custom model config resolver",
1274
+ description: "Enable [\"high\",\"max\",\"xhigh\"] in UI for custom model config resolver",
1273
1275
  pattern: Buffer.from(""),
1274
1276
  replacement: Buffer.from(""),
1275
- regexPattern: /id:([A-Za-z$_])\.model,modelProvider:\1\.provider\s*,displayName:([A-Za-z$_]),shortDisplayName:\2,supportedReasoningEfforts:\["(?:none|high)"(?:,"xhigh")?\],defaultReasoningEffort:"(?:none|high)",isCustom:!([01]),noImageSupport:(?:\1\.noImageSupport|!1)/g,
1276
- regexReplacement: "id:$1.model,modelProvider:$1.provider,displayName:$2,shortDisplayName:$2,supportedReasoningEfforts:[\"low\",\"high\",\"xhigh\"],defaultReasoningEffort:\"high\",isCustom:!$3,noImageSupport:!1",
1277
- alreadyPatchedRegexPattern: /id:([A-Za-z$_])\.model,modelProvider:\1\.provider,displayName:([A-Za-z$_]),shortDisplayName:\2,supportedReasoningEfforts:\["low","high","xhigh"\],defaultReasoningEffort:"high",isCustom:!([01]),noImageSupport:!1/g
1277
+ regexPattern: /id:([A-Za-z$_])\.model,modelProvider:\1\.provider\s*,displayName:([A-Za-z$_]),shortDisplayName:\2,supportedReasoningEfforts:\[(?:"(?:none|high)"(?:,"xhigh")?|"low","high","xhigh")\],defaultReasoningEffort:"(?:none|high)",isCustom:!([01]),noImageSupport:(?:\1\.noImageSupport|!1)/g,
1278
+ regexReplacement: "id:$1.model,modelProvider:$1.provider,displayName:$2,shortDisplayName:$2,supportedReasoningEfforts:[\"high\",\"max\",\"xhigh\"],defaultReasoningEffort:\"high\",isCustom:!$3,noImageSupport:!1",
1279
+ alreadyPatchedRegexPattern: /id:([A-Za-z$_])\.model,modelProvider:\1\.provider,displayName:([A-Za-z$_]),shortDisplayName:\2,supportedReasoningEfforts:\["high","max","xhigh"\],defaultReasoningEffort:"high",isCustom:!([01]),noImageSupport:!1/g
1278
1280
  });
1279
1281
  patches.push({
1280
1282
  name: "reasoningEffortSupported",
@@ -1410,8 +1412,8 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1410
1412
  await listAliases();
1411
1413
  }).command("remove", "Remove alias(es) by name or filter").argument("[alias-or-path]", "Alias name or file path to remove").option("--patch-version <version>", "Remove aliases created by this droid-patch version").option("--droid-version <version>", "Remove aliases for this droid version").option("--flag <flag>", "Remove aliases with this flag (is-custom, skip-login, websearch, api-base, reasoning-effort, disable-telemetry, standalone)").action(async (options, args) => {
1412
1414
  const target = args?.[0];
1413
- const patchVersion = options["patch-version"];
1414
- const droidVersion = options["droid-version"];
1415
+ const patchVersion = options.patchVersion;
1416
+ const droidVersion = options.droidVersion;
1415
1417
  const flagRaw = options.flag;
1416
1418
  let flag;
1417
1419
  if (flagRaw) {
@@ -1444,9 +1446,9 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1444
1446
  process.exit(1);
1445
1447
  }
1446
1448
  if (target.includes("/") || existsSync(target)) {
1447
- const { unlink: unlink$1 } = await import("node:fs/promises");
1449
+ const { unlink } = await import("node:fs/promises");
1448
1450
  try {
1449
- await unlink$1(target);
1451
+ await unlink(target);
1450
1452
  console.log(styleText("green", `[*] Removed: ${target}`));
1451
1453
  } catch (error) {
1452
1454
  console.error(styleText("red", `Error: ${error.message}`));
@@ -1459,9 +1461,9 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1459
1461
  await clearAllAliases();
1460
1462
  }).command("update", "Update aliases with latest droid binary").argument("[alias]", "Specific alias to update (optional, updates all if not specified)").option("--dry-run", "Preview without making changes").option("-p, --path <path>", "Path to new droid binary").option("-v, --verbose", "Enable verbose output").action(async (options, args) => {
1461
1463
  const aliasName = args?.[0];
1462
- const dryRun = options["dry-run"];
1464
+ const dryRun = !!options.dryRun;
1463
1465
  const newBinaryPath = options.path || findDefaultDroidPath();
1464
- const verbose = options.verbose;
1466
+ const verbose = !!options.verbose;
1465
1467
  console.log(styleText("cyan", "═".repeat(60)));
1466
1468
  console.log(styleText(["cyan", "bold"], " Droid-Patch Update"));
1467
1469
  console.log(styleText("cyan", "═".repeat(60)));
@@ -1532,21 +1534,21 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1532
1534
  if (meta.patches.reasoningEffort) {
1533
1535
  patches.push({
1534
1536
  name: "reasoningEffortSupportedXHighList",
1535
- description: "Enable [\"low\",\"high\",\"xhigh\"] in UI for custom model list",
1537
+ description: "Enable [\"high\",\"max\",\"xhigh\"] in UI for custom model list",
1536
1538
  pattern: Buffer.from(""),
1537
1539
  replacement: Buffer.from(""),
1538
- regexPattern: /id:([A-Za-z$_])\.id,displayName:\1\.displayName,shortDisplayName:\1\.(?:displayName|id),modelProvider:\1\.provider\s*,supportedReasoningEfforts:\["(?:none|high)"(?:,"xhigh")?\],defaultReasoningEffort:"(?:none|high)",isCustom:!([01]),noImageSupport:(?:\1\.noImageSupport|!1)/g,
1539
- regexReplacement: "id:$1.id,displayName:$1.displayName,shortDisplayName:$1.displayName,modelProvider:$1.provider,supportedReasoningEfforts:[\"low\",\"high\",\"xhigh\"],defaultReasoningEffort:\"high\",isCustom:!$2,noImageSupport:!1",
1540
- alreadyPatchedRegexPattern: /id:([A-Za-z$_])\.id,displayName:\1\.displayName,shortDisplayName:\1\.displayName,modelProvider:\1\.provider,supportedReasoningEfforts:\["low","high","xhigh"\],defaultReasoningEffort:"high",isCustom:!([01]),noImageSupport:!1/g
1540
+ regexPattern: /id:([A-Za-z$_])\.id,displayName:\1\.displayName,shortDisplayName:\1\.(?:displayName|id),modelProvider:\1\.provider\s*,supportedReasoningEfforts:\[(?:"(?:none|high)"(?:,"xhigh")?|"low","high","xhigh")\],defaultReasoningEffort:"(?:none|high)",isCustom:!([01]),noImageSupport:(?:\1\.noImageSupport|!1)/g,
1541
+ regexReplacement: "id:$1.id,displayName:$1.displayName,shortDisplayName:$1.displayName,modelProvider:$1.provider,supportedReasoningEfforts:[\"high\",\"max\",\"xhigh\"],defaultReasoningEffort:\"high\",isCustom:!$2,noImageSupport:!1",
1542
+ alreadyPatchedRegexPattern: /id:([A-Za-z$_])\.id,displayName:\1\.displayName,shortDisplayName:\1\.displayName,modelProvider:\1\.provider,supportedReasoningEfforts:\["high","max","xhigh"\],defaultReasoningEffort:"high",isCustom:!([01]),noImageSupport:!1/g
1541
1543
  });
1542
1544
  patches.push({
1543
1545
  name: "reasoningEffortSupportedXHighResolver",
1544
- description: "Enable [\"low\",\"high\",\"xhigh\"] in UI for custom model config resolver",
1546
+ description: "Enable [\"high\",\"max\",\"xhigh\"] in UI for custom model config resolver",
1545
1547
  pattern: Buffer.from(""),
1546
1548
  replacement: Buffer.from(""),
1547
- regexPattern: /id:([A-Za-z$_])\.model,modelProvider:\1\.provider\s*,displayName:([A-Za-z$_]),shortDisplayName:\2,supportedReasoningEfforts:\["(?:none|high)"(?:,"xhigh")?\],defaultReasoningEffort:"(?:none|high)",isCustom:!([01]),noImageSupport:(?:\1\.noImageSupport|!1)/g,
1548
- regexReplacement: "id:$1.model,modelProvider:$1.provider,displayName:$2,shortDisplayName:$2,supportedReasoningEfforts:[\"low\",\"high\",\"xhigh\"],defaultReasoningEffort:\"high\",isCustom:!$3,noImageSupport:!1",
1549
- alreadyPatchedRegexPattern: /id:([A-Za-z$_])\.model,modelProvider:\1\.provider,displayName:([A-Za-z$_]),shortDisplayName:\2,supportedReasoningEfforts:\["low","high","xhigh"\],defaultReasoningEffort:"high",isCustom:!([01]),noImageSupport:!1/g
1549
+ regexPattern: /id:([A-Za-z$_])\.model,modelProvider:\1\.provider\s*,displayName:([A-Za-z$_]),shortDisplayName:\2,supportedReasoningEfforts:\[(?:"(?:none|high)"(?:,"xhigh")?|"low","high","xhigh")\],defaultReasoningEffort:"(?:none|high)",isCustom:!([01]),noImageSupport:(?:\1\.noImageSupport|!1)/g,
1550
+ regexReplacement: "id:$1.model,modelProvider:$1.provider,displayName:$2,shortDisplayName:$2,supportedReasoningEfforts:[\"high\",\"max\",\"xhigh\"],defaultReasoningEffort:\"high\",isCustom:!$3,noImageSupport:!1",
1551
+ alreadyPatchedRegexPattern: /id:([A-Za-z$_])\.model,modelProvider:\1\.provider,displayName:([A-Za-z$_]),shortDisplayName:\2,supportedReasoningEfforts:\["high","max","xhigh"\],defaultReasoningEffort:"high",isCustom:!([01]),noImageSupport:!1/g
1550
1552
  });
1551
1553
  patches.push({
1552
1554
  name: "reasoningEffortSupported",
@@ -1617,8 +1619,8 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1617
1619
  continue;
1618
1620
  }
1619
1621
  if (process.platform === "darwin") try {
1620
- const { execSync: execSync$1 } = await import("node:child_process");
1621
- execSync$1(`codesign --force --deep --sign - "${outputPath}"`, { stdio: "pipe" });
1622
+ const { execSync } = await import("node:child_process");
1623
+ execSync(`codesign --force --deep --sign - "${outputPath}"`, { stdio: "pipe" });
1622
1624
  if (verbose) console.log(styleText("gray", ` Re-signed binary`));
1623
1625
  } catch {
1624
1626
  console.log(styleText("yellow", ` [!] Could not re-sign binary`));
@@ -1641,7 +1643,7 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1641
1643
  }
1642
1644
  delete meta.patches.statusline;
1643
1645
  delete meta.patches.sessions;
1644
- const { symlink: symlink$1, unlink: unlink$1, readlink: readlink$1, lstat } = await import("node:fs/promises");
1646
+ const { symlink, unlink, readlink, lstat } = await import("node:fs/promises");
1645
1647
  let aliasPath = meta.aliasPath;
1646
1648
  if (!aliasPath) {
1647
1649
  const commonPathDirs = [
@@ -1656,7 +1658,7 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1656
1658
  const possiblePath = join(dir, meta.name);
1657
1659
  if (existsSync(possiblePath)) try {
1658
1660
  if ((await lstat(possiblePath)).isSymbolicLink()) {
1659
- const target = await readlink$1(possiblePath);
1661
+ const target = await readlink(possiblePath);
1660
1662
  if (target.includes(".droid-patch/bins") || target.includes(".droid-patch/proxy") || target.includes(".droid-patch/statusline")) {
1661
1663
  aliasPath = possiblePath;
1662
1664
  if (verbose) console.log(styleText("gray", ` Found existing symlink: ${aliasPath}`));
@@ -1668,13 +1670,13 @@ bin("droid-patch", "CLI tool to patch droid binary with various modifications").
1668
1670
  }
1669
1671
  if (aliasPath) try {
1670
1672
  if (existsSync(aliasPath)) {
1671
- if (await readlink$1(aliasPath) !== execTargetPath) {
1672
- await unlink$1(aliasPath);
1673
- await symlink$1(execTargetPath, aliasPath);
1673
+ if (await readlink(aliasPath) !== execTargetPath) {
1674
+ await unlink(aliasPath);
1675
+ await symlink(execTargetPath, aliasPath);
1674
1676
  if (verbose) console.log(styleText("gray", ` Updated symlink: ${aliasPath}`));
1675
1677
  }
1676
1678
  } else {
1677
- await symlink$1(execTargetPath, aliasPath);
1679
+ await symlink(execTargetPath, aliasPath);
1678
1680
  if (verbose) console.log(styleText("gray", ` Recreated symlink: ${aliasPath}`));
1679
1681
  }
1680
1682
  meta.aliasPath = aliasPath;