@kb-labs/cli-commands 2.96.0 → 2.98.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 CHANGED
@@ -11,7 +11,7 @@ import { glob } from 'glob';
11
11
  import { defineSystemCommand, defineSystemCommandGroup } from '@kb-labs/shared-command-kit';
12
12
  import { createRegistry as createRegistry$1, formatDiagnosticReport } from '@kb-labs/core-registry';
13
13
  import { createRequire } from 'module';
14
- import { platform, platformSync } from '@kb-labs/core-runtime';
14
+ import { platform, platformSync, loadPlatformConfig } from '@kb-labs/core-runtime';
15
15
  import { getLogLevel, colors } from '@kb-labs/cli-runtime';
16
16
  import { access, readFile } from 'fs/promises';
17
17
  import { CredentialsManager } from '@kb-labs/cli-runtime/gateway';
@@ -19,8 +19,13 @@ import os from 'os';
19
19
 
20
20
  var __defProp = Object.defineProperty;
21
21
  var __getOwnPropNames = Object.getOwnPropertyNames;
22
- var __esm = (fn, res) => function __init() {
23
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
22
+ var __esm = (fn, res, err) => function __init() {
23
+ if (err) throw err[0];
24
+ try {
25
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
26
+ } catch (e) {
27
+ throw err = [e], e;
28
+ }
24
29
  };
25
30
  var __export = (target, all) => {
26
31
  for (var name in all)
@@ -4468,6 +4473,174 @@ var webhookRevoke = defineSystemCommand({
4468
4473
  return { ok: true };
4469
4474
  }
4470
4475
  });
4476
+ var SENSITIVE_FIELD_PATTERN = /key|secret|token|password|jwt|credential/i;
4477
+ function isSensitiveField(dottedField) {
4478
+ return dottedField.split(".").some((segment) => SENSITIVE_FIELD_PATTERN.test(segment));
4479
+ }
4480
+ var REDACTED = "***REDACTED***";
4481
+ function flatten(prefix, value, out) {
4482
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
4483
+ const entries = Object.entries(value);
4484
+ if (entries.length === 0) {
4485
+ out.push({ field: prefix, value: {} });
4486
+ return;
4487
+ }
4488
+ for (const [key, nested] of entries) {
4489
+ flatten(prefix ? `${prefix}.${key}` : key, nested, out);
4490
+ }
4491
+ return;
4492
+ }
4493
+ out.push({ field: prefix, value });
4494
+ }
4495
+ function redactLeaf(field, value) {
4496
+ if (isSensitiveField(field)) {
4497
+ return REDACTED;
4498
+ }
4499
+ return redactNested(field, value);
4500
+ }
4501
+ function redactNested(fieldPath, value) {
4502
+ if (Array.isArray(value)) {
4503
+ return value.map((item) => redactNested(fieldPath, item));
4504
+ }
4505
+ if (value !== null && typeof value === "object") {
4506
+ const out = {};
4507
+ for (const [key, nested] of Object.entries(value)) {
4508
+ const childPath = fieldPath ? `${fieldPath}.${key}` : key;
4509
+ out[key] = isSensitiveField(childPath) ? REDACTED : redactNested(childPath, nested);
4510
+ }
4511
+ return out;
4512
+ }
4513
+ return value;
4514
+ }
4515
+ var PLATFORM_SCOPE_FIELDS = /* @__PURE__ */ new Set(["platform", "adapters", "adapterOptions", "core", "execution"]);
4516
+ function buildRows(result) {
4517
+ const rows = [];
4518
+ const fieldSources = result.sources.fields ?? {};
4519
+ const defaultOtherSource = result.sameLocation ? "both" : "project";
4520
+ const platformConfig = result.platformConfig;
4521
+ for (const [topField, rawSource] of Object.entries(fieldSources)) {
4522
+ const value = platformConfig[topField];
4523
+ if (value === void 0) {
4524
+ continue;
4525
+ }
4526
+ const source = result.sameLocation ? "both" : rawSource;
4527
+ const leaves = [];
4528
+ flatten(topField, value, leaves);
4529
+ for (const leaf of leaves) {
4530
+ rows.push({ source, field: leaf.field, value: redactLeaf(leaf.field, leaf.value) });
4531
+ }
4532
+ }
4533
+ for (const ignoredField of result.sources.ignoredProjectFields ?? []) {
4534
+ const value = platformConfig[ignoredField];
4535
+ const leaves = [];
4536
+ flatten(ignoredField, value, leaves);
4537
+ for (const leaf of leaves) {
4538
+ rows.push({ source: "ignored", field: leaf.field, value: redactLeaf(leaf.field, leaf.value) });
4539
+ }
4540
+ }
4541
+ const rawPlatformConfig = result.rawPlatformConfig ?? {};
4542
+ const effectiveConfig = result.effectiveConfig ?? {};
4543
+ const otherTopFields = /* @__PURE__ */ new Set([...Object.keys(rawPlatformConfig), ...Object.keys(effectiveConfig)]);
4544
+ for (const topField of otherTopFields) {
4545
+ if (PLATFORM_SCOPE_FIELDS.has(topField)) {
4546
+ continue;
4547
+ }
4548
+ const hasPlatform = rawPlatformConfig[topField] !== void 0;
4549
+ const hasProject = effectiveConfig[topField] !== void 0;
4550
+ let source;
4551
+ let value;
4552
+ if (result.sameLocation) {
4553
+ source = "both";
4554
+ value = hasProject ? effectiveConfig[topField] : rawPlatformConfig[topField];
4555
+ } else if (hasPlatform && hasProject) {
4556
+ source = "both";
4557
+ value = effectiveConfig[topField];
4558
+ } else if (hasProject) {
4559
+ source = defaultOtherSource;
4560
+ value = effectiveConfig[topField];
4561
+ } else {
4562
+ source = "platform";
4563
+ value = rawPlatformConfig[topField];
4564
+ }
4565
+ const leaves = [];
4566
+ flatten(topField, value, leaves);
4567
+ for (const leaf of leaves) {
4568
+ rows.push({ source, field: leaf.field, value: redactLeaf(leaf.field, leaf.value) });
4569
+ }
4570
+ }
4571
+ rows.sort((a, b) => a.source === b.source ? a.field.localeCompare(b.field) : a.source.localeCompare(b.source));
4572
+ return rows;
4573
+ }
4574
+ function formatValue(value) {
4575
+ if (typeof value === "string") {
4576
+ return value;
4577
+ }
4578
+ return JSON.stringify(value);
4579
+ }
4580
+ var configShow = defineSystemCommand({
4581
+ name: "show",
4582
+ description: "Show the effective (merged) platform config with per-field provenance",
4583
+ longDescription: "Resolves the fully-merged platform config (platform root + project overrides) and prints each field alongside where it came from: platform, project, both, or ignored (a project attempt to override a platform-only field). Sensitive values (keys, secrets, tokens, passwords, credentials) are always redacted.",
4584
+ category: "config",
4585
+ aliases: [],
4586
+ examples: generateExamples("config show", "kb", [
4587
+ { flags: {} },
4588
+ { flags: { json: true } }
4589
+ ]),
4590
+ flags: {
4591
+ json: { type: "boolean", description: "Output machine-readable JSON" }
4592
+ },
4593
+ analytics: {
4594
+ command: "config.show",
4595
+ startEvent: "CONFIG_SHOW_STARTED",
4596
+ finishEvent: "CONFIG_SHOW_FINISHED"
4597
+ },
4598
+ async handler(ctx) {
4599
+ const cwd = getContextCwd(ctx);
4600
+ const result = await loadPlatformConfig({ startDir: cwd, loadEnvFile: false });
4601
+ const rows = buildRows(result);
4602
+ return {
4603
+ ok: true,
4604
+ status: "success",
4605
+ rows,
4606
+ sameLocation: result.sameLocation,
4607
+ platformRoot: result.platformRoot,
4608
+ projectRoot: result.projectRoot
4609
+ };
4610
+ },
4611
+ formatter(result, ctx, flags) {
4612
+ const rows = result.rows ?? [];
4613
+ if (flags.json) {
4614
+ ctx.ui?.json?.({
4615
+ sameLocation: result.sameLocation,
4616
+ platformRoot: result.platformRoot,
4617
+ projectRoot: result.projectRoot,
4618
+ fields: rows
4619
+ });
4620
+ return;
4621
+ }
4622
+ if (rows.length === 0) {
4623
+ ctx.ui.success("Effective Config", {
4624
+ sections: [{ header: "Config", items: ["No config fields resolved."] }]
4625
+ });
4626
+ return;
4627
+ }
4628
+ const fieldWidth = Math.max(...rows.map((r) => r.field.length), "FIELD".length);
4629
+ const sourceWidth = Math.max(...rows.map((r) => r.source.length), "SOURCE".length);
4630
+ const lines = [
4631
+ `${"SOURCE".padEnd(sourceWidth)} ${"FIELD".padEnd(fieldWidth)} VALUE`,
4632
+ ...rows.map(
4633
+ (r) => `${r.source.padEnd(sourceWidth)} ${r.field.padEnd(fieldWidth)} ${formatValue(r.value)}`
4634
+ )
4635
+ ];
4636
+ if (result.sameLocation) {
4637
+ lines.push("", "(sameLocation: platform and project resolve to the same file \u2014 merge is a no-op)");
4638
+ }
4639
+ ctx.ui.success("Effective Config", {
4640
+ sections: [{ header: "Config", items: lines }]
4641
+ });
4642
+ }
4643
+ });
4471
4644
 
4472
4645
  // src/commands/system/groups.ts
4473
4646
  var infoGroup = defineSystemCommandGroup("info", "System information commands", [
@@ -4505,6 +4678,9 @@ var webhookGroup = defineSystemCommandGroup("webhook", "Webhook management comma
4505
4678
  webhookList,
4506
4679
  webhookRevoke
4507
4680
  ]);
4681
+ var configGroup = defineSystemCommandGroup("config", "Config inspection commands", [
4682
+ configShow
4683
+ ]);
4508
4684
  var MARKER = "# kb completion";
4509
4685
  var ALIAS_MARKER = "# kb alias";
4510
4686
  var STATIC_FILE = path.join(os.homedir(), ".config", "kb", "completion.zsh");
@@ -4808,6 +4984,7 @@ async function registerBuiltinCommands(input = {}) {
4808
4984
  registry.registerGroup(authGroup);
4809
4985
  registry.registerGroup(platformGroup);
4810
4986
  registry.registerGroup(webhookGroup);
4987
+ registry.registerGroup(configGroup);
4811
4988
  registry.register(createCompletionCommand(registry));
4812
4989
  registry.register(diag);
4813
4990
  try {