opencrater 0.1.3 → 0.1.5
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.
- package/cli.js +61 -5
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -43,9 +43,21 @@ const CODEX_EVENTS = [
|
|
|
43
43
|
];
|
|
44
44
|
const MARKER = "--package " + PKG + " "; // identifies OUR hook entries only
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
// Resilient hook command: prefer the pre-installed local runtime (no npx on
|
|
47
|
+
// the hot path — concurrent fires racing a cold npx cache caused
|
|
48
|
+
// "opencrater-hook: command not found" noise in the host); fall back to npx;
|
|
49
|
+
// ALWAYS exit 0 with stderr silenced — a sponsor hook must never surface an
|
|
50
|
+
// error inside someone's session.
|
|
51
|
+
const cmdFor = (event, host) => {
|
|
52
|
+
const args = "--placement " + event + " --key " + KEY +
|
|
53
|
+
" --package " + PKG + " --host " + host;
|
|
54
|
+
const runtime = '"$HOME/.config/opencrater/runtime/node_modules/@opencrater/sdk/dist/hook.js"';
|
|
55
|
+
return (
|
|
56
|
+
"{ if [ -f " + runtime + " ]; then node " + runtime + " " + args +
|
|
57
|
+
"; else npx -y -p @opencrater/sdk opencrater-hook " + args +
|
|
58
|
+
"; fi; } 2>/dev/null || true"
|
|
59
|
+
);
|
|
60
|
+
};
|
|
49
61
|
|
|
50
62
|
const CLAUDE_SETTINGS = path.join(os.homedir(), ".claude", "settings.json");
|
|
51
63
|
const CODEX_HOOKS = path.join(
|
|
@@ -152,6 +164,9 @@ async function dismissNow() {
|
|
|
152
164
|
JSON.stringify({ impressionId: lock.impressionId, at: Date.now() }),
|
|
153
165
|
);
|
|
154
166
|
} catch {}
|
|
167
|
+
if (lock.dismissUrl) {
|
|
168
|
+
try { await fetch(lock.dismissUrl, { signal: AbortSignal.timeout(1000) }); } catch {}
|
|
169
|
+
}
|
|
155
170
|
if (lock.impressionId) {
|
|
156
171
|
const origin = process.env.OPENCRATER_API_ORIGIN || "https://api.opencrater.to";
|
|
157
172
|
try {
|
|
@@ -162,12 +177,50 @@ async function dismissNow() {
|
|
|
162
177
|
try { process.kill(lock.pid, "SIGTERM"); } catch {}
|
|
163
178
|
}
|
|
164
179
|
console.log("opencrater: ad dismissed — feedback recorded.");
|
|
180
|
+
console.log(" changed your mind? npx opencrater show");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Repaint the last sponsor card ("show ad again"). Reads the payload the
|
|
184
|
+
painter saved, resolves THIS terminal's tty, and spawns the local-runtime
|
|
185
|
+
painter detached — exactly how the hook does it. */
|
|
186
|
+
function showAgain() {
|
|
187
|
+
const dir = path.join(os.homedir(), ".config", "opencrater");
|
|
188
|
+
let saved = null;
|
|
189
|
+
try {
|
|
190
|
+
saved = JSON.parse(fs.readFileSync(path.join(dir, "last-ad.json"), "utf8"));
|
|
191
|
+
} catch {
|
|
192
|
+
console.log("opencrater: no recent ad to show.");
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const painter = path.join(dir, "runtime", "node_modules", "@opencrater", "sdk", "dist", "paint.js");
|
|
196
|
+
if (!fs.existsSync(painter)) {
|
|
197
|
+
console.log("opencrater: hook runtime not installed yet — run: npx opencrater on");
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const { spawnSync, spawn } = require("node:child_process");
|
|
201
|
+
// our own terminal's device (we are running interactively)
|
|
202
|
+
const tty = spawnSync("tty", { stdio: ["inherit", "pipe", "ignore"], encoding: "utf8" })
|
|
203
|
+
.stdout?.trim();
|
|
204
|
+
const env = { ...process.env, OPENCRATER_PAINT: JSON.stringify(saved.payload) };
|
|
205
|
+
if (tty && tty.startsWith("/dev/")) env.OPENCRATER_TTY = tty;
|
|
206
|
+
const child = spawn(process.execPath, [painter], { detached: true, stdio: "ignore", env });
|
|
207
|
+
child.unref();
|
|
208
|
+
console.log("opencrater: showing the last ad again.");
|
|
165
209
|
}
|
|
166
210
|
|
|
167
211
|
const cmd = process.argv[2] || "status";
|
|
168
212
|
if (cmd === "on" || cmd === "enable") {
|
|
169
213
|
enableIn(CLAUDE_SETTINGS, "claude_code");
|
|
170
214
|
enableIn(CODEX_HOOKS, "codex");
|
|
215
|
+
// Pre-install the local hook runtime (background): hooks then run via
|
|
216
|
+
// plain node — no npx resolution latency, no cold-cache races.
|
|
217
|
+
try {
|
|
218
|
+
const { spawn } = require("node:child_process");
|
|
219
|
+
spawn("npm", ["install", "--prefix",
|
|
220
|
+
path.join(os.homedir(), ".config", "opencrater", "runtime"),
|
|
221
|
+
"@opencrater/sdk@latest", "--silent", "--no-audit", "--no-fund"],
|
|
222
|
+
{ detached: true, stdio: "ignore" }).unref();
|
|
223
|
+
} catch {}
|
|
171
224
|
console.log("OpenCrater ads enabled for Claude Code + Codex.");
|
|
172
225
|
console.log("All hooks registered as triggers; cards render only at session edges");
|
|
173
226
|
console.log("(SessionStart, Stop, SessionEnd, Notification) with a machine-wide frequency cap.");
|
|
@@ -180,13 +233,16 @@ if (cmd === "on" || cmd === "enable") {
|
|
|
180
233
|
console.log(a || b ? "OpenCrater ads disabled. Publisher hooks (if any) were not touched." : "Nothing to remove — OpenCrater ads were not enabled.");
|
|
181
234
|
} else if (cmd === "x" || cmd === "dismiss") {
|
|
182
235
|
dismissNow();
|
|
236
|
+
} else if (cmd === "show" || cmd === "again") {
|
|
237
|
+
showAgain();
|
|
183
238
|
} else if (cmd === "status") {
|
|
184
239
|
const cc = statusIn(CLAUDE_SETTINGS);
|
|
185
240
|
const cx = statusIn(CODEX_HOOKS);
|
|
186
241
|
console.log("Claude Code:", cc.length ? "enabled on " + cc.join(", ") : "not enabled");
|
|
187
242
|
console.log("Codex: ", cx.length ? "enabled on " + cx.join(", ") : "not enabled");
|
|
188
243
|
} else {
|
|
189
|
-
console.log("Usage: npx opencrater <on|off|status|x>");
|
|
190
|
-
console.log(" x
|
|
244
|
+
console.log("Usage: npx opencrater <on|off|status|x|show>");
|
|
245
|
+
console.log(" x dismiss the sponsor card currently on screen");
|
|
246
|
+
console.log(" show bring the last dismissed ad back");
|
|
191
247
|
process.exitCode = 1;
|
|
192
248
|
}
|