@codetelemetry/connect 0.1.0
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/LICENSE +21 -0
- package/README.md +26 -0
- package/dist/bin/connect.d.ts +2 -0
- package/dist/bin/connect.js +6 -0
- package/dist/src/cli.d.ts +10 -0
- package/dist/src/cli.js +172 -0
- package/dist/src/codexConfig.d.ts +23 -0
- package/dist/src/codexConfig.js +265 -0
- package/dist/src/config.d.ts +26 -0
- package/dist/src/config.js +32 -0
- package/dist/src/connectivity.d.ts +27 -0
- package/dist/src/connectivity.js +54 -0
- package/dist/src/deviceClient.d.ts +32 -0
- package/dist/src/deviceClient.js +112 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +8 -0
- package/dist/src/keys.d.ts +5 -0
- package/dist/src/keys.js +24 -0
- package/dist/src/onboard.d.ts +47 -0
- package/dist/src/onboard.js +84 -0
- package/dist/src/otlp.d.ts +18 -0
- package/dist/src/otlp.js +60 -0
- package/dist/src/repositoryHook.d.ts +17 -0
- package/dist/src/repositoryHook.js +631 -0
- package/dist/src/settings.d.ts +28 -0
- package/dist/src/settings.js +97 -0
- package/package.json +25 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { assertKey } from "./keys.js";
|
|
4
|
+
import { installRepositoryObservationHook, removeRepositoryObservationFiles, removeRepositoryObservationHook, } from "./repositoryHook.js";
|
|
5
|
+
export function baseEnv(key, ingestEndpoint) {
|
|
6
|
+
return {
|
|
7
|
+
CLAUDE_CODE_ENABLE_TELEMETRY: "1",
|
|
8
|
+
OTEL_METRICS_EXPORTER: "otlp",
|
|
9
|
+
OTEL_LOGS_EXPORTER: "otlp",
|
|
10
|
+
OTEL_EXPORTER_OTLP_PROTOCOL: "http/protobuf",
|
|
11
|
+
OTEL_EXPORTER_OTLP_ENDPOINT: ingestEndpoint,
|
|
12
|
+
OTEL_EXPORTER_OTLP_HEADERS: `Authorization=Bearer ${key}`,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function enrichEnv() {
|
|
16
|
+
return {
|
|
17
|
+
OTEL_METRICS_INCLUDE_SESSION_ID: "true",
|
|
18
|
+
OTEL_LOG_USER_PROMPTS: "1",
|
|
19
|
+
OTEL_LOG_TOOL_DETAILS: "1",
|
|
20
|
+
OTEL_LOG_TOOL_CONTENT: "1",
|
|
21
|
+
OTEL_LOG_RAW_API_BODIES: "1",
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export const LEGACY_BROKEN_RESOURCE_ATTRS = "project.path=$PWD";
|
|
25
|
+
export function buildEnvBlock(key, ingestEndpoint, enrich) {
|
|
26
|
+
const base = baseEnv(key, ingestEndpoint);
|
|
27
|
+
return enrich ? { ...base, ...enrichEnv() } : base;
|
|
28
|
+
}
|
|
29
|
+
function readJson(filePath) {
|
|
30
|
+
if (!fs.existsSync(filePath))
|
|
31
|
+
return {};
|
|
32
|
+
const raw = fs.readFileSync(filePath, "utf8").trim();
|
|
33
|
+
if (!raw)
|
|
34
|
+
return {};
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(raw);
|
|
37
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
38
|
+
return parsed;
|
|
39
|
+
throw new Error("settings.json is not a JSON object");
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
throw new Error(`refusing to overwrite ${filePath}: it isn't valid JSON (${err.message}). ` +
|
|
43
|
+
`Fix or move it, then retry.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export function mergeSettings(existing, env) {
|
|
47
|
+
const prevEnv = existing.env && typeof existing.env === "object" && !Array.isArray(existing.env)
|
|
48
|
+
? { ...existing.env }
|
|
49
|
+
: {};
|
|
50
|
+
if (prevEnv.OTEL_RESOURCE_ATTRIBUTES === LEGACY_BROKEN_RESOURCE_ATTRS) {
|
|
51
|
+
delete prevEnv.OTEL_RESOURCE_ATTRIBUTES;
|
|
52
|
+
}
|
|
53
|
+
return { ...existing, env: { ...prevEnv, ...env } };
|
|
54
|
+
}
|
|
55
|
+
export function writeSettings(opts) {
|
|
56
|
+
const key = assertKey(opts.key);
|
|
57
|
+
const env = buildEnvBlock(key, opts.ingestEndpoint, !!opts.enrich);
|
|
58
|
+
const filePath = path.resolve(opts.settingsPath);
|
|
59
|
+
const existed = fs.existsSync(filePath);
|
|
60
|
+
const existing = readJson(filePath);
|
|
61
|
+
const envMerged = mergeSettings(existing, env);
|
|
62
|
+
const merged = opts.repositoryObservation
|
|
63
|
+
? installRepositoryObservationHook(envMerged, filePath)
|
|
64
|
+
: removeRepositoryObservationHook(envMerged);
|
|
65
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
66
|
+
let backupPath = null;
|
|
67
|
+
if (existed && opts.backup !== false) {
|
|
68
|
+
backupPath = `${filePath}.bak`;
|
|
69
|
+
fs.copyFileSync(filePath, backupPath);
|
|
70
|
+
}
|
|
71
|
+
fs.writeFileSync(filePath, JSON.stringify(merged, null, 2) + "\n", { mode: 0o600 });
|
|
72
|
+
try {
|
|
73
|
+
fs.chmodSync(filePath, 0o600);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
}
|
|
77
|
+
if (!opts.repositoryObservation)
|
|
78
|
+
removeRepositoryObservationFiles(filePath);
|
|
79
|
+
return { path: filePath, wrote: Object.keys(env), backupPath, created: !existed };
|
|
80
|
+
}
|
|
81
|
+
export function readSettingsSummary(filePath) {
|
|
82
|
+
if (!fs.existsSync(filePath))
|
|
83
|
+
return { exists: false, otelKeys: [], hasKey: false };
|
|
84
|
+
let obj;
|
|
85
|
+
try {
|
|
86
|
+
obj = readJson(filePath);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return { exists: true, otelKeys: [], hasKey: false };
|
|
90
|
+
}
|
|
91
|
+
const env = obj.env && typeof obj.env === "object" && !Array.isArray(obj.env)
|
|
92
|
+
? obj.env
|
|
93
|
+
: {};
|
|
94
|
+
const otelKeys = Object.keys(env).filter((k) => k.startsWith("OTEL_") || k === "CLAUDE_CODE_ENABLE_TELEMETRY");
|
|
95
|
+
const hasKey = typeof env.OTEL_EXPORTER_OTLP_HEADERS === "string" && env.OTEL_EXPORTER_OTLP_HEADERS.includes("cot_");
|
|
96
|
+
return { exists: true, otelKeys, hasKey };
|
|
97
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codetelemetry/connect",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Public-safe CLI and library for connecting Claude Code or Codex to CodeTelemetry.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://codetelemetry.com/docs/onboarding/connect-cli",
|
|
8
|
+
"repository": { "type": "git", "url": "git+https://github.com/ElliotGardiner/codetelemetry-connect.git" },
|
|
9
|
+
"bugs": { "url": "https://github.com/ElliotGardiner/codetelemetry-connect/issues" },
|
|
10
|
+
"bin": { "codetelemetry-connect": "./dist/bin/connect.js" },
|
|
11
|
+
"exports": { ".": { "types": "./dist/src/index.d.ts", "default": "./dist/src/index.js" } },
|
|
12
|
+
"files": ["dist"],
|
|
13
|
+
"publishConfig": { "access": "public" },
|
|
14
|
+
"scripts": {
|
|
15
|
+
"clean": "node scripts/cleanDist.ts",
|
|
16
|
+
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
17
|
+
"test": "node --test test/*.test.ts",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"audit:package": "node scripts/auditPackage.ts",
|
|
20
|
+
"test:packaged": "node scripts/packagedSmoke.ts",
|
|
21
|
+
"prepack": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"engines": { "node": ">=22.6" },
|
|
24
|
+
"devDependencies": { "@types/node": "^22.10.0", "typescript": "^5.9.3" }
|
|
25
|
+
}
|