mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(media-use): honor telemetryEnabled: false from shared config in optedOut (#5490)
* fix(media-use): honor telemetryEnabled: false from shared config in optedOut The CLI's 'hyperframes telemetry disable' writes telemetryEnabled: false to ~/.hyperframes/config.json, but the media-use scripts' optedOut() only checked env vars, so transcribe.mjs, transcript-cut.mjs and audio-duck.mjs kept sending PostHog events for users who had opted out through the CLI. optedOut() now also returns true when the shared config has telemetryEnabled === false, reusing the readSharedConfig() helper already in the same file. Applied byte-identically to both copies of telemetry.mjs (skills/media-use/scripts/lib and packages/cli/src/media-use/lib, per the copy-parity rule), with tests in both test files. Closes #5465 * test(media-use): sandbox HOME in the telemetry opt-out test and regenerate the skills manifest Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: James <james.russo@heygen.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
James
parent
aa9413b05e
commit
1577060dc1
@@ -35,9 +35,12 @@ function posthogHost() {
|
||||
return override || POSTHOG_HOST;
|
||||
}
|
||||
|
||||
/** True when telemetry must NOT be sent (opt-out envs, CI, dev). */
|
||||
/** True when telemetry must NOT be sent (opt-out envs, CI, dev, shared config). */
|
||||
export function optedOut() {
|
||||
return (
|
||||
// `hyperframes telemetry disable` writes telemetryEnabled: false to the
|
||||
// shared config; one opt-out must cover the CLI and the media-use scripts.
|
||||
readSharedConfig().telemetryEnabled === false ||
|
||||
process.env.HYPERFRAMES_NO_TELEMETRY === "1" ||
|
||||
process.env.DO_NOT_TRACK === "1" ||
|
||||
process.env.CI === "true" ||
|
||||
|
||||
@@ -57,6 +57,26 @@ test("optedOut respects DO_NOT_TRACK / HYPERFRAMES_NO_TELEMETRY / CI", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("optedOut honors telemetryEnabled: false from the shared config", () => {
|
||||
const savedEnv = { ...process.env };
|
||||
const { root, home } = sandbox();
|
||||
try {
|
||||
withoutTelemetryOptOut();
|
||||
const configPath = join(home, ".hyperframes", "config.json");
|
||||
assert.equal(optedOut(), false, "no config: tracking allowed");
|
||||
mkdirSync(join(home, ".hyperframes"), { recursive: true });
|
||||
writeFileSync(configPath, JSON.stringify({ telemetryEnabled: false }));
|
||||
assert.equal(optedOut(), true, "telemetryEnabled: false opts out");
|
||||
writeFileSync(configPath, JSON.stringify({ telemetryEnabled: true }));
|
||||
assert.equal(optedOut(), false, "telemetryEnabled: true allows tracking");
|
||||
writeFileSync(configPath, "{not json");
|
||||
assert.equal(optedOut(), false, "unreadable config: tracking allowed");
|
||||
} finally {
|
||||
restoreEnv(savedEnv);
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("track is a no-op (no network, resolves) when opted out", async () => {
|
||||
const savedEnv = { ...process.env };
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
"files": 1
|
||||
},
|
||||
"media-use": {
|
||||
"hash": "efb4902546396bfb",
|
||||
"files": 111
|
||||
"hash": "0b6e01d1fecb39d6",
|
||||
"files": 112
|
||||
},
|
||||
"motion-graphics": {
|
||||
"hash": "6db77031ad839f6a",
|
||||
|
||||
@@ -35,9 +35,12 @@ function posthogHost() {
|
||||
return override || POSTHOG_HOST;
|
||||
}
|
||||
|
||||
/** True when telemetry must NOT be sent (opt-out envs, CI, dev). */
|
||||
/** True when telemetry must NOT be sent (opt-out envs, CI, dev, shared config). */
|
||||
export function optedOut() {
|
||||
return (
|
||||
// `hyperframes telemetry disable` writes telemetryEnabled: false to the
|
||||
// shared config; one opt-out must cover the CLI and the media-use scripts.
|
||||
readSharedConfig().telemetryEnabled === false ||
|
||||
process.env.HYPERFRAMES_NO_TELEMETRY === "1" ||
|
||||
process.env.DO_NOT_TRACK === "1" ||
|
||||
process.env.CI === "true" ||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { dirname, join } from "node:path";
|
||||
import { test } from "node:test";
|
||||
import { optedOut } from "./telemetry.mjs";
|
||||
|
||||
// optedOut() reads ~/.hyperframes/config.json and env vars. Point HOME at a temp
|
||||
// dir so the run never touches the real config, and pin the env opt-outs to a
|
||||
// neutral state; restore both afterwards.
|
||||
const ENV_KEYS = [
|
||||
"HOME",
|
||||
"USERPROFILE",
|
||||
"HYPERFRAMES_NO_TELEMETRY",
|
||||
"DO_NOT_TRACK",
|
||||
"CI",
|
||||
"NODE_ENV",
|
||||
];
|
||||
const savedEnv = Object.fromEntries(ENV_KEYS.map((k) => [k, process.env[k]]));
|
||||
const home = mkdtempSync(join(tmpdir(), "mu-telemetry-"));
|
||||
const configPath = join(home, ".hyperframes", "config.json");
|
||||
|
||||
function writeConfig(contents) {
|
||||
if (contents === null) {
|
||||
rmSync(configPath, { force: true });
|
||||
} else {
|
||||
mkdirSync(dirname(configPath), { recursive: true });
|
||||
writeFileSync(configPath, contents);
|
||||
}
|
||||
}
|
||||
|
||||
test.before(() => {
|
||||
for (const key of ENV_KEYS) delete process.env[key];
|
||||
process.env.HOME = process.env.USERPROFILE = home;
|
||||
});
|
||||
|
||||
test.after(() => {
|
||||
for (const key of ENV_KEYS) {
|
||||
if (savedEnv[key] === undefined) delete process.env[key];
|
||||
else process.env[key] = savedEnv[key];
|
||||
}
|
||||
rmSync(home, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test("optedOut is false with no config and no opt-out env", () => {
|
||||
writeConfig(null);
|
||||
assert.equal(optedOut(), false);
|
||||
});
|
||||
|
||||
test("optedOut honors telemetryEnabled: false from the shared config", () => {
|
||||
writeConfig(JSON.stringify({ telemetryEnabled: false }));
|
||||
assert.equal(optedOut(), true);
|
||||
});
|
||||
|
||||
test("optedOut is false when the shared config enables telemetry", () => {
|
||||
writeConfig(JSON.stringify({ telemetryEnabled: true }));
|
||||
assert.equal(optedOut(), false);
|
||||
});
|
||||
|
||||
test("optedOut treats an unreadable shared config as no opt-out", () => {
|
||||
writeConfig("{not json");
|
||||
assert.equal(optedOut(), false);
|
||||
});
|
||||
|
||||
test("optedOut still honors the env opt-outs", () => {
|
||||
writeConfig(JSON.stringify({ telemetryEnabled: true }));
|
||||
process.env.DO_NOT_TRACK = "1";
|
||||
try {
|
||||
assert.equal(optedOut(), true);
|
||||
} finally {
|
||||
delete process.env.DO_NOT_TRACK;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user