@delegance/cli 0.2.1 → 0.2.2

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
@@ -76,7 +76,7 @@ var path = __toESM(require("path"));
76
76
  var os = __toESM(require("os"));
77
77
 
78
78
  // src/version.ts
79
- var CLI_VERSION = "0.2.1";
79
+ var CLI_VERSION = "0.2.2";
80
80
 
81
81
  // src/utils/config.ts
82
82
  var CONFIG_DIR = path.join(os.homedir(), ".delegance");
@@ -229,6 +229,7 @@ __export(output_exports, {
229
229
  error: () => error,
230
230
  formatCurrency: () => formatCurrency,
231
231
  formatDate: () => formatDate,
232
+ formatDateOnly: () => formatDateOnly,
232
233
  formatFileSize: () => formatFileSize,
233
234
  formatStatus: () => formatStatus,
234
235
  header: () => header,
@@ -236,6 +237,7 @@ __export(output_exports, {
236
237
  json: () => json,
237
238
  keyValue: () => keyValue,
238
239
  output: () => output,
240
+ renderCompactTable: () => renderCompactTable,
239
241
  success: () => success,
240
242
  table: () => table,
241
243
  warn: () => warn
@@ -298,12 +300,28 @@ function formatValue(value) {
298
300
  }
299
301
  return String(value);
300
302
  }
303
+ function visibleWidth(s) {
304
+ return s.replace(/\x1b\[[0-9;]*m/g, "").length;
305
+ }
306
+ function renderCompactTable(headers, rows) {
307
+ const cells = rows.map((r) => headers.map((_, i) => r[i] === null || r[i] === void 0 ? "-" : String(r[i])));
308
+ const widths = headers.map((h, i) => Math.max(visibleWidth(h), ...cells.map((r) => visibleWidth(r[i]))));
309
+ const line = (parts) => ` ${parts.map((p, i) => p + " ".repeat(widths[i] - visibleWidth(p))).join(" ")}`.replace(/\s+$/, "");
310
+ return [
311
+ line(headers.map((h) => import_chalk.default.bold(h))),
312
+ import_chalk.default.dim(line(widths.map((w) => "\u2500".repeat(w)))),
313
+ ...cells.map(line)
314
+ ].join("\n");
315
+ }
301
316
  function table(headers, rows, options = {}) {
317
+ if (options.compact) {
318
+ console.log(renderCompactTable(headers, rows));
319
+ return;
320
+ }
302
321
  const tbl = new import_cli_table3.default({
303
322
  head: headers.map((h) => import_chalk.default.bold(h)),
304
323
  style: {
305
- head: ["cyan"],
306
- compact: options.compact
324
+ head: ["cyan"]
307
325
  }
308
326
  });
309
327
  for (const row of rows) {
@@ -340,6 +358,15 @@ function formatDate(dateStr) {
340
358
  minute: "2-digit"
341
359
  });
342
360
  }
361
+ var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
362
+ function formatDateOnly(iso) {
363
+ if (!iso) return "";
364
+ const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(iso);
365
+ if (!m) return iso;
366
+ const month = MONTHS[Number(m[2]) - 1];
367
+ if (!month) return iso;
368
+ return `${month} ${Number(m[3])}, ${m[1]}`;
369
+ }
343
370
  function formatFileSize(bytes) {
344
371
  if (bytes === void 0) return import_chalk.default.gray("(unknown)");
345
372
  const units = ["B", "KB", "MB", "GB"];
@@ -409,14 +436,26 @@ function noteTraceId(traceId) {
409
436
  if (current && typeof traceId === "string" && TRACE_RE.test(traceId)) current.traceId = traceId;
410
437
  }
411
438
 
439
+ // src/utils/invocation.ts
440
+ var NPX_INVOCATION = "npx -y @delegance/cli";
441
+ function cliInvocation(env = process.env, argv = process.argv) {
442
+ const entry = (argv[1] ?? "").replace(/\\/g, "/");
443
+ if (entry.includes("/_npx/")) return NPX_INVOCATION;
444
+ if (env.npm_command === "exec" && /(^|\/)delegance(\.[cm]?js)?$/.test(entry)) return NPX_INVOCATION;
445
+ return "delegance";
446
+ }
447
+ function cliCommand(rest) {
448
+ return `${cliInvocation()} ${rest}`;
449
+ }
450
+
412
451
  // src/utils/client.ts
413
452
  var PORTAL_URL = "https://portal.delegancebrokerage.com";
414
453
  function getClient() {
415
454
  const apiKey = getApiKey();
416
455
  if (!apiKey) {
417
456
  error("Not authenticated");
418
- info('New to Delegance? Run "delegance signup" to create an account.');
419
- info('Have an API key? Run "delegance auth login", or set DELEGANCE_API_KEY.');
457
+ info(`New to Delegance? Run "${cliInvocation()} signup" to create an account.`);
458
+ info(`Have an API key? Run "${cliInvocation()} auth login", or set DELEGANCE_API_KEY.`);
420
459
  process.exit(1);
421
460
  }
422
461
  return new import_sdk.DeleganceClient({
@@ -428,7 +467,7 @@ function getCompanyId(options) {
428
467
  const companyId = options.company || getConfigValue("defaultCompanyId");
429
468
  if (!companyId) {
430
469
  error("No company specified");
431
- info('Use --company <id> or set a default with "delegance company use <id>"');
470
+ info(`Use --company <id> or set a default with "${cliInvocation()} company use <id>"`);
432
471
  process.exit(1);
433
472
  }
434
473
  return companyId;
@@ -440,9 +479,9 @@ function describeApiError(err) {
440
479
  }
441
480
  if (err instanceof import_sdk.AuthenticationError) {
442
481
  if (err.reason === "key_expired" || err.reason === "key_membership_revoked") {
443
- return { message: `${err.message}${traceSuffix}`, hint: 'Run "delegance auth login" to sign in again.' };
482
+ return { message: `${err.message}${traceSuffix}`, hint: `Run "${cliInvocation()} auth login" to sign in again.` };
444
483
  }
445
- return { message: `${err.message}${traceSuffix}`, hint: 'Check your key with "delegance auth status", or log in again.' };
484
+ return { message: `${err.message}${traceSuffix}`, hint: `Check your key with "${cliInvocation()} auth status", or log in again.` };
446
485
  }
447
486
  if (err instanceof import_sdk.ForbiddenError) {
448
487
  return { message: `${err.message}${traceSuffix}`, hint: "Your API key lacks the scope for this command. Create a key with the right scope in the portal." };
@@ -579,7 +618,7 @@ function exchangeRefusal(err) {
579
618
  case "already_collected":
580
619
  return `The key for this signup was already collected. If you lost it, create a new key at ${PORTAL_URL}/portal/settings/api-keys`;
581
620
  case "expired":
582
- return 'This signup expired (24 hours). Run "delegance signup" again.';
621
+ return `This signup expired (24 hours). Run "${cliInvocation()} signup" again.`;
583
622
  default:
584
623
  return null;
585
624
  }
@@ -609,14 +648,14 @@ function storeOrPrintKey(apiKey, store = storeApiKey) {
609
648
  return true;
610
649
  } catch (err) {
611
650
  error(`Could not save the key to ~/.delegance/credentials: ${err.message}`);
612
- warn('Your key is below. It is shown once. Save it now, then run "delegance auth login --key <key>".');
651
+ warn(`Your key is below. It is shown once. Save it now, then run "${cliInvocation()} auth login --key <key>".`);
613
652
  console.log(apiKey);
614
653
  return false;
615
654
  }
616
655
  }
617
656
  async function waitAndStore(pending, timeoutMs) {
618
657
  const signup = (0, import_sdk2.createSignup)({ baseUrl: pending.baseUrl });
619
- const spinner = (0, import_ora.default)(`Waiting for you to click the link sent to ${pending.email} (Ctrl-C is safe: resume with "delegance verify")`).start();
658
+ const spinner = (0, import_ora.default)(`Waiting for you to click the link sent to ${pending.email} (Ctrl-C is safe: resume with "${cliInvocation()} verify")`).start();
620
659
  const started = Date.now();
621
660
  try {
622
661
  const result = await signup.waitForKey(pending.enrollmentId, pending.deviceSecret, {
@@ -628,7 +667,7 @@ async function waitAndStore(pending, timeoutMs) {
628
667
  });
629
668
  if (result.status !== "ready") {
630
669
  spinner.warn("Still waiting on the email confirmation.");
631
- info('Run "delegance verify" after you click the link.');
670
+ info(`Run "${cliInvocation()} verify" after you click the link.`);
632
671
  return;
633
672
  }
634
673
  spinner.stop();
@@ -636,7 +675,7 @@ async function waitAndStore(pending, timeoutMs) {
636
675
  setConfig("defaultCompanyId", result.companyId);
637
676
  clearPendingSignup();
638
677
  if (stored) success(`Verified. API key ${maskApiKey(result.apiKey)} saved to ~/.delegance/credentials`);
639
- success("You can quote now: delegance quote start --coverage gl");
678
+ success(`You can quote now: ${cliInvocation()} quote start --coverage gl`);
640
679
  } catch (err) {
641
680
  spinner.stop();
642
681
  const why = exchangeRefusal(err);
@@ -670,7 +709,7 @@ function createSignupCommand() {
670
709
  const existing = loadPendingSignup();
671
710
  if (existing) {
672
711
  warn(`A signup for ${existing.email} is already waiting for its email confirmation.`);
673
- info('Run "delegance verify" to finish it, or "delegance verify --cancel" to start over.');
712
+ info(`Run "${cliInvocation()} verify" to finish it, or "${cliInvocation()} verify --cancel" to start over.`);
674
713
  process.exit(1);
675
714
  }
676
715
  if (!(process.stdin.isTTY && process.stdout.isTTY)) {
@@ -735,7 +774,7 @@ function createSignupCommand() {
735
774
  warn("We could not save your business address. Add it in the portal before quoting, or carriers cannot price you.");
736
775
  }
737
776
  if (options.wait === false) {
738
- info('After you click it, run "delegance verify" to collect your API key.');
777
+ info(`After you click it, run "${cliInvocation()} verify" to collect your API key.`);
739
778
  return;
740
779
  }
741
780
  await waitAndStore(pending, Number(options.timeout) * 6e4 || 15 * 6e4);
@@ -756,7 +795,7 @@ function createVerifyCommand() {
756
795
  return new import_commander.Command("verify").description("Finish a signup: wait for the email click and store your API key").option("--resend", "Send the confirm email again").option("--cancel", "Forget the in-progress signup on this machine").option("--timeout <minutes>", "How long to wait", "15").action(async (options) => {
757
796
  const pending = loadPendingSignup();
758
797
  if (!pending) {
759
- info('No signup is waiting on this machine. Start one with "delegance signup".');
798
+ info(`No signup is waiting on this machine. Start one with "${cliInvocation()} signup".`);
760
799
  return;
761
800
  }
762
801
  if (options.cancel) {
@@ -818,9 +857,9 @@ function deviceLoginRefusal(err) {
818
857
  case "access_denied":
819
858
  return "The request was denied in the portal. Nothing was stored.";
820
859
  case "expired":
821
- return 'The code expired before it was approved. Run "delegance auth login" again.';
860
+ return `The code expired before it was approved. Run "${cliInvocation()} auth login" again.`;
822
861
  case "already_collected":
823
- return 'This login was already used. Run "delegance auth login" again.';
862
+ return `This login was already used. Run "${cliInvocation()} auth login" again.`;
824
863
  default:
825
864
  return null;
826
865
  }
@@ -829,7 +868,7 @@ function notAvailable(err) {
829
868
  return err instanceof import_sdk3.DeleganceError && (err.statusCode === 404 || err.reason === "not_available");
830
869
  }
831
870
  function pasteFallbackHint() {
832
- info(`Create a key at ${PORTAL_URL}/portal/settings/api-keys, then run "delegance auth login --key <key>".`);
871
+ info(`Create a key at ${PORTAL_URL}/portal/settings/api-keys, then run "${cliInvocation()} auth login --key <key>".`);
833
872
  }
834
873
  async function readKeyInfo(apiKey, timeoutMs = 5e3) {
835
874
  try {
@@ -906,7 +945,7 @@ async function loginWithBrowser(openBrowser) {
906
945
  });
907
946
  if (result.status !== "ready") {
908
947
  spinner.fail("The code expired before it was approved.");
909
- info('Run "delegance auth login" again.');
948
+ info(`Run "${cliInvocation()} auth login" again.`);
910
949
  process.exit(1);
911
950
  }
912
951
  spinner.stop();
@@ -963,7 +1002,7 @@ function createAuthCommand() {
963
1002
  header("Authentication Status");
964
1003
  if (!isAuthenticated()) {
965
1004
  warn("Not authenticated");
966
- info('Run "delegance auth login" to sign in, or "delegance signup" to create an account');
1005
+ info(`Run "${cliInvocation()} auth login" to sign in, or "${cliInvocation()} signup" to create an account`);
967
1006
  return;
968
1007
  }
969
1008
  const apiKey = getApiKey() || "";
@@ -986,7 +1025,7 @@ function createAuthCommand() {
986
1025
  }
987
1026
  if (refused) {
988
1027
  warn(refused);
989
- info('Run "delegance auth login" to sign in again.');
1028
+ info(`Run "${cliInvocation()} auth login" to sign in again.`);
990
1029
  } else {
991
1030
  success("Authenticated");
992
1031
  }
@@ -1004,7 +1043,7 @@ function createAuthCommand() {
1004
1043
  const apiKey = getApiKey();
1005
1044
  if (!apiKey) {
1006
1045
  error("Not authenticated");
1007
- info('Run "delegance auth login" to sign in');
1046
+ info(`Run "${cliInvocation()} auth login" to sign in`);
1008
1047
  process.exit(1);
1009
1048
  }
1010
1049
  const spinner = (0, import_ora2.default)("Refreshing your key...").start();
@@ -1052,7 +1091,7 @@ function createAuthCommand() {
1052
1091
  auth.command("whoami").description("Show current authenticated identity").action(async () => {
1053
1092
  if (!isAuthenticated()) {
1054
1093
  error("Not authenticated");
1055
- info('Run "delegance auth login" to authenticate');
1094
+ info(`Run "${cliInvocation()} auth login" to authenticate`);
1056
1095
  process.exit(1);
1057
1096
  }
1058
1097
  const apiKey = getApiKey();
@@ -1248,7 +1287,7 @@ function createCompanyCommand() {
1248
1287
  const companyId = getConfigValue("defaultCompanyId");
1249
1288
  if (!companyId) {
1250
1289
  info("No default company set");
1251
- info('Use "delegance company use <id>" to set one');
1290
+ info(`Use "${cliInvocation()} company use <id>" to set one`);
1252
1291
  return;
1253
1292
  }
1254
1293
  const client = getClient();
@@ -1522,7 +1561,7 @@ function createDocumentCommand() {
1522
1561
  process.exit(1);
1523
1562
  } else {
1524
1563
  waitSpinner.warn(`Extraction still ${finished.status}`);
1525
- if (!options.json) info(`Run "delegance doc wait ${documentId}" to keep following it`);
1564
+ if (!options.json) info(`Run "${cliInvocation()} doc wait ${documentId}" to keep following it`);
1526
1565
  }
1527
1566
  return;
1528
1567
  }
@@ -1530,7 +1569,7 @@ function createDocumentCommand() {
1530
1569
  json(result);
1531
1570
  } else {
1532
1571
  info(`${result.reprocessesRemaining} reprocess attempts left today`);
1533
- info(`Run "delegance doc wait ${documentId}" to follow it`);
1572
+ info(`Run "${cliInvocation()} doc wait ${documentId}" to follow it`);
1534
1573
  }
1535
1574
  } catch (err) {
1536
1575
  spinner.fail("Failed to reprocess document");
@@ -1678,6 +1717,90 @@ var import_inquirer5 = __toESM(require("inquirer"));
1678
1717
  var import_ora6 = __toESM(require("ora"));
1679
1718
  var import_sdk4 = require("@delegance/sdk");
1680
1719
 
1720
+ // src/utils/coverage-names.ts
1721
+ var NAMES = {
1722
+ // General liability
1723
+ cgl: "General Liability",
1724
+ gl: "General Liability",
1725
+ general_liability: "General Liability",
1726
+ // Workers' comp
1727
+ wc: "Workers' Comp",
1728
+ workers_comp: "Workers' Comp",
1729
+ workers_compensation: "Workers' Comp",
1730
+ // Business owner's policy
1731
+ bop: "Business Owner's Policy",
1732
+ business_owners: "Business Owner's Policy",
1733
+ business_owners_policy: "Business Owner's Policy",
1734
+ // Cyber
1735
+ cyber: "Cyber",
1736
+ cyber_liability: "Cyber",
1737
+ // Professional liability (E&O)
1738
+ mpl: "Professional Liability (E&O)",
1739
+ pl: "Professional Liability (E&O)",
1740
+ pro_liab: "Professional Liability (E&O)",
1741
+ professional_liability: "Professional Liability (E&O)",
1742
+ eo: "Professional Liability (E&O)",
1743
+ e_o: "Professional Liability (E&O)",
1744
+ tech_eo: "Tech E&O",
1745
+ errors_omissions: "Tech E&O",
1746
+ // Auto
1747
+ ca: "Commercial Auto",
1748
+ auto: "Commercial Auto",
1749
+ commercial_auto: "Commercial Auto",
1750
+ // Property
1751
+ cp: "Commercial Property",
1752
+ property: "Commercial Property",
1753
+ commercial_property: "Commercial Property",
1754
+ // Umbrella
1755
+ umbrella: "Umbrella",
1756
+ excess: "Umbrella",
1757
+ commercial_umbrella: "Umbrella",
1758
+ // Builders risk
1759
+ br: "Builders' Risk",
1760
+ builders_risk: "Builders' Risk",
1761
+ // Inland marine and marine
1762
+ im: "Inland Marine",
1763
+ inland_marine: "Inland Marine",
1764
+ marine: "Marine",
1765
+ // Management liability family
1766
+ ml: "Management Liability",
1767
+ management_liability: "Management Liability",
1768
+ do: "Directors and Officers (D&O)",
1769
+ d_o: "Directors and Officers (D&O)",
1770
+ directors_officers: "Directors and Officers (D&O)",
1771
+ epli: "Employment Practices Liability",
1772
+ employment_practices: "Employment Practices Liability",
1773
+ crime: "Crime",
1774
+ fiduciary: "Fiduciary Liability",
1775
+ fiduciary_liability: "Fiduciary Liability",
1776
+ // Everything else on the canonical list
1777
+ product_liability: "Product Liability",
1778
+ liquor_liability: "Liquor Liability",
1779
+ contractors_liability: "Contractors' Liability",
1780
+ equipment_breakdown: "Equipment Breakdown",
1781
+ environmental_liability: "Environmental Liability",
1782
+ healthcare_medical: "Healthcare Medical Liability",
1783
+ life_sciences: "Life Sciences",
1784
+ hospitality_programs: "Hospitality Program",
1785
+ commercial_flood: "Commercial Flood",
1786
+ home_based_business: "Home-Based Business",
1787
+ foreign_package: "Foreign Package",
1788
+ multinational_package: "Multinational Package",
1789
+ political_risk: "Political Risk",
1790
+ trade_credit: "Trade Credit",
1791
+ kidnap_ransom: "Kidnap and Ransom",
1792
+ product_recall: "Product Recall",
1793
+ railroad_liability: "Railroad Liability"
1794
+ };
1795
+ function coverageName(code) {
1796
+ if (code === null || code === void 0) return "";
1797
+ const key = code.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
1798
+ return NAMES[key] ?? code;
1799
+ }
1800
+ function coverageNames(codes) {
1801
+ return codes.map(coverageName).filter(Boolean).join(", ");
1802
+ }
1803
+
1681
1804
  // src/commerce/questions.ts
1682
1805
  var COVERAGE_ALIASES = {
1683
1806
  gl: "general_liability",
@@ -1756,14 +1879,23 @@ function validateAnswers(questions, provided) {
1756
1879
  }
1757
1880
  return { answers, problems };
1758
1881
  }
1882
+ function rowStatus(q) {
1883
+ if (String(q.state).toUpperCase() === "REFERRED") {
1884
+ return q.resultStatus === "needs_info" ? "needs_info" : "referred";
1885
+ }
1886
+ return q.marketStatus || q.state;
1887
+ }
1759
1888
  function sortQuoteRows(quotes) {
1760
1889
  return quotes.map((q) => ({
1761
1890
  carrier: q.carrierName || q.carrierId,
1762
1891
  coverage: q.coverage ?? "",
1763
1892
  premium: q.premium,
1764
- status: q.marketStatus || q.state,
1893
+ status: rowStatus(q),
1765
1894
  bindable: q.bindable === true && q.state === "QUOTED",
1766
- opportunityId: q.opportunityId
1895
+ opportunityId: q.opportunityId,
1896
+ limits: typeof q.limits === "string" && q.limits.trim() ? q.limits : null,
1897
+ deductible: typeof q.deductible === "number" && Number.isFinite(q.deductible) ? q.deductible : null,
1898
+ message: typeof q.message === "string" && q.message.trim() ? q.message.trim() : null
1767
1899
  })).sort((a, b) => {
1768
1900
  if (a.bindable !== b.bindable) return a.bindable ? -1 : 1;
1769
1901
  if (a.premium === null && b.premium === null) return 0;
@@ -1772,8 +1904,50 @@ function sortQuoteRows(quotes) {
1772
1904
  return a.premium - b.premium;
1773
1905
  });
1774
1906
  }
1775
- function cheapestBindable(rows) {
1776
- return rows.find((r) => r.bindable && r.premium !== null) ?? null;
1907
+ function bestPerCoverage(rows) {
1908
+ const best = /* @__PURE__ */ new Map();
1909
+ for (const r of rows) {
1910
+ if (!r.bindable || r.premium === null) continue;
1911
+ const key = coverageName(r.coverage);
1912
+ const cur = best.get(key);
1913
+ if (!cur || r.premium < cur.premium) best.set(key, r);
1914
+ }
1915
+ return [...best.values()].sort((a, b) => a.premium - b.premium);
1916
+ }
1917
+ function groupRowsByCoverage(rows) {
1918
+ const order = /* @__PURE__ */ new Map();
1919
+ rows.forEach((r) => {
1920
+ const key = coverageName(r.coverage);
1921
+ if (!order.has(key)) order.set(key, order.size);
1922
+ });
1923
+ const rank = (r) => order.get(coverageName(r.coverage));
1924
+ return rows.map((r, i) => ({ r, i })).sort((a, b) => rank(a.r) - rank(b.r) || a.i - b.i).map((x) => x.r);
1925
+ }
1926
+ var STATUS_WORDS = {
1927
+ quote: "Quoted",
1928
+ quoted: "Quoted",
1929
+ declined: "Declined",
1930
+ decline: "Declined",
1931
+ quoting: "Pricing",
1932
+ pending: "Pricing",
1933
+ submitted: "Pricing",
1934
+ in_progress: "Pricing",
1935
+ referred: "Referred to an underwriter",
1936
+ refer: "Referred to an underwriter",
1937
+ needs_info: "Needs more info",
1938
+ awaiting_broker_review: "With a broker",
1939
+ broker_review: "With a broker",
1940
+ bind_requested: "Bind requested",
1941
+ bound: "Bound",
1942
+ expired: "Expired",
1943
+ error: "Failed",
1944
+ failed: "Failed"
1945
+ };
1946
+ function quoteStatusWord(status) {
1947
+ const key = status.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_");
1948
+ if (STATUS_WORDS[key]) return STATUS_WORDS[key];
1949
+ const words = key.replace(/_/g, " ").trim();
1950
+ return words ? words.charAt(0).toUpperCase() + words.slice(1) : status;
1777
1951
  }
1778
1952
  function summarizeStatus(s) {
1779
1953
  const quoted = s.carrierQuotes.filter((q) => q.premium !== null).length;
@@ -1823,7 +1997,14 @@ function formatKnown(q, value) {
1823
1997
  }
1824
1998
 
1825
1999
  // src/commerce/demo.ts
1826
- var DEMO_BUSINESS = "Riverbend Bakery (demo), Austin TX, 6 employees";
2000
+ var DEMO_BUSINESS = "Riverbend Bakery (demo), Austin TX";
2001
+ var DEMO_SHORT_LABELS = {
2002
+ annual_revenue: "Annual revenue",
2003
+ employees: "Full-time employees",
2004
+ delivery: "Delivers orders",
2005
+ delivery_vehicles: "Delivery vehicles",
2006
+ claims_5y: "Claims in last 5 years"
2007
+ };
1827
2008
  var DEMO_QUESTIONS = [
1828
2009
  { id: "annual_revenue", label: "Annual revenue (USD)", type: "currency", required: true, prefill: 85e4 },
1829
2010
  { id: "employees", label: "Full-time employees", type: "number", required: true, prefill: 6 },
@@ -1857,6 +2038,7 @@ var DEMO_QUESTIONS = [
1857
2038
  ];
1858
2039
  var DEMO_STATUS = {
1859
2040
  submissionId: "demo-submission",
2041
+ effectiveDate: "2026-11-01",
1860
2042
  coverages: ["general_liability", "workers_comp"],
1861
2043
  expiresAt: null,
1862
2044
  submitted: true,
@@ -1864,19 +2046,24 @@ var DEMO_STATUS = {
1864
2046
  allCarriersResolved: true,
1865
2047
  awaitingBrokerReviewCount: 0,
1866
2048
  carrierQuotes: [
1867
- { opportunityId: "demo-1", carrierId: "CARRIER_A", carrierName: "Carrier A", coverage: "CGL", state: "QUOTED", marketStatus: "quote", premium: 612, quoteNumber: "DEMO-GL-1", bindable: true },
1868
- { opportunityId: "demo-2", carrierId: "CARRIER_B", carrierName: "Carrier B", coverage: "CGL", state: "QUOTED", marketStatus: "quote", premium: 748, quoteNumber: "DEMO-GL-2", bindable: true },
1869
- { opportunityId: "demo-3", carrierId: "CARRIER_C", carrierName: "Carrier C", coverage: "WC", state: "QUOTED", marketStatus: "quote", premium: 1184, quoteNumber: "DEMO-WC-1", bindable: true },
1870
- { opportunityId: "demo-4", carrierId: "CARRIER_D", carrierName: "Carrier D", coverage: "WC", state: "DECLINED", marketStatus: "declined", premium: null, quoteNumber: null, bindable: false }
2049
+ { opportunityId: "demo-1", carrierId: "CARRIER_A", carrierName: "Carrier A", coverage: "CGL", state: "QUOTED", marketStatus: "quote", premium: 612, quoteNumber: "DEMO-GL-1", bindable: true, limits: "$1M per occurrence / $2M aggregate", deductible: 500 },
2050
+ { opportunityId: "demo-2", carrierId: "CARRIER_B", carrierName: "Carrier B", coverage: "CGL", state: "QUOTED", marketStatus: "quote", premium: 748, quoteNumber: "DEMO-GL-2", bindable: true, limits: "$1M per occurrence / $2M aggregate", deductible: 1e3 },
2051
+ { opportunityId: "demo-3", carrierId: "CARRIER_C", carrierName: "Carrier C", coverage: "WC", state: "QUOTED", marketStatus: "quote", premium: 1184, quoteNumber: "DEMO-WC-1", bindable: true, limits: "Statutory / $1M employers liability", deductible: 0 },
2052
+ { opportunityId: "demo-4", carrierId: "CARRIER_D", carrierName: "Carrier D", coverage: "WC", state: "DECLINED", marketStatus: "declined", premium: null, quoteNumber: null, bindable: false, limits: null, deductible: null }
1871
2053
  ]
1872
2054
  };
1873
2055
 
1874
2056
  // src/commands/instant-quote.ts
1875
- function activeRequestLines(err, coverageFlag) {
2057
+ function shellArg(value) {
2058
+ return /^[\w@%+=:,./-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
2059
+ }
2060
+ function activeRequestLines(err, coverageFlag, ctx = {}) {
1876
2061
  if (!(err instanceof import_sdk4.DeleganceError) || err.statusCode !== 409 || !err.body) return null;
1877
2062
  const { body } = err;
1878
2063
  const code = body.message;
1879
- const requote = `delegance quote start --coverage ${coverageFlag} --replace`;
2064
+ const answersArg = ctx.answersFile ? ` --answers ${shellArg(ctx.answersFile)}` : "";
2065
+ const requote = `${cliInvocation()} quote start --coverage ${coverageFlag}${answersArg} --replace`;
2066
+ const replaceCmd = ctx.submit ? `${cliInvocation()} quote submit ${shellArg(ctx.submit.submissionId)} --session-version ${shellArg(ctx.submit.sessionVersion)} --answers ${ctx.answersFile ? shellArg(ctx.answersFile) : "<file>"} --replace` : requote;
1880
2067
  if (code === "active_request_exists") {
1881
2068
  const active = Array.isArray(body.active) ? body.active : [];
1882
2069
  const first = active[0];
@@ -1884,7 +2071,7 @@ function activeRequestLines(err, coverageFlag) {
1884
2071
  const carriers = Array.isArray(first?.carriers) ? first.carriers.map((c) => `${c.carrierId}${c.state ? ` (${c.state.toLowerCase()})` : ""}`).join(", ") : "";
1885
2072
  return [
1886
2073
  `Already with carriers${id ? `: ${id}` : ""}${carriers ? `, ${carriers}` : ""}.`,
1887
- `Check it: ${id ? `delegance quote status ${id}` : "delegance quote status <id>"} Replace it: ${requote}`
2074
+ `Check it: ${id ? `${cliInvocation()} quote status ${id}` : `${cliInvocation()} quote status <id>`} Replace it: ${replaceCmd}`
1888
2075
  ];
1889
2076
  }
1890
2077
  if (code === "replace_conflict") {
@@ -2011,7 +2198,7 @@ function handoffLines(r) {
2011
2198
  if (!r.alreadyHandedOff && r.unansweredRequired > 0) {
2012
2199
  lines.push(`The broker will email you for the ${r.unansweredRequired} answer(s) still missing.`);
2013
2200
  }
2014
- lines.push(`Check it: delegance quote status ${r.submissionId}`);
2201
+ lines.push(`Check it: ${cliInvocation()} quote status ${r.submissionId}`);
2015
2202
  return lines;
2016
2203
  }
2017
2204
  async function runBrokerHandoff(submissionId, instantAnswers, opts) {
@@ -2052,7 +2239,7 @@ async function runBrokerHandoff(submissionId, instantAnswers, opts) {
2052
2239
  process.exit(1);
2053
2240
  }
2054
2241
  } else if (!opts.json && isInteractive() && plan.questions.length > 0) {
2055
- info(`A broker can place ${plan.coverages.join(", ")} with a market that quotes by hand. ${plan.questions.length} application question(s) left.`);
2242
+ info(`A broker can place ${coverageNames(plan.coverages)} with a market that quotes by hand. ${plan.questions.length} application question(s) left.`);
2056
2243
  info("Press Ctrl-C to stop at any point; what you have answered goes to the broker.");
2057
2244
  const onInterrupt = () => {
2058
2245
  complete = false;
@@ -2084,7 +2271,7 @@ async function sendHandoff(submissionId, input, idempotencyKey, asJson) {
2084
2271
  else handoffLines(result).forEach((l) => info(l));
2085
2272
  } catch (err) {
2086
2273
  spinner?.fail("Could not reach a broker");
2087
- console.error(`Try again: delegance quote handoff ${submissionId}`);
2274
+ console.error(`Try again: ${cliInvocation()} quote handoff ${submissionId}`);
2088
2275
  failWith("API error", err);
2089
2276
  }
2090
2277
  }
@@ -2095,8 +2282,34 @@ function printFloorDrops(failures) {
2095
2282
  floors.forEach((f) => console.log(` - ${f.carrierId}: ${f.missing}`));
2096
2283
  info("Add it to your business profile in the portal, then run the quote again.");
2097
2284
  }
2285
+ var AGENT_TIP = "Tip: your AI agent can do this for you. Open Claude Code, Codex, Gemini CLI or any coding agent in a folder with your insurance documents and ask it to get you a quote with npx -y @delegance/cli.";
2286
+ var premiumText = (n) => n === null ? "-" : formatCurrency(n);
2287
+ var deductibleText = (n) => n === null ? "-" : n === 0 ? "None" : formatCurrency(n);
2288
+ function bestPriceLines(best) {
2289
+ if (best.length === 0) return [];
2290
+ const names = best.map((r) => coverageName(r.coverage));
2291
+ const nameW = Math.max(...names.map((n) => n.length));
2292
+ const carrierW = Math.max(...best.map((r) => r.carrier.length));
2293
+ return [
2294
+ "Best price per coverage:",
2295
+ ...best.map((r, i) => ` ${names[i].padEnd(nameW)} ${r.carrier.padEnd(carrierW)} ${formatCurrency(r.premium)}/yr`)
2296
+ ];
2297
+ }
2298
+ function bindHintLines(submissionId, best) {
2299
+ if (best.length === 1) return [`Bind it: ${cliCommand(`bind ${submissionId} ${best[0].opportunityId}`)}`];
2300
+ return best.map((r) => `Bind ${coverageName(r.coverage)}: ${cliCommand(`bind ${submissionId} ${r.opportunityId}`)}`);
2301
+ }
2302
+ function demoClosingLines(best) {
2303
+ const example = best[0] ? ` (e.g. bind ... ${best[0].opportunityId})` : "";
2304
+ return [
2305
+ `Next, on a real quote: ${cliCommand("bind <quote id> <offer>")}${example}`,
2306
+ "DEMO: sample premiums, nothing went to a carrier.",
2307
+ `Get real quotes: ${cliCommand("signup")}`,
2308
+ AGENT_TIP
2309
+ ];
2310
+ }
2098
2311
  function printQuoteTable(status, opts = {}) {
2099
- const rows = sortQuoteRows(status.carrierQuotes);
2312
+ const rows = groupRowsByCoverage(sortQuoteRows(status.carrierQuotes));
2100
2313
  if (rows.length === 0) {
2101
2314
  if (status.brokerReview) {
2102
2315
  info(`A broker has this request (${status.brokerReview.status.replace(/_/g, " ")}). They place it by hand and email you with quotes or questions.`);
@@ -2106,25 +2319,67 @@ function printQuoteTable(status, opts = {}) {
2106
2319
  if (status.awaitingBrokerReviewCount > 0) info(`${status.awaitingBrokerReviewCount} quote(s) are with a broker for review.`);
2107
2320
  return;
2108
2321
  }
2109
- const best = cheapestBindable(rows);
2110
- if (best) {
2111
- console.log(import_chalk2.default.bold(`${opts.demo ? "[DEMO] " : ""}Cheapest bindable: ${best.carrier} ${best.coverage} at ${formatCurrency(best.premium)}/yr`));
2322
+ const best = bestPerCoverage(rows);
2323
+ const bestIds = new Set(best.map((r) => r.opportunityId));
2324
+ const effectiveDate = status.effectiveDate;
2325
+ console.log();
2326
+ if (effectiveDate && opts.showStartDate !== false) {
2327
+ console.log(`Coverage starts ${formatDateOnly(effectiveDate)}`);
2328
+ }
2329
+ const bestLines = bestPriceLines(best);
2330
+ if (bestLines.length) {
2331
+ console.log(import_chalk2.default.bold(bestLines[0]));
2332
+ bestLines.slice(1).forEach((l) => console.log(l));
2333
+ console.log();
2112
2334
  }
2113
2335
  table(
2114
- ["Carrier", "Coverage", "Premium/yr", "Status", "Bindable", "Offer id"],
2336
+ ["Carrier", "Coverage", "Premium/yr", "Limits", "Deductible", "Status", "Offer"],
2115
2337
  rows.map((r) => {
2116
- const cells = [r.carrier, r.coverage, r.premium === null ? "-" : formatCurrency(r.premium), r.status, r.bindable ? "yes" : "no", r.opportunityId];
2117
- return r === best ? cells.map((c) => import_chalk2.default.bold(String(c))) : cells;
2118
- })
2338
+ const cells = [
2339
+ r.carrier,
2340
+ coverageName(r.coverage),
2341
+ premiumText(r.premium),
2342
+ r.limits ?? "-",
2343
+ deductibleText(r.deductible),
2344
+ quoteStatusWord(r.status),
2345
+ r.opportunityId
2346
+ ];
2347
+ return bestIds.has(r.opportunityId) ? cells.map((c) => import_chalk2.default.bold(c)) : cells;
2348
+ }),
2349
+ { compact: true }
2119
2350
  );
2120
- console.log(import_chalk2.default.dim(summarizeStatus(status)));
2121
- if (best && !opts.demo) {
2122
- console.log(import_chalk2.default.green(`Bind it: delegance bind ${status.submissionId} ${best.opportunityId}`));
2351
+ const reasons = rows.filter((r) => r.message);
2352
+ if (reasons.length) {
2353
+ console.log();
2354
+ reasons.forEach((r) => console.log(`${r.carrier} (${quoteStatusWord(r.status)}): ${r.message}`));
2123
2355
  }
2124
- if (opts.demo) console.log(import_chalk2.default.yellow('DEMO: sample premiums, nothing was sent to a carrier. Run "delegance signup" for real quotes.'));
2356
+ console.log();
2357
+ console.log(import_chalk2.default.dim(`${summarizeStatus(status)}.`));
2358
+ if (opts.demo) {
2359
+ const [next, notice, signup, tip] = demoClosingLines(best);
2360
+ console.log(import_chalk2.default.green(next));
2361
+ console.log(import_chalk2.default.yellow(notice));
2362
+ console.log(import_chalk2.default.yellow(signup));
2363
+ console.log(import_chalk2.default.dim(tip));
2364
+ return;
2365
+ }
2366
+ bindHintLines(status.submissionId, best).forEach((l) => console.log(import_chalk2.default.green(l)));
2367
+ }
2368
+ function demoAnswerLines(answers, effectiveDate) {
2369
+ const pairs = [];
2370
+ for (const q of DEMO_QUESTIONS) {
2371
+ if (answers[q.id] === void 0) continue;
2372
+ const v = answers[q.id];
2373
+ const shown = q.type === "currency" && typeof v === "number" ? formatCurrency(v) : formatKnown(q, v);
2374
+ pairs.push([DEMO_SHORT_LABELS[q.id] ?? q.label, shown]);
2375
+ }
2376
+ if (effectiveDate) pairs.push(["Coverage starts", formatDateOnly(effectiveDate)]);
2377
+ const w = Math.max(...pairs.map(([k]) => k.length));
2378
+ return ["Sample answers (a real quote asks you these):", ...pairs.map(([k, v]) => ` ${k.padEnd(w)} ${v}`)];
2125
2379
  }
2126
2380
  async function runDemo(asJson, answersFile) {
2127
2381
  (asJson ? console.error : console.log)(import_chalk2.default.yellow(`DEMO quote for ${DEMO_BUSINESS}. Nothing leaves this machine.`));
2382
+ let printedStart = false;
2128
2383
  if (answersFile) {
2129
2384
  let provided;
2130
2385
  try {
@@ -2142,15 +2397,19 @@ async function runDemo(asJson, answersFile) {
2142
2397
  const mode = answerMode({ demo: true, hasAnswersFile: false, json: asJson, isTTY: isInteractive() });
2143
2398
  if (mode === "prompt") await askQuestions(DEMO_QUESTIONS);
2144
2399
  else {
2145
- suggestedAnswers(DEMO_QUESTIONS);
2146
- if (!asJson) info("No terminal to ask in, so the demo uses its suggested answers.");
2400
+ const assumed = suggestedAnswers(DEMO_QUESTIONS);
2401
+ if (!asJson) {
2402
+ demoAnswerLines(assumed, DEMO_STATUS.effectiveDate).forEach((l) => console.log(l));
2403
+ printedStart = true;
2404
+ }
2147
2405
  }
2148
2406
  }
2149
- const spinner = asJson ? null : (0, import_ora6.default)("Asking carriers (demo)...").start();
2407
+ const spinner = asJson ? null : (0, import_ora6.default)("Asking carriers (demo)...");
2408
+ if (spinner && process.stderr.isTTY) spinner.start();
2150
2409
  await new Promise((resolve) => setTimeout(resolve, asJson ? 0 : 1200));
2151
2410
  spinner?.succeed("4 carriers answered (demo)");
2152
2411
  if (asJson) json({ demo: true, ...DEMO_STATUS });
2153
- else printQuoteTable(DEMO_STATUS, { demo: true });
2412
+ else printQuoteTable(DEMO_STATUS, { demo: true, showStartDate: !printedStart });
2154
2413
  }
2155
2414
  function addInstantQuoteCommands(quote) {
2156
2415
  quote.command("start").description("Get instant quotes from real carriers: answers the questions, files them, waits for premiums").option("-c, --coverage <list>", "Coverages, comma-separated: gl, wc, bop, cyber, pl (E&O), auto, property, umbrella", "gl").option("-a, --answers <file>", "JSON file of answers keyed by question id (skips the prompts)").option("--demo", "Walk the flow on sample data; nothing is sent anywhere").option("--no-wait", 'File the quote and exit; check later with "quote status"').option("--timeout <minutes>", "How long to wait for premiums", "10").option("--replace", "Close the request already with carriers for this coverage and re-quote").option("--json", "Output as JSON").action(async (options) => {
@@ -2215,14 +2474,14 @@ function addInstantQuoteCommands(quote) {
2215
2474
  ...options.replace ? { replace: true } : {}
2216
2475
  });
2217
2476
  } catch (err) {
2218
- const guardLines = activeRequestLines(err, String(options.coverage));
2477
+ const guardLines = activeRequestLines(err, String(options.coverage), { answersFile: options.answers });
2219
2478
  if (guardLines) {
2220
2479
  submitSpinner.fail("Nothing was sent.");
2221
2480
  guardLines.forEach((l) => options.json ? console.error(l) : info(l));
2222
2481
  process.exit(1);
2223
2482
  }
2224
2483
  submitSpinner.fail("Submit failed");
2225
- console.error(`Before trying again, check whether it went through: delegance quote status ${session.submissionId}`);
2484
+ console.error(`Before trying again, check whether it went through: ${cliInvocation()} quote status ${session.submissionId}`);
2226
2485
  failWith("API error", err);
2227
2486
  }
2228
2487
  if (submitted.status === "no_carriers") {
@@ -2238,14 +2497,14 @@ function addInstantQuoteCommands(quote) {
2238
2497
  }
2239
2498
  if (submitted.status === "acord_pending") {
2240
2499
  submitSpinner.succeed("Sent to a broker: these coverages need a person, not an instant quote.");
2241
- info(`Track it with: delegance quote status ${session.submissionId}`);
2500
+ info(`Track it with: ${cliInvocation()} quote status ${session.submissionId}`);
2242
2501
  return;
2243
2502
  }
2244
2503
  submitSpinner.succeed(`Filed with ${submitted.quotes.filter((q) => q.status === "submitted").length} carrier(s).`);
2245
2504
  printFloorDrops(submitted.partialFailures);
2246
2505
  if (submitted.replaceNotice && !options.json) info(submitted.replaceNotice);
2247
2506
  if (options.wait === false) {
2248
- info(`Check premiums with: delegance quote status ${session.submissionId} --wait`);
2507
+ info(`Check premiums with: ${cliInvocation()} quote status ${session.submissionId} --wait`);
2249
2508
  return;
2250
2509
  }
2251
2510
  await waitAndPrint(session.submissionId, Number(options.timeout) * 6e4 || 6e5, !!options.json);
@@ -2274,22 +2533,25 @@ function addInstantQuoteCommands(quote) {
2274
2533
  }
2275
2534
  if (submitted.status !== "submitted") {
2276
2535
  info("Sent to a broker for these coverages.");
2277
- info(`Check it: delegance quote status ${submissionId}`);
2536
+ info(`Check it: ${cliInvocation()} quote status ${submissionId}`);
2278
2537
  return;
2279
2538
  }
2280
2539
  if (options.wait === false) {
2281
- info(`Check premiums with: delegance quote status ${submissionId} --wait`);
2540
+ info(`Check premiums with: ${cliInvocation()} quote status ${submissionId} --wait`);
2282
2541
  return;
2283
2542
  }
2284
2543
  await waitAndPrint(submissionId, Number(options.timeout) * 6e4 || 6e5, !!options.json);
2285
2544
  } catch (err) {
2286
- const guardLines = activeRequestLines(err, "<list>");
2545
+ const guardLines = activeRequestLines(err, "<list>", {
2546
+ answersFile: options.answers,
2547
+ submit: { submissionId, sessionVersion: String(options.sessionVersion) }
2548
+ });
2287
2549
  if (guardLines) {
2288
2550
  error("Nothing was sent.");
2289
2551
  guardLines.forEach((l) => options.json ? console.error(l) : info(l));
2290
2552
  process.exit(1);
2291
2553
  }
2292
- console.error(`Before trying again, check whether it went through: delegance quote status ${submissionId}`);
2554
+ console.error(`Before trying again, check whether it went through: ${cliInvocation()} quote status ${submissionId}`);
2293
2555
  failWith("Submit failed", err);
2294
2556
  }
2295
2557
  });
@@ -2325,7 +2587,7 @@ async function waitAndPrint(submissionId, timeoutMs, asJson) {
2325
2587
  spinner?.stop();
2326
2588
  if (asJson) json(status);
2327
2589
  else printQuoteTable(status);
2328
- if (!status.allCarriersResolved && !asJson) info(`Some carriers are still working. Check again: delegance quote status ${submissionId} --wait`);
2590
+ if (!status.allCarriersResolved && !asJson) info(`Some carriers are still working. Check again: ${cliInvocation()} quote status ${submissionId} --wait`);
2329
2591
  } catch (err) {
2330
2592
  spinner?.fail("Could not read the quote");
2331
2593
  failWith("API error", err);
@@ -2438,13 +2700,13 @@ function createQuoteCommand() {
2438
2700
  }
2439
2701
  console.log();
2440
2702
  info(`Queue IDs: ${result.queueIds.join(", ")}`);
2441
- info('Use "delegance quote list" to check status');
2703
+ info(`Use "${cliInvocation()} quote list" to check status`);
2442
2704
  }
2443
2705
  } catch (err) {
2444
2706
  spinner.fail("Failed to submit quote request");
2445
2707
  if (err instanceof import_sdk5.NotImplementedError) {
2446
2708
  error(QUOTE_SUBMISSION_UNAVAILABLE);
2447
- info("For an instant quote from the terminal: delegance quote start --coverage gl");
2709
+ info(`For an instant quote from the terminal: ${cliInvocation()} quote start --coverage gl`);
2448
2710
  info(`Or start a quote at ${PORTAL_URL}`);
2449
2711
  process.exit(1);
2450
2712
  }
@@ -2602,7 +2864,7 @@ function createPolicyCommand() {
2602
2864
  ["Carrier", "Type", "Policy #", "Expiry", "Status", "Premium"],
2603
2865
  policies.map((p) => [
2604
2866
  p.carrier || "Unknown",
2605
- p.policyType || p.name || "-",
2867
+ (p.policyType ? coverageName(p.policyType) : p.name) || "-",
2606
2868
  p.policyNumber || "-",
2607
2869
  p.expiryDate ? formatDate(p.expiryDate) : "-",
2608
2870
  formatPolicyStatus(p.isActive, p.daysUntilExpiry),
@@ -2636,21 +2898,21 @@ function createPolicyCommand() {
2636
2898
  if (urgent.length > 0) {
2637
2899
  warn(`\u26A0\uFE0F Expiring within 7 days (${urgent.length}):`);
2638
2900
  for (const p of urgent) {
2639
- console.log(` - ${p.carrier} ${p.policyType || p.name} - expires ${formatDate(p.expiryDate)}`);
2901
+ console.log(` - ${p.carrier} ${p.policyType ? coverageName(p.policyType) : p.name} - expires ${formatDate(p.expiryDate)}`);
2640
2902
  }
2641
2903
  console.log();
2642
2904
  }
2643
2905
  if (soon.length > 0) {
2644
2906
  info(`\u{1F4C5} Expiring within 30 days (${soon.length}):`);
2645
2907
  for (const p of soon) {
2646
- console.log(` - ${p.carrier} ${p.policyType || p.name} - expires ${formatDate(p.expiryDate)}`);
2908
+ console.log(` - ${p.carrier} ${p.policyType ? coverageName(p.policyType) : p.name} - expires ${formatDate(p.expiryDate)}`);
2647
2909
  }
2648
2910
  console.log();
2649
2911
  }
2650
2912
  if (later.length > 0) {
2651
2913
  console.log(`\u{1F4C6} Expiring later (${later.length}):`);
2652
2914
  for (const p of later) {
2653
- console.log(` - ${p.carrier} ${p.policyType || p.name} - ${p.daysUntilExpiry} days`);
2915
+ console.log(` - ${p.carrier} ${p.policyType ? coverageName(p.policyType) : p.name} - ${p.daysUntilExpiry} days`);
2654
2916
  }
2655
2917
  }
2656
2918
  }
@@ -2674,11 +2936,11 @@ function createPolicyCommand() {
2674
2936
  } else {
2675
2937
  const { policy: p, coverages } = found;
2676
2938
  console.log();
2677
- header(`${p.carrier} - ${p.policyType || p.name}`);
2939
+ header(`${p.carrier} - ${p.policyType ? coverageName(p.policyType) : p.name}`);
2678
2940
  console.log();
2679
2941
  console.log(` Policy #: ${p.policyNumber || "N/A"}`);
2680
2942
  console.log(` Carrier: ${p.carrier}`);
2681
- console.log(` Type: ${p.policyType || "N/A"}`);
2943
+ console.log(` Type: ${p.policyType ? coverageName(p.policyType) : "N/A"}`);
2682
2944
  console.log(` Effective: ${p.effectiveDate ? formatDate(p.effectiveDate) : "N/A"}`);
2683
2945
  console.log(` Expiry: ${p.expiryDate ? formatDate(p.expiryDate) : "N/A"}`);
2684
2946
  console.log(` Status: ${formatPolicyStatus(p.isActive, p.daysUntilExpiry)}`);
@@ -2729,14 +2991,14 @@ function createPolicyCommand() {
2729
2991
  return;
2730
2992
  }
2731
2993
  if (docs.length === 0) {
2732
- info("No source documents are linked to this policy yet. Upload one with: delegance document upload <file>");
2994
+ info(`No source documents are linked to this policy yet. Upload one with: ${cliInvocation()} document upload <file>`);
2733
2995
  return;
2734
2996
  }
2735
2997
  table(
2736
2998
  ["Document", "File", "Type", "Status", "Added"],
2737
2999
  docs.map((d) => [d.id, d.fileName ?? "-", d.documentType ?? "-", d.status, d.createdAt ? formatDate(d.createdAt) : "-"])
2738
3000
  );
2739
- info("Download one with: delegance document status <documentId>");
3001
+ info(`Download one with: ${cliInvocation()} document status <documentId>`);
2740
3002
  } catch (err) {
2741
3003
  failWith("API error", err);
2742
3004
  }
@@ -2769,9 +3031,9 @@ function createPolicyCommand() {
2769
3031
  await signWithStepUp(client, out.request.id, sig, void 0, void 0);
2770
3032
  } else {
2771
3033
  info(`Sign here: ${out.signatureUrl}`);
2772
- info(`Or sign from here: delegance policy sign ${out.request.id} --signer-name "..." --signer-title "..." --attest`);
3034
+ info(`Or sign from here: ${cliInvocation()} policy sign ${out.request.id} --signer-name "..." --signer-title "..." --attest`);
2773
3035
  }
2774
- info(`Check progress with "delegance policy cancellation ${out.request.id}"`);
3036
+ info(`Check progress with "${cliInvocation()} policy cancellation ${out.request.id}"`);
2775
3037
  } catch (err) {
2776
3038
  spinner.fail("Could not request the cancellation");
2777
3039
  failWith("API error", err);
@@ -2828,7 +3090,7 @@ async function signWithStepUp(client, requestId, sig, stepUpId, presetCode) {
2828
3090
  let code = presetCode;
2829
3091
  if (!code) {
2830
3092
  if (!process.stdin.isTTY) {
2831
- warn(`No terminal to type the code in. Finish with: delegance policy sign ${requestId} --signer-name "${sig.signerName}" --signer-title "${sig.signerTitle}" --attest --step-up ${id} --code <code>`);
3093
+ warn(`No terminal to type the code in. Finish with: ${cliInvocation()} policy sign ${requestId} --signer-name "${sig.signerName}" --signer-title "${sig.signerTitle}" --attest --step-up ${id} --code <code>`);
2832
3094
  return;
2833
3095
  }
2834
3096
  const answer = await import_inquirer7.default.prompt([{
@@ -2878,7 +3140,7 @@ function createCOICommand() {
2878
3140
  policiesSpinner.stop();
2879
3141
  if (policies.length === 0) {
2880
3142
  error("No active policies found");
2881
- info('Upload policy documents first with "delegance doc upload"');
3143
+ info(`Upload policy documents first with "${cliInvocation()} doc upload"`);
2882
3144
  process.exit(1);
2883
3145
  }
2884
3146
  const answers = await import_inquirer8.default.prompt([
@@ -2887,7 +3149,7 @@ function createCOICommand() {
2887
3149
  name: "selectedPolicies",
2888
3150
  message: "Select policies to include:",
2889
3151
  choices: policies.map((p) => ({
2890
- name: `${p.carrier} - ${p.policyType || p.name} (${p.policyNumber || "No #"})`,
3152
+ name: `${p.carrier} - ${p.policyType ? coverageName(p.policyType) : p.name} (${p.policyNumber || "No #"})`,
2891
3153
  value: p.id,
2892
3154
  checked: policyIds.includes(p.id)
2893
3155
  })),
@@ -2974,7 +3236,7 @@ function createCOICommand() {
2974
3236
  console.log();
2975
3237
  console.log("Policies included:");
2976
3238
  for (const p of result.policiesIncluded) {
2977
- console.log(` - ${p.carrier} (${p.policyType})`);
3239
+ console.log(` - ${p.carrier} (${coverageName(p.policyType)})`);
2978
3240
  }
2979
3241
  }
2980
3242
  } catch (err) {
@@ -2990,7 +3252,7 @@ function createCOICommand() {
2990
3252
  spinner.succeed(`Found ${count} COIs`);
2991
3253
  if (cois.length === 0) {
2992
3254
  info("No COIs generated yet");
2993
- info('Generate one with "delegance coi generate --interactive"');
3255
+ info(`Generate one with "${cliInvocation()} coi generate --interactive"`);
2994
3256
  return;
2995
3257
  }
2996
3258
  if (options.json) {
@@ -3067,7 +3329,7 @@ function createSOVCommand() {
3067
3329
  info(`SOV ID: ${result.sovId}`);
3068
3330
  info(`Status: ${result.status}`);
3069
3331
  if (!options.wait) {
3070
- info('Use "delegance sov status <id>" to check parsing progress');
3332
+ info(`Use "${cliInvocation()} sov status <id>" to check parsing progress`);
3071
3333
  }
3072
3334
  }
3073
3335
  } catch (err) {
@@ -3086,7 +3348,7 @@ function createSOVCommand() {
3086
3348
  spinner.succeed(`Found ${count} SOVs`);
3087
3349
  if (sovs.length === 0) {
3088
3350
  info("No SOVs found");
3089
- info('Upload one with "delegance sov upload schedule.xlsx"');
3351
+ info(`Upload one with "${cliInvocation()} sov upload schedule.xlsx"`);
3090
3352
  return;
3091
3353
  }
3092
3354
  if (options.json) {
@@ -3250,7 +3512,7 @@ function createAppetiteCommand() {
3250
3512
  if (!options.wait) {
3251
3513
  spinner.succeed(`Match queued: ${start.jobId}`);
3252
3514
  if (options.json) json(start);
3253
- else info(`Check it with "delegance appetite status ${start.jobId}"`);
3515
+ else info(`Check it with "${cliInvocation()} appetite status ${start.jobId}"`);
3254
3516
  return;
3255
3517
  }
3256
3518
  spinner.text = `Matching appetite (about ${start.estimatedSeconds}s)...`;
@@ -3396,7 +3658,7 @@ function createKnowledgeCommand() {
3396
3658
  );
3397
3659
  }
3398
3660
  if (pagination.hasMore && pagination.nextCursor) {
3399
- info(`More: delegance knowledge notecards --cursor ${pagination.nextCursor}`);
3661
+ info(`More: ${cliInvocation()} knowledge notecards --cursor ${pagination.nextCursor}`);
3400
3662
  }
3401
3663
  } catch (err) {
3402
3664
  spinner.fail("Failed to list notecards");
@@ -3520,7 +3782,7 @@ function createOnboardingCommand() {
3520
3782
  const result = await client.onboarding.requestVerification();
3521
3783
  spinner.succeed(`Verification sent to ${result.sentTo}`);
3522
3784
  if (options.json) json(result);
3523
- else info('Open the link in that email, then check progress with "delegance onboarding state"');
3785
+ else info(`Open the link in that email, then check progress with "${cliInvocation()} onboarding state"`);
3524
3786
  } catch (err) {
3525
3787
  spinner.fail("Failed to request verification");
3526
3788
  failWith("API error", err);
@@ -3645,6 +3907,11 @@ var import_ora16 = __toESM(require("ora"));
3645
3907
  var import_crypto3 = require("crypto");
3646
3908
  var import_sdk6 = require("@delegance/sdk");
3647
3909
  var KEYS_PORTAL_URL = `${PORTAL_URL}/portal/settings/api-keys`;
3910
+ function parseExpiresInDays(raw) {
3911
+ if (raw === void 0 || raw === "") return void 0;
3912
+ if (raw.trim().toLowerCase() === "never") return "never";
3913
+ return parseInt(raw, 10);
3914
+ }
3648
3915
  function parseScopes(raw) {
3649
3916
  const parts = (Array.isArray(raw) ? raw : [raw ?? "read,write"]).flatMap((p) => p.split(/[\s,]+/)).map((p) => p.trim()).filter(Boolean);
3650
3917
  const unknown = parts.filter((p) => !import_sdk6.API_KEY_SCOPES.includes(p));
@@ -3653,8 +3920,12 @@ function parseScopes(raw) {
3653
3920
  }
3654
3921
  return Array.from(new Set(parts));
3655
3922
  }
3656
- function replacementExpiryDays(expiresAt, now = /* @__PURE__ */ new Date()) {
3657
- if (!expiresAt) return void 0;
3923
+ var EXPIRING_SCOPES = /* @__PURE__ */ new Set(["write", "admin", "claims:write"]);
3924
+ function isReadOnlyScopeSet(scopes) {
3925
+ return !scopes.some((s) => EXPIRING_SCOPES.has(s));
3926
+ }
3927
+ function replacementExpiryDays(expiresAt, now = /* @__PURE__ */ new Date(), scopes = []) {
3928
+ if (!expiresAt) return isReadOnlyScopeSet(scopes) ? "never" : void 0;
3658
3929
  const ms = new Date(expiresAt).getTime() - now.getTime();
3659
3930
  if (!Number.isFinite(ms)) throw new Error(`Cannot read the old key's expiry "${expiresAt}"; not rotating`);
3660
3931
  const days = Math.ceil(ms / (24 * 60 * 60 * 1e3));
@@ -3703,14 +3974,14 @@ function createKeysCommand() {
3703
3974
  ])
3704
3975
  );
3705
3976
  if (pagination?.hasMore && pagination.nextCursor) {
3706
- info(`More keys: delegance keys list --cursor ${pagination.nextCursor}`);
3977
+ info(`More keys: ${cliInvocation()} keys list --cursor ${pagination.nextCursor}`);
3707
3978
  }
3708
3979
  } catch (err) {
3709
3980
  spinner.fail("Failed to list API keys");
3710
3981
  failWith("API error", err);
3711
3982
  }
3712
3983
  });
3713
- keys.command("create <name>").description("Create an API key (needs a key with the admin scope)").option("-s, --scopes <scopes>", `Comma-separated scopes (${import_sdk6.API_KEY_SCOPES.join(", ")})`, "read,write").option("-e, --expires-in-days <days>", "Expire the key after N days (1-365)").option("--json", "Output as JSON").action(async (name, options) => {
3984
+ keys.command("create <name>").description("Create an API key (needs a key with the admin scope)").option("-s, --scopes <scopes>", `Comma-separated scopes (${import_sdk6.API_KEY_SCOPES.join(", ")})`, "read,write").option("-e, --expires-in-days <days>", 'Expire the key after N days (1-365; default 90), or "never" for a read-only key').option("--json", "Output as JSON").action(async (name, options) => {
3714
3985
  let scopes;
3715
3986
  try {
3716
3987
  scopes = parseScopes(options.scopes);
@@ -3725,7 +3996,7 @@ function createKeysCommand() {
3725
3996
  {
3726
3997
  name,
3727
3998
  scopes,
3728
- expiresInDays: options.expiresInDays ? parseInt(options.expiresInDays) : void 0
3999
+ expiresInDays: parseExpiresInDays(options.expiresInDays)
3729
4000
  },
3730
4001
  { idempotencyKey: (0, import_crypto3.randomUUID)() }
3731
4002
  );
@@ -3760,7 +4031,7 @@ function createKeysCommand() {
3760
4031
  {
3761
4032
  name: `${current2.name} (rotated)`,
3762
4033
  scopes: current2.scopes,
3763
- expiresInDays: replacementExpiryDays(current2.expiresAt)
4034
+ expiresInDays: replacementExpiryDays(current2.expiresAt, /* @__PURE__ */ new Date(), current2.scopes)
3764
4035
  },
3765
4036
  { idempotencyKey: (0, import_crypto3.randomUUID)() }
3766
4037
  );
@@ -3771,6 +4042,9 @@ function createKeysCommand() {
3771
4042
  }
3772
4043
  printCreatedKey(created);
3773
4044
  console.log();
4045
+ if (!current2.expiresAt && !isReadOnlyScopeSet(current2.scopes)) {
4046
+ warn("The old key never expired. Keys that can write must expire now, so the new key lasts 90 days.");
4047
+ }
3774
4048
  warn(`The old key ${current2.prefix} is still active.`);
3775
4049
  info(`Switch your integrations to the new key, then revoke the old one at ${KEYS_PORTAL_URL}`);
3776
4050
  } catch (err) {
@@ -3862,7 +4136,7 @@ function createConfigCommand() {
3862
4136
  currentConfig.clear();
3863
4137
  clearCredentials();
3864
4138
  success("Configuration reset to defaults");
3865
- info('You will need to run "delegance auth login" again');
4139
+ info(`You will need to run "${cliInvocation()} auth login" again`);
3866
4140
  });
3867
4141
  config2.command("env").description("Show environment information").action(() => {
3868
4142
  header("Environment");
@@ -3888,7 +4162,7 @@ function createConfigCommand() {
3888
4162
  info("No profiles configured");
3889
4163
  info("Profiles allow you to switch between different accounts/environments");
3890
4164
  console.log();
3891
- info("Example: delegance config set-profile production --url https://portal.delegancebrokerage.com");
4165
+ info(`Example: ${cliInvocation()} config set-profile production --url https://portal.delegancebrokerage.com`);
3892
4166
  } else {
3893
4167
  for (const [name, profile] of Object.entries(profiles)) {
3894
4168
  const isActive = name === activeProfile;
@@ -3904,7 +4178,7 @@ function createConfigCommand() {
3904
4178
  const profiles = currentConfig.get("profiles") || {};
3905
4179
  if (!profiles[name] && name !== "default") {
3906
4180
  error(`Profile "${name}" not found`);
3907
- info("Create it with: delegance config set-profile <name> --url <base-url>");
4181
+ info(`Create it with: ${cliInvocation()} config set-profile <name> --url <base-url>`);
3908
4182
  process.exit(1);
3909
4183
  }
3910
4184
  currentConfig.set("activeProfile", name);
@@ -3938,7 +4212,7 @@ var import_inquirer10 = __toESM(require("inquirer"));
3938
4212
  var import_sdk7 = require("@delegance/sdk");
3939
4213
  var TYPES = ["bug", "idea", "question"];
3940
4214
  var MESSAGE_MAX = 500;
3941
- var USAGE = 'delegance feedback "what happened" [--type bug|idea|question] [--include-last]';
4215
+ var USAGE = `${cliInvocation()} feedback "what happened" [--type bug|idea|question] [--include-last]`;
3942
4216
  function feedbackInputMode(o) {
3943
4217
  if (o.message && o.message.trim()) return "given";
3944
4218
  return o.isTTY ? "prompt" : "usage_error";
@@ -3989,10 +4263,40 @@ function createFeedbackCommand() {
3989
4263
  });
3990
4264
  }
3991
4265
 
4266
+ // src/utils/checkbox-prompt.ts
4267
+ var import_inquirer11 = __toESM(require("inquirer"));
4268
+ var import_chalk3 = __toESM(require("chalk"));
4269
+ var CHECKBOX_HINT = "(space to select, Enter to continue)";
4270
+ var registered = false;
4271
+ function minimalCheckboxPrompt(Base) {
4272
+ return class MinimalCheckboxPrompt extends Base {
4273
+ constructor(...args) {
4274
+ super(...args);
4275
+ this.dontShowHints = true;
4276
+ }
4277
+ getQuestion() {
4278
+ const question = super.getQuestion();
4279
+ return this.status === "answered" ? question : `${question}${import_chalk3.default.dim(CHECKBOX_HINT)} `;
4280
+ }
4281
+ onAllKey() {
4282
+ }
4283
+ onInverseKey() {
4284
+ }
4285
+ };
4286
+ }
4287
+ function registerMinimalCheckbox() {
4288
+ if (registered) return;
4289
+ const prompts = import_inquirer11.default.prompt.prompts;
4290
+ const Base = prompts?.checkbox;
4291
+ if (!Base) return;
4292
+ import_inquirer11.default.registerPrompt("checkbox", minimalCheckboxPrompt(Base));
4293
+ registered = true;
4294
+ }
4295
+
3992
4296
  // src/commands/commerce.ts
3993
4297
  var import_commander18 = require("commander");
3994
4298
  var fs7 = __toESM(require("fs"));
3995
- var import_inquirer11 = __toESM(require("inquirer"));
4299
+ var import_inquirer12 = __toESM(require("inquirer"));
3996
4300
  var import_ora17 = __toESM(require("ora"));
3997
4301
  var import_sdk8 = require("@delegance/sdk");
3998
4302
  function formatCents(cents2, currency = "usd") {
@@ -4020,9 +4324,29 @@ function describeBindResult(r) {
4020
4324
  lines.push(r.next);
4021
4325
  return lines;
4022
4326
  }
4327
+ function exactDollars(cents2) {
4328
+ return `$${(cents2 / 100).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
4329
+ }
4330
+ function describeFinancing(f) {
4331
+ if (!f || !f.available) return [];
4332
+ const lines = [];
4333
+ if (f.checkoutUrl) {
4334
+ lines.push(`Pay over time with ${f.lender}: ${f.checkoutUrl}`);
4335
+ } else {
4336
+ lines.push(`Financing with ${f.lender} opens once your broker confirms the final premium.`);
4337
+ }
4338
+ const t = f.terms;
4339
+ if (t && t.aprBps !== null && t.downPaymentCents !== null && t.installmentCents !== null && t.numberOfInstallments !== null) {
4340
+ lines.push(
4341
+ `Lender terms: ${(t.aprBps / 100).toFixed(2)}% APR, ${exactDollars(t.downPaymentCents)} down, ${t.numberOfInstallments} payments of ${exactDollars(t.installmentCents)}.`
4342
+ );
4343
+ }
4344
+ lines.push(f.disclosure);
4345
+ return lines;
4346
+ }
4023
4347
  async function askCode() {
4024
4348
  if (!process.stdin.isTTY) return null;
4025
- const answer = await import_inquirer11.default.prompt([{
4349
+ const answer = await import_inquirer12.default.prompt([{
4026
4350
  type: "input",
4027
4351
  name: "code",
4028
4352
  message: "Code from your email:",
@@ -4035,7 +4359,7 @@ function createBindCommand() {
4035
4359
  const client = getClient();
4036
4360
  let attest = options.attest === true;
4037
4361
  if (!attest && process.stdin.isTTY && !options.json) {
4038
- const a = await import_inquirer11.default.prompt([{
4362
+ const a = await import_inquirer12.default.prompt([{
4039
4363
  type: "confirm",
4040
4364
  name: "ok",
4041
4365
  message: "Are the answers on this application accurate? Binding relies on them.",
@@ -4043,7 +4367,7 @@ function createBindCommand() {
4043
4367
  }]);
4044
4368
  attest = a.ok === true;
4045
4369
  if (!attest) {
4046
- warn('Not bound. Fix the answers with "delegance quote start", then bind again.');
4370
+ warn(`Not bound. Fix the answers with "${cliInvocation()} quote start", then bind again.`);
4047
4371
  return;
4048
4372
  }
4049
4373
  }
@@ -4059,7 +4383,7 @@ function createBindCommand() {
4059
4383
  info(`We emailed a 6-digit code to ${r.sentTo}. It expires in 10 minutes.`);
4060
4384
  const code = options.code ? String(options.code) : await askCode();
4061
4385
  if (!code) {
4062
- warn(`Finish with: delegance bind ${submissionId} ${offerId} --attest --step-up ${stepUpId} --code <code>`);
4386
+ warn(`Finish with: ${cliInvocation()} bind ${submissionId} ${offerId} --attest --step-up ${stepUpId} --code <code>`);
4063
4387
  return;
4064
4388
  }
4065
4389
  r = await client.instantQuotes.bindWithStepUp(submissionId, offerId, { ...attest ? { attest: true } : {}, stepUpId, code });
@@ -4073,9 +4397,10 @@ function createBindCommand() {
4073
4397
  return;
4074
4398
  }
4075
4399
  if (r.existing) warn(`A bind for this coverage is already open (${r.carrierName}). Showing it.`);
4076
- else if (r.tier !== "A") success(`Bind requested: ${r.carrierName} ${r.coverage}${r.premium === null ? "" : ` at ${formatCurrency(r.premium)}/yr`}`);
4400
+ else if (r.tier !== "A") success(`Bind requested: ${r.carrierName} ${coverageName(r.coverage)}${r.premium === null ? "" : ` at ${formatCurrency(r.premium)}/yr`}`);
4077
4401
  keyValue({ "Bind request": r.bindRequestId, Status: r.status });
4078
4402
  describeBindResult(r).forEach((l) => info(l));
4403
+ describeFinancing(r.financing).forEach((l) => info(l));
4079
4404
  } catch (err) {
4080
4405
  spinner?.stop();
4081
4406
  if (err instanceof import_sdk8.DeleganceError && [400, 403, 409].includes(err.statusCode ?? 0)) {
@@ -4116,7 +4441,7 @@ function createBillingCommand() {
4116
4441
  payments.map((p) => [p.id, formatCents(p.amount, p.currency), p.status, p.dueDate ? formatDate(p.dueDate) : "-", p.description ?? "-"])
4117
4442
  );
4118
4443
  keyValue({ "Open": `${formatCents(sum.openCents)} (${sum.openCount})`, "Paid": formatCents(sum.paidCents) });
4119
- if (sum.openCount > 0) info("Pay one with: delegance pay <paymentId>");
4444
+ if (sum.openCount > 0) info(`Pay one with: ${cliInvocation()} pay <paymentId>`);
4120
4445
  } catch (err) {
4121
4446
  failWith("API error", err);
4122
4447
  }
@@ -4141,7 +4466,7 @@ function createPayCommand() {
4141
4466
  payments.map((p) => [p.id, formatCents(p.amount, p.currency), p.description ?? "", p.payable ? `${p.status} (payable)` : p.status, p.dueDate ? formatDate(p.dueDate) : "-"])
4142
4467
  );
4143
4468
  const next = payments.find((p) => p.payable);
4144
- if (next) info(`Pay it: delegance pay ${next.id}`);
4469
+ if (next) info(`Pay it: ${cliInvocation()} pay ${next.id}`);
4145
4470
  return;
4146
4471
  }
4147
4472
  const { checkoutUrl } = await client.payments.checkout(paymentId);
@@ -4171,14 +4496,14 @@ function bondStartLines(r, ctx = {}) {
4171
4496
  out.push(` ${str(q.key)}: ${str(q.label)}${q.required ? " (required)" : ""}${opts}`);
4172
4497
  });
4173
4498
  }
4174
- out.push(`Answer with: delegance bond answer ${str(r.session_id)} --answers answers.json`);
4499
+ out.push(`Answer with: ${cliInvocation()} bond answer ${str(r.session_id)} --answers answers.json`);
4175
4500
  return out;
4176
4501
  }
4177
4502
  if (Array.isArray(r.candidates) && r.candidates.length) {
4178
4503
  out.push("That name fits more than one bond. Rerun with the exact name:");
4179
4504
  const rawState = (ctx.state ?? "").trim();
4180
4505
  const state = !rawState ? null : /^[A-Za-z]{2}$/.test(rawState) ? rawState.toUpperCase() : shellQuote(rawState);
4181
- r.candidates.forEach((name) => out.push(state ? ` delegance bond quote --state ${state} --bond ${shellQuote(str(name))}` : ` --bond ${shellQuote(str(name))}`));
4506
+ r.candidates.forEach((name) => out.push(state ? ` ${cliInvocation()} bond quote --state ${state} --bond ${shellQuote(str(name))}` : ` --bond ${shellQuote(str(name))}`));
4182
4507
  return out;
4183
4508
  }
4184
4509
  if (r.needsAmount) {
@@ -4233,7 +4558,7 @@ function createBondCommand() {
4233
4558
  if (options.json) json(r);
4234
4559
  else {
4235
4560
  console.log(JSON.stringify(r, null, 2));
4236
- info(`Check it: delegance bond status ${sessionId}`);
4561
+ info(`Check it: ${cliInvocation()} bond status ${sessionId}`);
4237
4562
  }
4238
4563
  } catch (err) {
4239
4564
  failWith("Could not submit the answers", err);
@@ -4310,6 +4635,7 @@ function createClaimCommand() {
4310
4635
 
4311
4636
  // src/program.ts
4312
4637
  function createProgram() {
4638
+ registerMinimalCheckbox();
4313
4639
  const program = new import_commander19.Command();
4314
4640
  program.name("delegance").description("CLI for the Delegance Brokerage platform").version(CLI_VERSION).enablePositionalOptions().option("-v, --verbose", "Enable verbose output").option("--json", "Output in JSON format").hook("preAction", () => {
4315
4641
  migrateLegacyConfigKey();