mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(media-use): tests never write into the person's media library (#4459)
* fix(media-use): tests never write into the person's media library * fix(media-use): guard the media home only in this repo's test runs * test(media-use): probe the media home from a plain child process * fix(media-use): keep miss logging best-effort when home is unresolvable * test(media-use): miss logging survives an unresolvable media home * docs(media-use): describe the media library without naming an app * chore(media-use): refresh the skills manifest hash
This commit is contained in:
@@ -545,6 +545,8 @@ jobs:
|
||||
- name: Verify standalone skill imports
|
||||
run: bun test scripts/check-skill-import-boundaries.test.mjs
|
||||
- name: Discover and run skills tests
|
||||
env:
|
||||
HYPERFRAMES_MEDIA_HOME_REQUIRED: "1"
|
||||
# We expand the test list via bash so the job fails loudly when the
|
||||
# matcher comes back empty, rather than silently no-op'ing (which
|
||||
# would defeat the whole point of this job).
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@
|
||||
"knip": "knip",
|
||||
"test:scripts": "node --import tsx --test scripts/animejs-v4-guidance.test.mjs scripts/check-tracked-artifacts.test.mjs scripts/check-registry-set-delta.test.mjs scripts/check-no-main-deletions.test.mjs scripts/check-pr-captures.test.mjs scripts/check-comment-citations.test.mjs scripts/comments-workflow.test.mjs scripts/comment-ratchet.test.mjs scripts/check-docs-snippet-motion.test.mjs scripts/registry-target-paths.test.mjs scripts/check-workspace-contracts.test.mjs scripts/check-media-use-copy-parity.test.mjs scripts/check-svg-sanitize-parity.test.mjs scripts/check-media-use-svg-sanitize-generated.test.mjs scripts/check-package-cycles.test.mjs scripts/check-cli-process-ownership.test.mjs scripts/check-large-files.test.mjs scripts/prune-fallow-audit-caches.test.mjs scripts/package-subpaths.test.mjs scripts/validate-release-channel.test.mjs scripts/publish-workflow.test.mjs scripts/pr-edit-concurrency.test.mjs scripts/merge-queue-workflows.test.mjs scripts/install-workspace-dependencies.test.mjs scripts/draft-changelog.test.ts scripts/set-version.test.ts scripts/release-prepare.test.ts scripts/cli-options.test.ts scripts/changelog-weekly.test.ts scripts/claude-plugin-compression.test.ts scripts/catalog-payload-assets.test.ts scripts/host-registry-assets.test.ts scripts/catalog-preview-temp.test.ts scripts/catalog-hosted-files.test.ts scripts/player-cdn-pin.test.ts scripts/studio-runtime-smoke.test.mjs scripts/verify-packed-manifests.test.mjs scripts/lint-skills.test.mjs scripts/creator-editing-recipes.test.mjs packages/gcp-cloud-run/check-dockerfile-workspaces.test.mjs packages/core/scripts/writeGeneratedFile.test.ts scripts/catalog-publication.test.mjs scripts/ci/resolve-workflow-pr.test.mjs scripts/check-catalog-source-pr.test.mjs scripts/generate-registry-items.test.ts scripts/catalog-drift.test.ts scripts/catalog-fetch-mirror.test.ts scripts/catalog-script-inlining.test.ts scripts/catalog-detail.test.ts scripts/generate-catalog-pages.test.ts scripts/verify-catalog-payloads.test.ts scripts/registry-skill-files.test.ts scripts/creator-editing-capabilities.test.mjs scripts/generate-catalog-previews.test.ts scripts/registry-primitive-payloads.test.ts registry/components/pan-stations/pan-stations.test.mjs && vitest run scripts/catalog/ scripts/contrastRatchet.test.ts scripts/generate-catalog-payloads.test.ts",
|
||||
"typecheck:scripts": "tsc --noEmit -p scripts/tsconfig.json",
|
||||
"test:skills": "node --test 'skills/**/*.test.mjs' 'packages/cli/src/media-use/**/*.test.mjs'",
|
||||
"test:skills": "HYPERFRAMES_MEDIA_HOME_REQUIRED=1 node --test 'skills/**/*.test.mjs' 'packages/cli/src/media-use/**/*.test.mjs'",
|
||||
"generate:previews": "tsx scripts/generate-template-previews.ts",
|
||||
"generate:catalog-previews": "tsx scripts/generate-catalog-previews.ts",
|
||||
"package:codex-plugin": "node scripts/package-codex-plugin.mjs",
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import { readFileSync, writeFileSync, mkdirSync, existsSync, copyFileSync } from "node:fs";
|
||||
import { join, basename } from "node:path";
|
||||
import { createHash } from "node:crypto";
|
||||
import { homedir } from "node:os";
|
||||
import { readManifest, appendRecord, normalizePrompt } from "./manifest.mjs";
|
||||
import { globalMediaDir, mediaHome } from "./media-home.mjs";
|
||||
|
||||
export { globalMediaDir };
|
||||
|
||||
const SCHEMA_PREFIX = "mu-v1-";
|
||||
const KEY_HEX_CHARS = 16;
|
||||
const COMPLETE_SENTINEL = ".hf-complete";
|
||||
|
||||
export function globalMediaDir() {
|
||||
return join(homedir(), ".media");
|
||||
}
|
||||
|
||||
export function contentHash(filePath) {
|
||||
const bytes = readFileSync(filePath);
|
||||
return createHash("sha256").update(bytes).digest("hex");
|
||||
@@ -30,11 +28,11 @@ function markComplete(entryDir) {
|
||||
}
|
||||
|
||||
// The manifest helpers append their own ".media" to the dir they get, so the
|
||||
// global manifest must be addressed by HOME, not by globalMediaDir() — passing
|
||||
// global manifest must be addressed by mediaHome(), not by globalMediaDir() — passing
|
||||
// the latter nested it at ~/.media/.media/manifest.jsonl, invisible to the
|
||||
// Studio /api/assets/global route (which reads the documented flat path).
|
||||
export function readGlobalManifest() {
|
||||
return readManifest(homedir());
|
||||
return readManifest(mediaHome());
|
||||
}
|
||||
|
||||
// Resolve a content-sha (full or unambiguous prefix) to a reusable global-cache
|
||||
@@ -105,7 +103,7 @@ export function cachePut(filePath, record) {
|
||||
reusable: true,
|
||||
cached_path: dest,
|
||||
};
|
||||
appendRecord(homedir(), globalRecord);
|
||||
appendRecord(mediaHome(), globalRecord);
|
||||
return { sha, cached_path: dest };
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ import { tmpdir } from "node:os";
|
||||
import { listCandidates, formatCandidates, CANDIDATE_CAP } from "./candidates.mjs";
|
||||
import { findGlobalBySha } from "./cache.mjs";
|
||||
|
||||
// candidates + findGlobalBySha are offline (no heygen), so we can override HOME
|
||||
// candidates + findGlobalBySha are offline (no heygen), so we can point HYPERFRAMES_MEDIA_HOME
|
||||
// to a temp dir and seed a fake global ~/.media manifest deterministically.
|
||||
function sandbox() {
|
||||
const root = mkdtempSync(join(tmpdir(), "mu-cand-"));
|
||||
const project = join(root, "proj");
|
||||
const home = join(root, "home");
|
||||
process.env.HOME = home;
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = home;
|
||||
return { root, project, home };
|
||||
}
|
||||
function seedManifest(dir, records) {
|
||||
|
||||
@@ -34,6 +34,8 @@ import {
|
||||
promote,
|
||||
} from "./cache.mjs";
|
||||
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = mkdtempSync(join(tmpdir(), "mu-media-home-"));
|
||||
|
||||
let tmp;
|
||||
|
||||
function setup() {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
// The one owner of where the person's media library lives. This repo's test runs set
|
||||
// HYPERFRAMES_MEDIA_HOME_REQUIRED, so a test that forgot HYPERFRAMES_MEDIA_HOME fails instead
|
||||
// of writing fixtures into the media library apps list as the person's own files.
|
||||
export function mediaHome() {
|
||||
const override = process.env.HYPERFRAMES_MEDIA_HOME;
|
||||
if (override) return override;
|
||||
if (process.env.HYPERFRAMES_MEDIA_HOME_REQUIRED) {
|
||||
throw new Error(
|
||||
"media-use: a test reached the real ~/.media; set HYPERFRAMES_MEDIA_HOME to a temp dir",
|
||||
);
|
||||
}
|
||||
return homedir();
|
||||
}
|
||||
|
||||
export function globalMediaDir() {
|
||||
return join(mediaHome(), ".media");
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { test } from "node:test";
|
||||
|
||||
import { cachePut } from "./cache.mjs";
|
||||
import { globalMediaDir } from "./media-home.mjs";
|
||||
|
||||
const HOME = mkdtempSync(join(tmpdir(), "media-home-"));
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = HOME;
|
||||
|
||||
test("the global cache writes into the media home a test points it at", () => {
|
||||
const work = mkdtempSync(join(tmpdir(), "media-home-src-"));
|
||||
const file = join(work, "clip.wav");
|
||||
writeFileSync(file, "media-home regression bytes");
|
||||
cachePut(file, { id: "bgm_001", type: "bgm", provenance: { prompt: "media home probe" } });
|
||||
const manifest = join(HOME, ".media", "manifest.jsonl");
|
||||
assert.ok(existsSync(manifest), "the temp media home holds the global manifest");
|
||||
assert.match(readFileSync(manifest, "utf8"), /media home probe/);
|
||||
assert.equal(globalMediaDir(), join(HOME, ".media"));
|
||||
});
|
||||
|
||||
// A child process that resolves the media dir, with only the given media-home variables set.
|
||||
function runProbe(env) {
|
||||
const lib = new URL("./media-home.mjs", import.meta.url).href;
|
||||
const childEnv = { ...process.env };
|
||||
delete childEnv.HYPERFRAMES_MEDIA_HOME;
|
||||
delete childEnv.HYPERFRAMES_MEDIA_HOME_REQUIRED;
|
||||
delete childEnv.NODE_TEST_CONTEXT;
|
||||
const run = spawnSync(
|
||||
process.execPath,
|
||||
[
|
||||
"--input-type=module",
|
||||
"-e",
|
||||
`const m = await import(${JSON.stringify(lib)}); console.log("dir=" + m.globalMediaDir());`,
|
||||
],
|
||||
{ encoding: "utf8", env: { ...childEnv, ...env } },
|
||||
);
|
||||
return { status: run.status, output: `${run.stdout}${run.stderr}` };
|
||||
}
|
||||
|
||||
test("a repo test run that never points the media home anywhere fails instead of writing", () => {
|
||||
const { status, output } = runProbe({ HYPERFRAMES_MEDIA_HOME_REQUIRED: "1" });
|
||||
assert.notEqual(status, 0, output);
|
||||
assert.match(output, /set HYPERFRAMES_MEDIA_HOME to a temp dir/);
|
||||
});
|
||||
|
||||
// Node sets NODE_TEST_CONTEXT for every project's test runs, so another project whose own tests
|
||||
// spawn this CLI must get the person's real library, not the guard.
|
||||
test("another project's node --test run still resolves the real media home", () => {
|
||||
const home = mkdtempSync(join(tmpdir(), "media-home-user-"));
|
||||
const { status, output } = runProbe({
|
||||
HOME: home,
|
||||
USERPROFILE: home,
|
||||
NODE_TEST_CONTEXT: "child-v8",
|
||||
});
|
||||
assert.equal(status, 0, output);
|
||||
assert.ok(output.includes(`dir=${join(home, ".media")}`), output);
|
||||
});
|
||||
@@ -1,19 +1,19 @@
|
||||
import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { dirname, join } from "node:path";
|
||||
import { globalMediaDir } from "./media-home.mjs";
|
||||
|
||||
const MISSES_FILE = "misses.jsonl";
|
||||
|
||||
function missesPath() {
|
||||
return join(homedir(), ".media", MISSES_FILE);
|
||||
return join(globalMediaDir(), MISSES_FILE);
|
||||
}
|
||||
|
||||
export function recordMiss({ type, intent, provider_override, local_only }) {
|
||||
try {
|
||||
const dir = join(homedir(), ".media");
|
||||
mkdirSync(dir, { recursive: true });
|
||||
const path = missesPath();
|
||||
mkdirSync(dirname(path), { recursive: true });
|
||||
appendFileSync(
|
||||
join(dir, MISSES_FILE),
|
||||
path,
|
||||
JSON.stringify({
|
||||
ts: new Date().toISOString(),
|
||||
type,
|
||||
|
||||
@@ -9,7 +9,7 @@ function sandbox() {
|
||||
const root = mkdtempSync(join(tmpdir(), "mu-misses-"));
|
||||
const home = join(root, "home");
|
||||
mkdirSync(home, { recursive: true });
|
||||
process.env.HOME = home;
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = home;
|
||||
return { root, home };
|
||||
}
|
||||
|
||||
@@ -54,6 +54,17 @@ test("recordMiss swallows filesystem failures", () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("recordMiss stays best-effort when the media home cannot be resolved", () => {
|
||||
const savedEnv = { ...process.env };
|
||||
delete process.env.HYPERFRAMES_MEDIA_HOME;
|
||||
process.env.HYPERFRAMES_MEDIA_HOME_REQUIRED = "1";
|
||||
try {
|
||||
assert.doesNotThrow(() => recordMiss({ type: "sfx", intent: "no home", local_only: true }));
|
||||
} finally {
|
||||
restoreEnv(savedEnv);
|
||||
}
|
||||
});
|
||||
|
||||
test("readMisses skips corrupt lines", () => {
|
||||
const savedEnv = { ...process.env };
|
||||
const { root, home } = sandbox();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { basename, dirname, join, resolve } from "node:path";
|
||||
import { globalMediaDir } from "./media-home.mjs";
|
||||
|
||||
/**
|
||||
* Remembered defaults — the lightweight tier of HyperFrames user memory.
|
||||
@@ -41,7 +41,7 @@ export function projectPrefsPath(projectDir) {
|
||||
}
|
||||
|
||||
export function userPrefsPath() {
|
||||
return join(homedir(), ".media", PREFS_FILE);
|
||||
return join(globalMediaDir(), PREFS_FILE);
|
||||
}
|
||||
|
||||
function emptyFile() {
|
||||
|
||||
@@ -19,7 +19,7 @@ function sandbox() {
|
||||
mkdirSync(home, { recursive: true });
|
||||
mkdirSync(projectA, { recursive: true });
|
||||
mkdirSync(projectB, { recursive: true });
|
||||
process.env.HOME = home;
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = home;
|
||||
return { root, home, projectA, projectB };
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
rmSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { basename, join, resolve } from "node:path";
|
||||
import { globalMediaDir } from "./media-home.mjs";
|
||||
import { appendRecord, mediaDir, nextId } from "./manifest.mjs";
|
||||
import { regenerateIndex } from "./index-gen.mjs";
|
||||
import { mergedPreferences } from "./prefs-store.mjs";
|
||||
@@ -58,7 +58,7 @@ export function projectRecipesDir(projectDir) {
|
||||
}
|
||||
|
||||
export function userRecipesDir() {
|
||||
return join(homedir(), ".media", "recipes");
|
||||
return join(globalMediaDir(), "recipes");
|
||||
}
|
||||
|
||||
export function slugifyRecipeName(name) {
|
||||
|
||||
@@ -83,7 +83,7 @@ function sandbox() {
|
||||
mkdirSync(project, { recursive: true });
|
||||
writeFileSync(join(project, "frame.md"), "# Frame spec\nbackground: #101014\n");
|
||||
writeFileSync(join(project, "STORYBOARD.md"), STORYBOARD);
|
||||
process.env.HOME = home;
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = home;
|
||||
return { root, home, project };
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ function sandbox() {
|
||||
const projectDir = join(root, "project");
|
||||
mkdirSync(home, { recursive: true });
|
||||
mkdirSync(projectDir, { recursive: true });
|
||||
process.env.HOME = home;
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = home;
|
||||
return { root, home, projectDir };
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { randomUUID } from "node:crypto";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { globalMediaDir } from "./media-home.mjs";
|
||||
|
||||
const POSTHOG_API_KEY = "phc_zjjbX0PnWxERXrMHhkEJWj9A9BhGVLRReICgsfTMmpx";
|
||||
const POSTHOG_HOST = "https://us.i.posthog.com";
|
||||
@@ -72,7 +73,7 @@ function writeSharedConfig(config) {
|
||||
// one — otherwise cross-surface continuity would start over on upgrade.
|
||||
function legacyMediaAnonId() {
|
||||
try {
|
||||
const file = join(homedir(), ".media", "anon-id");
|
||||
const file = join(globalMediaDir(), "anon-id");
|
||||
if (existsSync(file)) {
|
||||
const id = readFileSync(file, "utf8").trim();
|
||||
if (id) return id;
|
||||
|
||||
@@ -18,6 +18,7 @@ function sandbox() {
|
||||
const home = join(root, "home");
|
||||
mkdirSync(home, { recursive: true });
|
||||
process.env.HOME = home;
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = home;
|
||||
return { root, home };
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,14 @@ const CAN_TSX =
|
||||
spawnSync(process.execPath, ["--import", "tsx", "--input-type=module", "-e", "0"], {
|
||||
stdio: "ignore",
|
||||
}).status === 0;
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = mkdtempSync(join(tmpdir(), "mu-resolve-home-"));
|
||||
|
||||
let tmp;
|
||||
|
||||
function setup() {
|
||||
tmp = mkdtempSync(join(tmpdir(), "mu-resolve-test-"));
|
||||
// A fresh global cache per test, apart from the project so the two manifests never coincide.
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = mkdtempSync(join(tmpdir(), "mu-resolve-home-"));
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
|
||||
@@ -15,6 +15,7 @@ export const MEDIA_USE_COPY_NAMES = [
|
||||
"index-gen.mjs",
|
||||
"manifest.mjs",
|
||||
"media-fetch.mjs",
|
||||
"media-home.mjs",
|
||||
"npx-sync.mjs",
|
||||
"parakeet-words.mjs",
|
||||
"prefs-store.mjs",
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
"files": 1
|
||||
},
|
||||
"media-use": {
|
||||
"hash": "b35de041b87e763d",
|
||||
"files": 98
|
||||
"hash": "7915441c22070c00",
|
||||
"files": 99
|
||||
},
|
||||
"motion-graphics": {
|
||||
"hash": "ab9d2e9c205ce1b1",
|
||||
|
||||
@@ -6,6 +6,8 @@ import { execFileSync } from "node:child_process";
|
||||
import test from "node:test";
|
||||
import { pathToFileURL } from "node:url";
|
||||
|
||||
process.env.HYPERFRAMES_MEDIA_HOME = mkdtempSync(join(tmpdir(), "media-use-compat-home-"));
|
||||
|
||||
function run(scriptsDir, script, args) {
|
||||
return execFileSync(process.execPath, [join(scriptsDir, script), ...args], {
|
||||
encoding: "utf8",
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
// The one owner of where the person's media library lives. This repo's test runs set
|
||||
// HYPERFRAMES_MEDIA_HOME_REQUIRED, so a test that forgot HYPERFRAMES_MEDIA_HOME fails instead
|
||||
// of writing fixtures into the media library apps list as the person's own files.
|
||||
export function mediaHome() {
|
||||
const override = process.env.HYPERFRAMES_MEDIA_HOME;
|
||||
if (override) return override;
|
||||
if (process.env.HYPERFRAMES_MEDIA_HOME_REQUIRED) {
|
||||
throw new Error(
|
||||
"media-use: a test reached the real ~/.media; set HYPERFRAMES_MEDIA_HOME to a temp dir",
|
||||
);
|
||||
}
|
||||
return homedir();
|
||||
}
|
||||
|
||||
export function globalMediaDir() {
|
||||
return join(mediaHome(), ".media");
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { basename, dirname, join, resolve } from "node:path";
|
||||
import { globalMediaDir } from "./media-home.mjs";
|
||||
|
||||
/**
|
||||
* Remembered defaults — the lightweight tier of HyperFrames user memory.
|
||||
@@ -41,7 +41,7 @@ export function projectPrefsPath(projectDir) {
|
||||
}
|
||||
|
||||
export function userPrefsPath() {
|
||||
return join(homedir(), ".media", PREFS_FILE);
|
||||
return join(globalMediaDir(), PREFS_FILE);
|
||||
}
|
||||
|
||||
function emptyFile() {
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
rmSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { basename, join, resolve } from "node:path";
|
||||
import { globalMediaDir } from "./media-home.mjs";
|
||||
import { appendRecord, mediaDir, nextId } from "./manifest.mjs";
|
||||
import { regenerateIndex } from "./index-gen.mjs";
|
||||
import { mergedPreferences } from "./prefs-store.mjs";
|
||||
@@ -58,7 +58,7 @@ export function projectRecipesDir(projectDir) {
|
||||
}
|
||||
|
||||
export function userRecipesDir() {
|
||||
return join(homedir(), ".media", "recipes");
|
||||
return join(globalMediaDir(), "recipes");
|
||||
}
|
||||
|
||||
export function slugifyRecipeName(name) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { randomUUID } from "node:crypto";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { globalMediaDir } from "./media-home.mjs";
|
||||
|
||||
const POSTHOG_API_KEY = "phc_zjjbX0PnWxERXrMHhkEJWj9A9BhGVLRReICgsfTMmpx";
|
||||
const POSTHOG_HOST = "https://us.i.posthog.com";
|
||||
@@ -72,7 +73,7 @@ function writeSharedConfig(config) {
|
||||
// one — otherwise cross-surface continuity would start over on upgrade.
|
||||
function legacyMediaAnonId() {
|
||||
try {
|
||||
const file = join(homedir(), ".media", "anon-id");
|
||||
const file = join(globalMediaDir(), "anon-id");
|
||||
if (existsSync(file)) {
|
||||
const id = readFileSync(file, "utf8").trim();
|
||||
if (id) return id;
|
||||
|
||||
Reference in New Issue
Block a user