clisponsor 1.0.1 → 1.0.3

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.
@@ -193,6 +193,29 @@ function addClaudeCommandHook(settings, eventName, command) {
193
193
  return true;
194
194
  }
195
195
 
196
+ function addGeminiCommandHook(settings, eventName, matcher, command) {
197
+ if (!isPlainObject(settings.hooks)) settings.hooks = {};
198
+ const current = Array.isArray(settings.hooks[eventName]) ? settings.hooks[eventName] : [];
199
+ const exists = current.some((entry) => isClisponsorHookEntry(entry));
200
+ if (exists) return false;
201
+
202
+ settings.hooks[eventName] = [
203
+ ...current,
204
+ {
205
+ matcher,
206
+ hooks: [
207
+ {
208
+ name: "clisponsor",
209
+ type: "command",
210
+ command,
211
+ timeout: 5000,
212
+ },
213
+ ],
214
+ },
215
+ ];
216
+ return true;
217
+ }
218
+
196
219
  function removeClaudeCommandHooks(settings) {
197
220
  if (!isPlainObject(settings.hooks)) return false;
198
221
  let changed = false;
@@ -343,9 +366,20 @@ function geminiHookSource() {
343
366
  import fs from "node:fs";
344
367
  import crypto from "node:crypto";
345
368
  const cfg = JSON.parse(fs.readFileSync(${JSON.stringify(CONFIG_PATH)}, "utf8"));
346
- const event = process.argv[2] || "StartTurn";
347
- const placements = { SessionStart: "StartSession", UserPromptSubmit: "StartTurn", Stop: "EndTurn", StartTurn: "StartTurn" };
369
+ const event = process.argv[2] || "BeforeAgent";
370
+ const placements = { SessionStart: "StartSession", BeforeAgent: "StartTurn", AfterAgent: "EndTurn", StartTurn: "StartTurn" };
348
371
  const serveBaseUrl = cfg.serveBaseUrl || cfg.apiBaseUrl;
372
+ function sponsoredLine(line) {
373
+ return "[Sponsored] " + line;
374
+ }
375
+ function readStdin() {
376
+ return new Promise((resolve) => {
377
+ let data = "";
378
+ process.stdin.on("data", (chunk) => (data += chunk));
379
+ process.stdin.on("end", () => resolve(data));
380
+ });
381
+ }
382
+ await readStdin();
349
383
  try {
350
384
  if (!serveBaseUrl || !cfg.userId || !cfg.deviceCode || !cfg.deviceSecret) process.exit(0);
351
385
  const placement = placements[event] || event;
@@ -361,24 +395,33 @@ try {
361
395
  });
362
396
  if (res.ok) {
363
397
  const ad = await res.json();
364
- if (ad.display_line) console.log(ad.display_line);
398
+ if (ad.display_line) console.log(JSON.stringify({ systemMessage: sponsoredLine(ad.display_line) }));
365
399
  }
366
- } catch {}
400
+ } catch {
401
+ process.exit(0);
402
+ }
367
403
  `;
368
404
  }
369
405
 
370
406
  function installGemini() {
407
+ if (!commandExists("gemini")) {
408
+ console.log("Gemini CLI not found. To enable CLIsponsor for Gemini, install Gemini CLI and rerun: npx clisponsor install");
409
+ return;
410
+ }
411
+
371
412
  const geminiDir = path.join(CONFIG_DIR, "gemini");
372
413
  fs.mkdirSync(geminiDir, { recursive: true });
373
414
  const hookPath = path.join(geminiDir, "clisponsor_gemini_hook.mjs");
374
415
  fs.writeFileSync(hookPath, geminiHookSource(), { mode: 0o755 });
375
- if (commandExists("gemini")) {
376
- console.log("Gemini CLI hook script staged.");
377
- console.log("Gemini CLI does not expose a CLIsponsor auto-configuration target yet; configure it to run:");
378
- console.log(`node ${JSON.stringify(hookPath)} StartTurn`);
379
- } else {
380
- console.log("Gemini CLI hook script staged. After installing Gemini CLI, rerun: npx clisponsor install");
381
- }
416
+
417
+ const settingsPath = path.join(HOME, ".gemini", "settings.json");
418
+ const settings = readEditableJson(settingsPath, {});
419
+ addGeminiCommandHook(settings, "SessionStart", "startup", `node ${JSON.stringify(hookPath)} SessionStart`);
420
+ addGeminiCommandHook(settings, "BeforeAgent", "*", `node ${JSON.stringify(hookPath)} BeforeAgent`);
421
+ addGeminiCommandHook(settings, "AfterAgent", "*", `node ${JSON.stringify(hookPath)} AfterAgent`);
422
+ writeJson(settingsPath, settings);
423
+ console.log(`Updated ${settingsPath}`);
424
+ console.log("Gemini CLI hook installed.");
382
425
  }
383
426
 
384
427
  function installAll() {
@@ -406,6 +449,14 @@ function uninstallClaude() {
406
449
  }
407
450
 
408
451
  function uninstallGemini() {
452
+ const settingsPath = path.join(HOME, ".gemini", "settings.json");
453
+ const settings = readEditableJson(settingsPath, {});
454
+ if (removeClaudeCommandHooks(settings)) {
455
+ writeJson(settingsPath, settings);
456
+ console.log(`Removed CLIsponsor hooks from ${settingsPath}`);
457
+ } else {
458
+ console.log("No CLIsponsor Gemini hooks found.");
459
+ }
409
460
  fs.rmSync(path.join(CONFIG_DIR, "gemini", "clisponsor_gemini_hook.mjs"), { force: true });
410
461
  try {
411
462
  fs.rmdirSync(path.join(CONFIG_DIR, "gemini"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clisponsor",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "CLIsponsor installer for Codex, Claude Code, and Gemini sponsored CLI placements.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -22,6 +22,10 @@ function readStdin() {
22
22
  });
23
23
  }
24
24
 
25
+ function sponsoredLine(line) {
26
+ return `[Sponsored] ${line}`;
27
+ }
28
+
25
29
  await readStdin();
26
30
 
27
31
  try {
@@ -46,7 +50,7 @@ try {
46
50
  });
47
51
  if (!res.ok) process.exit(0);
48
52
  const ad = await res.json();
49
- if (ad.display_line) console.log(JSON.stringify({ systemMessage: ad.display_line }));
53
+ if (ad.display_line) console.log(JSON.stringify({ systemMessage: sponsoredLine(ad.display_line) }));
50
54
  } catch {
51
55
  process.exit(0);
52
56
  }
@@ -23,6 +23,10 @@ function readConfig() {
23
23
  return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf8"));
24
24
  }
25
25
 
26
+ function sponsoredLine(line) {
27
+ return `[Sponsored] ${line}`;
28
+ }
29
+
26
30
  const cfg = readConfig();
27
31
  const serveBaseUrl = cfg.serveBaseUrl || cfg.apiBaseUrl;
28
32
  await readStdin();
@@ -50,7 +54,7 @@ try {
50
54
  });
51
55
  if (!res.ok) process.exit(0);
52
56
  const ad = await res.json();
53
- if (ad.display_line) console.log(JSON.stringify({ systemMessage: ad.display_line }));
57
+ if (ad.display_line) console.log(JSON.stringify({ systemMessage: sponsoredLine(ad.display_line) }));
54
58
  } catch {
55
59
  process.exit(0);
56
60
  }