opencrater 0.2.2 → 0.2.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.
Files changed (2) hide show
  1. package/cli.js +28 -8
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -283,16 +283,28 @@ function showAgain() {
283
283
  return;
284
284
  }
285
285
  const { spawnSync, spawn } = require("node:child_process");
286
- // our own terminal's device (we are running interactively)
287
- const tty = spawnSync("tty", { stdio: ["inherit", "pipe", "ignore"], encoding: "utf8" })
288
- .stdout?.trim();
286
+ const isWin = process.platform === "win32";
289
287
  // Replay: live ✕ (local), but never re-poll or re-record the original
290
288
  // impression — it was already dismissed once.
291
289
  const payload = { ...saved.payload, replay: true };
292
290
  delete payload.impressionId;
293
291
  const env = { ...process.env, OPENCRATER_PAINT: JSON.stringify(payload) };
294
- if (tty && tty.startsWith("/dev/")) env.OPENCRATER_TTY = tty;
295
- const child = spawn(process.execPath, [painter], { detached: true, stdio: "ignore", env });
292
+ // Unix: resolve our terminal device so the detached painter can open it.
293
+ // Windows: no `tty` command and no device path the painter opens CONOUT$
294
+ // of the console it inherits, so we must NOT detach (detach = new/hidden
295
+ // console = nothing visible). Mirror the SDK's painterSpawnOptions.
296
+ if (!isWin) {
297
+ const tty = spawnSync("tty", { stdio: ["inherit", "pipe", "ignore"], encoding: "utf8" })
298
+ .stdout?.trim();
299
+ if (tty && tty.startsWith("/dev/")) env.OPENCRATER_TTY = tty;
300
+ }
301
+ const child = spawn(process.execPath, [painter], {
302
+ detached: !isWin,
303
+ stdio: "ignore",
304
+ env,
305
+ ...(isWin ? { windowsHide: true } : {}),
306
+ });
307
+ child.on("error", () => {});
296
308
  child.unref();
297
309
  console.log("opencrater: showing the last ad again.");
298
310
  }
@@ -347,13 +359,21 @@ if (cmd === "on" || cmd === "enable") {
347
359
  console.log(" overlay surface); message-level sponsorship is on the roadmap.");
348
360
  }
349
361
  // Pre-install the local hook runtime (background): hooks then run via
350
- // plain node — no npx resolution latency, no cold-cache races.
362
+ // plain node — no npx resolution latency, no cold-cache races. Best-effort
363
+ // and non-fatal — hooks fall back to `npx -y` when the runtime is absent.
351
364
  try {
352
365
  const { spawn } = require("node:child_process");
353
- spawn("npm", ["install", "--prefix",
366
+ // Windows: `npm` is `npm.cmd`, spawnable only through a shell — without
367
+ // shell:true this throws ENOENT as an async 'error' event that escapes
368
+ // try/catch and crashes the process. shell:true + an error handler keep
369
+ // it silent on every platform.
370
+ const isWin = process.platform === "win32";
371
+ const child = spawn("npm", ["install", "--prefix",
354
372
  path.join(os.homedir(), ".config", "opencrater", "runtime"),
355
373
  "@opencrater/sdk@latest", "--silent", "--no-audit", "--no-fund"],
356
- { detached: true, stdio: "ignore" }).unref();
374
+ { detached: true, stdio: "ignore", shell: isWin, windowsHide: true });
375
+ child.on("error", () => {});
376
+ child.unref();
357
377
  } catch {}
358
378
  console.log("OpenCrater ads enabled for Claude Code + Codex.");
359
379
  console.log("All hooks registered as triggers; cards render only at session edges");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencrater",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "OpenCrater — sponsor cards in Claude Code and Codex. Free, one command, opt out anytime.",
5
5
  "keywords": [
6
6
  "opencrater",