@codetelemetry/connect 0.1.0 → 0.1.1
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.
|
@@ -7,6 +7,7 @@ export declare function normalizeRepositoryRemote(value: string): string;
|
|
|
7
7
|
export declare function selectCodexOtelExporterLine(raw: string): string;
|
|
8
8
|
export declare function repositoryHookSource(options?: {
|
|
9
9
|
codexConfigPath?: string;
|
|
10
|
+
claudeSettingsPath?: string;
|
|
10
11
|
}): string;
|
|
11
12
|
export declare function quotedCommand(filePath: string, platform?: string): string;
|
|
12
13
|
export declare function validateCodexRepositoryObservationHook(configPath: string): void;
|
|
@@ -111,6 +111,9 @@ export function repositoryHookSource(options = {}) {
|
|
|
111
111
|
const codexConfigPath = options.codexConfigPath
|
|
112
112
|
? path.resolve(options.codexConfigPath)
|
|
113
113
|
: "";
|
|
114
|
+
const claudeSettingsPath = options.claudeSettingsPath
|
|
115
|
+
? path.resolve(options.claudeSettingsPath)
|
|
116
|
+
: "";
|
|
114
117
|
return String.raw `"use strict";
|
|
115
118
|
const crypto = require("node:crypto");
|
|
116
119
|
const fs = require("node:fs");
|
|
@@ -119,6 +122,7 @@ const https = require("node:https");
|
|
|
119
122
|
const path = require("node:path");
|
|
120
123
|
const { execFileSync } = require("node:child_process");
|
|
121
124
|
const codexConfigPath = ${JSON.stringify(codexConfigPath)};
|
|
125
|
+
const claudeSettingsPath = ${JSON.stringify(claudeSettingsPath)};
|
|
122
126
|
const observationStatePath = path.join(__dirname, ${JSON.stringify(REPOSITORY_HOOK_STATE_FILE)});
|
|
123
127
|
const observationLockPath = observationStatePath + ".lock";
|
|
124
128
|
const maxObservationStateEntries = ${REPOSITORY_HOOK_STATE_MAX_ENTRIES};
|
|
@@ -302,8 +306,24 @@ function codexTelemetryConfig() {
|
|
|
302
306
|
};
|
|
303
307
|
} catch { return {}; }
|
|
304
308
|
}
|
|
309
|
+
function claudeTelemetryConfig() {
|
|
310
|
+
if (!claudeSettingsPath) return {};
|
|
311
|
+
try {
|
|
312
|
+
// Claude Code does not pass the OTEL_* exporter variables from settings.json
|
|
313
|
+
// into hook processes, so read the live env block at hook time. As with
|
|
314
|
+
// config.toml, the bearer key is never copied into this script and key
|
|
315
|
+
// rotation does not change the trusted hook definition.
|
|
316
|
+
const env = JSON.parse(fs.readFileSync(claudeSettingsPath, "utf8")).env || {};
|
|
317
|
+
return {
|
|
318
|
+
endpoint: String(env.OTEL_EXPORTER_OTLP_ENDPOINT || ""),
|
|
319
|
+
headers: otlpAuthHeaders(String(env.OTEL_EXPORTER_OTLP_HEADERS || "")),
|
|
320
|
+
};
|
|
321
|
+
} catch { return {}; }
|
|
322
|
+
}
|
|
305
323
|
function environmentAuthHeaders() {
|
|
306
|
-
|
|
324
|
+
return otlpAuthHeaders(String(process.env.OTEL_EXPORTER_OTLP_HEADERS || ""));
|
|
325
|
+
}
|
|
326
|
+
function otlpAuthHeaders(raw) {
|
|
307
327
|
for (const part of raw.split(",")) {
|
|
308
328
|
const separator = part.indexOf("=");
|
|
309
329
|
if (separator < 0 || part.slice(0, separator).trim().toLowerCase() !== "authorization") continue;
|
|
@@ -316,15 +336,28 @@ function environmentAuthHeaders() {
|
|
|
316
336
|
}
|
|
317
337
|
return {};
|
|
318
338
|
}
|
|
339
|
+
function logsEndpoint(base) {
|
|
340
|
+
const trimmed = String(base || "").replace(/\/$/, "");
|
|
341
|
+
if (!trimmed) return "";
|
|
342
|
+
return trimmed.endsWith("/v1/logs") ? trimmed : trimmed + "/v1/logs";
|
|
343
|
+
}
|
|
319
344
|
function deliveryDestination() {
|
|
320
|
-
const base =
|
|
345
|
+
const base = logsEndpoint(process.env.OTEL_EXPORTER_OTLP_ENDPOINT);
|
|
321
346
|
// Endpoint and credentials are one provenance-bearing choice. In particular,
|
|
322
|
-
// never attach the key from config.toml to an
|
|
347
|
+
// never attach the key from config.toml or settings.json to an
|
|
348
|
+
// environment-provided endpoint.
|
|
323
349
|
if (base) return {
|
|
324
|
-
endpoint: base
|
|
350
|
+
endpoint: base,
|
|
325
351
|
headers: environmentAuthHeaders(),
|
|
326
352
|
source: "environment",
|
|
327
353
|
};
|
|
354
|
+
const settings = claudeTelemetryConfig();
|
|
355
|
+
const settingsEndpoint = logsEndpoint(settings.endpoint);
|
|
356
|
+
if (settingsEndpoint) return {
|
|
357
|
+
endpoint: settingsEndpoint,
|
|
358
|
+
headers: settings.headers || {},
|
|
359
|
+
source: "settings",
|
|
360
|
+
};
|
|
328
361
|
const config = codexTelemetryConfig();
|
|
329
362
|
const authorization = String(config.authorization || "");
|
|
330
363
|
return {
|
|
@@ -590,7 +623,7 @@ export function installRepositoryObservationHook(settings, settingsPath) {
|
|
|
590
623
|
const directory = path.dirname(path.resolve(settingsPath));
|
|
591
624
|
const hookPath = path.join(directory, REPOSITORY_HOOK_FILE);
|
|
592
625
|
fs.mkdirSync(directory, { recursive: true });
|
|
593
|
-
fs.writeFileSync(hookPath, repositoryHookSource(), { mode: 0o700 });
|
|
626
|
+
fs.writeFileSync(hookPath, repositoryHookSource({ claudeSettingsPath: settingsPath }), { mode: 0o700 });
|
|
594
627
|
try {
|
|
595
628
|
fs.chmodSync(hookPath, 0o700);
|
|
596
629
|
}
|