autotel-cli 0.16.1 → 0.17.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.
Files changed (2) hide show
  1. package/dist/index.js +86 -5
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -3307,6 +3307,73 @@ function checkLoggerInstrumentation(packageRoot, deps) {
3307
3307
  };
3308
3308
  }
3309
3309
  //#endregion
3310
+ //#region src/lib/capture-coverage.ts
3311
+ /**
3312
+ * Mirrors `CAPTURE_SURFACES` in `autotel/evidence`, duplicated because the CLI
3313
+ * does not depend on the runtime package. Keep the two lists in step.
3314
+ */
3315
+ const CAPTURE_SURFACES = [
3316
+ "llm_calls",
3317
+ "tool_calls",
3318
+ "user_prompts",
3319
+ "file_io",
3320
+ "subprocess",
3321
+ "network",
3322
+ "ide_context"
3323
+ ];
3324
+ /**
3325
+ * Which dependency makes each surface observable. A surface with no rule is
3326
+ * unobservable by anything in the toolchain — `subprocess` and `ide_context`
3327
+ * are there deliberately, and reporting them is the most useful line this check
3328
+ * produces. Adding a rule here is how a surface stops being reported as a blind
3329
+ * spot, so an omission understates coverage rather than overstating it.
3330
+ */
3331
+ const OBSERVED_BY = {
3332
+ llm_calls: ["autotel-genai"],
3333
+ tool_calls: ["autotel-genai", "autotel-mcp-instrumentation"],
3334
+ user_prompts: ["autotel-agents"],
3335
+ file_io: ["@opentelemetry/instrumentation-fs", "@opentelemetry/auto-instrumentations-node"],
3336
+ network: [
3337
+ "@opentelemetry/instrumentation-http",
3338
+ "@opentelemetry/instrumentation-undici",
3339
+ "@opentelemetry/auto-instrumentations-node"
3340
+ ]
3341
+ };
3342
+ function assessCaptureCoverage(deps) {
3343
+ const observed = [];
3344
+ const unobserved = [];
3345
+ for (const surface of CAPTURE_SURFACES) if ((OBSERVED_BY[surface] ?? []).some((pkg) => deps[pkg] !== void 0)) observed.push(surface);
3346
+ else unobserved.push(surface);
3347
+ return {
3348
+ observed,
3349
+ unobserved
3350
+ };
3351
+ }
3352
+ const NO_SOURCE = "nothing in the autotel toolchain observes this";
3353
+ function sourceHint(surface) {
3354
+ const sources = OBSERVED_BY[surface];
3355
+ return sources ? `install one of: ${sources.join(", ")}` : NO_SOURCE;
3356
+ }
3357
+ /** One check per surface, for `autotel doctor --capture`. */
3358
+ function captureCoverageChecks(deps) {
3359
+ const { observed, unobserved } = assessCaptureCoverage(deps);
3360
+ return [...observed.map((surface) => ({
3361
+ id: `capture-${surface}`,
3362
+ title: `Capture: ${surface}`,
3363
+ level: "info",
3364
+ status: "ok",
3365
+ message: `${surface} is observable`
3366
+ })), ...unobserved.map((surface) => ({
3367
+ id: `capture-${surface}`,
3368
+ title: `Capture: ${surface}`,
3369
+ level: "info",
3370
+ status: "warn",
3371
+ informational: true,
3372
+ message: `traces cannot show ${surface} — its absence proves nothing`,
3373
+ details: [sourceHint(surface), "Declare the gap on your spans with captureCoverageAttributes() from autotel/evidence"]
3374
+ }))];
3375
+ }
3376
+ //#endregion
3310
3377
  //#region src/commands/doctor.ts
3311
3378
  /**
3312
3379
  * All available check definitions
@@ -3346,6 +3413,11 @@ const CHECK_DEFINITIONS = [
3346
3413
  id: "logger-instrumentation",
3347
3414
  title: "Logger instrumentation",
3348
3415
  description: "Check if logger instrumentation packages are installed"
3416
+ },
3417
+ {
3418
+ id: "capture-coverage",
3419
+ title: "Capture coverage",
3420
+ description: "Report which capture surfaces this project can observe at all (--capture)"
3349
3421
  }
3350
3422
  ];
3351
3423
  /**
@@ -3379,6 +3451,7 @@ async function runChecks(options, projectRoot) {
3379
3451
  ...project.packageJson.dependencies,
3380
3452
  ...project.packageJson.devDependencies
3381
3453
  };
3454
+ if (options.capture) checks.push(...captureCoverageChecks(deps));
3382
3455
  const autotelInfo = getAutotelInfo(project.packageJson);
3383
3456
  if (autotelInfo.installed) checks.push({
3384
3457
  id: "autotel-installed",
@@ -3583,11 +3656,14 @@ function calculateSummary(checks) {
3583
3656
  };
3584
3657
  }
3585
3658
  /**
3586
- * Determine exit code from checks
3659
+ * Determine exit code from checks. Informational checks are excluded: they
3660
+ * describe what the setup can observe rather than judging it, and a permanent
3661
+ * fact of the world must not gate CI.
3587
3662
  */
3588
3663
  function getExitCode(checks) {
3589
- const hasErrors = checks.some((c) => c.status === "error");
3590
- const hasWarnings = checks.some((c) => c.status === "warn");
3664
+ const judged = checks.filter((c) => !c.informational);
3665
+ const hasErrors = judged.some((c) => c.status === "error");
3666
+ const hasWarnings = judged.some((c) => c.status === "warn");
3591
3667
  if (hasErrors) return 2;
3592
3668
  if (hasWarnings) return 1;
3593
3669
  return 0;
@@ -6638,6 +6714,10 @@ const COMMANDS = [
6638
6714
  name: "--env-file",
6639
6715
  takesValue: true,
6640
6716
  description: "Path to env file to check"
6717
+ },
6718
+ {
6719
+ name: "--capture",
6720
+ description: "Report which capture surfaces this project can observe at all"
6641
6721
  }
6642
6722
  ],
6643
6723
  mutating: false,
@@ -9450,7 +9530,7 @@ function createProgram() {
9450
9530
  });
9451
9531
  addGlobalOptions(initCmd);
9452
9532
  program.addCommand(initCmd);
9453
- const doctorCmd = new Command("doctor").description("Run diagnostics on your autotel setup").option("--json", "Output machine-readable JSON").option("--fix", "Auto-fix resolvable issues").option("--list-checks", "List all available checks").option("--env-file <path>", "Specify env file to check").action(async (opts) => {
9533
+ const doctorCmd = new Command("doctor").description("Run diagnostics on your autotel setup").option("--json", "Output machine-readable JSON").option("--fix", "Auto-fix resolvable issues").option("--list-checks", "List all available checks").option("--env-file <path>", "Specify env file to check").option("--capture", "Report which capture surfaces this project can observe at all").action(async (opts) => {
9454
9534
  await runDoctor({
9455
9535
  cwd: opts.cwd ?? process.cwd(),
9456
9536
  dryRun: false,
@@ -9462,7 +9542,8 @@ function createProgram() {
9462
9542
  json: opts.json ?? false,
9463
9543
  fix: opts.fix ?? false,
9464
9544
  listChecks: opts.listChecks ?? false,
9465
- envFile: opts.envFile
9545
+ envFile: opts.envFile,
9546
+ capture: opts.capture ?? false
9466
9547
  });
9467
9548
  });
9468
9549
  addGlobalOptions(doctorCmd);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autotel-cli",
3
- "version": "0.16.1",
3
+ "version": "0.17.0",
4
4
  "description": "CLI for autotel - setup wizard, diagnostics, and incremental features",
5
5
  "type": "module",
6
6
  "bin": {
@@ -25,7 +25,7 @@
25
25
  "semver": "^7.8.5",
26
26
  "ts-morph": "^28.0.0",
27
27
  "yaml": "^2.9.0",
28
- "autotel-mcp": "0.5.1"
28
+ "autotel-mcp": "0.5.2"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@eslint/js": "^10.0.1",