codexport 0.3.3 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.js +41 -6
  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.3";
14
+ const VERSION = "0.3.5";
15
15
  const DEFAULT_PORT = 17342;
16
16
  const DEFAULT_TIMEOUT_MS = 5_000;
17
17
  const CODEXPORT_DIR = ".codexport";
@@ -497,6 +497,18 @@ 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 {
503
+ command: "uvx",
504
+ args: ["--from", "git+https://github.com/Microck/discord.py-self-mcp.git", "discord-py-self-mcp", ...remainingArgs],
505
+ repair: {
506
+ whenMissing: "uvx",
507
+ command: "__codexport_install_uv",
508
+ args: []
509
+ }
510
+ };
511
+ }
500
512
  if (name === "qmd" || commandName === "qmd") {
501
513
  const remainingArgs = allStrings(args) ? args : [];
502
514
  return { command: "npx", args: ["-y", "-p", "@tobilu/qmd", "qmd", ...remainingArgs] };
@@ -842,7 +854,7 @@ async function repairMcpLauncherIfNeeded(launcher, env) {
842
854
  await installUv(env);
843
855
  }
844
856
  else {
845
- await runCommandWithEnv(launcher.repair.command, launcher.repair.args, env);
857
+ await runRepairCommandWithEnv(launcher.repair.command, launcher.repair.args, env);
846
858
  }
847
859
  if (!(await executableExists(launcher.repair.whenMissing, env))) {
848
860
  throw new CliError(`MCP repair completed but ${launcher.repair.whenMissing} is still not on PATH.`, 1);
@@ -850,7 +862,7 @@ async function repairMcpLauncherIfNeeded(launcher, env) {
850
862
  }
851
863
  async function installUv(env) {
852
864
  if (platform() === "win32") {
853
- await runCommandWithEnv("powershell.exe", [
865
+ await runRepairCommandWithEnv("powershell.exe", [
854
866
  "-NoProfile",
855
867
  "-ExecutionPolicy",
856
868
  "Bypass",
@@ -859,7 +871,7 @@ async function installUv(env) {
859
871
  ], env);
860
872
  }
861
873
  else {
862
- await runCommandWithEnv("sh", ["-c", "curl -LsSf https://astral.sh/uv/install.sh | sh"], env);
874
+ await runRepairCommandWithEnv("sh", ["-c", "curl -LsSf https://astral.sh/uv/install.sh | sh"], env);
863
875
  }
864
876
  const installHome = env.HOME ?? env.USERPROFILE ?? homedir();
865
877
  const uvBinDir = platform() === "win32"
@@ -935,11 +947,15 @@ async function repairGitquarryEnvIfNeeded(name, env) {
935
947
  }
936
948
  const installHome = env.HOME ?? env.USERPROFILE ?? homedir();
937
949
  const installDir = path.join(installHome, ".codexport", "tools", "gitquarry");
938
- await ensureDir(installDir);
939
- await runCommandWithEnv("npm", ["install", "--prefix", installDir, "gitquarry"], env);
940
950
  const binaryPath = platform() === "win32"
941
951
  ? path.join(installDir, "node_modules", ".bin", "gitquarry.cmd")
942
952
  : path.join(installDir, "node_modules", ".bin", "gitquarry");
953
+ if (await pathExists(binaryPath)) {
954
+ env.GITQUARRY_CLI_PATH = binaryPath;
955
+ return;
956
+ }
957
+ await ensureDir(installDir);
958
+ await runRepairCommandWithEnv("npm", ["install", "--prefix", installDir, "gitquarry"], env);
943
959
  if (!(await pathExists(binaryPath))) {
944
960
  throw new CliError("MCP repair installed gitquarry but could not find its npm shim.", 1);
945
961
  }
@@ -1023,6 +1039,25 @@ function runCommandWithEnv(command, args, env) {
1023
1039
  });
1024
1040
  });
1025
1041
  }
1042
+ function runRepairCommandWithEnv(command, args, env) {
1043
+ return new Promise((resolve, reject) => {
1044
+ const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"], env });
1045
+ child.stdout.on("data", (chunk) => process.stderr.write(chunk));
1046
+ child.stderr.on("data", (chunk) => process.stderr.write(chunk));
1047
+ child.on("error", (error) => {
1048
+ const message = error.code === "ENOENT"
1049
+ ? `MCP repair program not found: ${command}. Install it on this follower or add it to PATH.`
1050
+ : asError(error).message;
1051
+ reject(new CliError(message, 1));
1052
+ });
1053
+ child.on("exit", (code) => {
1054
+ if (code === 0)
1055
+ resolve();
1056
+ else
1057
+ reject(new CliError(`${command} ${args.join(" ")} exited with ${code}`, code ?? 1));
1058
+ });
1059
+ });
1060
+ }
1026
1061
  async function installMasterService(ctx, port, dryRun) {
1027
1062
  const command = `${process.execPath} ${realpathSync(fileURLToPath(import.meta.url))} master serve --port ${port}`;
1028
1063
  if (platform() === "linux") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexport",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
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",