clisponsor 1.0.1 → 1.0.2

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 +59 -11
  2. package/package.json +1 -1
@@ -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,17 @@ 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 readStdin() {
373
+ return new Promise((resolve) => {
374
+ let data = "";
375
+ process.stdin.on("data", (chunk) => (data += chunk));
376
+ process.stdin.on("end", () => resolve(data));
377
+ });
378
+ }
379
+ await readStdin();
349
380
  try {
350
381
  if (!serveBaseUrl || !cfg.userId || !cfg.deviceCode || !cfg.deviceSecret) process.exit(0);
351
382
  const placement = placements[event] || event;
@@ -361,24 +392,33 @@ try {
361
392
  });
362
393
  if (res.ok) {
363
394
  const ad = await res.json();
364
- if (ad.display_line) console.log(ad.display_line);
395
+ if (ad.display_line) console.log(JSON.stringify({ systemMessage: ad.display_line }));
365
396
  }
366
- } catch {}
397
+ } catch {
398
+ process.exit(0);
399
+ }
367
400
  `;
368
401
  }
369
402
 
370
403
  function installGemini() {
404
+ if (!commandExists("gemini")) {
405
+ console.log("Gemini CLI not found. To enable CLIsponsor for Gemini, install Gemini CLI and rerun: npx clisponsor install");
406
+ return;
407
+ }
408
+
371
409
  const geminiDir = path.join(CONFIG_DIR, "gemini");
372
410
  fs.mkdirSync(geminiDir, { recursive: true });
373
411
  const hookPath = path.join(geminiDir, "clisponsor_gemini_hook.mjs");
374
412
  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
- }
413
+
414
+ const settingsPath = path.join(HOME, ".gemini", "settings.json");
415
+ const settings = readEditableJson(settingsPath, {});
416
+ addGeminiCommandHook(settings, "SessionStart", "startup", `node ${JSON.stringify(hookPath)} SessionStart`);
417
+ addGeminiCommandHook(settings, "BeforeAgent", "*", `node ${JSON.stringify(hookPath)} BeforeAgent`);
418
+ addGeminiCommandHook(settings, "AfterAgent", "*", `node ${JSON.stringify(hookPath)} AfterAgent`);
419
+ writeJson(settingsPath, settings);
420
+ console.log(`Updated ${settingsPath}`);
421
+ console.log("Gemini CLI hook installed.");
382
422
  }
383
423
 
384
424
  function installAll() {
@@ -406,6 +446,14 @@ function uninstallClaude() {
406
446
  }
407
447
 
408
448
  function uninstallGemini() {
449
+ const settingsPath = path.join(HOME, ".gemini", "settings.json");
450
+ const settings = readEditableJson(settingsPath, {});
451
+ if (removeClaudeCommandHooks(settings)) {
452
+ writeJson(settingsPath, settings);
453
+ console.log(`Removed CLIsponsor hooks from ${settingsPath}`);
454
+ } else {
455
+ console.log("No CLIsponsor Gemini hooks found.");
456
+ }
409
457
  fs.rmSync(path.join(CONFIG_DIR, "gemini", "clisponsor_gemini_hook.mjs"), { force: true });
410
458
  try {
411
459
  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.2",
4
4
  "description": "CLIsponsor installer for Codex, Claude Code, and Gemini sponsored CLI placements.",
5
5
  "type": "module",
6
6
  "engines": {