opencrater 0.2.1 → 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.
- package/cli.js +53 -11
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -23,8 +23,29 @@ const fs = require("node:fs");
|
|
|
23
23
|
const path = require("node:path");
|
|
24
24
|
const os = require("node:os");
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
// Default = the house channel. Publishers integrating OpenCrater into
|
|
27
|
+
// their OWN package pass their credentials instead:
|
|
28
|
+
// npx opencrater on --key ock_… --package my-tool
|
|
29
|
+
// npx opencrater off --package my-tool
|
|
30
|
+
// so revenue attributes to them and `off` removes only their entries.
|
|
31
|
+
// Flags are parsed up front; everything below reads KEY/PKG.
|
|
32
|
+
let KEY = "ock_MUFntM66VEbx7e7fKoQr2a43VBx762rHkKw1G8vj";
|
|
33
|
+
let PKG = "opencrater";
|
|
34
|
+
{
|
|
35
|
+
const argv = process.argv;
|
|
36
|
+
for (let i = 2; i < argv.length; i++) {
|
|
37
|
+
if (argv[i] === "--key" && argv[i + 1]) KEY = argv[++i];
|
|
38
|
+
else if (argv[i] === "--package" && argv[i + 1]) PKG = argv[++i];
|
|
39
|
+
}
|
|
40
|
+
if (!/^ock_[A-Za-z0-9]{8,64}$/.test(KEY)) {
|
|
41
|
+
console.error("opencrater: --key must look like ock_…");
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
if (!/^[A-Za-z0-9@/_.-]{1,128}$/.test(PKG)) {
|
|
45
|
+
console.error("opencrater: --package must be 1-128 chars of [a-zA-Z0-9@/_.-]");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
28
49
|
// EVERY host hook is registered as a trigger; the SDK + platform decide
|
|
29
50
|
// which ones actually render (recommended session-edge hooks by default,
|
|
30
51
|
// remotely tunable). Registering everything also feeds the recommendation
|
|
@@ -262,16 +283,28 @@ function showAgain() {
|
|
|
262
283
|
return;
|
|
263
284
|
}
|
|
264
285
|
const { spawnSync, spawn } = require("node:child_process");
|
|
265
|
-
|
|
266
|
-
const tty = spawnSync("tty", { stdio: ["inherit", "pipe", "ignore"], encoding: "utf8" })
|
|
267
|
-
.stdout?.trim();
|
|
286
|
+
const isWin = process.platform === "win32";
|
|
268
287
|
// Replay: live ✕ (local), but never re-poll or re-record the original
|
|
269
288
|
// impression — it was already dismissed once.
|
|
270
289
|
const payload = { ...saved.payload, replay: true };
|
|
271
290
|
delete payload.impressionId;
|
|
272
291
|
const env = { ...process.env, OPENCRATER_PAINT: JSON.stringify(payload) };
|
|
273
|
-
|
|
274
|
-
|
|
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", () => {});
|
|
275
308
|
child.unref();
|
|
276
309
|
console.log("opencrater: showing the last ad again.");
|
|
277
310
|
}
|
|
@@ -326,13 +359,21 @@ if (cmd === "on" || cmd === "enable") {
|
|
|
326
359
|
console.log(" overlay surface); message-level sponsorship is on the roadmap.");
|
|
327
360
|
}
|
|
328
361
|
// Pre-install the local hook runtime (background): hooks then run via
|
|
329
|
-
// 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.
|
|
330
364
|
try {
|
|
331
365
|
const { spawn } = require("node:child_process");
|
|
332
|
-
|
|
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",
|
|
333
372
|
path.join(os.homedir(), ".config", "opencrater", "runtime"),
|
|
334
373
|
"@opencrater/sdk@latest", "--silent", "--no-audit", "--no-fund"],
|
|
335
|
-
{ detached: true, stdio: "ignore" })
|
|
374
|
+
{ detached: true, stdio: "ignore", shell: isWin, windowsHide: true });
|
|
375
|
+
child.on("error", () => {});
|
|
376
|
+
child.unref();
|
|
336
377
|
} catch {}
|
|
337
378
|
console.log("OpenCrater ads enabled for Claude Code + Codex.");
|
|
338
379
|
console.log("All hooks registered as triggers; cards render only at session edges");
|
|
@@ -366,7 +407,8 @@ if (cmd === "on" || cmd === "enable") {
|
|
|
366
407
|
console.log("Gemini CLI:", !hosts.gemini_cli ? "not installed" : gm.length ? "enabled (" + gm.length + " hooks)" : "detected — run: npx opencrater on");
|
|
367
408
|
if (hosts.openclaw) console.log("OpenClaw: detected — message-level sponsorship on the roadmap");
|
|
368
409
|
} else {
|
|
369
|
-
console.log("Usage: npx opencrater <on|off|status|x|report|show>");
|
|
410
|
+
console.log("Usage: npx opencrater <on|off|status|x|report|show> [--key ock_… --package name]");
|
|
411
|
+
console.log(" --key/--package publisher attribution (defaults to the OpenCrater house channel)");
|
|
370
412
|
console.log(" x dismiss the sponsor card currently on screen");
|
|
371
413
|
console.log(" report report the ad (never shows on this machine again)");
|
|
372
414
|
console.log(" show bring the last dismissed ad back");
|