codexport 0.3.2 → 0.3.4

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.
Files changed (2) hide show
  1. package/dist/index.js +45 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { homedir, platform } from "node:os";
11
11
  import path from "node:path";
12
12
  import { spawn } from "node:child_process";
13
13
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
14
- const VERSION = "0.3.2";
14
+ const VERSION = "0.3.4";
15
15
  const DEFAULT_PORT = 17342;
16
16
  const DEFAULT_TIMEOUT_MS = 5_000;
17
17
  const CODEXPORT_DIR = ".codexport";
@@ -497,6 +497,10 @@ function portableMcpLauncher(name, command, args, sourceHome, server) {
497
497
  if (nodePackage) {
498
498
  return { command: "npx", args: ["-y", nodePackage.packageName, ...nodePackage.remainingArgs] };
499
499
  }
500
+ if (name === "discord-py-self" || commandName === "discord-py-self-mcp") {
501
+ const remainingArgs = allStrings(args) ? args : [];
502
+ return { command: "npx", args: ["-y", "discord-selfbot-mcp", ...remainingArgs] };
503
+ }
500
504
  if (name === "qmd" || commandName === "qmd") {
501
505
  const remainingArgs = allStrings(args) ? args : [];
502
506
  return { command: "npx", args: ["-y", "-p", "@tobilu/qmd", "qmd", ...remainingArgs] };
@@ -842,7 +846,7 @@ async function repairMcpLauncherIfNeeded(launcher, env) {
842
846
  await installUv(env);
843
847
  }
844
848
  else {
845
- await runCommandWithEnv(launcher.repair.command, launcher.repair.args, env);
849
+ await runRepairCommandWithEnv(launcher.repair.command, launcher.repair.args, env);
846
850
  }
847
851
  if (!(await executableExists(launcher.repair.whenMissing, env))) {
848
852
  throw new CliError(`MCP repair completed but ${launcher.repair.whenMissing} is still not on PATH.`, 1);
@@ -850,7 +854,7 @@ async function repairMcpLauncherIfNeeded(launcher, env) {
850
854
  }
851
855
  async function installUv(env) {
852
856
  if (platform() === "win32") {
853
- await runCommandWithEnv("powershell.exe", [
857
+ await runRepairCommandWithEnv("powershell.exe", [
854
858
  "-NoProfile",
855
859
  "-ExecutionPolicy",
856
860
  "Bypass",
@@ -859,7 +863,7 @@ async function installUv(env) {
859
863
  ], env);
860
864
  }
861
865
  else {
862
- await runCommandWithEnv("sh", ["-c", "curl -LsSf https://astral.sh/uv/install.sh | sh"], env);
866
+ await runRepairCommandWithEnv("sh", ["-c", "curl -LsSf https://astral.sh/uv/install.sh | sh"], env);
863
867
  }
864
868
  const installHome = env.HOME ?? env.USERPROFILE ?? homedir();
865
869
  const uvBinDir = platform() === "win32"
@@ -928,14 +932,26 @@ async function repairGitquarryEnvIfNeeded(name, env) {
928
932
  const current = env.GITQUARRY_CLI_PATH;
929
933
  if (current && await executableExists(current, env))
930
934
  return;
931
- if (!(await executableExists("gitquarry", env))) {
932
- await runCommandWithEnv("npm", ["install", "-g", "gitquarry"], env);
935
+ const existing = await resolveExecutable("gitquarry", env);
936
+ if (existing) {
937
+ env.GITQUARRY_CLI_PATH = existing;
938
+ return;
933
939
  }
934
- const resolved = await resolveExecutable("gitquarry", env);
935
- if (!resolved) {
936
- throw new CliError("MCP repair could not find gitquarry after installing the gitquarry npm package.", 1);
940
+ const installHome = env.HOME ?? env.USERPROFILE ?? homedir();
941
+ const installDir = path.join(installHome, ".codexport", "tools", "gitquarry");
942
+ const binaryPath = platform() === "win32"
943
+ ? path.join(installDir, "node_modules", ".bin", "gitquarry.cmd")
944
+ : path.join(installDir, "node_modules", ".bin", "gitquarry");
945
+ if (await pathExists(binaryPath)) {
946
+ env.GITQUARRY_CLI_PATH = binaryPath;
947
+ return;
937
948
  }
938
- env.GITQUARRY_CLI_PATH = resolved;
949
+ await ensureDir(installDir);
950
+ await runRepairCommandWithEnv("npm", ["install", "--prefix", installDir, "gitquarry"], env);
951
+ if (!(await pathExists(binaryPath))) {
952
+ throw new CliError("MCP repair installed gitquarry but could not find its npm shim.", 1);
953
+ }
954
+ env.GITQUARRY_CLI_PATH = binaryPath;
939
955
  }
940
956
  async function executableExists(command, env) {
941
957
  return Boolean(await resolveExecutable(command, env));
@@ -1015,6 +1031,25 @@ function runCommandWithEnv(command, args, env) {
1015
1031
  });
1016
1032
  });
1017
1033
  }
1034
+ function runRepairCommandWithEnv(command, args, env) {
1035
+ return new Promise((resolve, reject) => {
1036
+ const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"], env });
1037
+ child.stdout.on("data", (chunk) => process.stderr.write(chunk));
1038
+ child.stderr.on("data", (chunk) => process.stderr.write(chunk));
1039
+ child.on("error", (error) => {
1040
+ const message = error.code === "ENOENT"
1041
+ ? `MCP repair program not found: ${command}. Install it on this follower or add it to PATH.`
1042
+ : asError(error).message;
1043
+ reject(new CliError(message, 1));
1044
+ });
1045
+ child.on("exit", (code) => {
1046
+ if (code === 0)
1047
+ resolve();
1048
+ else
1049
+ reject(new CliError(`${command} ${args.join(" ")} exited with ${code}`, code ?? 1));
1050
+ });
1051
+ });
1052
+ }
1018
1053
  async function installMasterService(ctx, port, dryRun) {
1019
1054
  const command = `${process.execPath} ${realpathSync(fileURLToPath(import.meta.url))} master serve --port ${port}`;
1020
1055
  if (platform() === "linux") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexport",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "sync a canonical Codex setup from one master machine to follower machines",
5
5
  "author": "Microck <contact@micr.dev>",
6
6
  "license": "MIT",