clisponsor 1.0.3 → 1.0.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.
- package/bin/clisponsor.mjs +119 -39
- package/package.json +1 -1
package/bin/clisponsor.mjs
CHANGED
|
@@ -130,6 +130,23 @@ function chmodExecutable(file) {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
function commandExists(command) {
|
|
133
|
+
const paths = String(process.env.PATH || "").split(path.delimiter).filter(Boolean);
|
|
134
|
+
const extensions = process.platform === "win32" ? String(process.env.PATHEXT || ".EXE;.CMD;.BAT").split(";") : [""];
|
|
135
|
+
for (const directory of paths) {
|
|
136
|
+
for (const extension of extensions) {
|
|
137
|
+
const candidate = path.join(directory, command + extension.toLowerCase());
|
|
138
|
+
try {
|
|
139
|
+
fs.accessSync(candidate, fs.constants.X_OK);
|
|
140
|
+
return true;
|
|
141
|
+
} catch {}
|
|
142
|
+
if (extension) {
|
|
143
|
+
try {
|
|
144
|
+
fs.accessSync(path.join(directory, command + extension.toUpperCase()), fs.constants.X_OK);
|
|
145
|
+
return true;
|
|
146
|
+
} catch {}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
133
150
|
try {
|
|
134
151
|
execFileSync(command, ["--version"], { stdio: "ignore" });
|
|
135
152
|
return true;
|
|
@@ -140,14 +157,15 @@ function commandExists(command) {
|
|
|
140
157
|
|
|
141
158
|
function isClisponsorCommand(value) {
|
|
142
159
|
return (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
160
|
+
typeof value === "string" &&
|
|
161
|
+
(value.includes("clisponsor_claude_hook.mjs") ||
|
|
162
|
+
value.includes("clisponsor_gemini_hook.mjs") ||
|
|
163
|
+
value.includes("clisponsor_antigravity_hook.mjs") ||
|
|
164
|
+
value.includes(`${path.sep}.clisponsor${path.sep}`) ||
|
|
165
|
+
value.includes("/.clisponsor/") ||
|
|
166
|
+
value.includes("\\.clisponsor\\"))
|
|
167
|
+
);
|
|
168
|
+
}
|
|
151
169
|
|
|
152
170
|
function isClisponsorHookEntry(entry) {
|
|
153
171
|
if (!isPlainObject(entry)) return false;
|
|
@@ -299,6 +317,11 @@ async function login() {
|
|
|
299
317
|
}
|
|
300
318
|
|
|
301
319
|
function installCodex() {
|
|
320
|
+
if (!commandExists("codex")) {
|
|
321
|
+
console.log("Codex CLI not found. To enable CLIsponsor for Codex, install Codex CLI and rerun: npx clisponsor@latest install");
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
302
325
|
const pluginRoot = path.join(CONFIG_DIR, "codex-plugin");
|
|
303
326
|
copyDir(path.join(ROOT, "templates", "codex-plugin"), pluginRoot);
|
|
304
327
|
patchFile(path.join(pluginRoot, "hooks", "hooks.json"), {
|
|
@@ -328,29 +351,23 @@ function installCodex() {
|
|
|
328
351
|
},
|
|
329
352
|
],
|
|
330
353
|
});
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
try {
|
|
335
|
-
execFileSync("codex", ["plugin", "add", "clisponsor@clisponsor-local"], { stdio: "ignore" });
|
|
336
|
-
console.log("Codex CLI plugin installed.");
|
|
337
|
-
} catch {
|
|
338
|
-
console.log("Codex CLI plugin staged. After installing Codex CLI, rerun: npx clisponsor install");
|
|
339
|
-
}
|
|
354
|
+
execFileSync("codex", ["plugin", "marketplace", "add", marketplaceRoot], { stdio: "ignore" });
|
|
355
|
+
execFileSync("codex", ["plugin", "add", "clisponsor@clisponsor-local"], { stdio: "ignore" });
|
|
356
|
+
console.log("Codex CLI plugin installed.");
|
|
340
357
|
}
|
|
341
358
|
|
|
342
359
|
function installClaude() {
|
|
360
|
+
if (!commandExists("claude")) {
|
|
361
|
+
console.log("Claude Code CLI not found. To enable CLIsponsor for Claude Code, install Claude Code CLI and rerun: npx clisponsor@latest install");
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
343
365
|
const claudeDir = path.join(CONFIG_DIR, "claude");
|
|
344
366
|
const installedHook = path.join(claudeDir, "clisponsor_claude_hook.mjs");
|
|
345
367
|
fs.mkdirSync(claudeDir, { recursive: true });
|
|
346
368
|
fs.copyFileSync(path.join(ROOT, "templates", "claude", "clisponsor_claude_hook.mjs"), installedHook);
|
|
347
369
|
chmodExecutable(installedHook);
|
|
348
370
|
|
|
349
|
-
if (!commandExists("claude")) {
|
|
350
|
-
console.log("Claude Code CLI hook staged. After installing Claude Code CLI, rerun: npx clisponsor install");
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
371
|
const settingsPath = path.join(HOME, ".claude", "settings.json");
|
|
355
372
|
const settings = readEditableJson(settingsPath, {});
|
|
356
373
|
addClaudeCommandHook(settings, "SessionStart", `node ${JSON.stringify(installedHook)} SessionStart`);
|
|
@@ -361,13 +378,15 @@ function installClaude() {
|
|
|
361
378
|
console.log("Claude Code CLI hook installed.");
|
|
362
379
|
}
|
|
363
380
|
|
|
364
|
-
function
|
|
381
|
+
function agentHookSource(client, options = {}) {
|
|
382
|
+
const outputMode = options.outputMode || "systemMessage";
|
|
365
383
|
return `#!/usr/bin/env node
|
|
366
384
|
import fs from "node:fs";
|
|
367
385
|
import crypto from "node:crypto";
|
|
368
386
|
const cfg = JSON.parse(fs.readFileSync(${JSON.stringify(CONFIG_PATH)}, "utf8"));
|
|
369
387
|
const event = process.argv[2] || "BeforeAgent";
|
|
370
|
-
const
|
|
388
|
+
const outputMode = ${JSON.stringify(outputMode)};
|
|
389
|
+
const placements = { SessionStart: "StartSession", PreInvocation: "StartSession", BeforeAgent: "StartTurn", UserPromptSubmit: "StartTurn", PreToolUse: "StartTurn", AfterAgent: "EndTurn", PostInvocation: "EndTurn", Stop: "EndTurn", StartTurn: "StartTurn" };
|
|
371
390
|
const serveBaseUrl = cfg.serveBaseUrl || cfg.apiBaseUrl;
|
|
372
391
|
function sponsoredLine(line) {
|
|
373
392
|
return "[Sponsored] " + line;
|
|
@@ -383,7 +402,7 @@ await readStdin();
|
|
|
383
402
|
try {
|
|
384
403
|
if (!serveBaseUrl || !cfg.userId || !cfg.deviceCode || !cfg.deviceSecret) process.exit(0);
|
|
385
404
|
const placement = placements[event] || event;
|
|
386
|
-
const body = { user_id: cfg.userId, device_code: cfg.deviceCode, client:
|
|
405
|
+
const body = { user_id: cfg.userId, device_code: cfg.deviceCode, client: ${JSON.stringify(client)}, hook_event: event, placement, idempotency_key: crypto.randomUUID(), metadata: { hookVersion: ${JSON.stringify(HOOK_VERSION)} } };
|
|
387
406
|
const res = await fetch(serveBaseUrl + "/v1/ads/serve", {
|
|
388
407
|
method: "POST",
|
|
389
408
|
headers: {
|
|
@@ -395,7 +414,13 @@ try {
|
|
|
395
414
|
});
|
|
396
415
|
if (res.ok) {
|
|
397
416
|
const ad = await res.json();
|
|
398
|
-
if (
|
|
417
|
+
if (outputMode === "antigravity") {
|
|
418
|
+
const payload = { decision: "allow" };
|
|
419
|
+
if (ad.display_line) payload.systemMessage = sponsoredLine(ad.display_line);
|
|
420
|
+
console.log(JSON.stringify(payload));
|
|
421
|
+
} else if (ad.display_line) {
|
|
422
|
+
console.log(JSON.stringify({ systemMessage: sponsoredLine(ad.display_line) }));
|
|
423
|
+
}
|
|
399
424
|
}
|
|
400
425
|
} catch {
|
|
401
426
|
process.exit(0);
|
|
@@ -405,14 +430,14 @@ try {
|
|
|
405
430
|
|
|
406
431
|
function installGemini() {
|
|
407
432
|
if (!commandExists("gemini")) {
|
|
408
|
-
console.log("Gemini CLI not found. To enable CLIsponsor for Gemini, install Gemini CLI and rerun: npx clisponsor install");
|
|
433
|
+
console.log("Gemini CLI not found. To enable CLIsponsor for Gemini, install Gemini CLI and rerun: npx clisponsor@latest install");
|
|
409
434
|
return;
|
|
410
435
|
}
|
|
411
436
|
|
|
412
437
|
const geminiDir = path.join(CONFIG_DIR, "gemini");
|
|
413
438
|
fs.mkdirSync(geminiDir, { recursive: true });
|
|
414
439
|
const hookPath = path.join(geminiDir, "clisponsor_gemini_hook.mjs");
|
|
415
|
-
fs.writeFileSync(hookPath,
|
|
440
|
+
fs.writeFileSync(hookPath, agentHookSource("Gemini"), { mode: 0o755 });
|
|
416
441
|
|
|
417
442
|
const settingsPath = path.join(HOME, ".gemini", "settings.json");
|
|
418
443
|
const settings = readEditableJson(settingsPath, {});
|
|
@@ -424,10 +449,46 @@ function installGemini() {
|
|
|
424
449
|
console.log("Gemini CLI hook installed.");
|
|
425
450
|
}
|
|
426
451
|
|
|
452
|
+
function installAntigravity() {
|
|
453
|
+
if (!commandExists("agy")) {
|
|
454
|
+
console.log("Antigravity CLI not found. To enable CLIsponsor for Antigravity, install Antigravity CLI and rerun: npx clisponsor@latest install");
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const antigravityDir = path.join(CONFIG_DIR, "antigravity");
|
|
459
|
+
fs.mkdirSync(antigravityDir, { recursive: true });
|
|
460
|
+
const hookPath = path.join(antigravityDir, "clisponsor_antigravity_hook.mjs");
|
|
461
|
+
fs.writeFileSync(hookPath, agentHookSource("Antigravity", { outputMode: "antigravity" }), { mode: 0o755 });
|
|
462
|
+
|
|
463
|
+
const hooksPath = path.join(HOME, ".gemini", "config", "hooks.json");
|
|
464
|
+
const hooksConfig = readEditableJson(hooksPath, {});
|
|
465
|
+
addGeminiCommandHook(hooksConfig, "PreInvocation", "*", `node ${JSON.stringify(hookPath)} PreInvocation`);
|
|
466
|
+
addGeminiCommandHook(hooksConfig, "UserPromptSubmit", "*", `node ${JSON.stringify(hookPath)} UserPromptSubmit`);
|
|
467
|
+
addGeminiCommandHook(hooksConfig, "PostInvocation", "*", `node ${JSON.stringify(hookPath)} PostInvocation`);
|
|
468
|
+
addGeminiCommandHook(hooksConfig, "Stop", "*", `node ${JSON.stringify(hookPath)} Stop`);
|
|
469
|
+
writeJson(hooksPath, hooksConfig);
|
|
470
|
+
console.log(`Updated ${hooksPath}`);
|
|
471
|
+
console.log("Antigravity CLI hook installed.");
|
|
472
|
+
}
|
|
473
|
+
|
|
427
474
|
function installAll() {
|
|
428
475
|
installCodex();
|
|
429
476
|
installClaude();
|
|
430
477
|
installGemini();
|
|
478
|
+
installAntigravity();
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function install() {
|
|
482
|
+
const target = process.argv[3] && !process.argv[3].startsWith("--") ? process.argv[3] : "all";
|
|
483
|
+
if (!["all", "codex", "claude", "gemini", "antigravity", "agy"].includes(target)) {
|
|
484
|
+
console.error("Unknown install target. Use: codex, claude, gemini, antigravity, or all.");
|
|
485
|
+
process.exit(1);
|
|
486
|
+
}
|
|
487
|
+
if (target === "all") installAll();
|
|
488
|
+
else if (target === "codex") installCodex();
|
|
489
|
+
else if (target === "claude") installClaude();
|
|
490
|
+
else if (target === "gemini") installGemini();
|
|
491
|
+
else installAntigravity();
|
|
431
492
|
}
|
|
432
493
|
|
|
433
494
|
function uninstallCodex() {
|
|
@@ -464,15 +525,32 @@ function uninstallGemini() {
|
|
|
464
525
|
console.log("Removed Gemini hook script.");
|
|
465
526
|
}
|
|
466
527
|
|
|
528
|
+
function uninstallAntigravity() {
|
|
529
|
+
const hooksPath = path.join(HOME, ".gemini", "config", "hooks.json");
|
|
530
|
+
const hooksConfig = readEditableJson(hooksPath, {});
|
|
531
|
+
if (removeClaudeCommandHooks(hooksConfig)) {
|
|
532
|
+
writeJson(hooksPath, hooksConfig);
|
|
533
|
+
console.log(`Removed CLIsponsor hooks from ${hooksPath}`);
|
|
534
|
+
} else {
|
|
535
|
+
console.log("No CLIsponsor Antigravity hooks found.");
|
|
536
|
+
}
|
|
537
|
+
fs.rmSync(path.join(CONFIG_DIR, "antigravity", "clisponsor_antigravity_hook.mjs"), { force: true });
|
|
538
|
+
try {
|
|
539
|
+
fs.rmdirSync(path.join(CONFIG_DIR, "antigravity"));
|
|
540
|
+
} catch {}
|
|
541
|
+
console.log("Removed Antigravity hook script.");
|
|
542
|
+
}
|
|
543
|
+
|
|
467
544
|
function uninstall() {
|
|
468
545
|
const target = process.argv[3] && !process.argv[3].startsWith("--") ? process.argv[3] : "all";
|
|
469
|
-
if (!["all", "codex", "claude", "gemini"].includes(target)) {
|
|
470
|
-
console.error("Unknown uninstall target. Use: codex, claude, gemini, or all.");
|
|
546
|
+
if (!["all", "codex", "claude", "gemini", "antigravity", "agy"].includes(target)) {
|
|
547
|
+
console.error("Unknown uninstall target. Use: codex, claude, gemini, antigravity, or all.");
|
|
471
548
|
process.exit(1);
|
|
472
549
|
}
|
|
473
550
|
if (target === "all" || target === "codex") uninstallCodex();
|
|
474
551
|
if (target === "all" || target === "claude") uninstallClaude();
|
|
475
552
|
if (target === "all" || target === "gemini") uninstallGemini();
|
|
553
|
+
if (target === "all" || target === "antigravity" || target === "agy") uninstallAntigravity();
|
|
476
554
|
if (hasFlag("--config")) {
|
|
477
555
|
fs.rmSync(CONFIG_PATH, { force: true });
|
|
478
556
|
console.log(`Removed ${CONFIG_PATH}`);
|
|
@@ -526,12 +604,13 @@ async function doctor() {
|
|
|
526
604
|
email: cfg.email || null,
|
|
527
605
|
userId: cfg.userId || null,
|
|
528
606
|
deviceCode: cfg.deviceCode || null,
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
607
|
+
installed: {
|
|
608
|
+
codexPluginStaged: fs.existsSync(path.join(CONFIG_DIR, "codex-marketplace", "plugins", "clisponsor")),
|
|
609
|
+
claudeSettings: fs.existsSync(path.join(HOME, ".claude", "settings.json")),
|
|
610
|
+
claudeHookScript: fs.existsSync(path.join(CONFIG_DIR, "claude", "clisponsor_claude_hook.mjs")),
|
|
611
|
+
geminiHookScript: fs.existsSync(path.join(CONFIG_DIR, "gemini", "clisponsor_gemini_hook.mjs")),
|
|
612
|
+
antigravityHookScript: fs.existsSync(path.join(CONFIG_DIR, "antigravity", "clisponsor_antigravity_hook.mjs")),
|
|
613
|
+
},
|
|
535
614
|
network: {},
|
|
536
615
|
};
|
|
537
616
|
|
|
@@ -557,6 +636,7 @@ async function doctor() {
|
|
|
557
636
|
console.log(`Claude settings: ${diagnostics.installed.claudeSettings ? "yes" : "no"}`);
|
|
558
637
|
console.log(`Claude hook script: ${diagnostics.installed.claudeHookScript ? "yes" : "no"}`);
|
|
559
638
|
console.log(`Gemini hook script: ${diagnostics.installed.geminiHookScript ? "yes" : "no"}`);
|
|
639
|
+
console.log(`Antigravity hook script: ${diagnostics.installed.antigravityHookScript ? "yes" : "no"}`);
|
|
560
640
|
if (skipNetwork) {
|
|
561
641
|
console.log("Network: skipped");
|
|
562
642
|
} else {
|
|
@@ -567,9 +647,9 @@ async function doctor() {
|
|
|
567
647
|
|
|
568
648
|
function help() {
|
|
569
649
|
console.log(`clisponsor commands:
|
|
570
|
-
clisponsor install
|
|
650
|
+
clisponsor install [all|codex|claude|gemini|antigravity]
|
|
571
651
|
clisponsor login <email> [--label=<device-label>]
|
|
572
|
-
clisponsor uninstall [--config]
|
|
652
|
+
clisponsor uninstall [all|codex|claude|gemini|antigravity] [--config]
|
|
573
653
|
clisponsor status
|
|
574
654
|
clisponsor doctor [--json] [--skip-network]
|
|
575
655
|
|
|
@@ -579,7 +659,7 @@ Environment:
|
|
|
579
659
|
|
|
580
660
|
const command = process.argv[2] || "help";
|
|
581
661
|
if (command === "login") await login();
|
|
582
|
-
else if (command === "install"
|
|
662
|
+
else if (command === "install") install();
|
|
583
663
|
else if (command === "uninstall") uninstall();
|
|
584
664
|
else if (command === "status") await status();
|
|
585
665
|
else if (command === "doctor") await doctor();
|