@odla-ai/cli 0.35.0 → 0.35.3

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/bin.cjs CHANGED
@@ -347,10 +347,40 @@ var init_handshake_state = __esm({
347
347
  }
348
348
  });
349
349
 
350
+ // src/cached-credential.ts
351
+ function noteCachedCredential(tokenFile) {
352
+ noted = tokenFile;
353
+ }
354
+ function isCredentialRejection(error) {
355
+ const message2 = error instanceof Error ? error.message : String(error ?? "");
356
+ return /\((401|403)\)\s*$/.test(message2.trim());
357
+ }
358
+ function explainRejectedCredential(error) {
359
+ const tokenFile = noted;
360
+ if (!tokenFile || !isCredentialRejection(error)) return null;
361
+ noted = null;
362
+ (0, import_node_fs5.rmSync)(tokenFile, { force: true });
363
+ return [
364
+ "auth: the cached credential was rejected by odla, so it was revoked before its cached expiry.",
365
+ " The usual cause is a newer sign-in for this project: collecting a handshake retires the",
366
+ " principal's other credentials, so a second terminal or worktree supersedes this one.",
367
+ ` Discarded ${tokenFile}; re-run this command to request a fresh approval.`
368
+ ].join("\n");
369
+ }
370
+ var import_node_fs5, noted;
371
+ var init_cached_credential = __esm({
372
+ "src/cached-credential.ts"() {
373
+ "use strict";
374
+ init_cjs_shims();
375
+ import_node_fs5 = require("fs");
376
+ noted = null;
377
+ }
378
+ });
379
+
350
380
  // src/local.ts
351
381
  function readJsonFile(path) {
352
382
  try {
353
- return JSON.parse((0, import_node_fs5.readFileSync)(path, "utf8"));
383
+ return JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8"));
354
384
  } catch {
355
385
  return null;
356
386
  }
@@ -360,10 +390,10 @@ function writePrivateJson(path, value2) {
360
390
  `);
361
391
  }
362
392
  function readCredentials(path) {
363
- if (!(0, import_node_fs5.existsSync)(path)) return null;
393
+ if (!(0, import_node_fs6.existsSync)(path)) return null;
364
394
  let value2;
365
395
  try {
366
- value2 = JSON.parse((0, import_node_fs5.readFileSync)(path, "utf8"));
396
+ value2 = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8"));
367
397
  } catch {
368
398
  throw new Error(`credentials file ${path} is not valid JSON; fix or remove it before provisioning`);
369
399
  }
@@ -394,13 +424,13 @@ function mergeCredential(current, update) {
394
424
  }
395
425
  function ensureGitignore(rootDir, localPaths = []) {
396
426
  const path = (0, import_node_path3.resolve)(rootDir, ".gitignore");
397
- const existing = (0, import_node_fs5.existsSync)(path) ? (0, import_node_fs5.readFileSync)(path, "utf8") : "";
427
+ const existing = (0, import_node_fs6.existsSync)(path) ? (0, import_node_fs6.readFileSync)(path, "utf8") : "";
398
428
  const configured = localPaths.map((localPath) => gitignoreEntry(rootDir, localPath)).filter((line2) => !!line2);
399
429
  const wanted = [.../* @__PURE__ */ new Set([...GITIGNORE_LINES, ...configured])];
400
430
  const missing = wanted.filter((line2) => !existing.split(/\r?\n/).includes(line2));
401
431
  if (missing.length === 0) return;
402
432
  const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
403
- (0, import_node_fs5.writeFileSync)(path, `${existing}${prefix}${missing.join("\n")}
433
+ (0, import_node_fs6.writeFileSync)(path, `${existing}${prefix}${missing.join("\n")}
404
434
  `);
405
435
  }
406
436
  function o11yDevVars(cfg) {
@@ -428,7 +458,7 @@ function writeDevVars(path, credentials, env, o11y) {
428
458
  if (o11y.version) lines.push(`ODLA_O11Y_VERSION="${o11y.version}"`);
429
459
  if (entry.o11yToken) lines.push(`ODLA_O11Y_TOKEN="${entry.o11yToken}"`);
430
460
  }
431
- const existing = (0, import_node_fs5.existsSync)(path) ? (0, import_node_fs5.readFileSync)(path, "utf8") : "";
461
+ const existing = (0, import_node_fs6.existsSync)(path) ? (0, import_node_fs6.readFileSync)(path, "utf8") : "";
432
462
  const retained = existing.split(/\r?\n/).filter((line2) => !isManagedDevVar(line2));
433
463
  while (retained.at(-1) === "") retained.pop();
434
464
  const prefix = retained.length ? `${retained.join("\n")}
@@ -442,11 +472,11 @@ function isManagedDevVar(line2) {
442
472
  return !!match?.[1] && MANAGED_DEV_VARS.has(match[1]);
443
473
  }
444
474
  function writePrivateText(path, text3) {
445
- (0, import_node_fs5.mkdirSync)((0, import_node_path3.dirname)(path), { recursive: true });
475
+ (0, import_node_fs6.mkdirSync)((0, import_node_path3.dirname)(path), { recursive: true });
446
476
  const temporary = `${path}.tmp-${process.pid}-${Date.now()}`;
447
- (0, import_node_fs5.writeFileSync)(temporary, text3, { mode: 384 });
448
- (0, import_node_fs5.chmodSync)(temporary, 384);
449
- (0, import_node_fs5.renameSync)(temporary, path);
477
+ (0, import_node_fs6.writeFileSync)(temporary, text3, { mode: 384 });
478
+ (0, import_node_fs6.chmodSync)(temporary, 384);
479
+ (0, import_node_fs6.renameSync)(temporary, path);
450
480
  }
451
481
  function gitignoreEntry(rootDir, path) {
452
482
  const rel = (0, import_node_path3.relative)((0, import_node_path3.resolve)(rootDir), (0, import_node_path3.resolve)(path));
@@ -457,12 +487,12 @@ function displayPath(path, rootDir = process.cwd()) {
457
487
  const rel = (0, import_node_path3.relative)(rootDir, path);
458
488
  return rel && !rel.startsWith("..") ? rel : path;
459
489
  }
460
- var import_node_fs5, import_node_path3, GITIGNORE_LINES, MANAGED_DEV_VARS;
490
+ var import_node_fs6, import_node_path3, GITIGNORE_LINES, MANAGED_DEV_VARS;
461
491
  var init_local = __esm({
462
492
  "src/local.ts"() {
463
493
  "use strict";
464
494
  init_cjs_shims();
465
- import_node_fs5 = require("fs");
495
+ import_node_fs6 = require("fs");
466
496
  import_node_path3 = require("path");
467
497
  GITIGNORE_LINES = [".odla/*.local.json", ".odla/dev-token.json", ".dev.vars"];
468
498
  MANAGED_DEV_VARS = /* @__PURE__ */ new Set([
@@ -499,6 +529,7 @@ async function getDeveloperToken(cfg, options, doFetch, out, grantRequest = {})
499
529
  }
500
530
  if (cached?.token && cached.platform === audience && (cached.expiresAt ?? 0) > Date.now() + 6e4 && cachedGrantCovers(cached, grantIntent)) {
501
531
  out.error(`auth: using cached developer token (${displayPath(cfg.local.tokenFile, cfg.rootDir)})`);
532
+ noteCachedCredential(cfg.local.tokenFile);
502
533
  return cached.token;
503
534
  }
504
535
  } else {
@@ -638,6 +669,7 @@ var init_token = __esm({
638
669
  import_node_process4 = __toESM(require("process"), 1);
639
670
  init_handshake_approval();
640
671
  init_handshake_state();
672
+ init_cached_credential();
641
673
  init_local();
642
674
  }
643
675
  });
@@ -729,7 +761,7 @@ async function scopedToken(platform, scope, options, doFetch, out) {
729
761
  if (options.cache !== false) {
730
762
  const tokens = cache2?.platform === audience ? { ...cache2.tokens ?? {} } : {};
731
763
  tokens[scope] = { token, expiresAt };
732
- if ((0, import_node_fs6.existsSync)((0, import_node_path4.join)(rootDir, ".git"))) ensureGitignore(rootDir, [tokenFile]);
764
+ if ((0, import_node_fs7.existsSync)((0, import_node_path4.join)(rootDir, ".git"))) ensureGitignore(rootDir, [tokenFile]);
733
765
  writePrivateJson(tokenFile, { platform: audience, email, tokens });
734
766
  out.error(`auth: cached ${scope} grant (${tokenFile}; mode 0600)`);
735
767
  } else {
@@ -737,12 +769,12 @@ async function scopedToken(platform, scope, options, doFetch, out) {
737
769
  }
738
770
  return token;
739
771
  }
740
- var import_node_fs6, import_node_path4, import_node_process6, import_db2, SCOPE_PURPOSE;
772
+ var import_node_fs7, import_node_path4, import_node_process6, import_db2, SCOPE_PURPOSE;
741
773
  var init_admin_ai_auth = __esm({
742
774
  "src/admin-ai-auth.ts"() {
743
775
  "use strict";
744
776
  init_cjs_shims();
745
- import_node_fs6 = require("fs");
777
+ import_node_fs7 = require("fs");
746
778
  import_node_path4 = require("path");
747
779
  import_node_process6 = __toESM(require("process"), 1);
748
780
  import_db2 = require("@odla-ai/db");
@@ -1660,7 +1692,7 @@ var init_monitoring_validation = __esm({
1660
1692
  // src/config.ts
1661
1693
  async function loadProjectConfig(configPath = "odla.config.mjs", options = {}) {
1662
1694
  const resolved = (0, import_node_path5.resolve)(configPath);
1663
- if (!(0, import_node_fs7.existsSync)(resolved)) {
1695
+ if (!(0, import_node_fs8.existsSync)(resolved)) {
1664
1696
  throw new Error(`config not found: ${configPath}. Run "odla-ai init" first or pass --config.`);
1665
1697
  }
1666
1698
  const raw = await loadConfigModule(resolved);
@@ -1695,7 +1727,7 @@ async function resolveDataExport(cfg, value2, names) {
1695
1727
  if (typeof value2 !== "string") return value2;
1696
1728
  const target = (0, import_node_path5.isAbsolute)(value2) ? value2 : (0, import_node_path5.resolve)(cfg.rootDir, value2);
1697
1729
  if (target.endsWith(".json")) {
1698
- return JSON.parse((0, import_node_fs7.readFileSync)(target, "utf8"));
1730
+ return JSON.parse((0, import_node_fs8.readFileSync)(target, "utf8"));
1699
1731
  }
1700
1732
  const mod = await import((0, import_node_url.pathToFileURL)(target).href);
1701
1733
  for (const name of names) {
@@ -1771,7 +1803,7 @@ function validId2(value2) {
1771
1803
  return typeof value2 === "string" && /^[a-z0-9][a-z0-9-]*$/.test(value2);
1772
1804
  }
1773
1805
  async function loadConfigModule(path) {
1774
- if (path.endsWith(".json")) return JSON.parse((0, import_node_fs7.readFileSync)(path, "utf8"));
1806
+ if (path.endsWith(".json")) return JSON.parse((0, import_node_fs8.readFileSync)(path, "utf8"));
1775
1807
  const nonce = `${Date.now()}-${configImportSerial++}`;
1776
1808
  const mod = await import(`${(0, import_node_url.pathToFileURL)(path).href}?reload=${nonce}`);
1777
1809
  const value2 = mod.default ?? mod.config;
@@ -1784,12 +1816,12 @@ function trimSlash(value2) {
1784
1816
  function unique3(values) {
1785
1817
  return [...new Set(values.filter(Boolean))];
1786
1818
  }
1787
- var import_node_fs7, import_node_path5, import_node_url, import_apps, DEFAULT_PLATFORM, DEFAULT_ENVS, DEFAULT_SERVICES, configImportSerial, GOOGLE_CALENDAR_EVENTS_SCOPE;
1819
+ var import_node_fs8, import_node_path5, import_node_url, import_apps, DEFAULT_PLATFORM, DEFAULT_ENVS, DEFAULT_SERVICES, configImportSerial, GOOGLE_CALENDAR_EVENTS_SCOPE;
1788
1820
  var init_config = __esm({
1789
1821
  "src/config.ts"() {
1790
1822
  "use strict";
1791
1823
  init_cjs_shims();
1792
- import_node_fs7 = require("fs");
1824
+ import_node_fs8 = require("fs");
1793
1825
  import_node_path5 = require("path");
1794
1826
  import_node_url = require("url");
1795
1827
  import_apps = require("@odla-ai/apps");
@@ -1868,10 +1900,10 @@ function assertOperatorName(value2, label) {
1868
1900
  }
1869
1901
  }
1870
1902
  function readOperatorProfiles(file) {
1871
- if (!(0, import_node_fs8.existsSync)(file)) return emptyProfiles();
1903
+ if (!(0, import_node_fs9.existsSync)(file)) return emptyProfiles();
1872
1904
  let raw;
1873
1905
  try {
1874
- raw = JSON.parse((0, import_node_fs8.readFileSync)(file, "utf8"));
1906
+ raw = JSON.parse((0, import_node_fs9.readFileSync)(file, "utf8"));
1875
1907
  } catch {
1876
1908
  throw new Error(`operator context file ${file} is not valid JSON`);
1877
1909
  }
@@ -1929,12 +1961,12 @@ function clean(value2) {
1929
1961
  const normalized = value2?.trim();
1930
1962
  return normalized || void 0;
1931
1963
  }
1932
- var import_node_fs8, import_node_os, import_node_path6, import_node_process8;
1964
+ var import_node_fs9, import_node_os, import_node_path6, import_node_process8;
1933
1965
  var init_operator_profiles = __esm({
1934
1966
  "src/operator-profiles.ts"() {
1935
1967
  "use strict";
1936
1968
  init_cjs_shims();
1937
- import_node_fs8 = require("fs");
1969
+ import_node_fs9 = require("fs");
1938
1970
  import_node_os = require("os");
1939
1971
  import_node_path6 = require("path");
1940
1972
  import_node_process8 = __toESM(require("process"), 1);
@@ -1950,7 +1982,7 @@ async function resolveOperatorContext(parsed, options = {}) {
1950
1982
  const configArgument = stringOpt(parsed.options.config) ?? "odla.config.mjs";
1951
1983
  const configPath = (0, import_node_path7.resolve)(configArgument);
1952
1984
  const explicitConfig = parsed.options.config !== void 0;
1953
- const hasConfig = (0, import_node_fs9.existsSync)(configPath);
1985
+ const hasConfig = (0, import_node_fs10.existsSync)(configPath);
1954
1986
  if (!hasConfig && (!options.allowMissingConfig || explicitConfig)) {
1955
1987
  await loadProjectConfig(configArgument);
1956
1988
  }
@@ -2036,12 +2068,12 @@ function clean2(value2) {
2036
2068
  const normalized = value2?.trim();
2037
2069
  return normalized || void 0;
2038
2070
  }
2039
- var import_node_fs9, import_node_path7, import_node_process9, DEFAULT_PLATFORM2;
2071
+ var import_node_fs10, import_node_path7, import_node_process9, DEFAULT_PLATFORM2;
2040
2072
  var init_operator_context = __esm({
2041
2073
  "src/operator-context.ts"() {
2042
2074
  "use strict";
2043
2075
  init_cjs_shims();
2044
- import_node_fs9 = require("fs");
2076
+ import_node_fs10 = require("fs");
2045
2077
  import_node_path7 = require("path");
2046
2078
  import_node_process9 = __toESM(require("process"), 1);
2047
2079
  init_argv();
@@ -2507,7 +2539,7 @@ async function appImport(options) {
2507
2539
  const out = options.stdout ?? console;
2508
2540
  const say = options.json ? (line2) => out.error(line2) : (line2) => out.log(line2);
2509
2541
  const { tenant } = resolveTenant(cfg, options.env);
2510
- const text3 = options.file === "-" ? (options.readStdin ?? (() => (0, import_node_fs10.readFileSync)(0, "utf8")))() : (0, import_node_fs10.readFileSync)(options.file, "utf8");
2542
+ const text3 = options.file === "-" ? (options.readStdin ?? (() => (0, import_node_fs11.readFileSync)(0, "utf8")))() : (0, import_node_fs11.readFileSync)(options.file, "utf8");
2511
2543
  const { format, sources } = (0, import_import.parseImport)(text3, options.ns);
2512
2544
  if (format === "namespace-map" && options.ns) {
2513
2545
  throw new Error("--ns cannot be combined with a {namespace: rows} file \u2014 the file already names each namespace");
@@ -2535,12 +2567,12 @@ ${detail}${more}`);
2535
2567
  }
2536
2568
  return requireStudioHuman(options.configPath, "database import", "database", options.env);
2537
2569
  }
2538
- var import_node_fs10, import_import;
2570
+ var import_node_fs11, import_import;
2539
2571
  var init_app_import = __esm({
2540
2572
  "src/app-import.ts"() {
2541
2573
  "use strict";
2542
2574
  init_cjs_shims();
2543
- import_node_fs10 = require("fs");
2575
+ import_node_fs11 = require("fs");
2544
2576
  import_import = require("@odla-ai/db/import");
2545
2577
  init_config();
2546
2578
  init_human_session();
@@ -3537,7 +3569,7 @@ var init_config_reconcile_digest = __esm({
3537
3569
  function readPlan(path) {
3538
3570
  let value2;
3539
3571
  try {
3540
- const raw = (0, import_node_fs11.readFileSync)(path, "utf8");
3572
+ const raw = (0, import_node_fs12.readFileSync)(path, "utf8");
3541
3573
  if (Buffer.byteLength(raw) > 128 * 1024) throw new Error("plan exceeds 128 KiB");
3542
3574
  value2 = JSON.parse(raw);
3543
3575
  } catch (error) {
@@ -3653,13 +3685,13 @@ function invalidPlan(message2) {
3653
3685
  function record3(value2) {
3654
3686
  return !!value2 && typeof value2 === "object" && !Array.isArray(value2);
3655
3687
  }
3656
- var import_apps3, import_node_fs11, DIGEST, REVISION, OPERATION_ID, ACTION_ID, ENV, SERVICE;
3688
+ var import_apps3, import_node_fs12, DIGEST, REVISION, OPERATION_ID, ACTION_ID, ENV, SERVICE;
3657
3689
  var init_config_operation_validate = __esm({
3658
3690
  "src/config-operation-validate.ts"() {
3659
3691
  "use strict";
3660
3692
  init_cjs_shims();
3661
3693
  import_apps3 = require("@odla-ai/apps");
3662
- import_node_fs11 = require("fs");
3694
+ import_node_fs12 = require("fs");
3663
3695
  init_config_operation_error();
3664
3696
  init_config_reconcile_digest();
3665
3697
  DIGEST = /^sha256:[0-9a-f]{64}$/;
@@ -4477,14 +4509,14 @@ var init_config_reconcile_command = __esm({
4477
4509
  function findWranglerConfig(rootDir) {
4478
4510
  for (const name of WRANGLER_CONFIG_FILES) {
4479
4511
  const path = (0, import_node_path11.join)(rootDir, name);
4480
- if ((0, import_node_fs12.existsSync)(path)) return path;
4512
+ if ((0, import_node_fs13.existsSync)(path)) return path;
4481
4513
  }
4482
4514
  return null;
4483
4515
  }
4484
4516
  function readWranglerConfig(path) {
4485
4517
  if (path.endsWith(".toml")) return null;
4486
4518
  try {
4487
- return JSON.parse(stripJsonComments((0, import_node_fs12.readFileSync)(path, "utf8")));
4519
+ return JSON.parse(stripJsonComments((0, import_node_fs13.readFileSync)(path, "utf8")));
4488
4520
  } catch {
4489
4521
  return null;
4490
4522
  }
@@ -4588,13 +4620,13 @@ function wranglerBulkSecrets(run, opts) {
4588
4620
  ];
4589
4621
  return run("npx", args, { input: JSON.stringify(opts.secrets), cwd: opts.cwd });
4590
4622
  }
4591
- var import_node_child_process2, import_node_fs12, import_node_path11, defaultRunner, WRANGLER_CONFIG_FILES;
4623
+ var import_node_child_process2, import_node_fs13, import_node_path11, defaultRunner, WRANGLER_CONFIG_FILES;
4592
4624
  var init_wrangler = __esm({
4593
4625
  "src/wrangler.ts"() {
4594
4626
  "use strict";
4595
4627
  init_cjs_shims();
4596
4628
  import_node_child_process2 = require("child_process");
4597
- import_node_fs12 = require("fs");
4629
+ import_node_fs13 = require("fs");
4598
4630
  import_node_path11 = require("path");
4599
4631
  defaultRunner = (cmd, args, opts) => new Promise((resolvePromise, reject) => {
4600
4632
  const child = (0, import_node_child_process2.spawn)(cmd, args, { cwd: opts?.cwd, stdio: ["pipe", "pipe", "pipe"] });
@@ -4657,7 +4689,7 @@ function wranglerWarnings(rootDir) {
4657
4689
  const dir = (0, import_node_path12.resolve)(rootDir, assets.directory);
4658
4690
  if (dir === (0, import_node_path12.resolve)(rootDir)) {
4659
4691
  warnings.push(`${label}assets.directory is the project root \u2014 point it at a dedicated build dir (wrangler dev fails with "spawn EBADF")`);
4660
- } else if ((0, import_node_fs13.existsSync)((0, import_node_path12.join)(dir, "node_modules"))) {
4692
+ } else if ((0, import_node_fs14.existsSync)((0, import_node_path12.join)(dir, "node_modules"))) {
4661
4693
  warnings.push(`${label}assets.directory contains node_modules \u2014 wrangler dev's watcher will exhaust file descriptors`);
4662
4694
  }
4663
4695
  }
@@ -4693,12 +4725,12 @@ function o11yProjectWarnings(rootDir) {
4693
4725
  return warnings;
4694
4726
  }
4695
4727
  const main = typeof config.main === "string" ? (0, import_node_path12.resolve)(rootDir, config.main) : null;
4696
- if (!main || !(0, import_node_fs13.existsSync)(main)) {
4728
+ if (!main || !(0, import_node_fs14.existsSync)(main)) {
4697
4729
  warnings.push("cannot verify o11y Worker instrumentation \u2014 wrangler main is missing or unreadable");
4698
4730
  } else {
4699
4731
  let source = "";
4700
4732
  try {
4701
- source = (0, import_node_fs13.readFileSync)(main, "utf8");
4733
+ source = (0, import_node_fs14.readFileSync)(main, "utf8");
4702
4734
  } catch {
4703
4735
  }
4704
4736
  if (!/\bwithObservability\b/.test(source)) {
@@ -4722,18 +4754,18 @@ function calendarProjectWarnings(rootDir) {
4722
4754
  }
4723
4755
  function readPackageJson(rootDir) {
4724
4756
  try {
4725
- return JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path12.join)(rootDir, "package.json"), "utf8"));
4757
+ return JSON.parse((0, import_node_fs14.readFileSync)((0, import_node_path12.join)(rootDir, "package.json"), "utf8"));
4726
4758
  } catch {
4727
4759
  return null;
4728
4760
  }
4729
4761
  }
4730
- var import_node_child_process3, import_node_fs13, import_node_path12, defaultExec;
4762
+ var import_node_child_process3, import_node_fs14, import_node_path12, defaultExec;
4731
4763
  var init_doctor_checks = __esm({
4732
4764
  "src/doctor-checks.ts"() {
4733
4765
  "use strict";
4734
4766
  init_cjs_shims();
4735
4767
  import_node_child_process3 = require("child_process");
4736
- import_node_fs13 = require("fs");
4768
+ import_node_fs14 = require("fs");
4737
4769
  import_node_path12 = require("path");
4738
4770
  init_redact();
4739
4771
  init_local();
@@ -5073,7 +5105,7 @@ function initProject(options) {
5073
5105
  const out = options.stdout ?? console;
5074
5106
  const rootDir = (0, import_node_path13.resolve)(options.rootDir ?? process.cwd());
5075
5107
  const configPath = (0, import_node_path13.resolve)(rootDir, options.configPath ?? "odla.config.mjs");
5076
- if ((0, import_node_fs14.existsSync)(configPath) && !options.force) {
5108
+ if ((0, import_node_fs15.existsSync)(configPath) && !options.force) {
5077
5109
  throw new Error(`${configPath} already exists. Pass --force to overwrite.`);
5078
5110
  }
5079
5111
  if (!/^[a-z0-9][a-z0-9-]*$/.test(options.appId)) {
@@ -5089,10 +5121,10 @@ function initProject(options) {
5089
5121
  }
5090
5122
  }
5091
5123
  const aiProvider = options.aiProvider;
5092
- (0, import_node_fs14.mkdirSync)((0, import_node_path13.dirname)(configPath), { recursive: true });
5093
- (0, import_node_fs14.mkdirSync)((0, import_node_path13.resolve)(rootDir, "src/odla"), { recursive: true });
5094
- (0, import_node_fs14.mkdirSync)((0, import_node_path13.resolve)(rootDir, ".odla"), { recursive: true });
5095
- (0, import_node_fs14.writeFileSync)(configPath, configTemplate({ appId: options.appId, name: options.name, envs, services, aiProvider }));
5124
+ (0, import_node_fs15.mkdirSync)((0, import_node_path13.dirname)(configPath), { recursive: true });
5125
+ (0, import_node_fs15.mkdirSync)((0, import_node_path13.resolve)(rootDir, "src/odla"), { recursive: true });
5126
+ (0, import_node_fs15.mkdirSync)((0, import_node_path13.resolve)(rootDir, ".odla"), { recursive: true });
5127
+ (0, import_node_fs15.writeFileSync)(configPath, configTemplate({ appId: options.appId, name: options.name, envs, services, aiProvider }));
5096
5128
  writeIfMissing((0, import_node_path13.resolve)(rootDir, "src/odla/schema.mjs"), schemaTemplate());
5097
5129
  writeIfMissing((0, import_node_path13.resolve)(rootDir, "src/odla/rules.mjs"), rulesTemplate());
5098
5130
  ensureGitignore(rootDir);
@@ -5101,8 +5133,8 @@ function initProject(options) {
5101
5133
  out.log("updated .gitignore for local odla credentials");
5102
5134
  }
5103
5135
  function writeIfMissing(path, text3) {
5104
- if ((0, import_node_fs14.existsSync)(path)) return;
5105
- (0, import_node_fs14.writeFileSync)(path, text3);
5136
+ if ((0, import_node_fs15.existsSync)(path)) return;
5137
+ (0, import_node_fs15.writeFileSync)(path, text3);
5106
5138
  }
5107
5139
  function configTemplate(input) {
5108
5140
  const calendar = input.services.includes("calendar") ? ` calendar: {
@@ -5205,12 +5237,12 @@ function defaultKeyEnv(provider) {
5205
5237
  function relativeDisplay(path, rootDir) {
5206
5238
  return path.startsWith(rootDir) ? path.slice(rootDir.length + 1) : path;
5207
5239
  }
5208
- var import_node_fs14, import_node_path13, import_apps9;
5240
+ var import_node_fs15, import_node_path13, import_apps9;
5209
5241
  var init_init = __esm({
5210
5242
  "src/init.ts"() {
5211
5243
  "use strict";
5212
5244
  init_cjs_shims();
5213
- import_node_fs14 = require("fs");
5245
+ import_node_fs15 = require("fs");
5214
5246
  import_node_path13 = require("path");
5215
5247
  import_apps9 = require("@odla-ai/apps");
5216
5248
  init_local();
@@ -5559,7 +5591,7 @@ function installSkill(options = {}) {
5559
5591
  plans.set(target, { target, content: content2, boundary, managedMerge });
5560
5592
  };
5561
5593
  const planSkillTree = (targetDir2, boundary = root) => {
5562
- for (const rel of files) plan((0, import_node_path14.join)(targetDir2, rel), (0, import_node_fs15.readFileSync)((0, import_node_path14.join)(sourceDir, rel), "utf8"), false, boundary);
5594
+ for (const rel of files) plan((0, import_node_path14.join)(targetDir2, rel), (0, import_node_fs16.readFileSync)((0, import_node_path14.join)(sourceDir, rel), "utf8"), false, boundary);
5563
5595
  };
5564
5596
  let targetDir;
5565
5597
  if (options.global) {
@@ -5579,7 +5611,7 @@ function installSkill(options = {}) {
5579
5611
  for (const harness of harnesses) rememberTarget(harness, sharedRoot);
5580
5612
  if (harnesses.includes("claude")) {
5581
5613
  for (const skill of skillNames(files)) {
5582
- const canonical2 = (0, import_node_fs15.readFileSync)((0, import_node_path14.join)(sourceDir, skill, "SKILL.md"), "utf8");
5614
+ const canonical2 = (0, import_node_fs16.readFileSync)((0, import_node_path14.join)(sourceDir, skill, "SKILL.md"), "utf8");
5583
5615
  plan((0, import_node_path14.join)(claudeRoot, skill, "SKILL.md"), claudeAdapter(skill, canonical2));
5584
5616
  }
5585
5617
  rememberTarget("claude", claudeRoot);
@@ -5614,11 +5646,11 @@ function installSkill(options = {}) {
5614
5646
  conflicts.push(`${file.target} (redirected by symbolic link ${symlink})`);
5615
5647
  continue;
5616
5648
  }
5617
- if (!(0, import_node_fs15.existsSync)(file.target)) {
5649
+ if (!(0, import_node_fs16.existsSync)(file.target)) {
5618
5650
  writtenPaths.add(file.target);
5619
5651
  continue;
5620
5652
  }
5621
- const current = (0, import_node_fs15.readFileSync)(file.target, "utf8");
5653
+ const current = (0, import_node_fs16.readFileSync)(file.target, "utf8");
5622
5654
  if (current === file.content) {
5623
5655
  unchangedPaths.add(file.target);
5624
5656
  } else if (file.managedMerge || options.force) {
@@ -5635,9 +5667,9 @@ ${conflicts.map((f) => ` - ${f}`).join("\n")}`
5635
5667
  );
5636
5668
  }
5637
5669
  for (const file of plans.values()) {
5638
- if (!(0, import_node_fs15.existsSync)(file.target) || (0, import_node_fs15.readFileSync)(file.target, "utf8") !== file.content) {
5639
- (0, import_node_fs15.mkdirSync)((0, import_node_path14.dirname)(file.target), { recursive: true });
5640
- (0, import_node_fs15.writeFileSync)(file.target, file.content);
5670
+ if (!(0, import_node_fs16.existsSync)(file.target) || (0, import_node_fs16.readFileSync)(file.target, "utf8") !== file.content) {
5671
+ (0, import_node_fs16.mkdirSync)((0, import_node_path14.dirname)(file.target), { recursive: true });
5672
+ (0, import_node_fs16.writeFileSync)(file.target, file.content);
5641
5673
  }
5642
5674
  }
5643
5675
  const skills = skillNames(files);
@@ -5678,9 +5710,9 @@ function normalizeHarnesses(values, global) {
5678
5710
  function managedFileContent(path, block, force, boundary) {
5679
5711
  const symlink = symlinkedComponent(boundary, path);
5680
5712
  if (symlink) throw new Error(`refusing to manage ${path}: symbolic link component ${symlink}`);
5681
- if (!(0, import_node_fs15.existsSync)(path)) return `${block}
5713
+ if (!(0, import_node_fs16.existsSync)(path)) return `${block}
5682
5714
  `;
5683
- const current = (0, import_node_fs15.readFileSync)(path, "utf8");
5715
+ const current = (0, import_node_fs16.readFileSync)(path, "utf8");
5684
5716
  const start = "<!-- odla-ai agent setup:start -->";
5685
5717
  const end = "<!-- odla-ai agent setup:end -->";
5686
5718
  const startAt = current.indexOf(start);
@@ -5709,7 +5741,7 @@ function symlinkedComponent(boundary, target) {
5709
5741
  for (const part of rel.split(import_node_path14.sep).filter(Boolean)) {
5710
5742
  current = (0, import_node_path14.join)(current, part);
5711
5743
  try {
5712
- if ((0, import_node_fs15.lstatSync)(current).isSymbolicLink()) return current;
5744
+ if ((0, import_node_fs16.lstatSync)(current).isSymbolicLink()) return current;
5713
5745
  } catch (error) {
5714
5746
  if (error.code !== "ENOENT") throw error;
5715
5747
  }
@@ -5720,10 +5752,10 @@ function skillNames(files) {
5720
5752
  return [...new Set(files.filter((file) => /(^|[\\/])SKILL\.md$/.test(file)).map((file) => file.split(/[\\/]/)[0]))].sort();
5721
5753
  }
5722
5754
  function listFiles(dir) {
5723
- if (!(0, import_node_fs15.existsSync)(dir)) return [];
5755
+ if (!(0, import_node_fs16.existsSync)(dir)) return [];
5724
5756
  const results = [];
5725
5757
  const walk = (current) => {
5726
- for (const entry of (0, import_node_fs15.readdirSync)(current, { withFileTypes: true })) {
5758
+ for (const entry of (0, import_node_fs16.readdirSync)(current, { withFileTypes: true })) {
5727
5759
  const path = (0, import_node_path14.join)(current, entry.name);
5728
5760
  if (entry.isDirectory()) walk(path);
5729
5761
  else results.push((0, import_node_path14.relative)(dir, path));
@@ -5732,12 +5764,12 @@ function listFiles(dir) {
5732
5764
  walk(dir);
5733
5765
  return results.sort();
5734
5766
  }
5735
- var import_node_fs15, import_node_os2, import_node_path14, import_node_url2, AGENT_HARNESSES;
5767
+ var import_node_fs16, import_node_os2, import_node_path14, import_node_url2, AGENT_HARNESSES;
5736
5768
  var init_skill = __esm({
5737
5769
  "src/skill.ts"() {
5738
5770
  "use strict";
5739
5771
  init_cjs_shims();
5740
- import_node_fs15 = require("fs");
5772
+ import_node_fs16 = require("fs");
5741
5773
  import_node_os2 = require("os");
5742
5774
  import_node_path14 = require("path");
5743
5775
  import_node_url2 = require("url");
@@ -10255,7 +10287,7 @@ var init_code_runtime_config = __esm({
10255
10287
  async function codeConnect(options) {
10256
10288
  const cwd = options.cwd ?? process.cwd();
10257
10289
  const configPath = (0, import_node_path15.resolve)(cwd, options.configPath);
10258
- const cfg = (0, import_node_fs16.existsSync)(configPath) ? await loadProjectConfig(configPath) : null;
10290
+ const cfg = (0, import_node_fs17.existsSync)(configPath) ? await loadProjectConfig(configPath) : null;
10259
10291
  const requestedAppId = options.appId?.trim();
10260
10292
  if (requestedAppId && !/^[a-z0-9][a-z0-9-]{1,62}$/.test(requestedAppId)) {
10261
10293
  throw new Error("--app-id must be a valid odla app id");
@@ -10419,12 +10451,12 @@ function apiFailure(action2, status, value2) {
10419
10451
  function record6(value2) {
10420
10452
  return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
10421
10453
  }
10422
- var import_node_fs16, import_node_os3, import_node_path15;
10454
+ var import_node_fs17, import_node_os3, import_node_path15;
10423
10455
  var init_code_connect = __esm({
10424
10456
  "src/code-connect.ts"() {
10425
10457
  "use strict";
10426
10458
  init_cjs_shims();
10427
- import_node_fs16 = require("fs");
10459
+ import_node_fs17 = require("fs");
10428
10460
  import_node_os3 = require("os");
10429
10461
  import_node_path15 = require("path");
10430
10462
  init_node();
@@ -14408,22 +14440,52 @@ function recordInvocation(parsed) {
14408
14440
  options: Object.entries(parsed.options).map(([name, value2]) => value2 === false ? `no-${name}` : name).sort()
14409
14441
  };
14410
14442
  if (!entry.path.length) return;
14411
- (0, import_node_fs17.appendFileSync)(file, `${JSON.stringify(entry)}
14443
+ (0, import_node_fs18.appendFileSync)(file, `${JSON.stringify(entry)}
14412
14444
  `);
14413
14445
  } catch {
14414
14446
  }
14415
14447
  }
14416
- var import_node_fs17, import_node_process13;
14448
+ var import_node_fs18, import_node_process13;
14417
14449
  var init_record = __esm({
14418
14450
  "src/record.ts"() {
14419
14451
  "use strict";
14420
14452
  init_cjs_shims();
14421
- import_node_fs17 = require("fs");
14453
+ import_node_fs18 = require("fs");
14422
14454
  import_node_process13 = __toESM(require("process"), 1);
14423
14455
  init_surface();
14424
14456
  }
14425
14457
  });
14426
14458
 
14459
+ // src/advisory-output.ts
14460
+ function advisoryCollectingFetch(inner, sink) {
14461
+ return (async (input, init) => {
14462
+ const response2 = await inner(input, init);
14463
+ try {
14464
+ sink.push(...(0, import_apps14.parseAdvisories)(response2));
14465
+ } catch {
14466
+ }
14467
+ return response2;
14468
+ });
14469
+ }
14470
+ function renderAdvisories(out, advisories, env = process.env) {
14471
+ if (env.ODLA_NO_ADVISORIES) return;
14472
+ const seen = /* @__PURE__ */ new Set();
14473
+ for (const advisory of advisories) {
14474
+ const key = `${advisory.code}:${advisory.message}`;
14475
+ if (seen.has(key)) continue;
14476
+ seen.add(key);
14477
+ out.error((0, import_apps14.formatAdvisory)(advisory));
14478
+ }
14479
+ }
14480
+ var import_apps14;
14481
+ var init_advisory_output = __esm({
14482
+ "src/advisory-output.ts"() {
14483
+ "use strict";
14484
+ init_cjs_shims();
14485
+ import_apps14 = require("@odla-ai/apps");
14486
+ }
14487
+ });
14488
+
14427
14489
  // src/runbook-actions.ts
14428
14490
  async function call(ctx, method, path, body) {
14429
14491
  const res = await ctx.doFetch(`${ctx.platformUrl.replace(/\/$/, "")}/registry/pm${path}`, {
@@ -14452,14 +14514,25 @@ async function bySlug(ctx, slug) {
14452
14514
  "GET",
14453
14515
  `/runbook?app=${encodeURIComponent(ctx.appId)}&slug=${encodeURIComponent(slug)}&limit=1`
14454
14516
  );
14455
- const found = page2.records[0];
14456
- if (!found) throw new Error(`no runbook "${slug}" in ${ctx.appId}`);
14457
- return found;
14517
+ const filtered = page2.records.find((record11) => record11.slug === slug);
14518
+ if (filtered) return filtered;
14519
+ const limit = 100;
14520
+ for (let offset = 0; ; offset += limit) {
14521
+ const fallback = await call(
14522
+ ctx,
14523
+ "GET",
14524
+ `/runbook?app=${encodeURIComponent(ctx.appId)}&limit=${limit}&offset=${offset}`
14525
+ );
14526
+ const found = fallback.records.find((record11) => record11.slug === slug);
14527
+ if (found) return found;
14528
+ if (!fallback.records.length || offset + fallback.records.length >= fallback.total) break;
14529
+ }
14530
+ throw new Error(`no runbook "${slug}" in ${ctx.appId}`);
14458
14531
  }
14459
14532
  function readBody(file, inline) {
14460
14533
  if (inline !== void 0) return inline;
14461
14534
  if (file === void 0) throw new Error("supply the new text with --file <path>, --file - (stdin), or --body");
14462
- return (0, import_node_fs18.readFileSync)(file === "-" ? 0 : file, "utf8");
14535
+ return (0, import_node_fs19.readFileSync)(file === "-" ? 0 : file, "utf8");
14463
14536
  }
14464
14537
  async function runbookList(ctx, all, query) {
14465
14538
  const params = new URLSearchParams();
@@ -14538,7 +14611,7 @@ async function runbookRevert(ctx, slug, version) {
14538
14611
  ctx,
14539
14612
  "POST",
14540
14613
  `/runbook/${encodeURIComponent(runbook.id)}/revert`,
14541
- { version }
14614
+ { version, expectedVersion: runbook.version }
14542
14615
  );
14543
14616
  if (ctx.json) return ctx.out.log(JSON.stringify(result, null, 2));
14544
14617
  ctx.out.log(`${slug} reverted to v${version}, now v${result.record?.version ?? runbook.version + 1}`);
@@ -14548,12 +14621,12 @@ async function runbookRemove(ctx, slug) {
14548
14621
  await call(ctx, "DELETE", `/runbook/${encodeURIComponent(runbook.id)}`);
14549
14622
  ctx.out.log(`removed ${slug}`);
14550
14623
  }
14551
- var import_node_fs18, PLATFORM_SCOPE, stamp;
14624
+ var import_node_fs19, PLATFORM_SCOPE, stamp;
14552
14625
  var init_runbook_actions = __esm({
14553
14626
  "src/runbook-actions.ts"() {
14554
14627
  "use strict";
14555
14628
  init_cjs_shims();
14556
- import_node_fs18 = require("fs");
14629
+ import_node_fs19 = require("fs");
14557
14630
  init_version();
14558
14631
  init_runbook_requires();
14559
14632
  PLATFORM_SCOPE = "$platform";
@@ -14586,12 +14659,12 @@ function parseRunbook(text3, slug) {
14586
14659
  };
14587
14660
  }
14588
14661
  function readRunbookDir(dir) {
14589
- if (!(0, import_node_fs19.statSync)(dir, { throwIfNoEntry: false })?.isDirectory()) throw new Error(`not a directory: ${dir}`);
14590
- const files = (0, import_node_fs19.readdirSync)(dir).filter((f) => f.endsWith(".md")).sort();
14662
+ if (!(0, import_node_fs20.statSync)(dir, { throwIfNoEntry: false })?.isDirectory()) throw new Error(`not a directory: ${dir}`);
14663
+ const files = (0, import_node_fs20.readdirSync)(dir).filter((f) => f.endsWith(".md")).sort();
14591
14664
  if (!files.length) throw new Error(`no .md files in ${dir}`);
14592
14665
  return files.map((file) => {
14593
14666
  const slug = (0, import_node_path17.basename)(file, ".md");
14594
- const parsed = parseRunbook((0, import_node_fs19.readFileSync)((0, import_node_path17.join)(dir, file), "utf8"), slug);
14667
+ const parsed = parseRunbook((0, import_node_fs20.readFileSync)((0, import_node_path17.join)(dir, file), "utf8"), slug);
14595
14668
  return { file, slug, ...parsed, words: parsed.body.split(/\s+/).filter(Boolean).length };
14596
14669
  });
14597
14670
  }
@@ -14661,12 +14734,12 @@ async function upsert(ctx, r, visibility) {
14661
14734
  );
14662
14735
  return "updated";
14663
14736
  }
14664
- var import_node_fs19, import_node_path17;
14737
+ var import_node_fs20, import_node_path17;
14665
14738
  var init_runbook_import = __esm({
14666
14739
  "src/runbook-import.ts"() {
14667
14740
  "use strict";
14668
14741
  init_cjs_shims();
14669
- import_node_fs19 = require("fs");
14742
+ import_node_fs20 = require("fs");
14670
14743
  import_node_path17 = require("path");
14671
14744
  init_runbook_actions();
14672
14745
  }
@@ -14846,9 +14919,9 @@ ${body.split("\n").map((line2) => `+${line2}`).join("\n")}
14846
14919
  function manifestLabeller(root) {
14847
14920
  return (workspace) => {
14848
14921
  const manifest = (0, import_node_path18.join)(root, workspace, "package.json");
14849
- if (!(0, import_node_fs20.existsSync)(manifest)) return void 0;
14922
+ if (!(0, import_node_fs21.existsSync)(manifest)) return void 0;
14850
14923
  try {
14851
- const name = JSON.parse((0, import_node_fs20.readFileSync)(manifest, "utf8")).name;
14924
+ const name = JSON.parse((0, import_node_fs21.readFileSync)(manifest, "utf8")).name;
14852
14925
  return typeof name === "string" ? name : void 0;
14853
14926
  } catch {
14854
14927
  return void 0;
@@ -14914,7 +14987,7 @@ function report4(ctx, impacts) {
14914
14987
  async function runbookImpact(ctx, options, deps = {}) {
14915
14988
  const cwd = deps.cwd ?? process.cwd();
14916
14989
  const runGit = deps.runGit ?? gitRunner(cwd);
14917
- const read3 = deps.readRepoFile ?? ((path) => (0, import_node_fs20.readFileSync)((0, import_node_path18.join)(cwd, path), "utf8"));
14990
+ const read3 = deps.readRepoFile ?? ((path) => (0, import_node_fs21.readFileSync)((0, import_node_path18.join)(cwd, path), "utf8"));
14918
14991
  const surfaces = changedSurfaces(collectDiff(runGit, options.base, read3), manifestLabeller(cwd));
14919
14992
  if (!surfaces.length) {
14920
14993
  return ctx.out.log(
@@ -14925,13 +14998,13 @@ async function runbookImpact(ctx, options, deps = {}) {
14925
14998
  if (ctx.json) return ctx.out.log(JSON.stringify({ base: options.base, impacts }, null, 2));
14926
14999
  report4(ctx, impacts);
14927
15000
  }
14928
- var import_node_child_process6, import_node_fs20, import_node_path18, SOURCE3, editHint;
15001
+ var import_node_child_process6, import_node_fs21, import_node_path18, SOURCE3, editHint;
14929
15002
  var init_runbook_impact = __esm({
14930
15003
  "src/runbook-impact.ts"() {
14931
15004
  "use strict";
14932
15005
  init_cjs_shims();
14933
15006
  import_node_child_process6 = require("child_process");
14934
- import_node_fs20 = require("fs");
15007
+ import_node_fs21 = require("fs");
14935
15008
  import_node_path18 = require("path");
14936
15009
  init_runbook_impact_scan();
14937
15010
  init_runbook_actions();
@@ -15101,25 +15174,25 @@ function editText(initial, slug, deps = {}) {
15101
15174
  );
15102
15175
  if (!interactive())
15103
15176
  throw new Error(`cannot open an editor without a terminal \u2014 pass --file <path> or --body "\u2026" instead`);
15104
- const dir = (0, import_node_fs21.mkdtempSync)((0, import_node_path19.join)((0, import_node_os4.tmpdir)(), "odla-runbook-"));
15177
+ const dir = (0, import_node_fs22.mkdtempSync)((0, import_node_path19.join)((0, import_node_os4.tmpdir)(), "odla-runbook-"));
15105
15178
  const file = (0, import_node_path19.join)(dir, `${slug}.md`);
15106
15179
  try {
15107
- (0, import_node_fs21.writeFileSync)(file, initial, { mode: 384 });
15180
+ (0, import_node_fs22.writeFileSync)(file, initial, { mode: 384 });
15108
15181
  const code = defaultRunOrInjected(deps)(editor, file);
15109
15182
  if (code !== 0) throw new Error(`editor "${editor}" exited with ${code}; nothing was written`);
15110
- const edited = (0, import_node_fs21.readFileSync)(file, "utf8");
15183
+ const edited = (0, import_node_fs22.readFileSync)(file, "utf8");
15111
15184
  return edited === initial ? null : edited;
15112
15185
  } finally {
15113
- (0, import_node_fs21.rmSync)(dir, { recursive: true, force: true });
15186
+ (0, import_node_fs22.rmSync)(dir, { recursive: true, force: true });
15114
15187
  }
15115
15188
  }
15116
- var import_node_child_process7, import_node_fs21, import_node_os4, import_node_path19, import_node_process14, EDITOR_ENV, defaultRunOrInjected;
15189
+ var import_node_child_process7, import_node_fs22, import_node_os4, import_node_path19, import_node_process14, EDITOR_ENV, defaultRunOrInjected;
15117
15190
  var init_runbook_editor = __esm({
15118
15191
  "src/runbook-editor.ts"() {
15119
15192
  "use strict";
15120
15193
  init_cjs_shims();
15121
15194
  import_node_child_process7 = require("child_process");
15122
- import_node_fs21 = require("fs");
15195
+ import_node_fs22 = require("fs");
15123
15196
  import_node_os4 = require("os");
15124
15197
  import_node_path19 = require("path");
15125
15198
  import_node_process14 = __toESM(require("process"), 1);
@@ -16100,6 +16173,23 @@ __export(cli_exports, {
16100
16173
  runCli: () => runCli
16101
16174
  });
16102
16175
  async function runCli(argv2 = process.argv.slice(2), dependencies = {}) {
16176
+ const out = redactingOutput(dependencies.stdout ?? console);
16177
+ const advisories = [];
16178
+ const withAdvisoryReader = {
16179
+ ...dependencies,
16180
+ fetch: advisoryCollectingFetch(dependencies.fetch ?? fetch, advisories)
16181
+ };
16182
+ try {
16183
+ return await dispatchCli(argv2, withAdvisoryReader);
16184
+ } catch (error) {
16185
+ const explanation = explainRejectedCredential(error);
16186
+ if (explanation) out.error(explanation);
16187
+ throw error;
16188
+ } finally {
16189
+ renderAdvisories(out, advisories);
16190
+ }
16191
+ }
16192
+ async function dispatchCli(argv2, dependencies) {
16103
16193
  const runtime = {
16104
16194
  ...dependencies,
16105
16195
  stdout: redactingOutput(dependencies.stdout ?? console)
@@ -16289,6 +16379,8 @@ var init_cli = __esm({
16289
16379
  init_monitor_command();
16290
16380
  init_provision();
16291
16381
  init_record();
16382
+ init_advisory_output();
16383
+ init_cached_credential();
16292
16384
  init_redact();
16293
16385
  init_runbook_command();
16294
16386
  init_security_command();