oh-langfuse 0.1.79 → 0.1.80

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.
@@ -14,19 +14,19 @@ function addResult(results, item, ok, detail, fix = "") {
14
14
  results.push({ item, ok, detail, fix });
15
15
  }
16
16
 
17
- function pythonExecutableInVenv(claudeDir) {
18
- return process.platform === "win32"
19
- ? path.join(claudeDir, "langfuse-venv", "Scripts", "python.exe")
20
- : path.join(claudeDir, "langfuse-venv", "bin", "python");
21
- }
22
-
23
- function fallbackPythonCommand() {
24
- return process.platform === "win32" ? "python" : "python3";
25
- }
26
-
27
- function isolatedPythonPath(claudeDir) {
28
- return path.join(claudeDir, "langfuse-python");
29
- }
17
+ function pythonExecutableInVenv(claudeDir) {
18
+ return process.platform === "win32"
19
+ ? path.join(claudeDir, "langfuse-venv", "Scripts", "python.exe")
20
+ : path.join(claudeDir, "langfuse-venv", "bin", "python");
21
+ }
22
+
23
+ function fallbackPythonCommand() {
24
+ return process.platform === "win32" ? "python" : "python3";
25
+ }
26
+
27
+ function isolatedPythonPath(claudeDir) {
28
+ return path.join(claudeDir, "langfuse-python");
29
+ }
30
30
 
31
31
  function launcherPath(hooksDir) {
32
32
  return process.platform === "win32"
@@ -71,18 +71,18 @@ function pathExists(p) {
71
71
  return typeof p === "string" && p.length > 0 && fs.existsSync(p);
72
72
  }
73
73
 
74
- function checkPythonLangfuseImport(pythonPath, extraPythonPath = "") {
75
- if (!pathExists(pythonPath) && pythonPath !== "python3" && pythonPath !== "python") return { ok: false, detail: "python executable missing" };
76
- const env = { ...process.env };
77
- if (extraPythonPath) {
78
- env.PYTHONPATH = process.env.PYTHONPATH ? `${extraPythonPath}${path.delimiter}${process.env.PYTHONPATH}` : extraPythonPath;
79
- }
80
- const result = spawnSync(pythonPath, ["-c", "import langfuse; print('OK')"], {
81
- encoding: "utf8",
82
- timeout: 15000,
83
- windowsHide: true,
84
- env
85
- });
74
+ function checkPythonLangfuseImport(pythonPath, extraPythonPath = "") {
75
+ if (!pathExists(pythonPath) && pythonPath !== "python3" && pythonPath !== "python") return { ok: false, detail: "python executable missing" };
76
+ const env = { ...process.env };
77
+ if (extraPythonPath) {
78
+ env.PYTHONPATH = process.env.PYTHONPATH ? `${extraPythonPath}${path.delimiter}${process.env.PYTHONPATH}` : extraPythonPath;
79
+ }
80
+ const result = spawnSync(pythonPath, ["-c", "import langfuse; print('OK')"], {
81
+ encoding: "utf8",
82
+ timeout: 15000,
83
+ windowsHide: true,
84
+ env
85
+ });
86
86
  if (result.status === 0) return { ok: true, detail: "OK" };
87
87
  const err = `${result.stderr || result.stdout || result.error?.message || "unknown error"}`.trim();
88
88
  return { ok: false, detail: err || "import failed" };
@@ -93,11 +93,11 @@ function main() {
93
93
  const claudeDir = path.join(userHome, ".claude");
94
94
  const hooksDir = path.join(claudeDir, "hooks");
95
95
  const settingsPath = path.join(claudeDir, "settings.json");
96
- const pyPath = path.join(hooksDir, "langfuse_hook.py");
97
- const expectedLauncher = launcherPath(hooksDir);
98
- const expectedPython = pythonExecutableInVenv(claudeDir);
99
- const fallbackTarget = isolatedPythonPath(claudeDir);
100
- const logPath = path.join(claudeDir, "state", "langfuse_hook.log");
96
+ const pyPath = path.join(hooksDir, "langfuse_hook.py");
97
+ const expectedLauncher = launcherPath(hooksDir);
98
+ const expectedPython = pythonExecutableInVenv(claudeDir);
99
+ const fallbackTarget = isolatedPythonPath(claudeDir);
100
+ const logPath = path.join(claudeDir, "state", "langfuse_hook.log");
101
101
 
102
102
  const results = [];
103
103
 
@@ -152,26 +152,26 @@ function main() {
152
152
  "Run setup again. Claude Code should execute the generated Python hook command."
153
153
  );
154
154
 
155
- addResult(
156
- results,
157
- "hook python executable",
158
- pathExists(expectedPython) || fs.existsSync(fallbackTarget),
159
- pathExists(expectedPython) ? expectedPython : `${fallbackPythonCommand()} with PYTHONPATH=${fallbackTarget}`,
160
- "Run setup again to recreate the Python venv."
161
- );
162
-
163
- const importCheck = pathExists(expectedPython)
164
- ? checkPythonLangfuseImport(expectedPython)
165
- : checkPythonLangfuseImport(fallbackPythonCommand(), fallbackTarget);
166
- addResult(
167
- results,
168
- "python package langfuse",
169
- importCheck.ok,
170
- importCheck.detail,
171
- pathExists(expectedPython)
172
- ? `Run: ${expectedPython} -m pip install -U langfuse`
173
- : "Run setup again to install langfuse into the isolated PYTHONPATH target."
174
- );
155
+ addResult(
156
+ results,
157
+ "hook python executable",
158
+ pathExists(expectedPython) || fs.existsSync(fallbackTarget),
159
+ pathExists(expectedPython) ? expectedPython : `${fallbackPythonCommand()} with PYTHONPATH=${fallbackTarget}`,
160
+ "Run setup again to recreate the Python venv."
161
+ );
162
+
163
+ const importCheck = pathExists(expectedPython)
164
+ ? checkPythonLangfuseImport(expectedPython)
165
+ : checkPythonLangfuseImport(fallbackPythonCommand(), fallbackTarget);
166
+ addResult(
167
+ results,
168
+ "python package langfuse",
169
+ importCheck.ok,
170
+ importCheck.detail,
171
+ pathExists(expectedPython)
172
+ ? `Run: ${expectedPython} -m pip install -U langfuse`
173
+ : "Run setup again to install langfuse into the isolated PYTHONPATH target."
174
+ );
175
175
 
176
176
  addResult(results, "hook log path", true, logPath);
177
177
 
@@ -2,30 +2,30 @@ import fs from "node:fs";
2
2
  import fsp from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import os from "node:os";
5
- import { execFileSync, spawnSync } from "node:child_process";
6
- import { fileURLToPath } from "node:url";
7
- import { defaultWindowsNpmCliCandidates, listSystemCliCandidates } from "./cli-detection-utils.mjs";
8
- import { writeRuntimeInstallRecord } from "./runtime-state-utils.mjs";
9
-
10
- const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
11
- const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
12
-
13
- const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
14
- const LEGACY_LANGFUSE_BASE_URLS = new Set([
15
- "http://120.46.221.227:3000",
16
- "https://120.46.221.227:3000",
17
- ]);
18
- const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
19
- const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
20
-
21
- function normalizeLegacyBaseUrl(baseUrl) {
22
- const value = String(baseUrl || "").trim().replace(/\/+$/, "");
23
- return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
24
- }
25
-
26
- function normalizeUserId(v) {
27
- return String(v || "").trim();
28
- }
5
+ import { execFileSync, spawnSync } from "node:child_process";
6
+ import { fileURLToPath } from "node:url";
7
+ import { defaultWindowsNpmCliCandidates, listSystemCliCandidates } from "./cli-detection-utils.mjs";
8
+ import { writeRuntimeInstallRecord } from "./runtime-state-utils.mjs";
9
+
10
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
11
+ const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
12
+
13
+ const DEFAULT_LANGFUSE_BASE_URL = "https://metrics.openharmonyinsight.cn";
14
+ const LEGACY_LANGFUSE_BASE_URLS = new Set([
15
+ "http://120.46.221.227:3000",
16
+ "https://120.46.221.227:3000",
17
+ ]);
18
+ const USER_ID_PATTERN = /^[a-z](?:\d{8}|wx\d{7})$/;
19
+ const USER_ID_PATTERN_TEXT = "^[a-z](?:\\d{8}|wx\\d{7})$";
20
+
21
+ function normalizeLegacyBaseUrl(baseUrl) {
22
+ const value = String(baseUrl || "").trim().replace(/\/+$/, "");
23
+ return LEGACY_LANGFUSE_BASE_URLS.has(value) ? DEFAULT_LANGFUSE_BASE_URL : baseUrl;
24
+ }
25
+
26
+ function normalizeUserId(v) {
27
+ return String(v || "").trim();
28
+ }
29
29
 
30
30
  function assertValidUserId(userId) {
31
31
  if (!USER_ID_PATTERN.test(normalizeUserId(userId))) {
@@ -172,7 +172,7 @@ function writeAutoUpdateHelper(target) {
172
172
  const helperDir = autoUpdateHelperDir();
173
173
  ensureDir(helperDir);
174
174
  const runtimePath = autoUpdateRuntimePath();
175
- const fallbackArgs = ["-y", "--registry=https://registry.npmjs.org/", "oh-langfuse@latest", "auto-update", target, "--skip-check", "--startup-status"];
175
+ const fallbackArgs = ["-y", "--registry=https://registry.npmjs.org/", "oh-langfuse@latest", "auto-update", target, "--skip-check", "--startup-status"];
176
176
 
177
177
  if (process.platform === "win32") {
178
178
  const helper = path.join(helperDir, `oh-langfuse-auto-update-${target}.cmd`);
@@ -187,7 +187,7 @@ function writeAutoUpdateHelper(target) {
187
187
  "exit /b 0",
188
188
  ""
189
189
  ];
190
- fs.writeFileSync(helper, lines.join(os.EOL), "utf8");
190
+ fs.writeFileSync(helper, lines.join(os.EOL), "utf8");
191
191
  return helper;
192
192
  }
193
193
 
@@ -232,16 +232,16 @@ function existingCliCandidate(candidate, shimDir) {
232
232
  }
233
233
  }
234
234
 
235
- function listCliCandidatesFromPath(target) {
236
- return listSystemCliCandidates(target);
237
- }
238
-
239
- function resolveAgentCli({ target, preferred = "", shimDir = "" }) {
240
- const candidates = [
241
- preferred,
242
- ...defaultWindowsNpmCliCandidates(target),
243
- ...listCliCandidatesFromPath(target)
244
- ];
235
+ function listCliCandidatesFromPath(target) {
236
+ return listSystemCliCandidates(target);
237
+ }
238
+
239
+ function resolveAgentCli({ target, preferred = "", shimDir = "" }) {
240
+ const candidates = [
241
+ preferred,
242
+ ...defaultWindowsNpmCliCandidates(target),
243
+ ...listCliCandidatesFromPath(target)
244
+ ];
245
245
  for (const candidate of candidates) {
246
246
  const found = existingCliCandidate(candidate, shimDir);
247
247
  if (found) return found;
@@ -295,7 +295,7 @@ function writeAgentCommandShim({ baseDir, target, executable, realCli, publicKey
295
295
  "exit /b %ERRORLEVEL%",
296
296
  ""
297
297
  ].filter(Boolean).join(os.EOL);
298
- fs.writeFileSync(shim, content, "utf8");
298
+ fs.writeFileSync(shim, content, "utf8");
299
299
  return { shim, shimDir };
300
300
  }
301
301
 
@@ -327,7 +327,7 @@ function createAgentLauncher({ baseDir, target, executable }) {
327
327
  `${executable} %*`,
328
328
  ""
329
329
  ].join(os.EOL);
330
- fs.writeFileSync(launcher, content, "utf8");
330
+ fs.writeFileSync(launcher, content, "utf8");
331
331
  return launcher;
332
332
  }
333
333
 
@@ -350,87 +350,87 @@ function pythonExecutableInVenv(venvDir) {
350
350
  : path.join(venvDir, "bin", "python");
351
351
  }
352
352
 
353
- function pythonEnv(extraPythonPath = "") {
354
- const env = { ...process.env, PYTHONUTF8: "1" };
355
- if (extraPythonPath) {
356
- env.PYTHONPATH = process.env.PYTHONPATH ? `${extraPythonPath}${path.delimiter}${process.env.PYTHONPATH}` : extraPythonPath;
357
- }
358
- return env;
359
- }
360
-
361
- function pythonCanImport(pythonCmd, moduleName, extraPythonPath = "") {
362
- try {
363
- execFileSync(pythonCmd, ["-c", `import ${moduleName}`], { stdio: "ignore", encoding: "utf8", env: pythonEnv(extraPythonPath) });
364
- return true;
365
- } catch {
366
- return false;
367
- }
368
- }
369
-
370
- function installLangfuseIntoTargetDir({ pythonCmd, baseDir, pipIndexUrl }) {
371
- const targetDir = path.join(baseDir, "langfuse-python");
372
- ensureDir(targetDir);
373
- console.log(`Installing Python package into isolated target: ${targetDir}`);
374
- execFileSync(
375
- pythonCmd,
376
- ["-m", "pip", "install", "--target", targetDir, "--upgrade", "langfuse", "-i", pipIndexUrl],
377
- { stdio: "inherit", encoding: "utf8", env: pythonEnv() }
378
- );
379
- if (!pythonCanImport(pythonCmd, "langfuse", targetDir)) {
380
- throw new Error(`langfuse was installed into ${targetDir}, but ${pythonCmd} still cannot import it with PYTHONPATH.`);
381
- }
382
- return { python: pythonCmd, pythonPath: targetDir };
383
- }
384
-
385
- function runPipInstallWithFallback({ pythonCmd, baseDir, pipIndexUrl }) {
386
- const attempts = [
387
- () => installLangfuseIntoTargetDir({ pythonCmd, baseDir, pipIndexUrl }),
388
- () => installLangfuseIntoTargetDir({ pythonCmd: "python3", baseDir, pipIndexUrl }),
389
- () => installLangfuseIntoTargetDir({ pythonCmd: "python", baseDir, pipIndexUrl })
390
- ];
391
-
392
- const errors = [];
393
- for (const attempt of attempts) {
394
- try {
395
- return attempt();
396
- } catch (error) {
397
- errors.push(error?.message || String(error));
398
- }
399
- }
400
-
401
- throw new Error(
402
- `Failed to install langfuse into isolated Python target. Last errors: ${errors.join(" | ")}`
403
- );
404
- }
405
-
406
- function installLangfuseWithSystemPython({ pythonCmd, baseDir, pipIndexUrl }) {
407
- console.log("Python venv is unavailable; falling back to isolated PYTHONPATH install for langfuse.");
408
- return runPipInstallWithFallback({ pythonCmd, baseDir, pipIndexUrl });
409
- }
410
-
411
- async function createHookLauncher({ hooksDir, hookPython, hookPythonPath = "", pyPath }) {
412
- if (process.platform === "win32") {
413
- const launcher = path.join(hooksDir, "run-langfuse-hook.cmd");
414
- const content = [
415
- "@echo off",
416
- hookPythonPath ? `set PYTHONPATH=${hookPythonPath};%PYTHONPATH%` : null,
417
- `${cmdQuote(hookPython)} ${cmdQuote(pyPath)}`,
418
- ""
419
- ].filter(Boolean).join(os.EOL);
420
- await fsp.writeFile(launcher, content, "utf8");
421
- return launcher;
422
- }
423
-
424
- const launcher = path.join(hooksDir, "run-langfuse-hook.sh");
425
- const content = [
426
- "#!/usr/bin/env sh",
427
- hookPythonPath ? `if [ -n "\${PYTHONPATH:-}" ]; then export PYTHONPATH=${shQuote(hookPythonPath)}:"$PYTHONPATH"; else export PYTHONPATH=${shQuote(hookPythonPath)}; fi` : null,
428
- `exec ${shQuote(hookPython)} ${shQuote(pyPath)}`,
429
- ""
430
- ].filter(Boolean).join("\n");
431
- await fsp.writeFile(launcher, content, "utf8");
432
- fs.chmodSync(launcher, 0o755);
433
- return launcher;
353
+ function pythonEnv(extraPythonPath = "") {
354
+ const env = { ...process.env, PYTHONUTF8: "1" };
355
+ if (extraPythonPath) {
356
+ env.PYTHONPATH = process.env.PYTHONPATH ? `${extraPythonPath}${path.delimiter}${process.env.PYTHONPATH}` : extraPythonPath;
357
+ }
358
+ return env;
359
+ }
360
+
361
+ function pythonCanImport(pythonCmd, moduleName, extraPythonPath = "") {
362
+ try {
363
+ execFileSync(pythonCmd, ["-c", `import ${moduleName}`], { stdio: "ignore", encoding: "utf8", env: pythonEnv(extraPythonPath) });
364
+ return true;
365
+ } catch {
366
+ return false;
367
+ }
368
+ }
369
+
370
+ function installLangfuseIntoTargetDir({ pythonCmd, baseDir, pipIndexUrl }) {
371
+ const targetDir = path.join(baseDir, "langfuse-python");
372
+ ensureDir(targetDir);
373
+ console.log(`Installing Python package into isolated target: ${targetDir}`);
374
+ execFileSync(
375
+ pythonCmd,
376
+ ["-m", "pip", "install", "--target", targetDir, "--upgrade", "langfuse", "-i", pipIndexUrl],
377
+ { stdio: "inherit", encoding: "utf8", env: pythonEnv() }
378
+ );
379
+ if (!pythonCanImport(pythonCmd, "langfuse", targetDir)) {
380
+ throw new Error(`langfuse was installed into ${targetDir}, but ${pythonCmd} still cannot import it with PYTHONPATH.`);
381
+ }
382
+ return { python: pythonCmd, pythonPath: targetDir };
383
+ }
384
+
385
+ function runPipInstallWithFallback({ pythonCmd, baseDir, pipIndexUrl }) {
386
+ const attempts = [
387
+ () => installLangfuseIntoTargetDir({ pythonCmd, baseDir, pipIndexUrl }),
388
+ () => installLangfuseIntoTargetDir({ pythonCmd: "python3", baseDir, pipIndexUrl }),
389
+ () => installLangfuseIntoTargetDir({ pythonCmd: "python", baseDir, pipIndexUrl })
390
+ ];
391
+
392
+ const errors = [];
393
+ for (const attempt of attempts) {
394
+ try {
395
+ return attempt();
396
+ } catch (error) {
397
+ errors.push(error?.message || String(error));
398
+ }
399
+ }
400
+
401
+ throw new Error(
402
+ `Failed to install langfuse into isolated Python target. Last errors: ${errors.join(" | ")}`
403
+ );
404
+ }
405
+
406
+ function installLangfuseWithSystemPython({ pythonCmd, baseDir, pipIndexUrl }) {
407
+ console.log("Python venv is unavailable; falling back to isolated PYTHONPATH install for langfuse.");
408
+ return runPipInstallWithFallback({ pythonCmd, baseDir, pipIndexUrl });
409
+ }
410
+
411
+ async function createHookLauncher({ hooksDir, hookPython, hookPythonPath = "", pyPath }) {
412
+ if (process.platform === "win32") {
413
+ const launcher = path.join(hooksDir, "run-langfuse-hook.cmd");
414
+ const content = [
415
+ "@echo off",
416
+ hookPythonPath ? `set PYTHONPATH=${hookPythonPath};%PYTHONPATH%` : null,
417
+ `${cmdQuote(hookPython)} ${cmdQuote(pyPath)}`,
418
+ ""
419
+ ].filter(Boolean).join(os.EOL);
420
+ await fsp.writeFile(launcher, content, "utf8");
421
+ return launcher;
422
+ }
423
+
424
+ const launcher = path.join(hooksDir, "run-langfuse-hook.sh");
425
+ const content = [
426
+ "#!/usr/bin/env sh",
427
+ hookPythonPath ? `if [ -n "\${PYTHONPATH:-}" ]; then export PYTHONPATH=${shQuote(hookPythonPath)}:"$PYTHONPATH"; else export PYTHONPATH=${shQuote(hookPythonPath)}; fi` : null,
428
+ `exec ${shQuote(hookPython)} ${shQuote(pyPath)}`,
429
+ ""
430
+ ].filter(Boolean).join("\n");
431
+ await fsp.writeFile(launcher, content, "utf8");
432
+ fs.chmodSync(launcher, 0o755);
433
+ return launcher;
434
434
  }
435
435
 
436
436
  function createOrUpdateLangfuseVenv({ baseDir, pipIndexUrl = "https://pypi.tuna.tsinghua.edu.cn/simple" }) {
@@ -441,13 +441,13 @@ function createOrUpdateLangfuseVenv({ baseDir, pipIndexUrl = "https://pypi.tuna.
441
441
  if (!fs.existsSync(venvPython)) {
442
442
  console.log(`Creating Python virtual environment: ${venvDir}`);
443
443
  try {
444
- execFileSync(pythonCmd, ["-m", "venv", venvDir], { stdio: "inherit", encoding: "utf8", env: { ...process.env, PYTHONUTF8: "1" } });
445
- } catch (e) {
446
- if (process.platform !== "win32") {
447
- return installLangfuseWithSystemPython({ pythonCmd, baseDir, pipIndexUrl });
448
- }
449
- throw new Error("Failed to create Python venv. Please confirm Python venv support is available.");
450
- }
444
+ execFileSync(pythonCmd, ["-m", "venv", venvDir], { stdio: "inherit", encoding: "utf8", env: { ...process.env, PYTHONUTF8: "1" } });
445
+ } catch (e) {
446
+ if (process.platform !== "win32") {
447
+ return installLangfuseWithSystemPython({ pythonCmd, baseDir, pipIndexUrl });
448
+ }
449
+ throw new Error("Failed to create Python venv. Please confirm Python venv support is available.");
450
+ }
451
451
  }
452
452
 
453
453
  console.log("Installing/updating Python package in venv: langfuse");
@@ -456,23 +456,23 @@ function createOrUpdateLangfuseVenv({ baseDir, pipIndexUrl = "https://pypi.tuna.
456
456
  venvPython,
457
457
  ["-m", "pip", "install", "-U", "langfuse", "-i", pipIndexUrl],
458
458
  { stdio: "inherit", encoding: "utf8", env: { ...process.env, PYTHONUTF8: "1" } }
459
- );
460
- } catch (e) {
461
- if (process.platform !== "win32") {
462
- return installLangfuseWithSystemPython({ pythonCmd, baseDir, pipIndexUrl });
463
- }
464
- throw new Error(`Failed to install langfuse in venv: ${venvPython} -m pip install -U langfuse -i ${pipIndexUrl}`);
465
- }
466
-
467
- if (!pythonCanImport(venvPython, "langfuse")) {
468
- if (process.platform !== "win32") {
469
- return installLangfuseWithSystemPython({ pythonCmd, baseDir, pipIndexUrl });
470
- }
471
- throw new Error(`langfuse was installed in venv, but cannot be imported by ${venvPython}`);
472
- }
473
-
474
- return { python: venvPython, pythonPath: "" };
475
- }
459
+ );
460
+ } catch (e) {
461
+ if (process.platform !== "win32") {
462
+ return installLangfuseWithSystemPython({ pythonCmd, baseDir, pipIndexUrl });
463
+ }
464
+ throw new Error(`Failed to install langfuse in venv: ${venvPython} -m pip install -U langfuse -i ${pipIndexUrl}`);
465
+ }
466
+
467
+ if (!pythonCanImport(venvPython, "langfuse")) {
468
+ if (process.platform !== "win32") {
469
+ return installLangfuseWithSystemPython({ pythonCmd, baseDir, pipIndexUrl });
470
+ }
471
+ throw new Error(`langfuse was installed in venv, but cannot be imported by ${venvPython}`);
472
+ }
473
+
474
+ return { python: venvPython, pythonPath: "" };
475
+ }
476
476
 
477
477
  async function main() {
478
478
  const args = parseArgs(process.argv.slice(2));
@@ -483,14 +483,14 @@ async function main() {
483
483
  }
484
484
  assertValidUserId(userId);
485
485
 
486
- const langfuseHost = normalizeLegacyBaseUrl(
487
- args.langfuseBaseUrl ||
488
- args.langfuseHost ||
489
- args.host ||
490
- process.env.LANGFUSE_BASEURL ||
491
- process.env.LANGFUSE_HOST ||
492
- DEFAULT_LANGFUSE_BASE_URL
493
- );
486
+ const langfuseHost = normalizeLegacyBaseUrl(
487
+ args.langfuseBaseUrl ||
488
+ args.langfuseHost ||
489
+ args.host ||
490
+ process.env.LANGFUSE_BASEURL ||
491
+ process.env.LANGFUSE_HOST ||
492
+ DEFAULT_LANGFUSE_BASE_URL
493
+ );
494
494
 
495
495
  const publicKey =
496
496
  args.publicKey || process.env.LANGFUSE_PUBLIC_KEY || "pk-lf-da0c90a7-6e93-4eb7-bb86-c1047c8d187d";
@@ -554,9 +554,9 @@ async function main() {
554
554
  if (nextPyText !== pyText) {
555
555
  await fsp.writeFile(pyPath, nextPyText, "utf8");
556
556
  }
557
- const hookRuntime = createOrUpdateLangfuseVenv({ baseDir: claudeDir, pipIndexUrl });
558
- const hookPython = hookRuntime.python;
559
- const hookLauncher = await createHookLauncher({ hooksDir, hookPython, hookPythonPath: hookRuntime.pythonPath, pyPath });
557
+ const hookRuntime = createOrUpdateLangfuseVenv({ baseDir: claudeDir, pipIndexUrl });
558
+ const hookPython = hookRuntime.python;
559
+ const hookLauncher = await createHookLauncher({ hooksDir, hookPython, hookPythonPath: hookRuntime.pythonPath, pyPath });
560
560
  const claudeShimDir = path.join(claudeDir, "bin");
561
561
  const realClaudeCli = resolveAgentCli({ target: "claude", preferred: args.cmd || "", shimDir: claudeShimDir });
562
562
  const directShim = writeAgentCommandShim({