@lorekit/cli 1.7.0 → 1.7.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/telemetry.mjs +21 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lorekit/cli",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "Install the LoreKit shared-memory skill and run health checks for the LoreKit MCP server.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/telemetry.mjs CHANGED
@@ -256,6 +256,19 @@ function errorLabel(e) {
256
256
  return 'Error';
257
257
  }
258
258
 
259
+ /**
260
+ * Coerce a command handler's return value to a numeric exit code. Commands may
261
+ * resolve to a bare number, or to an { exitCode, ...extra } object (which lets
262
+ * them surface bounded diagnostic fields for telemetry); anything else → 0.
263
+ * Single source of truth for exit-code normalization on both traceCommand paths.
264
+ * @param {unknown} result
265
+ * @returns {number}
266
+ */
267
+ function normalizeExitCode(result) {
268
+ if (result !== null && typeof result === 'object') return result.exitCode ?? 0;
269
+ return result ?? 0;
270
+ }
271
+
259
272
  /**
260
273
  * Time a human-facing command, record its outcome, and export one span + one
261
274
  * counter point. Returns the command's exit code unchanged. Telemetry failures
@@ -274,8 +287,13 @@ export async function traceCommand(command, args, version, run) {
274
287
  config = { enabled: false };
275
288
  }
276
289
 
277
- // Fast path: no export configured → run with zero overhead.
278
- if (!config.enabled) return run();
290
+ // Fast path: no export configured → run with zero telemetry overhead. Still
291
+ // normalize the result to a numeric exit code: commands may resolve to an
292
+ // { exitCode, ...extra } object (e.g. `doctor`), and only the instrumented
293
+ // path below unwraps it. Returning `run()` raw would leak that object all the
294
+ // way to `process.exit(obj)` in the bin entry → ERR_INVALID_ARG_TYPE crash
295
+ // (exit 1) for every user without an OTLP endpoint configured.
296
+ if (!config.enabled) return normalizeExitCode(await run());
279
297
 
280
298
  const startMs = Date.now();
281
299
  let exitCode = 0;
@@ -287,16 +305,14 @@ export async function traceCommand(command, args, version, run) {
287
305
  // Commands may return either a plain exit code (number) or an object with
288
306
  // { exitCode, ...extra } — the latter lets commands surface bounded,
289
307
  // non-PII diagnostic fields (e.g. which checks failed in `doctor`).
308
+ exitCode = normalizeExitCode(result);
290
309
  if (result !== null && typeof result === 'object') {
291
- exitCode = result.exitCode ?? 0;
292
310
  const { exitCode: _ec, ...rest } = result;
293
311
  // Flatten any array-valued extras to a comma-joined string so they fit
294
312
  // the flat attribute bag shape (OTLP stringValue).
295
313
  for (const [k, v] of Object.entries(rest)) {
296
314
  extraAttrs[k] = Array.isArray(v) ? v.join(',') : v;
297
315
  }
298
- } else {
299
- exitCode = result ?? 0;
300
316
  }
301
317
  if (typeof exitCode === 'number' && exitCode !== 0) {
302
318
  status = 'error';