Skip to content

Commit 20ceda1

Browse files
author
jiachengzhen
committed
fix(memos-local): resolve telemetry credentials path in ESM mode
The plugin runs as ESM (type: module) but telemetry.ts relied on __dirname which is undefined in ESM. Credentials file existed on disk but was never found, silently disabling all telemetry since day one. Now accepts pluginDir from index.ts (resolved via import.meta.url) and uses it as primary search path for telemetry.credentials.json. Made-with: Cursor
1 parent 89af2d8 commit 20ceda1

2 files changed

Lines changed: 26 additions & 19 deletions

File tree

apps/memos-local-openclaw/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ const memosLocalPlugin = {
225225
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf-8"));
226226
pluginVersion = pkg.version ?? pluginVersion;
227227
} catch {}
228-
const telemetry = new Telemetry(ctx.config.telemetry ?? {}, stateDir, pluginVersion, ctx.log);
228+
const telemetry = new Telemetry(ctx.config.telemetry ?? {}, stateDir, pluginVersion, ctx.log, pluginDir);
229229

230230
// Install bundled memory-guide skill so OpenClaw loads it (write from embedded content so it works regardless of deploy layout)
231231
const workspaceSkillsDir = path.join(workspaceDir, "skills");

apps/memos-local-openclaw/src/telemetry.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,27 @@ export interface TelemetryConfig {
1818
enabled?: boolean;
1919
}
2020

21-
function loadTelemetryCredentials(): { endpoint: string; pid: string; env: string } {
21+
function loadTelemetryCredentials(pluginDir?: string): { endpoint: string; pid: string; env: string } {
2222
if (process.env.MEMOS_ARMS_ENDPOINT) {
2323
return {
2424
endpoint: process.env.MEMOS_ARMS_ENDPOINT,
2525
pid: process.env.MEMOS_ARMS_PID ?? "",
2626
env: process.env.MEMOS_ARMS_ENV ?? "prod",
2727
};
2828
}
29-
try {
30-
const credPath = path.resolve(__dirname, "..", "telemetry.credentials.json");
31-
const raw = fs.readFileSync(credPath, "utf-8");
32-
const creds = JSON.parse(raw);
33-
if (creds.endpoint) return { endpoint: creds.endpoint, pid: creds.pid ?? "", env: creds.env ?? "prod" };
34-
} catch {}
29+
const bases = pluginDir ? [pluginDir, path.join(pluginDir, "src")] : [];
30+
if (typeof __dirname === "string") bases.push(path.resolve(__dirname, ".."), __dirname);
31+
const candidates = bases.map(b => path.join(b, "telemetry.credentials.json"));
32+
for (const credPath of candidates) {
33+
try {
34+
const raw = fs.readFileSync(credPath, "utf-8");
35+
const creds = JSON.parse(raw);
36+
if (creds.endpoint) return { endpoint: creds.endpoint, pid: creds.pid ?? "", env: creds.env ?? "prod" };
37+
} catch {}
38+
}
3539
return { endpoint: "", pid: "", env: "prod" };
3640
}
3741

38-
const _creds = loadTelemetryCredentials();
39-
const ARMS_ENDPOINT = _creds.endpoint;
40-
const ARMS_PID = _creds.pid;
41-
const ARMS_ENV = _creds.env;
42-
4342
const FLUSH_AT = 10;
4443
const FLUSH_INTERVAL_MS = 30_000;
4544
const SEND_TIMEOUT_MS = 30_000;
@@ -67,19 +66,27 @@ export class Telemetry {
6766
private flushTimer: ReturnType<typeof setInterval> | null = null;
6867
private sessionId: string;
6968
private firstSeenDate: string;
69+
private armsEndpoint: string;
70+
private armsPid: string;
71+
private armsEnv: string;
7072

71-
constructor(config: TelemetryConfig, stateDir: string, pluginVersion: string, log: Logger) {
73+
constructor(config: TelemetryConfig, stateDir: string, pluginVersion: string, log: Logger, pluginDir?: string) {
7274
this.log = log;
7375
this.pluginVersion = pluginVersion;
7476
this.enabled = config.enabled !== false;
7577
this.distinctId = this.loadOrCreateAnonymousId(stateDir);
7678
this.firstSeenDate = this.loadOrCreateFirstSeen(stateDir);
7779
this.sessionId = this.loadOrCreateSessionId(stateDir);
7880

79-
if (!this.enabled || !ARMS_ENDPOINT) {
81+
const creds = loadTelemetryCredentials(pluginDir);
82+
this.armsEndpoint = creds.endpoint;
83+
this.armsPid = creds.pid;
84+
this.armsEnv = creds.env;
85+
86+
if (!this.enabled || !this.armsEndpoint) {
8087
this.enabled = false;
8188
this.log.debug(
82-
!ARMS_ENDPOINT
89+
!this.armsEndpoint
8390
? "Telemetry disabled (no credentials configured)"
8491
: "Telemetry disabled (opt-out)",
8592
);
@@ -192,8 +199,8 @@ export class Telemetry {
192199
private buildPayload(events: ArmsEvent[]): Record<string, unknown> {
193200
return {
194201
app: {
195-
id: ARMS_PID,
196-
env: ARMS_ENV,
202+
id: this.armsPid,
203+
env: this.armsEnv,
197204
version: this.pluginVersion,
198205
type: "node",
199206
},
@@ -212,7 +219,7 @@ export class Telemetry {
212219
const payload = this.buildPayload(batch);
213220

214221
try {
215-
const resp = await fetch(ARMS_ENDPOINT, {
222+
const resp = await fetch(this.armsEndpoint, {
216223
method: "POST",
217224
headers: { "Content-Type": "text/plain" },
218225
body: JSON.stringify(payload),

0 commit comments

Comments
 (0)