oh-langfuse 0.1.7 → 0.1.9

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/bin/cli.js +78 -41
  3. package/package.json +12 -12
package/README.md CHANGED
@@ -40,7 +40,7 @@ npm start
40
40
  npm 发布后运行:
41
41
 
42
42
  ```bash
43
- npx oh-langfuse
43
+ npx oh-langfuse@latest
44
44
  ```
45
45
 
46
46
  交互界面支持:
package/bin/cli.js CHANGED
@@ -260,7 +260,7 @@ async function askText(rl, label, { defaultValue = "", required = false } = {})
260
260
  }
261
261
  }
262
262
 
263
- async function askYesNo(rl, label, { defaultValue = true } = {}) {
263
+ async function askYesNo(rl, label, { defaultValue = true } = {}) {
264
264
  const hint = defaultValue ? "Y/n" : "y/N";
265
265
  while (true) {
266
266
  const answer = (await rl.question(`${paint(label, t.cyan)} ${paint(`(${hint})`, t.muted)} `)).trim().toLowerCase();
@@ -268,10 +268,47 @@ async function askYesNo(rl, label, { defaultValue = true } = {}) {
268
268
  if (["y", "yes"].includes(answer)) return true;
269
269
  if (["n", "no"].includes(answer)) return false;
270
270
  console.log(paint("Please answer y or n.", t.red));
271
- }
272
- }
273
-
274
- function renderChoiceScreen(label, choices, index, options = {}) {
271
+ }
272
+ }
273
+
274
+ function keySeq(raw, key = {}) {
275
+ return String(key.sequence ?? raw ?? "");
276
+ }
277
+
278
+ function isCtrlC(raw, key = {}) {
279
+ return Boolean(key.ctrl && key.name === "c") || keySeq(raw, key) === "\x03";
280
+ }
281
+
282
+ function isEscape(raw, key = {}) {
283
+ const seq = keySeq(raw, key);
284
+ return key.name === "escape" || seq === "\x1b";
285
+ }
286
+
287
+ function isUpKey(raw, key = {}) {
288
+ const seq = keySeq(raw, key);
289
+ return key.name === "up" || seq === "\x1b[A" || seq === "\x1bOA";
290
+ }
291
+
292
+ function isDownKey(raw, key = {}) {
293
+ const seq = keySeq(raw, key);
294
+ return key.name === "down" || seq === "\x1b[B" || seq === "\x1bOB";
295
+ }
296
+
297
+ function isEnterKey(raw, key = {}) {
298
+ const seq = keySeq(raw, key);
299
+ return key.name === "return" || key.name === "enter" || seq === "\r" || seq === "\n";
300
+ }
301
+
302
+ function isSpaceKey(raw, key = {}) {
303
+ return key.name === "space" || keySeq(raw, key) === " ";
304
+ }
305
+
306
+ function numberKey(raw, key = {}) {
307
+ const seq = keySeq(raw, key);
308
+ return /^[1-9]$/.test(seq) ? Number.parseInt(seq, 10) : Number.NaN;
309
+ }
310
+
311
+ function renderChoiceScreen(label, choices, index, options = {}) {
275
312
  clearScreen();
276
313
  renderBrand(options);
277
314
  console.log("");
@@ -308,23 +345,23 @@ async function askChoice(rl, label, choices, options = {}) {
308
345
  resolve(value);
309
346
  }
310
347
 
311
- function onKeypress(_, key = {}) {
312
- if (key.ctrl && key.name === "c") return cleanup("exit");
313
- if (key.name === "q" || key.name === "escape") return cleanup("exit");
314
- if (key.name === "up") {
315
- index = (index - 1 + choices.length) % choices.length;
316
- renderChoiceScreen(label, choices, index, options);
317
- return;
318
- }
319
- if (key.name === "down") {
320
- index = (index + 1) % choices.length;
321
- renderChoiceScreen(label, choices, index, options);
322
- return;
323
- }
324
- if (key.name === "return" || key.name === "enter") return cleanup(choices[index].value);
325
- const num = Number.parseInt(key.sequence, 10);
326
- if (Number.isInteger(num) && choices[num - 1]) return cleanup(choices[num - 1].value);
327
- }
348
+ function onKeypress(raw, key = {}) {
349
+ if (isCtrlC(raw, key)) return cleanup("exit");
350
+ if (isUpKey(raw, key)) {
351
+ index = (index - 1 + choices.length) % choices.length;
352
+ renderChoiceScreen(label, choices, index, options);
353
+ return;
354
+ }
355
+ if (isDownKey(raw, key)) {
356
+ index = (index + 1) % choices.length;
357
+ renderChoiceScreen(label, choices, index, options);
358
+ return;
359
+ }
360
+ if (keySeq(raw, key).toLowerCase() === "q" || isEscape(raw, key)) return cleanup("exit");
361
+ if (isEnterKey(raw, key)) return cleanup(choices[index].value);
362
+ const num = numberKey(raw, key);
363
+ if (Number.isInteger(num) && choices[num - 1]) return cleanup(choices[num - 1].value);
364
+ }
328
365
 
329
366
  readline.emitKeypressEvents(stdin);
330
367
  if (stdin.isTTY) stdin.setRawMode(true);
@@ -393,25 +430,25 @@ async function askMultiChoice(rl, label, choices, options = {}) {
393
430
  renderMultiChoiceScreen(label, choices, index, selected, options);
394
431
  }
395
432
 
396
- function onKeypress(_, key = {}) {
397
- if (key.ctrl && key.name === "c") return cleanup([]);
398
- if (key.name === "q" || key.name === "escape") return cleanup([]);
399
- if (key.name === "up") {
400
- index = (index - 1 + choices.length) % choices.length;
401
- renderMultiChoiceScreen(label, choices, index, selected, options);
402
- return;
403
- }
404
- if (key.name === "down") {
405
- index = (index + 1) % choices.length;
406
- renderMultiChoiceScreen(label, choices, index, selected, options);
407
- return;
408
- }
409
- if (key.name === "space") return toggle();
410
- if (key.name === "return" || key.name === "enter") return cleanup([...selected]);
411
- const num = Number.parseInt(key.sequence, 10);
412
- if (Number.isInteger(num) && choices[num - 1]) {
413
- index = num - 1;
414
- toggle();
433
+ function onKeypress(raw, key = {}) {
434
+ if (isCtrlC(raw, key)) return cleanup([]);
435
+ if (isUpKey(raw, key)) {
436
+ index = (index - 1 + choices.length) % choices.length;
437
+ renderMultiChoiceScreen(label, choices, index, selected, options);
438
+ return;
439
+ }
440
+ if (isDownKey(raw, key)) {
441
+ index = (index + 1) % choices.length;
442
+ renderMultiChoiceScreen(label, choices, index, selected, options);
443
+ return;
444
+ }
445
+ if (keySeq(raw, key).toLowerCase() === "q" || isEscape(raw, key)) return cleanup([]);
446
+ if (isSpaceKey(raw, key)) return toggle();
447
+ if (isEnterKey(raw, key)) return cleanup([...selected]);
448
+ const num = numberKey(raw, key);
449
+ if (Number.isInteger(num) && choices[num - 1]) {
450
+ index = num - 1;
451
+ toggle();
415
452
  }
416
453
  }
417
454
 
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
- "name": "oh-langfuse",
3
- "version": "0.1.7",
2
+ "name": "oh-langfuse",
3
+ "version": "0.1.9",
4
4
  "private": false,
5
5
  "type": "module",
6
- "description": "Use npm scripts to configure Claude Code / OpenCode / Codex with Langfuse tracing.",
7
- "bin": {
8
- "oh-langfuse": "bin/cli.js",
9
- "code-tool-langfuse": "bin/cli.js"
10
- },
6
+ "description": "Use npm scripts to configure Claude Code / OpenCode / Codex with Langfuse tracing.",
7
+ "bin": {
8
+ "oh-langfuse": "bin/cli.js",
9
+ "code-tool-langfuse": "bin/cli.js"
10
+ },
11
11
  "files": [
12
12
  "bin",
13
13
  "scripts",
@@ -18,11 +18,11 @@
18
18
  "setup-langfuse.bat",
19
19
  "setup-langfuse.sh"
20
20
  ],
21
- "scripts": {
22
- "start": "node bin/cli.js",
23
- "check": "node --check bin/cli.js",
24
- "pack:check": "npm pack --dry-run",
25
- "claude:setup": "node scripts/langfuse-setup.mjs",
21
+ "scripts": {
22
+ "start": "node bin/cli.js",
23
+ "check": "node --check bin/cli.js",
24
+ "pack:check": "npm pack --dry-run",
25
+ "claude:setup": "node scripts/langfuse-setup.mjs",
26
26
  "claude:check": "node scripts/langfuse-check.mjs",
27
27
  "langfuse:setup": "node scripts/langfuse-setup.mjs",
28
28
  "langfuse:check": "node scripts/langfuse-check.mjs",