autotel-cli 0.16.2 → 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.
- package/dist/index.js +86 -5
- package/package.json +1 -1
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
|
|
3590
|
-
const
|
|
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);
|