opencrater 0.1.6 → 0.1.7

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/cli.js +38 -4
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -212,10 +212,43 @@ function showAgain() {
212
212
  console.log("opencrater: showing the last ad again.");
213
213
  }
214
214
 
215
+ /* Auto-detect which AI CLIs exist on this machine — `on` connects every
216
+ detected host's config automatically, and new hosts picked up here flow
217
+ into detection as we add them. */
218
+ function hasBin(name) {
219
+ try {
220
+ const { spawnSync } = require("node:child_process");
221
+ return spawnSync("which", [name], { stdio: "ignore" }).status === 0;
222
+ } catch { return false; }
223
+ }
224
+ function detectHosts() {
225
+ return {
226
+ claude_code: fs.existsSync(path.join(os.homedir(), ".claude")) || hasBin("claude"),
227
+ codex: fs.existsSync(path.join(process.env.CODEX_HOME || path.join(os.homedir(), ".codex"))) || hasBin("codex"),
228
+ };
229
+ }
230
+
215
231
  const cmd = process.argv[2] || "status";
216
232
  if (cmd === "on" || cmd === "enable") {
217
- enableIn(CLAUDE_SETTINGS, "claude_code");
218
- enableIn(CODEX_HOOKS, "codex");
233
+ const hosts = detectHosts();
234
+ if (!hosts.claude_code && !hosts.codex) {
235
+ console.log("No supported AI CLI found (looked for Claude Code and Codex).");
236
+ console.log("Install one, then run: npx opencrater on");
237
+ process.exit(1);
238
+ }
239
+ if (hosts.claude_code) {
240
+ enableIn(CLAUDE_SETTINGS, "claude_code");
241
+ console.log("✓ Claude Code detected — connected (" + CLAUDE_SETTINGS + ")");
242
+ } else {
243
+ console.log("· Claude Code not found — skipped");
244
+ }
245
+ if (hosts.codex) {
246
+ enableIn(CODEX_HOOKS, "codex");
247
+ console.log("✓ Codex detected — connected (" + CODEX_HOOKS + ")");
248
+ console.log(" Codex will ask once to trust the new hooks on its next launch — approve to enable.");
249
+ } else {
250
+ console.log("· Codex not found — skipped");
251
+ }
219
252
  // Pre-install the local hook runtime (background): hooks then run via
220
253
  // plain node — no npx resolution latency, no cold-cache races.
221
254
  try {
@@ -240,10 +273,11 @@ if (cmd === "on" || cmd === "enable") {
240
273
  } else if (cmd === "show" || cmd === "again") {
241
274
  showAgain();
242
275
  } else if (cmd === "status") {
276
+ const hosts = detectHosts();
243
277
  const cc = statusIn(CLAUDE_SETTINGS);
244
278
  const cx = statusIn(CODEX_HOOKS);
245
- console.log("Claude Code:", cc.length ? "enabled on " + cc.join(", ") : "not enabled");
246
- console.log("Codex: ", cx.length ? "enabled on " + cx.join(", ") : "not enabled");
279
+ console.log("Claude Code:", !hosts.claude_code ? "not installed" : cc.length ? "enabled (" + cc.length + " hooks)" : "detected — run: npx opencrater on");
280
+ console.log("Codex: ", !hosts.codex ? "not installed" : cx.length ? "enabled (" + cx.length + " hooks)" : "detected — run: npx opencrater on");
247
281
  } else {
248
282
  console.log("Usage: npx opencrater <on|off|status|x|show>");
249
283
  console.log(" x dismiss the sponsor card currently on screen");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencrater",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "OpenCrater — sponsor cards in Claude Code and Codex. Free, one command, opt out anytime.",
5
5
  "keywords": [
6
6
  "opencrater",