clisponsor 1.0.15 → 1.0.16

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/bin/clisponsor.mjs +128 -18
  2. package/package.json +1 -1
@@ -170,6 +170,69 @@ function qwenHome() {
170
170
  return process.env.QWEN_HOME || path.join(HOME, ".qwen");
171
171
  }
172
172
 
173
+ function colorEnabled() {
174
+ return Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
175
+ }
176
+
177
+ function color(value, code) {
178
+ if (!colorEnabled()) return value;
179
+ return `\u001b[${code}m${value}\u001b[0m`;
180
+ }
181
+
182
+ function green(value) {
183
+ return color(value, "32");
184
+ }
185
+
186
+ function red(value) {
187
+ return color(value, "31");
188
+ }
189
+
190
+ function cyan(value) {
191
+ return color(value, "36");
192
+ }
193
+
194
+ function dim(value) {
195
+ return color(value, "2");
196
+ }
197
+
198
+ function bold(value) {
199
+ return color(value, "1");
200
+ }
201
+
202
+ function targetSuffix(spec) {
203
+ return dim(`(${spec.command})`);
204
+ }
205
+
206
+ function installLine(symbol, spec, message, colorFn = (value) => value) {
207
+ console.log(`${colorFn(symbol)} ${spec.label} ${targetSuffix(spec)} - ${message}`);
208
+ }
209
+
210
+ function startInstallSpinner(spec) {
211
+ if (!process.stdout.isTTY) return () => {};
212
+ const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
213
+ let index = 0;
214
+ const render = () => {
215
+ process.stdout.write(`\r${cyan(frames[index % frames.length])} ${spec.label} ${targetSuffix(spec)} - installing...`);
216
+ index += 1;
217
+ };
218
+ render();
219
+ const timer = setInterval(render, 80);
220
+ return () => {
221
+ clearInterval(timer);
222
+ process.stdout.write("\r\u001b[2K");
223
+ };
224
+ }
225
+
226
+ function withoutInstallLogs(action) {
227
+ const originalLog = console.log;
228
+ console.log = () => {};
229
+ try {
230
+ return action();
231
+ } finally {
232
+ console.log = originalLog;
233
+ }
234
+ }
235
+
173
236
  function commandExists(command) {
174
237
  const paths = String(process.env.PATH || "").split(path.delimiter).filter(Boolean);
175
238
  const extensions = process.platform === "win32" ? String(process.env.PATHEXT || ".EXE;.CMD;.BAT").split(";") : [""];
@@ -952,32 +1015,79 @@ function installQwen() {
952
1015
  console.log("Qwen Code CLI hook installed.");
953
1016
  }
954
1017
 
1018
+ function installTargets() {
1019
+ return [
1020
+ { target: "codex", label: "Codex CLI", command: "codex", install: installCodex },
1021
+ { target: "claude", label: "Claude Code CLI", command: "claude", install: installClaude },
1022
+ { target: "gemini", label: "Gemini CLI", command: "gemini", install: installGemini },
1023
+ { target: "antigravity", aliases: ["agy"], label: "Antigravity CLI", command: "agy", install: installAntigravity },
1024
+ { target: "opencode", label: "OpenCode CLI", command: "opencode", install: installOpenCode },
1025
+ { target: "pi", label: "Pi Coding Agent", command: "pi", install: installPi },
1026
+ { target: "copilot", label: "GitHub Copilot CLI", command: "copilot", install: installCopilot },
1027
+ { target: "qwen", label: "Qwen Code", command: "qwen", install: installQwen },
1028
+ ];
1029
+ }
1030
+
1031
+ function targetNames() {
1032
+ return installTargets().flatMap((spec) => [spec.target, ...(spec.aliases || [])]);
1033
+ }
1034
+
1035
+ function findInstallTarget(target) {
1036
+ return installTargets().find((spec) => spec.target === target || (spec.aliases || []).includes(target));
1037
+ }
1038
+
1039
+ function renderInstallHeader(target) {
1040
+ const scope = target === "all" ? "supported CLIs" : findInstallTarget(target)?.label || target;
1041
+ console.log(bold("CLIsponsor installer"));
1042
+ console.log(dim(`Scanning ${scope} on this machine...`));
1043
+ console.log("");
1044
+ }
1045
+
1046
+ function renderInstallSummary(results) {
1047
+ const installed = results.filter((result) => result.status === "installed").length;
1048
+ const missing = results.filter((result) => result.status === "missing").length;
1049
+ const failed = results.filter((result) => result.status === "failed").length;
1050
+ console.log("");
1051
+ const summary = `${installed} installed, ${missing} not found${failed ? `, ${failed} failed` : ""}.`;
1052
+ console.log(failed ? red(summary) : green(summary));
1053
+ if (missing) {
1054
+ console.log(dim("Install missing CLIs and rerun: npx clisponsor@latest install"));
1055
+ }
1056
+ }
1057
+
1058
+ function installTarget(spec) {
1059
+ if (!commandExists(spec.command)) {
1060
+ installLine("✕", spec, "not found", red);
1061
+ return { target: spec.target, status: "missing" };
1062
+ }
1063
+
1064
+ const stopSpinner = startInstallSpinner(spec);
1065
+ try {
1066
+ withoutInstallLogs(spec.install);
1067
+ stopSpinner();
1068
+ installLine("✓", spec, "installed", green);
1069
+ return { target: spec.target, status: "installed" };
1070
+ } catch (error) {
1071
+ stopSpinner();
1072
+ installLine("!", spec, `failed: ${error.message}`, red);
1073
+ return { target: spec.target, status: "failed", error };
1074
+ }
1075
+ }
1076
+
955
1077
  function installAll() {
956
- installCodex();
957
- installClaude();
958
- installGemini();
959
- installAntigravity();
960
- installOpenCode();
961
- installPi();
962
- installCopilot();
963
- installQwen();
1078
+ return installTargets().map((spec) => installTarget(spec));
964
1079
  }
965
1080
 
966
1081
  function install() {
967
1082
  const target = process.argv[3] && !process.argv[3].startsWith("--") ? process.argv[3] : "all";
968
- if (!["all", "codex", "claude", "gemini", "antigravity", "agy", "opencode", "pi", "copilot", "qwen"].includes(target)) {
1083
+ if (!["all", ...targetNames()].includes(target)) {
969
1084
  console.error("Unknown install target. Use: codex, claude, gemini, antigravity, opencode, pi, copilot, qwen, or all.");
970
1085
  process.exit(1);
971
1086
  }
972
- if (target === "all") installAll();
973
- else if (target === "codex") installCodex();
974
- else if (target === "claude") installClaude();
975
- else if (target === "gemini") installGemini();
976
- else if (target === "opencode") installOpenCode();
977
- else if (target === "pi") installPi();
978
- else if (target === "copilot") installCopilot();
979
- else if (target === "qwen") installQwen();
980
- else installAntigravity();
1087
+ renderInstallHeader(target);
1088
+ const results = target === "all" ? installAll() : [installTarget(findInstallTarget(target))];
1089
+ renderInstallSummary(results);
1090
+ if (results.some((result) => result.status === "failed")) process.exit(1);
981
1091
  }
982
1092
 
983
1093
  function uninstallCodex() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clisponsor",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "CLIsponsor installer for Codex, Claude Code, Gemini, Antigravity, OpenCode, Pi, GitHub Copilot CLI, and Qwen Code sponsored CLI placements.",
5
5
  "type": "module",
6
6
  "engines": {