agent-inspect 1.8.0 → 1.9.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.
@@ -23,7 +23,7 @@ var process2__default = /*#__PURE__*/_interopDefault(process2);
23
23
  var tty__default = /*#__PURE__*/_interopDefault(tty);
24
24
 
25
25
  // package.json
26
- var version = "1.8.0";
26
+ var version = "1.9.0";
27
27
 
28
28
  // packages/core/src/types.ts
29
29
  var STEP_TYPES = [
@@ -4069,6 +4069,151 @@ ${attrsSection}
4069
4069
  };
4070
4070
  }
4071
4071
 
4072
+ // packages/core/src/explain.ts
4073
+ function flatten(nodes, out = []) {
4074
+ for (const node of nodes) {
4075
+ out.push({ node, index: out.length + 1 });
4076
+ flatten(node.children, out);
4077
+ }
4078
+ return out;
4079
+ }
4080
+ function redactValue(redactor, key, value) {
4081
+ return redactor.redactValue(key, value);
4082
+ }
4083
+ function fact(id, label, value, redactor) {
4084
+ return {
4085
+ id,
4086
+ label,
4087
+ value: redactValue(redactor, id.split(".").at(-1) ?? id, value),
4088
+ source: "trace",
4089
+ confidence: "observed"
4090
+ };
4091
+ }
4092
+ function topKinds(run) {
4093
+ return Object.entries(run.metadata.kinds).filter(([, count]) => count > 0).sort((a, b) => {
4094
+ if (b[1] !== a[1]) return b[1] - a[1];
4095
+ return a[0].localeCompare(b[0]);
4096
+ }).slice(0, 5).map(([kind, count]) => `${kind}:${count}`);
4097
+ }
4098
+ function countErrorNodes(nodes) {
4099
+ return nodes.filter((entry) => entry.node.event.status === "error").length;
4100
+ }
4101
+ function slowestNode(nodes) {
4102
+ return nodes.filter((entry) => entry.node.event.durationMs !== void 0).sort((a, b) => {
4103
+ const delta = (b.node.event.durationMs ?? 0) - (a.node.event.durationMs ?? 0);
4104
+ return delta !== 0 ? delta : a.index - b.index;
4105
+ })[0];
4106
+ }
4107
+ function attributeFacts(nodes, redactor) {
4108
+ const facts = [];
4109
+ for (const entry of nodes) {
4110
+ const attrs = entry.node.event.attributes;
4111
+ if (attrs === void 0) continue;
4112
+ for (const key of Object.keys(attrs).sort()) {
4113
+ facts.push({
4114
+ id: `node.${entry.index}.attributes.${key}`,
4115
+ label: `${entry.node.event.name} attribute ${key}`,
4116
+ value: redactValue(redactor, key, attrs[key]),
4117
+ source: "trace",
4118
+ confidence: "observed"
4119
+ });
4120
+ if (facts.length >= 8) return facts;
4121
+ }
4122
+ }
4123
+ return facts;
4124
+ }
4125
+ function buildFacts(run, redactor) {
4126
+ const nodes = flatten(run.children);
4127
+ const facts = [
4128
+ fact("run.id", "Run id", run.runId, redactor),
4129
+ fact("run.name", "Run name", run.name ?? run.runId, redactor),
4130
+ fact("run.status", "Run status", run.status ?? "unknown", redactor),
4131
+ fact("run.totalEvents", "Total events", run.metadata.totalEvents, redactor),
4132
+ fact("run.stepCount", "Top-level step count", run.children.length, redactor),
4133
+ fact("run.nodeCount", "Total node count", nodes.length, redactor),
4134
+ fact("run.errorNodeCount", "Error node count", countErrorNodes(nodes), redactor),
4135
+ fact("run.kinds", "Observed kind mix", topKinds(run), redactor)
4136
+ ];
4137
+ if (run.durationMs !== void 0) {
4138
+ facts.push(fact("run.durationMs", "Run duration milliseconds", run.durationMs, redactor));
4139
+ }
4140
+ const slowest = slowestNode(nodes);
4141
+ if (slowest !== void 0) {
4142
+ facts.push(
4143
+ fact("run.slowestNode", "Slowest observed node", {
4144
+ name: slowest.node.event.name,
4145
+ kind: slowest.node.event.kind,
4146
+ durationMs: slowest.node.event.durationMs
4147
+ }, redactor)
4148
+ );
4149
+ }
4150
+ facts.push(...attributeFacts(nodes, redactor));
4151
+ return facts;
4152
+ }
4153
+ function buildInferences(run, facts) {
4154
+ const inferences = [];
4155
+ const errorFact = facts.find((item) => item.id === "run.errorNodeCount");
4156
+ const kindFact = facts.find((item) => item.id === "run.kinds");
4157
+ const durationFact = facts.find((item) => item.id === "run.durationMs");
4158
+ const errorNodeCount = typeof errorFact?.value === "number" ? errorFact.value : 0;
4159
+ if (run.status === "error" || errorNodeCount > 0) {
4160
+ inferences.push({
4161
+ id: "outcome.error",
4162
+ label: "Outcome",
4163
+ text: "The run recorded an error status or at least one error node.",
4164
+ evidence: ["run.status", "run.errorNodeCount"],
4165
+ confidence: "deterministic"
4166
+ });
4167
+ } else if (run.status === "ok") {
4168
+ inferences.push({
4169
+ id: "outcome.success",
4170
+ label: "Outcome",
4171
+ text: "The run completed without observed error nodes.",
4172
+ evidence: ["run.status", "run.errorNodeCount"],
4173
+ confidence: "deterministic"
4174
+ });
4175
+ }
4176
+ if (kindFact !== void 0) {
4177
+ inferences.push({
4178
+ id: "shape.kind-mix",
4179
+ label: "Trace shape",
4180
+ text: "The explanation is based on the observed event kind mix, not generated content.",
4181
+ evidence: [kindFact.id],
4182
+ confidence: "deterministic"
4183
+ });
4184
+ }
4185
+ if (durationFact !== void 0) {
4186
+ inferences.push({
4187
+ id: "timing.duration",
4188
+ label: "Timing",
4189
+ text: "Timing claims are limited to persisted duration fields in the trace.",
4190
+ evidence: [durationFact.id],
4191
+ confidence: "deterministic"
4192
+ });
4193
+ }
4194
+ return inferences;
4195
+ }
4196
+ function buildLocalExplanation(run, options = {}) {
4197
+ const redactionProfile = options.redactionProfile ?? "local";
4198
+ const resolved = resolveRedactionProfile(redactionProfile);
4199
+ const redactor = new Redactor({ extraKeys: resolved.extraKeys });
4200
+ const mode = options.mode ?? "local";
4201
+ const facts = buildFacts(run, redactor);
4202
+ return {
4203
+ mode,
4204
+ runId: String(redactValue(redactor, "runId", run.runId)),
4205
+ ...run.name !== void 0 ? { name: String(redactValue(redactor, "name", run.name)) } : {},
4206
+ ...run.status !== void 0 ? { status: run.status } : {},
4207
+ redactionProfile,
4208
+ facts,
4209
+ inferences: mode === "dry-run" ? [] : buildInferences(run, facts),
4210
+ notes: [
4211
+ "Generated locally without provider or network calls.",
4212
+ "Facts are observed from normalized trace data; inferences are deterministic labels."
4213
+ ]
4214
+ };
4215
+ }
4216
+
4072
4217
  // packages/core/src/stats.ts
4073
4218
  function percentile(sorted, p) {
4074
4219
  if (sorted.length === 0) return void 0;
@@ -8958,9 +9103,164 @@ async function readStdin(stdin) {
8958
9103
  }
8959
9104
  return content;
8960
9105
  }
9106
+ function isMissingFileError2(error) {
9107
+ return error !== null && typeof error === "object" && "code" in error && error.code === "ENOENT";
9108
+ }
9109
+ async function inputFromTarget(target, options, stdin) {
9110
+ if (target === "-") {
9111
+ return { type: "string", content: await readStdin(stdin) };
9112
+ }
9113
+ try {
9114
+ const stats2 = await promises.stat(target);
9115
+ if (stats2.isDirectory()) return { type: "directory", path: target };
9116
+ return { type: "file", path: target };
9117
+ } catch (error) {
9118
+ if (!isMissingFileError2(error)) throw error;
9119
+ }
9120
+ const runPath = getTraceFilePath(target, resolveTraceDir({ dir: options.dir }));
9121
+ const stats = await promises.stat(runPath);
9122
+ if (stats.isDirectory()) return { type: "directory", path: runPath };
9123
+ return { type: "file", path: runPath };
9124
+ }
9125
+
9126
+ // packages/cli/src/explain.ts
9127
+ function parseRedactionProfile3(value) {
9128
+ const profile = (value ?? "local").trim().toLowerCase();
9129
+ if (profile === "local" || profile === "share" || profile === "strict") {
9130
+ return profile;
9131
+ }
9132
+ throw new Error(
9133
+ `Unsupported --redaction-profile "${value ?? ""}". Use local, share, or strict.`
9134
+ );
9135
+ }
9136
+ function selectRun(result, runId) {
9137
+ if (runId !== void 0) {
9138
+ return result.runs.find((run) => run.runId === runId);
9139
+ }
9140
+ return result.runs.length === 1 ? result.runs[0] : void 0;
9141
+ }
9142
+ function printMultipleRuns(result) {
9143
+ console.error(
9144
+ `Trace contains ${result.runs.length} runs. Re-run with --run <run-id>.`
9145
+ );
9146
+ for (const run of result.runs) {
9147
+ console.error(`- ${run.runId}${run.name !== void 0 ? ` name=${run.name}` : ""}`);
9148
+ }
9149
+ }
9150
+ function renderHuman(result) {
9151
+ const lines = [
9152
+ `Explain: ${result.name ?? result.runId}`,
9153
+ `Mode: ${result.mode}`,
9154
+ `Status: ${result.status ?? "unknown"}`,
9155
+ `Redaction: ${result.redactionProfile}`,
9156
+ "",
9157
+ "Facts:"
9158
+ ];
9159
+ for (const fact2 of result.facts) {
9160
+ lines.push(`- ${fact2.id}: ${JSON.stringify(fact2.value)}`);
9161
+ }
9162
+ lines.push("", "Inferences:");
9163
+ if (result.inferences.length === 0) {
9164
+ lines.push("- none");
9165
+ } else {
9166
+ for (const inference of result.inferences) {
9167
+ lines.push(`- ${inference.label}: ${inference.text}`);
9168
+ }
9169
+ }
9170
+ lines.push("", "Notes:");
9171
+ for (const note of result.notes) {
9172
+ lines.push(`- ${note}`);
9173
+ }
9174
+ return lines.join("\n");
9175
+ }
9176
+ function writeJson(result) {
9177
+ console.log(JSON.stringify(result, null, 2));
9178
+ }
9179
+ function rejectProvider(provider, json) {
9180
+ process.exitCode = 1;
9181
+ const message = `Provider explain is not implemented in this build: ${provider}. Use --dry-run to inspect the redacted local payload.`;
9182
+ if (json) {
9183
+ writeJson({
9184
+ ok: false,
9185
+ error: { code: "PROVIDER_NOT_IMPLEMENTED", message }
9186
+ });
9187
+ return;
9188
+ }
9189
+ console.error(message);
9190
+ }
9191
+ async function explainCommand(target, options = {}, stdin = process.stdin) {
9192
+ if (options.provider !== void 0) {
9193
+ rejectProvider(options.provider, options.json);
9194
+ return;
9195
+ }
9196
+ let redactionProfile;
9197
+ try {
9198
+ redactionProfile = parseRedactionProfile3(options.redactionProfile);
9199
+ } catch (error) {
9200
+ process.exitCode = 1;
9201
+ console.error(error instanceof Error ? error.message : String(error));
9202
+ return;
9203
+ }
9204
+ try {
9205
+ const input3 = await inputFromTarget(target, options, stdin);
9206
+ const read = await openTrace(input3, {
9207
+ ...options.format !== void 0 ? { format: options.format } : {}
9208
+ });
9209
+ const selected = selectRun(read, options.run);
9210
+ if (selected === void 0) {
9211
+ process.exitCode = 1;
9212
+ const message = options.run !== void 0 ? `Run not found: ${options.run}` : `Trace contains ${read.runs.length} runs. Specify --run <run-id>.`;
9213
+ if (options.json) {
9214
+ writeJson({ ok: false, error: { message }, runs: read.runs });
9215
+ } else if (options.run !== void 0) {
9216
+ console.error(message);
9217
+ } else {
9218
+ printMultipleRuns(read);
9219
+ }
9220
+ return;
9221
+ }
9222
+ const mode = options.dryRun ? "dry-run" : "local";
9223
+ const explanation = buildLocalExplanation(selected, {
9224
+ mode,
9225
+ redactionProfile
9226
+ });
9227
+ if (options.json) {
9228
+ writeJson({
9229
+ ok: true,
9230
+ format: read.format,
9231
+ sourceFiles: read.sourceFiles,
9232
+ warnings: read.warnings,
9233
+ unsupportedFields: read.unsupportedFields,
9234
+ explanation
9235
+ });
9236
+ return;
9237
+ }
9238
+ console.log(renderHuman(explanation));
9239
+ } catch (error) {
9240
+ process.exitCode = 1;
9241
+ const message = error instanceof Error ? error.message : String(error);
9242
+ const code = error instanceof TraceReadError ? error.code : void 0;
9243
+ if (options.json) {
9244
+ writeJson({
9245
+ ok: false,
9246
+ error: { ...code !== void 0 ? { code } : {}, message }
9247
+ });
9248
+ return;
9249
+ }
9250
+ console.error(message);
9251
+ }
9252
+ }
9253
+ async function readStdin2(stdin) {
9254
+ stdin.setEncoding("utf8");
9255
+ let content = "";
9256
+ for await (const chunk of stdin) {
9257
+ content += typeof chunk === "string" ? chunk : String(chunk);
9258
+ }
9259
+ return content;
9260
+ }
8961
9261
  async function inputFromPathOrStdin(input3, stdin) {
8962
9262
  if (input3 === void 0 || input3 === "-") {
8963
- return { type: "string", content: await readStdin(stdin) };
9263
+ return { type: "string", content: await readStdin2(stdin) };
8964
9264
  }
8965
9265
  const stats = await promises.stat(input3);
8966
9266
  if (stats.isDirectory()) return { type: "directory", path: input3 };
@@ -9011,13 +9311,13 @@ function printRun(result, run) {
9011
9311
  printNode(node, 0);
9012
9312
  }
9013
9313
  }
9014
- function selectRun(result, runId) {
9314
+ function selectRun2(result, runId) {
9015
9315
  if (runId !== void 0) {
9016
9316
  return result.runs.find((run) => run.runId === runId);
9017
9317
  }
9018
9318
  return result.runs.length === 1 ? result.runs[0] : void 0;
9019
9319
  }
9020
- function printMultipleRuns(result) {
9320
+ function printMultipleRuns2(result) {
9021
9321
  console.error(
9022
9322
  `Trace contains ${result.runs.length} runs. Re-run with --run <run-id>.`
9023
9323
  );
@@ -9031,7 +9331,7 @@ function printMultipleRuns(result) {
9031
9331
  console.error(`- ${bits.join(" ")}`);
9032
9332
  }
9033
9333
  }
9034
- function writeJson(output2) {
9334
+ function writeJson2(output2) {
9035
9335
  console.log(JSON.stringify(output2, null, 2));
9036
9336
  }
9037
9337
  async function openCommand(input3, options = {}, stdin = process.stdin) {
@@ -9040,12 +9340,12 @@ async function openCommand(input3, options = {}, stdin = process.stdin) {
9040
9340
  const result = await openTrace(traceInput, {
9041
9341
  ...options.format !== void 0 ? { format: options.format } : {}
9042
9342
  });
9043
- const selected = selectRun(result, options.run);
9343
+ const selected = selectRun2(result, options.run);
9044
9344
  if (selected === void 0) {
9045
9345
  process.exitCode = 1;
9046
9346
  const message = options.run !== void 0 ? `Run not found: ${options.run}` : `Trace contains ${result.runs.length} runs. Specify --run <run-id>.`;
9047
9347
  if (options.json) {
9048
- writeJson({
9348
+ writeJson2({
9049
9349
  format: result.format,
9050
9350
  sourceFiles: result.sourceFiles,
9051
9351
  warnings: result.warnings,
@@ -9056,12 +9356,12 @@ async function openCommand(input3, options = {}, stdin = process.stdin) {
9056
9356
  } else if (options.run !== void 0) {
9057
9357
  console.error(message);
9058
9358
  } else {
9059
- printMultipleRuns(result);
9359
+ printMultipleRuns2(result);
9060
9360
  }
9061
9361
  return;
9062
9362
  }
9063
9363
  if (options.json) {
9064
- writeJson({
9364
+ writeJson2({
9065
9365
  format: result.format,
9066
9366
  sourceFiles: result.sourceFiles,
9067
9367
  warnings: result.warnings,
@@ -9081,7 +9381,7 @@ async function openCommand(input3, options = {}, stdin = process.stdin) {
9081
9381
  const code = error instanceof TraceReadError ? error.code : void 0;
9082
9382
  const warnings = error instanceof TraceReadError ? error.warnings : [];
9083
9383
  if (options.json) {
9084
- writeJson({
9384
+ writeJson2({
9085
9385
  warnings,
9086
9386
  error: { ...code !== void 0 ? { code } : {}, message }
9087
9387
  });
@@ -9185,7 +9485,7 @@ function errorResult(input3, diagnostics, selectedRun) {
9185
9485
  function flattenNodes(nodes) {
9186
9486
  return nodes.flatMap((node) => [node, ...flattenNodes(node.children)]);
9187
9487
  }
9188
- function buildFacts(input3, selectedRun) {
9488
+ function buildFacts2(input3, selectedRun) {
9189
9489
  const scopedRuns = selectedRun ? [selectedRun] : input3.read.runs;
9190
9490
  const scopedRunIds = new Set(scopedRuns.map((run) => run.runId));
9191
9491
  const scopedEvents = selectedRun === void 0 ? input3.read.events : input3.read.events.filter((event) => scopedRunIds.has(event.runId));
@@ -10193,7 +10493,7 @@ function createBaselineRegressionRule(options) {
10193
10493
  )
10194
10494
  ];
10195
10495
  }
10196
- const baselineFacts = buildFacts(options.baseline, baselineSelection.run);
10496
+ const baselineFacts = buildFacts2(options.baseline, baselineSelection.run);
10197
10497
  const baselineContext = {
10198
10498
  ...baselineFacts,
10199
10499
  selectedRun: baselineSelection.run,
@@ -10312,7 +10612,7 @@ function runTraceChecks(input3, options = {}) {
10312
10612
  if (rules.diagnostics.length > 0) {
10313
10613
  return errorResult(input3, rules.diagnostics, selected.run);
10314
10614
  }
10315
- const facts = buildFacts(input3, selected.run);
10615
+ const facts = buildFacts2(input3, selected.run);
10316
10616
  const context = {
10317
10617
  ...facts,
10318
10618
  ...selected.run ? { selectedRun: selected.run } : {},
@@ -10347,33 +10647,6 @@ function runTraceChecks(input3, options = {}) {
10347
10647
  diagnostics
10348
10648
  };
10349
10649
  }
10350
- async function readStdin2(stdin) {
10351
- stdin.setEncoding("utf8");
10352
- let content = "";
10353
- for await (const chunk of stdin) {
10354
- content += typeof chunk === "string" ? chunk : String(chunk);
10355
- }
10356
- return content;
10357
- }
10358
- function isMissingFileError2(error) {
10359
- return error !== null && typeof error === "object" && "code" in error && error.code === "ENOENT";
10360
- }
10361
- async function inputFromTarget(target, options, stdin) {
10362
- if (target === "-") {
10363
- return { type: "string", content: await readStdin2(stdin) };
10364
- }
10365
- try {
10366
- const stats2 = await promises.stat(target);
10367
- if (stats2.isDirectory()) return { type: "directory", path: target };
10368
- return { type: "file", path: target };
10369
- } catch (error) {
10370
- if (!isMissingFileError2(error)) throw error;
10371
- }
10372
- const runPath = getTraceFilePath(target, resolveTraceDir({ dir: options.dir }));
10373
- const stats = await promises.stat(runPath);
10374
- if (stats.isDirectory()) return { type: "directory", path: runPath };
10375
- return { type: "file", path: runPath };
10376
- }
10377
10650
 
10378
10651
  // packages/cli/src/check.ts
10379
10652
  var DEFAULT_SELECT = ["run.status"];
@@ -10820,7 +11093,7 @@ function stable3(value) {
10820
11093
  Object.keys(record).sort((a, b) => a.localeCompare(b)).map((key) => [key, stable3(record[key])])
10821
11094
  );
10822
11095
  }
10823
- function writeJson2(value) {
11096
+ function writeJson3(value) {
10824
11097
  return `${JSON.stringify(stable3(value), null, 2)}
10825
11098
  `;
10826
11099
  }
@@ -10838,7 +11111,7 @@ function increment(record, key) {
10838
11111
  const label = key && key.trim() !== "" ? key : "unknown";
10839
11112
  record[label] = (record[label] ?? 0) + 1;
10840
11113
  }
10841
- function selectRun2(read, runId) {
11114
+ function selectRun3(read, runId) {
10842
11115
  if (runId !== void 0) {
10843
11116
  return read.runs.find((run) => run.runId === runId);
10844
11117
  }
@@ -10986,7 +11259,7 @@ async function artifactsCommand(target, options = {}, stdin = process.stdin) {
10986
11259
  process.exitCode = 1;
10987
11260
  return;
10988
11261
  }
10989
- const selectedRun = selectRun2(read, options.run);
11262
+ const selectedRun = selectRun3(read, options.run);
10990
11263
  const check = runTraceChecks(
10991
11264
  { read },
10992
11265
  {
@@ -11023,12 +11296,12 @@ async function artifactsCommand(target, options = {}, stdin = process.stdin) {
11023
11296
  }
11024
11297
  const files = [];
11025
11298
  await promises.mkdir(outputDir, { recursive: true });
11026
- await writeArtifact(outputDir, "trace.json", writeJson2(trace), files);
11027
- await writeArtifact(outputDir, "check.json", writeJson2(check), files);
11299
+ await writeArtifact(outputDir, "trace.json", writeJson3(trace), files);
11300
+ await writeArtifact(outputDir, "check.json", writeJson3(check), files);
11028
11301
  await writeArtifact(
11029
11302
  outputDir,
11030
11303
  "diff.json",
11031
- writeJson2(diff ?? { status: "not_requested", findings: [], diagnostics: [] }),
11304
+ writeJson3(diff ?? { status: "not_requested", findings: [], diagnostics: [] }),
11032
11305
  files
11033
11306
  );
11034
11307
  await writeArtifact(outputDir, "summary.md", renderMarkdown(trace, check, diff), files);
@@ -11058,9 +11331,9 @@ ${renderMarkdown(trace, check, diff)}`, "utf-8");
11058
11331
  ...summaryTarget !== void 0 && summaryTarget.trim() !== "" ? { githubSummary: path10__default.default.resolve(summaryTarget) } : {},
11059
11332
  note: NOTE
11060
11333
  };
11061
- await promises.writeFile(path10__default.default.join(outputDir, "manifest.json"), writeJson2(manifest), "utf-8");
11334
+ await promises.writeFile(path10__default.default.join(outputDir, "manifest.json"), writeJson3(manifest), "utf-8");
11062
11335
  if (options.json === true) {
11063
- console.log(writeJson2(manifest).trimEnd());
11336
+ console.log(writeJson3(manifest).trimEnd());
11064
11337
  } else {
11065
11338
  console.log(`Wrote AgentInspect artifacts to ${outputDir}`);
11066
11339
  console.log(`Status: ${manifest.status}`);
@@ -11279,6 +11552,23 @@ function createCliProgram() {
11279
11552
  ).action((runId, opts) => {
11280
11553
  runCommand(() => reportCommand(runId, opts));
11281
11554
  });
11555
+ program.command("explain").description("Explain a local trace with deterministic facts (no provider calls)").argument("<trace-path-or-run-id>", "trace file, directory, stdin -, or run id").option("--dir <path>", "trace directory for run-id lookup").addOption(
11556
+ new commander.Option("--format <format>", "trace input format").choices([
11557
+ "agent-inspect-jsonl",
11558
+ "openinference-json",
11559
+ "otlp-json"
11560
+ ])
11561
+ ).option("--run <run-id>", "select a run when the trace contains multiple runs").option("--dry-run", "emit only the local facts payload that a provider could receive").option(
11562
+ "--provider <provider>",
11563
+ "reserved for explicit provider explain; currently rejected without network calls"
11564
+ ).option("--json", "print deterministic JSON explanation result").addOption(
11565
+ new commander.Option(
11566
+ "--redaction-profile <profile>",
11567
+ "redaction profile for explanation payload: local, share, strict (default: local)"
11568
+ ).choices(["local", "share", "strict"])
11569
+ ).action((target, opts) => {
11570
+ runCommand(() => explainCommand(target, opts));
11571
+ });
11282
11572
  return program;
11283
11573
  }
11284
11574
  function isPrimaryModule() {