opencrater 0.1.2 → 0.1.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 +35 -1
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -133,6 +133,37 @@ function statusIn(file) {
133
133
  );
134
134
  }
135
135
 
136
+ /* Dismiss the sponsor card currently on screen — no browser needed.
137
+ Writes the painter's local dismiss signal, records the dismissal against
138
+ the API (idempotent), and SIGTERMs the painter so the card clears NOW. */
139
+ async function dismissNow() {
140
+ const dir = path.join(os.homedir(), ".config", "opencrater");
141
+ let lock = null;
142
+ try {
143
+ lock = JSON.parse(fs.readFileSync(path.join(dir, "painter.lock"), "utf8"));
144
+ } catch {
145
+ console.log("opencrater: no sponsor card is on screen.");
146
+ return;
147
+ }
148
+ try {
149
+ fs.mkdirSync(dir, { recursive: true });
150
+ fs.writeFileSync(
151
+ path.join(dir, "dismiss.signal"),
152
+ JSON.stringify({ impressionId: lock.impressionId, at: Date.now() }),
153
+ );
154
+ } catch {}
155
+ if (lock.impressionId) {
156
+ const origin = process.env.OPENCRATER_API_ORIGIN || "https://api.opencrater.to";
157
+ try {
158
+ await fetch(origin + "/x/" + lock.impressionId, { signal: AbortSignal.timeout(2500) });
159
+ } catch {}
160
+ }
161
+ if (lock.pid && lock.pid > 1) {
162
+ try { process.kill(lock.pid, "SIGTERM"); } catch {}
163
+ }
164
+ console.log("opencrater: ad dismissed — feedback recorded.");
165
+ }
166
+
136
167
  const cmd = process.argv[2] || "status";
137
168
  if (cmd === "on" || cmd === "enable") {
138
169
  enableIn(CLAUDE_SETTINGS, "claude_code");
@@ -147,12 +178,15 @@ if (cmd === "on" || cmd === "enable") {
147
178
  const a = disableIn(CLAUDE_SETTINGS);
148
179
  const b = disableIn(CODEX_HOOKS);
149
180
  console.log(a || b ? "OpenCrater ads disabled. Publisher hooks (if any) were not touched." : "Nothing to remove — OpenCrater ads were not enabled.");
181
+ } else if (cmd === "x" || cmd === "dismiss") {
182
+ dismissNow();
150
183
  } else if (cmd === "status") {
151
184
  const cc = statusIn(CLAUDE_SETTINGS);
152
185
  const cx = statusIn(CODEX_HOOKS);
153
186
  console.log("Claude Code:", cc.length ? "enabled on " + cc.join(", ") : "not enabled");
154
187
  console.log("Codex: ", cx.length ? "enabled on " + cx.join(", ") : "not enabled");
155
188
  } else {
156
- console.log("Usage: npx opencrater <on|off|status>");
189
+ console.log("Usage: npx opencrater <on|off|status|x>");
190
+ console.log(" x dismiss the sponsor card currently on screen");
157
191
  process.exitCode = 1;
158
192
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencrater",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "OpenCrater — sponsor cards in Claude Code and Codex. Free, one command, opt out anytime.",
5
5
  "keywords": [
6
6
  "opencrater",