@lorekit/cli 1.6.0 → 1.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lorekit/cli",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
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/doctor.mjs CHANGED
@@ -24,8 +24,9 @@ export async function doctor(args) {
24
24
  const root = resolveProjectRoot(args.dir);
25
25
  let failures = 0;
26
26
  let warnings = 0;
27
+ const failedChecks = [];
27
28
  const record = (kind, label, detail) => {
28
- if (kind === 'fail') failures++;
29
+ if (kind === 'fail') { failures++; failedChecks.push(label); }
29
30
  if (kind === 'warn') warnings++;
30
31
  status(kind, label, detail);
31
32
  };
@@ -91,7 +92,8 @@ export async function doctor(args) {
91
92
  }.`,
92
93
  );
93
94
  }
94
- return failures === 0 ? 0 : 1;
95
+ const exitCode = failures === 0 ? 0 : 1;
96
+ return { exitCode, 'lorekit.cli.doctor.failed_checks': failedChecks };
95
97
  }
96
98
 
97
99
  // Merge doctor's --endpoint / --token flags into the env the resolver reads, so
package/src/telemetry.mjs CHANGED
@@ -135,12 +135,13 @@ function resourceAttributes(version) {
135
135
  * Collect the bounded, non-PII attributes for a command invocation. Only the
136
136
  * command name, allow-listed boolean flags, the outcome and the exit code.
137
137
  */
138
- export function commandAttributes({ command, args = {}, outcome, exitCode }) {
138
+ export function commandAttributes({ command, args = {}, outcome, exitCode, extraAttrs = {} }) {
139
139
  const attrs = { 'lorekit.cli.command': command, 'lorekit.cli.outcome': outcome };
140
140
  if (typeof exitCode === 'number') attrs['lorekit.cli.exit_code'] = exitCode;
141
141
  for (const flag of FLAG_ATTRS) {
142
142
  if (args[flag]) attrs[`lorekit.cli.flag.${flag}`] = true;
143
143
  }
144
+ Object.assign(attrs, extraAttrs);
144
145
  return attrs;
145
146
  }
146
147
 
@@ -280,8 +281,23 @@ export async function traceCommand(command, args, version, run) {
280
281
  let exitCode = 0;
281
282
  let status = 'ok';
282
283
  let statusMessage;
284
+ let extraAttrs = {};
283
285
  try {
284
- exitCode = await run();
286
+ const result = await run();
287
+ // Commands may return either a plain exit code (number) or an object with
288
+ // { exitCode, ...extra } — the latter lets commands surface bounded,
289
+ // non-PII diagnostic fields (e.g. which checks failed in `doctor`).
290
+ if (result !== null && typeof result === 'object') {
291
+ exitCode = result.exitCode ?? 0;
292
+ const { exitCode: _ec, ...rest } = result;
293
+ // Flatten any array-valued extras to a comma-joined string so they fit
294
+ // the flat attribute bag shape (OTLP stringValue).
295
+ for (const [k, v] of Object.entries(rest)) {
296
+ extraAttrs[k] = Array.isArray(v) ? v.join(',') : v;
297
+ }
298
+ } else {
299
+ exitCode = result ?? 0;
300
+ }
285
301
  if (typeof exitCode === 'number' && exitCode !== 0) {
286
302
  status = 'error';
287
303
  statusMessage = `exit ${exitCode}`;
@@ -308,6 +324,7 @@ export async function traceCommand(command, args, version, run) {
308
324
  args,
309
325
  outcome: status === 'error' ? 'error' : 'ok',
310
326
  exitCode: typeof exitCode === 'number' ? exitCode : undefined,
327
+ extraAttrs,
311
328
  });
312
329
  await exportInvocation(config, {
313
330
  version,