@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.
@@ -24,13 +24,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/bin/delegance.ts
27
- var import_chalk3 = __toESM(require("chalk"));
27
+ var import_chalk4 = __toESM(require("chalk"));
28
28
 
29
29
  // src/program.ts
30
30
  var import_commander19 = require("commander");
31
31
 
32
32
  // src/version.ts
33
- var CLI_VERSION = "0.2.1";
33
+ var CLI_VERSION = "0.2.2";
34
34
 
35
35
  // src/commands/auth.ts
36
36
  var os4 = __toESM(require("os"));
@@ -235,12 +235,28 @@ function formatValue(value) {
235
235
  }
236
236
  return String(value);
237
237
  }
238
+ function visibleWidth(s) {
239
+ return s.replace(/\x1b\[[0-9;]*m/g, "").length;
240
+ }
241
+ function renderCompactTable(headers, rows) {
242
+ const cells = rows.map((r) => headers.map((_, i) => r[i] === null || r[i] === void 0 ? "-" : String(r[i])));
243
+ const widths = headers.map((h, i) => Math.max(visibleWidth(h), ...cells.map((r) => visibleWidth(r[i]))));
244
+ const line = (parts) => ` ${parts.map((p, i) => p + " ".repeat(widths[i] - visibleWidth(p))).join(" ")}`.replace(/\s+$/, "");
245
+ return [
246
+ line(headers.map((h) => import_chalk.default.bold(h))),
247
+ import_chalk.default.dim(line(widths.map((w) => "\u2500".repeat(w)))),
248
+ ...cells.map(line)
249
+ ].join("\n");
250
+ }
238
251
  function table(headers, rows, options = {}) {
252
+ if (options.compact) {
253
+ console.log(renderCompactTable(headers, rows));
254
+ return;
255
+ }
239
256
  const tbl = new import_cli_table3.default({
240
257
  head: headers.map((h) => import_chalk.default.bold(h)),
241
258
  style: {
242
- head: ["cyan"],
243
- compact: options.compact
259
+ head: ["cyan"]
244
260
  }
245
261
  });
246
262
  for (const row of rows) {
@@ -262,6 +278,15 @@ function formatDate(dateStr) {
262
278
  minute: "2-digit"
263
279
  });
264
280
  }
281
+ var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
282
+ function formatDateOnly(iso) {
283
+ if (!iso) return "";
284
+ const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(iso);
285
+ if (!m) return iso;
286
+ const month = MONTHS[Number(m[2]) - 1];
287
+ if (!month) return iso;
288
+ return `${month} ${Number(m[3])}, ${m[1]}`;
289
+ }
265
290
  function formatFileSize(bytes) {
266
291
  if (bytes === void 0) return import_chalk.default.gray("(unknown)");
267
292
  const units = ["B", "KB", "MB", "GB"];
@@ -371,14 +396,26 @@ function installLastCommandRecorder(program2) {
371
396
  });
372
397
  }
373
398
 
399
+ // src/utils/invocation.ts
400
+ var NPX_INVOCATION = "npx -y @delegance/cli";
401
+ function cliInvocation(env = process.env, argv = process.argv) {
402
+ const entry = (argv[1] ?? "").replace(/\\/g, "/");
403
+ if (entry.includes("/_npx/")) return NPX_INVOCATION;
404
+ if (env.npm_command === "exec" && /(^|\/)delegance(\.[cm]?js)?$/.test(entry)) return NPX_INVOCATION;
405
+ return "delegance";
406
+ }
407
+ function cliCommand(rest) {
408
+ return `${cliInvocation()} ${rest}`;
409
+ }
410
+
374
411
  // src/utils/client.ts
375
412
  var PORTAL_URL = "https://portal.delegancebrokerage.com";
376
413
  function getClient() {
377
414
  const apiKey = getApiKey();
378
415
  if (!apiKey) {
379
416
  error("Not authenticated");
380
- info('New to Delegance? Run "delegance signup" to create an account.');
381
- info('Have an API key? Run "delegance auth login", or set DELEGANCE_API_KEY.');
417
+ info(`New to Delegance? Run "${cliInvocation()} signup" to create an account.`);
418
+ info(`Have an API key? Run "${cliInvocation()} auth login", or set DELEGANCE_API_KEY.`);
382
419
  process.exit(1);
383
420
  }
384
421
  return new import_sdk.DeleganceClient({
@@ -390,7 +427,7 @@ function getCompanyId(options) {
390
427
  const companyId = options.company || getConfigValue("defaultCompanyId");
391
428
  if (!companyId) {
392
429
  error("No company specified");
393
- info('Use --company <id> or set a default with "delegance company use <id>"');
430
+ info(`Use --company <id> or set a default with "${cliInvocation()} company use <id>"`);
394
431
  process.exit(1);
395
432
  }
396
433
  return companyId;
@@ -402,9 +439,9 @@ function describeApiError(err) {
402
439
  }
403
440
  if (err instanceof import_sdk.AuthenticationError) {
404
441
  if (err.reason === "key_expired" || err.reason === "key_membership_revoked") {
405
- return { message: `${err.message}${traceSuffix}`, hint: 'Run "delegance auth login" to sign in again.' };
442
+ return { message: `${err.message}${traceSuffix}`, hint: `Run "${cliInvocation()} auth login" to sign in again.` };
406
443
  }
407
- return { message: `${err.message}${traceSuffix}`, hint: 'Check your key with "delegance auth status", or log in again.' };
444
+ return { message: `${err.message}${traceSuffix}`, hint: `Check your key with "${cliInvocation()} auth status", or log in again.` };
408
445
  }
409
446
  if (err instanceof import_sdk.ForbiddenError) {
410
447
  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." };
@@ -541,7 +578,7 @@ function exchangeRefusal(err) {
541
578
  case "already_collected":
542
579
  return `The key for this signup was already collected. If you lost it, create a new key at ${PORTAL_URL}/portal/settings/api-keys`;
543
580
  case "expired":
544
- return 'This signup expired (24 hours). Run "delegance signup" again.';
581
+ return `This signup expired (24 hours). Run "${cliInvocation()} signup" again.`;
545
582
  default:
546
583
  return null;
547
584
  }
@@ -571,14 +608,14 @@ function storeOrPrintKey(apiKey, store = storeApiKey) {
571
608
  return true;
572
609
  } catch (err) {
573
610
  error(`Could not save the key to ~/.delegance/credentials: ${err.message}`);
574
- warn('Your key is below. It is shown once. Save it now, then run "delegance auth login --key <key>".');
611
+ warn(`Your key is below. It is shown once. Save it now, then run "${cliInvocation()} auth login --key <key>".`);
575
612
  console.log(apiKey);
576
613
  return false;
577
614
  }
578
615
  }
579
616
  async function waitAndStore(pending, timeoutMs) {
580
617
  const signup = (0, import_sdk2.createSignup)({ baseUrl: pending.baseUrl });
581
- 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();
618
+ 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();
582
619
  const started = Date.now();
583
620
  try {
584
621
  const result = await signup.waitForKey(pending.enrollmentId, pending.deviceSecret, {
@@ -590,7 +627,7 @@ async function waitAndStore(pending, timeoutMs) {
590
627
  });
591
628
  if (result.status !== "ready") {
592
629
  spinner.warn("Still waiting on the email confirmation.");
593
- info('Run "delegance verify" after you click the link.');
630
+ info(`Run "${cliInvocation()} verify" after you click the link.`);
594
631
  return;
595
632
  }
596
633
  spinner.stop();
@@ -598,7 +635,7 @@ async function waitAndStore(pending, timeoutMs) {
598
635
  setConfig("defaultCompanyId", result.companyId);
599
636
  clearPendingSignup();
600
637
  if (stored) success(`Verified. API key ${maskApiKey(result.apiKey)} saved to ~/.delegance/credentials`);
601
- success("You can quote now: delegance quote start --coverage gl");
638
+ success(`You can quote now: ${cliInvocation()} quote start --coverage gl`);
602
639
  } catch (err) {
603
640
  spinner.stop();
604
641
  const why = exchangeRefusal(err);
@@ -632,7 +669,7 @@ function createSignupCommand() {
632
669
  const existing = loadPendingSignup();
633
670
  if (existing) {
634
671
  warn(`A signup for ${existing.email} is already waiting for its email confirmation.`);
635
- info('Run "delegance verify" to finish it, or "delegance verify --cancel" to start over.');
672
+ info(`Run "${cliInvocation()} verify" to finish it, or "${cliInvocation()} verify --cancel" to start over.`);
636
673
  process.exit(1);
637
674
  }
638
675
  if (!(process.stdin.isTTY && process.stdout.isTTY)) {
@@ -697,7 +734,7 @@ function createSignupCommand() {
697
734
  warn("We could not save your business address. Add it in the portal before quoting, or carriers cannot price you.");
698
735
  }
699
736
  if (options.wait === false) {
700
- info('After you click it, run "delegance verify" to collect your API key.');
737
+ info(`After you click it, run "${cliInvocation()} verify" to collect your API key.`);
701
738
  return;
702
739
  }
703
740
  await waitAndStore(pending, Number(options.timeout) * 6e4 || 15 * 6e4);
@@ -718,7 +755,7 @@ function createVerifyCommand() {
718
755
  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) => {
719
756
  const pending = loadPendingSignup();
720
757
  if (!pending) {
721
- info('No signup is waiting on this machine. Start one with "delegance signup".');
758
+ info(`No signup is waiting on this machine. Start one with "${cliInvocation()} signup".`);
722
759
  return;
723
760
  }
724
761
  if (options.cancel) {
@@ -780,9 +817,9 @@ function deviceLoginRefusal(err) {
780
817
  case "access_denied":
781
818
  return "The request was denied in the portal. Nothing was stored.";
782
819
  case "expired":
783
- return 'The code expired before it was approved. Run "delegance auth login" again.';
820
+ return `The code expired before it was approved. Run "${cliInvocation()} auth login" again.`;
784
821
  case "already_collected":
785
- return 'This login was already used. Run "delegance auth login" again.';
822
+ return `This login was already used. Run "${cliInvocation()} auth login" again.`;
786
823
  default:
787
824
  return null;
788
825
  }
@@ -791,7 +828,7 @@ function notAvailable(err) {
791
828
  return err instanceof import_sdk3.DeleganceError && (err.statusCode === 404 || err.reason === "not_available");
792
829
  }
793
830
  function pasteFallbackHint() {
794
- info(`Create a key at ${PORTAL_URL}/portal/settings/api-keys, then run "delegance auth login --key <key>".`);
831
+ info(`Create a key at ${PORTAL_URL}/portal/settings/api-keys, then run "${cliInvocation()} auth login --key <key>".`);
795
832
  }
796
833
  async function readKeyInfo(apiKey, timeoutMs = 5e3) {
797
834
  try {
@@ -868,7 +905,7 @@ async function loginWithBrowser(openBrowser) {
868
905
  });
869
906
  if (result.status !== "ready") {
870
907
  spinner.fail("The code expired before it was approved.");
871
- info('Run "delegance auth login" again.');
908
+ info(`Run "${cliInvocation()} auth login" again.`);
872
909
  process.exit(1);
873
910
  }
874
911
  spinner.stop();
@@ -925,7 +962,7 @@ function createAuthCommand() {
925
962
  header("Authentication Status");
926
963
  if (!isAuthenticated()) {
927
964
  warn("Not authenticated");
928
- info('Run "delegance auth login" to sign in, or "delegance signup" to create an account');
965
+ info(`Run "${cliInvocation()} auth login" to sign in, or "${cliInvocation()} signup" to create an account`);
929
966
  return;
930
967
  }
931
968
  const apiKey = getApiKey() || "";
@@ -948,7 +985,7 @@ function createAuthCommand() {
948
985
  }
949
986
  if (refused) {
950
987
  warn(refused);
951
- info('Run "delegance auth login" to sign in again.');
988
+ info(`Run "${cliInvocation()} auth login" to sign in again.`);
952
989
  } else {
953
990
  success("Authenticated");
954
991
  }
@@ -966,7 +1003,7 @@ function createAuthCommand() {
966
1003
  const apiKey = getApiKey();
967
1004
  if (!apiKey) {
968
1005
  error("Not authenticated");
969
- info('Run "delegance auth login" to sign in');
1006
+ info(`Run "${cliInvocation()} auth login" to sign in`);
970
1007
  process.exit(1);
971
1008
  }
972
1009
  const spinner = (0, import_ora2.default)("Refreshing your key...").start();
@@ -1014,7 +1051,7 @@ function createAuthCommand() {
1014
1051
  auth.command("whoami").description("Show current authenticated identity").action(async () => {
1015
1052
  if (!isAuthenticated()) {
1016
1053
  error("Not authenticated");
1017
- info('Run "delegance auth login" to authenticate');
1054
+ info(`Run "${cliInvocation()} auth login" to authenticate`);
1018
1055
  process.exit(1);
1019
1056
  }
1020
1057
  const apiKey = getApiKey();
@@ -1210,7 +1247,7 @@ function createCompanyCommand() {
1210
1247
  const companyId = getConfigValue("defaultCompanyId");
1211
1248
  if (!companyId) {
1212
1249
  info("No default company set");
1213
- info('Use "delegance company use <id>" to set one');
1250
+ info(`Use "${cliInvocation()} company use <id>" to set one`);
1214
1251
  return;
1215
1252
  }
1216
1253
  const client = getClient();
@@ -1484,7 +1521,7 @@ function createDocumentCommand() {
1484
1521
  process.exit(1);
1485
1522
  } else {
1486
1523
  waitSpinner.warn(`Extraction still ${finished.status}`);
1487
- if (!options.json) info(`Run "delegance doc wait ${documentId}" to keep following it`);
1524
+ if (!options.json) info(`Run "${cliInvocation()} doc wait ${documentId}" to keep following it`);
1488
1525
  }
1489
1526
  return;
1490
1527
  }
@@ -1492,7 +1529,7 @@ function createDocumentCommand() {
1492
1529
  json(result);
1493
1530
  } else {
1494
1531
  info(`${result.reprocessesRemaining} reprocess attempts left today`);
1495
- info(`Run "delegance doc wait ${documentId}" to follow it`);
1532
+ info(`Run "${cliInvocation()} doc wait ${documentId}" to follow it`);
1496
1533
  }
1497
1534
  } catch (err) {
1498
1535
  spinner.fail("Failed to reprocess document");
@@ -1640,6 +1677,90 @@ var import_inquirer5 = __toESM(require("inquirer"));
1640
1677
  var import_ora6 = __toESM(require("ora"));
1641
1678
  var import_sdk4 = require("@delegance/sdk");
1642
1679
 
1680
+ // src/utils/coverage-names.ts
1681
+ var NAMES = {
1682
+ // General liability
1683
+ cgl: "General Liability",
1684
+ gl: "General Liability",
1685
+ general_liability: "General Liability",
1686
+ // Workers' comp
1687
+ wc: "Workers' Comp",
1688
+ workers_comp: "Workers' Comp",
1689
+ workers_compensation: "Workers' Comp",
1690
+ // Business owner's policy
1691
+ bop: "Business Owner's Policy",
1692
+ business_owners: "Business Owner's Policy",
1693
+ business_owners_policy: "Business Owner's Policy",
1694
+ // Cyber
1695
+ cyber: "Cyber",
1696
+ cyber_liability: "Cyber",
1697
+ // Professional liability (E&O)
1698
+ mpl: "Professional Liability (E&O)",
1699
+ pl: "Professional Liability (E&O)",
1700
+ pro_liab: "Professional Liability (E&O)",
1701
+ professional_liability: "Professional Liability (E&O)",
1702
+ eo: "Professional Liability (E&O)",
1703
+ e_o: "Professional Liability (E&O)",
1704
+ tech_eo: "Tech E&O",
1705
+ errors_omissions: "Tech E&O",
1706
+ // Auto
1707
+ ca: "Commercial Auto",
1708
+ auto: "Commercial Auto",
1709
+ commercial_auto: "Commercial Auto",
1710
+ // Property
1711
+ cp: "Commercial Property",
1712
+ property: "Commercial Property",
1713
+ commercial_property: "Commercial Property",
1714
+ // Umbrella
1715
+ umbrella: "Umbrella",
1716
+ excess: "Umbrella",
1717
+ commercial_umbrella: "Umbrella",
1718
+ // Builders risk
1719
+ br: "Builders' Risk",
1720
+ builders_risk: "Builders' Risk",
1721
+ // Inland marine and marine
1722
+ im: "Inland Marine",
1723
+ inland_marine: "Inland Marine",
1724
+ marine: "Marine",
1725
+ // Management liability family
1726
+ ml: "Management Liability",
1727
+ management_liability: "Management Liability",
1728
+ do: "Directors and Officers (D&O)",
1729
+ d_o: "Directors and Officers (D&O)",
1730
+ directors_officers: "Directors and Officers (D&O)",
1731
+ epli: "Employment Practices Liability",
1732
+ employment_practices: "Employment Practices Liability",
1733
+ crime: "Crime",
1734
+ fiduciary: "Fiduciary Liability",
1735
+ fiduciary_liability: "Fiduciary Liability",
1736
+ // Everything else on the canonical list
1737
+ product_liability: "Product Liability",
1738
+ liquor_liability: "Liquor Liability",
1739
+ contractors_liability: "Contractors' Liability",
1740
+ equipment_breakdown: "Equipment Breakdown",
1741
+ environmental_liability: "Environmental Liability",
1742
+ healthcare_medical: "Healthcare Medical Liability",
1743
+ life_sciences: "Life Sciences",
1744
+ hospitality_programs: "Hospitality Program",
1745
+ commercial_flood: "Commercial Flood",
1746
+ home_based_business: "Home-Based Business",
1747
+ foreign_package: "Foreign Package",
1748
+ multinational_package: "Multinational Package",
1749
+ political_risk: "Political Risk",
1750
+ trade_credit: "Trade Credit",
1751
+ kidnap_ransom: "Kidnap and Ransom",
1752
+ product_recall: "Product Recall",
1753
+ railroad_liability: "Railroad Liability"
1754
+ };
1755
+ function coverageName(code) {
1756
+ if (code === null || code === void 0) return "";
1757
+ const key = code.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
1758
+ return NAMES[key] ?? code;
1759
+ }
1760
+ function coverageNames(codes) {
1761
+ return codes.map(coverageName).filter(Boolean).join(", ");
1762
+ }
1763
+
1643
1764
  // src/commerce/questions.ts
1644
1765
  var COVERAGE_ALIASES = {
1645
1766
  gl: "general_liability",
@@ -1718,14 +1839,23 @@ function validateAnswers(questions, provided) {
1718
1839
  }
1719
1840
  return { answers, problems };
1720
1841
  }
1842
+ function rowStatus(q) {
1843
+ if (String(q.state).toUpperCase() === "REFERRED") {
1844
+ return q.resultStatus === "needs_info" ? "needs_info" : "referred";
1845
+ }
1846
+ return q.marketStatus || q.state;
1847
+ }
1721
1848
  function sortQuoteRows(quotes) {
1722
1849
  return quotes.map((q) => ({
1723
1850
  carrier: q.carrierName || q.carrierId,
1724
1851
  coverage: q.coverage ?? "",
1725
1852
  premium: q.premium,
1726
- status: q.marketStatus || q.state,
1853
+ status: rowStatus(q),
1727
1854
  bindable: q.bindable === true && q.state === "QUOTED",
1728
- opportunityId: q.opportunityId
1855
+ opportunityId: q.opportunityId,
1856
+ limits: typeof q.limits === "string" && q.limits.trim() ? q.limits : null,
1857
+ deductible: typeof q.deductible === "number" && Number.isFinite(q.deductible) ? q.deductible : null,
1858
+ message: typeof q.message === "string" && q.message.trim() ? q.message.trim() : null
1729
1859
  })).sort((a, b) => {
1730
1860
  if (a.bindable !== b.bindable) return a.bindable ? -1 : 1;
1731
1861
  if (a.premium === null && b.premium === null) return 0;
@@ -1734,8 +1864,50 @@ function sortQuoteRows(quotes) {
1734
1864
  return a.premium - b.premium;
1735
1865
  });
1736
1866
  }
1737
- function cheapestBindable(rows) {
1738
- return rows.find((r) => r.bindable && r.premium !== null) ?? null;
1867
+ function bestPerCoverage(rows) {
1868
+ const best = /* @__PURE__ */ new Map();
1869
+ for (const r of rows) {
1870
+ if (!r.bindable || r.premium === null) continue;
1871
+ const key = coverageName(r.coverage);
1872
+ const cur = best.get(key);
1873
+ if (!cur || r.premium < cur.premium) best.set(key, r);
1874
+ }
1875
+ return [...best.values()].sort((a, b) => a.premium - b.premium);
1876
+ }
1877
+ function groupRowsByCoverage(rows) {
1878
+ const order = /* @__PURE__ */ new Map();
1879
+ rows.forEach((r) => {
1880
+ const key = coverageName(r.coverage);
1881
+ if (!order.has(key)) order.set(key, order.size);
1882
+ });
1883
+ const rank = (r) => order.get(coverageName(r.coverage));
1884
+ return rows.map((r, i) => ({ r, i })).sort((a, b) => rank(a.r) - rank(b.r) || a.i - b.i).map((x) => x.r);
1885
+ }
1886
+ var STATUS_WORDS = {
1887
+ quote: "Quoted",
1888
+ quoted: "Quoted",
1889
+ declined: "Declined",
1890
+ decline: "Declined",
1891
+ quoting: "Pricing",
1892
+ pending: "Pricing",
1893
+ submitted: "Pricing",
1894
+ in_progress: "Pricing",
1895
+ referred: "Referred to an underwriter",
1896
+ refer: "Referred to an underwriter",
1897
+ needs_info: "Needs more info",
1898
+ awaiting_broker_review: "With a broker",
1899
+ broker_review: "With a broker",
1900
+ bind_requested: "Bind requested",
1901
+ bound: "Bound",
1902
+ expired: "Expired",
1903
+ error: "Failed",
1904
+ failed: "Failed"
1905
+ };
1906
+ function quoteStatusWord(status) {
1907
+ const key = status.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_");
1908
+ if (STATUS_WORDS[key]) return STATUS_WORDS[key];
1909
+ const words = key.replace(/_/g, " ").trim();
1910
+ return words ? words.charAt(0).toUpperCase() + words.slice(1) : status;
1739
1911
  }
1740
1912
  function summarizeStatus(s) {
1741
1913
  const quoted = s.carrierQuotes.filter((q) => q.premium !== null).length;
@@ -1785,7 +1957,14 @@ function formatKnown(q, value) {
1785
1957
  }
1786
1958
 
1787
1959
  // src/commerce/demo.ts
1788
- var DEMO_BUSINESS = "Riverbend Bakery (demo), Austin TX, 6 employees";
1960
+ var DEMO_BUSINESS = "Riverbend Bakery (demo), Austin TX";
1961
+ var DEMO_SHORT_LABELS = {
1962
+ annual_revenue: "Annual revenue",
1963
+ employees: "Full-time employees",
1964
+ delivery: "Delivers orders",
1965
+ delivery_vehicles: "Delivery vehicles",
1966
+ claims_5y: "Claims in last 5 years"
1967
+ };
1789
1968
  var DEMO_QUESTIONS = [
1790
1969
  { id: "annual_revenue", label: "Annual revenue (USD)", type: "currency", required: true, prefill: 85e4 },
1791
1970
  { id: "employees", label: "Full-time employees", type: "number", required: true, prefill: 6 },
@@ -1819,6 +1998,7 @@ var DEMO_QUESTIONS = [
1819
1998
  ];
1820
1999
  var DEMO_STATUS = {
1821
2000
  submissionId: "demo-submission",
2001
+ effectiveDate: "2026-11-01",
1822
2002
  coverages: ["general_liability", "workers_comp"],
1823
2003
  expiresAt: null,
1824
2004
  submitted: true,
@@ -1826,19 +2006,24 @@ var DEMO_STATUS = {
1826
2006
  allCarriersResolved: true,
1827
2007
  awaitingBrokerReviewCount: 0,
1828
2008
  carrierQuotes: [
1829
- { opportunityId: "demo-1", carrierId: "CARRIER_A", carrierName: "Carrier A", coverage: "CGL", state: "QUOTED", marketStatus: "quote", premium: 612, quoteNumber: "DEMO-GL-1", bindable: true },
1830
- { opportunityId: "demo-2", carrierId: "CARRIER_B", carrierName: "Carrier B", coverage: "CGL", state: "QUOTED", marketStatus: "quote", premium: 748, quoteNumber: "DEMO-GL-2", bindable: true },
1831
- { opportunityId: "demo-3", carrierId: "CARRIER_C", carrierName: "Carrier C", coverage: "WC", state: "QUOTED", marketStatus: "quote", premium: 1184, quoteNumber: "DEMO-WC-1", bindable: true },
1832
- { opportunityId: "demo-4", carrierId: "CARRIER_D", carrierName: "Carrier D", coverage: "WC", state: "DECLINED", marketStatus: "declined", premium: null, quoteNumber: null, bindable: false }
2009
+ { 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 },
2010
+ { 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 },
2011
+ { 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 },
2012
+ { 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 }
1833
2013
  ]
1834
2014
  };
1835
2015
 
1836
2016
  // src/commands/instant-quote.ts
1837
- function activeRequestLines(err, coverageFlag) {
2017
+ function shellArg(value) {
2018
+ return /^[\w@%+=:,./-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
2019
+ }
2020
+ function activeRequestLines(err, coverageFlag, ctx = {}) {
1838
2021
  if (!(err instanceof import_sdk4.DeleganceError) || err.statusCode !== 409 || !err.body) return null;
1839
2022
  const { body } = err;
1840
2023
  const code = body.message;
1841
- const requote = `delegance quote start --coverage ${coverageFlag} --replace`;
2024
+ const answersArg = ctx.answersFile ? ` --answers ${shellArg(ctx.answersFile)}` : "";
2025
+ const requote = `${cliInvocation()} quote start --coverage ${coverageFlag}${answersArg} --replace`;
2026
+ 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;
1842
2027
  if (code === "active_request_exists") {
1843
2028
  const active = Array.isArray(body.active) ? body.active : [];
1844
2029
  const first = active[0];
@@ -1846,7 +2031,7 @@ function activeRequestLines(err, coverageFlag) {
1846
2031
  const carriers = Array.isArray(first?.carriers) ? first.carriers.map((c) => `${c.carrierId}${c.state ? ` (${c.state.toLowerCase()})` : ""}`).join(", ") : "";
1847
2032
  return [
1848
2033
  `Already with carriers${id ? `: ${id}` : ""}${carriers ? `, ${carriers}` : ""}.`,
1849
- `Check it: ${id ? `delegance quote status ${id}` : "delegance quote status <id>"} Replace it: ${requote}`
2034
+ `Check it: ${id ? `${cliInvocation()} quote status ${id}` : `${cliInvocation()} quote status <id>`} Replace it: ${replaceCmd}`
1850
2035
  ];
1851
2036
  }
1852
2037
  if (code === "replace_conflict") {
@@ -1973,7 +2158,7 @@ function handoffLines(r) {
1973
2158
  if (!r.alreadyHandedOff && r.unansweredRequired > 0) {
1974
2159
  lines.push(`The broker will email you for the ${r.unansweredRequired} answer(s) still missing.`);
1975
2160
  }
1976
- lines.push(`Check it: delegance quote status ${r.submissionId}`);
2161
+ lines.push(`Check it: ${cliInvocation()} quote status ${r.submissionId}`);
1977
2162
  return lines;
1978
2163
  }
1979
2164
  async function runBrokerHandoff(submissionId, instantAnswers, opts) {
@@ -2014,7 +2199,7 @@ async function runBrokerHandoff(submissionId, instantAnswers, opts) {
2014
2199
  process.exit(1);
2015
2200
  }
2016
2201
  } else if (!opts.json && isInteractive() && plan.questions.length > 0) {
2017
- info(`A broker can place ${plan.coverages.join(", ")} with a market that quotes by hand. ${plan.questions.length} application question(s) left.`);
2202
+ info(`A broker can place ${coverageNames(plan.coverages)} with a market that quotes by hand. ${plan.questions.length} application question(s) left.`);
2018
2203
  info("Press Ctrl-C to stop at any point; what you have answered goes to the broker.");
2019
2204
  const onInterrupt = () => {
2020
2205
  complete = false;
@@ -2046,7 +2231,7 @@ async function sendHandoff(submissionId, input, idempotencyKey, asJson) {
2046
2231
  else handoffLines(result).forEach((l) => info(l));
2047
2232
  } catch (err) {
2048
2233
  spinner?.fail("Could not reach a broker");
2049
- console.error(`Try again: delegance quote handoff ${submissionId}`);
2234
+ console.error(`Try again: ${cliInvocation()} quote handoff ${submissionId}`);
2050
2235
  failWith("API error", err);
2051
2236
  }
2052
2237
  }
@@ -2057,8 +2242,34 @@ function printFloorDrops(failures) {
2057
2242
  floors.forEach((f) => console.log(` - ${f.carrierId}: ${f.missing}`));
2058
2243
  info("Add it to your business profile in the portal, then run the quote again.");
2059
2244
  }
2245
+ 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.";
2246
+ var premiumText = (n) => n === null ? "-" : formatCurrency(n);
2247
+ var deductibleText = (n) => n === null ? "-" : n === 0 ? "None" : formatCurrency(n);
2248
+ function bestPriceLines(best) {
2249
+ if (best.length === 0) return [];
2250
+ const names = best.map((r) => coverageName(r.coverage));
2251
+ const nameW = Math.max(...names.map((n) => n.length));
2252
+ const carrierW = Math.max(...best.map((r) => r.carrier.length));
2253
+ return [
2254
+ "Best price per coverage:",
2255
+ ...best.map((r, i) => ` ${names[i].padEnd(nameW)} ${r.carrier.padEnd(carrierW)} ${formatCurrency(r.premium)}/yr`)
2256
+ ];
2257
+ }
2258
+ function bindHintLines(submissionId, best) {
2259
+ if (best.length === 1) return [`Bind it: ${cliCommand(`bind ${submissionId} ${best[0].opportunityId}`)}`];
2260
+ return best.map((r) => `Bind ${coverageName(r.coverage)}: ${cliCommand(`bind ${submissionId} ${r.opportunityId}`)}`);
2261
+ }
2262
+ function demoClosingLines(best) {
2263
+ const example = best[0] ? ` (e.g. bind ... ${best[0].opportunityId})` : "";
2264
+ return [
2265
+ `Next, on a real quote: ${cliCommand("bind <quote id> <offer>")}${example}`,
2266
+ "DEMO: sample premiums, nothing went to a carrier.",
2267
+ `Get real quotes: ${cliCommand("signup")}`,
2268
+ AGENT_TIP
2269
+ ];
2270
+ }
2060
2271
  function printQuoteTable(status, opts = {}) {
2061
- const rows = sortQuoteRows(status.carrierQuotes);
2272
+ const rows = groupRowsByCoverage(sortQuoteRows(status.carrierQuotes));
2062
2273
  if (rows.length === 0) {
2063
2274
  if (status.brokerReview) {
2064
2275
  info(`A broker has this request (${status.brokerReview.status.replace(/_/g, " ")}). They place it by hand and email you with quotes or questions.`);
@@ -2068,25 +2279,67 @@ function printQuoteTable(status, opts = {}) {
2068
2279
  if (status.awaitingBrokerReviewCount > 0) info(`${status.awaitingBrokerReviewCount} quote(s) are with a broker for review.`);
2069
2280
  return;
2070
2281
  }
2071
- const best = cheapestBindable(rows);
2072
- if (best) {
2073
- console.log(import_chalk2.default.bold(`${opts.demo ? "[DEMO] " : ""}Cheapest bindable: ${best.carrier} ${best.coverage} at ${formatCurrency(best.premium)}/yr`));
2282
+ const best = bestPerCoverage(rows);
2283
+ const bestIds = new Set(best.map((r) => r.opportunityId));
2284
+ const effectiveDate = status.effectiveDate;
2285
+ console.log();
2286
+ if (effectiveDate && opts.showStartDate !== false) {
2287
+ console.log(`Coverage starts ${formatDateOnly(effectiveDate)}`);
2288
+ }
2289
+ const bestLines = bestPriceLines(best);
2290
+ if (bestLines.length) {
2291
+ console.log(import_chalk2.default.bold(bestLines[0]));
2292
+ bestLines.slice(1).forEach((l) => console.log(l));
2293
+ console.log();
2074
2294
  }
2075
2295
  table(
2076
- ["Carrier", "Coverage", "Premium/yr", "Status", "Bindable", "Offer id"],
2296
+ ["Carrier", "Coverage", "Premium/yr", "Limits", "Deductible", "Status", "Offer"],
2077
2297
  rows.map((r) => {
2078
- const cells = [r.carrier, r.coverage, r.premium === null ? "-" : formatCurrency(r.premium), r.status, r.bindable ? "yes" : "no", r.opportunityId];
2079
- return r === best ? cells.map((c) => import_chalk2.default.bold(String(c))) : cells;
2080
- })
2298
+ const cells = [
2299
+ r.carrier,
2300
+ coverageName(r.coverage),
2301
+ premiumText(r.premium),
2302
+ r.limits ?? "-",
2303
+ deductibleText(r.deductible),
2304
+ quoteStatusWord(r.status),
2305
+ r.opportunityId
2306
+ ];
2307
+ return bestIds.has(r.opportunityId) ? cells.map((c) => import_chalk2.default.bold(c)) : cells;
2308
+ }),
2309
+ { compact: true }
2081
2310
  );
2082
- console.log(import_chalk2.default.dim(summarizeStatus(status)));
2083
- if (best && !opts.demo) {
2084
- console.log(import_chalk2.default.green(`Bind it: delegance bind ${status.submissionId} ${best.opportunityId}`));
2311
+ const reasons = rows.filter((r) => r.message);
2312
+ if (reasons.length) {
2313
+ console.log();
2314
+ reasons.forEach((r) => console.log(`${r.carrier} (${quoteStatusWord(r.status)}): ${r.message}`));
2085
2315
  }
2086
- if (opts.demo) console.log(import_chalk2.default.yellow('DEMO: sample premiums, nothing was sent to a carrier. Run "delegance signup" for real quotes.'));
2316
+ console.log();
2317
+ console.log(import_chalk2.default.dim(`${summarizeStatus(status)}.`));
2318
+ if (opts.demo) {
2319
+ const [next, notice, signup, tip] = demoClosingLines(best);
2320
+ console.log(import_chalk2.default.green(next));
2321
+ console.log(import_chalk2.default.yellow(notice));
2322
+ console.log(import_chalk2.default.yellow(signup));
2323
+ console.log(import_chalk2.default.dim(tip));
2324
+ return;
2325
+ }
2326
+ bindHintLines(status.submissionId, best).forEach((l) => console.log(import_chalk2.default.green(l)));
2327
+ }
2328
+ function demoAnswerLines(answers, effectiveDate) {
2329
+ const pairs = [];
2330
+ for (const q of DEMO_QUESTIONS) {
2331
+ if (answers[q.id] === void 0) continue;
2332
+ const v = answers[q.id];
2333
+ const shown = q.type === "currency" && typeof v === "number" ? formatCurrency(v) : formatKnown(q, v);
2334
+ pairs.push([DEMO_SHORT_LABELS[q.id] ?? q.label, shown]);
2335
+ }
2336
+ if (effectiveDate) pairs.push(["Coverage starts", formatDateOnly(effectiveDate)]);
2337
+ const w = Math.max(...pairs.map(([k]) => k.length));
2338
+ return ["Sample answers (a real quote asks you these):", ...pairs.map(([k, v]) => ` ${k.padEnd(w)} ${v}`)];
2087
2339
  }
2088
2340
  async function runDemo(asJson, answersFile) {
2089
2341
  (asJson ? console.error : console.log)(import_chalk2.default.yellow(`DEMO quote for ${DEMO_BUSINESS}. Nothing leaves this machine.`));
2342
+ let printedStart = false;
2090
2343
  if (answersFile) {
2091
2344
  let provided;
2092
2345
  try {
@@ -2104,15 +2357,19 @@ async function runDemo(asJson, answersFile) {
2104
2357
  const mode = answerMode({ demo: true, hasAnswersFile: false, json: asJson, isTTY: isInteractive() });
2105
2358
  if (mode === "prompt") await askQuestions(DEMO_QUESTIONS);
2106
2359
  else {
2107
- suggestedAnswers(DEMO_QUESTIONS);
2108
- if (!asJson) info("No terminal to ask in, so the demo uses its suggested answers.");
2360
+ const assumed = suggestedAnswers(DEMO_QUESTIONS);
2361
+ if (!asJson) {
2362
+ demoAnswerLines(assumed, DEMO_STATUS.effectiveDate).forEach((l) => console.log(l));
2363
+ printedStart = true;
2364
+ }
2109
2365
  }
2110
2366
  }
2111
- const spinner = asJson ? null : (0, import_ora6.default)("Asking carriers (demo)...").start();
2367
+ const spinner = asJson ? null : (0, import_ora6.default)("Asking carriers (demo)...");
2368
+ if (spinner && process.stderr.isTTY) spinner.start();
2112
2369
  await new Promise((resolve) => setTimeout(resolve, asJson ? 0 : 1200));
2113
2370
  spinner?.succeed("4 carriers answered (demo)");
2114
2371
  if (asJson) json({ demo: true, ...DEMO_STATUS });
2115
- else printQuoteTable(DEMO_STATUS, { demo: true });
2372
+ else printQuoteTable(DEMO_STATUS, { demo: true, showStartDate: !printedStart });
2116
2373
  }
2117
2374
  function addInstantQuoteCommands(quote) {
2118
2375
  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) => {
@@ -2177,14 +2434,14 @@ function addInstantQuoteCommands(quote) {
2177
2434
  ...options.replace ? { replace: true } : {}
2178
2435
  });
2179
2436
  } catch (err) {
2180
- const guardLines = activeRequestLines(err, String(options.coverage));
2437
+ const guardLines = activeRequestLines(err, String(options.coverage), { answersFile: options.answers });
2181
2438
  if (guardLines) {
2182
2439
  submitSpinner.fail("Nothing was sent.");
2183
2440
  guardLines.forEach((l) => options.json ? console.error(l) : info(l));
2184
2441
  process.exit(1);
2185
2442
  }
2186
2443
  submitSpinner.fail("Submit failed");
2187
- console.error(`Before trying again, check whether it went through: delegance quote status ${session.submissionId}`);
2444
+ console.error(`Before trying again, check whether it went through: ${cliInvocation()} quote status ${session.submissionId}`);
2188
2445
  failWith("API error", err);
2189
2446
  }
2190
2447
  if (submitted.status === "no_carriers") {
@@ -2200,14 +2457,14 @@ function addInstantQuoteCommands(quote) {
2200
2457
  }
2201
2458
  if (submitted.status === "acord_pending") {
2202
2459
  submitSpinner.succeed("Sent to a broker: these coverages need a person, not an instant quote.");
2203
- info(`Track it with: delegance quote status ${session.submissionId}`);
2460
+ info(`Track it with: ${cliInvocation()} quote status ${session.submissionId}`);
2204
2461
  return;
2205
2462
  }
2206
2463
  submitSpinner.succeed(`Filed with ${submitted.quotes.filter((q) => q.status === "submitted").length} carrier(s).`);
2207
2464
  printFloorDrops(submitted.partialFailures);
2208
2465
  if (submitted.replaceNotice && !options.json) info(submitted.replaceNotice);
2209
2466
  if (options.wait === false) {
2210
- info(`Check premiums with: delegance quote status ${session.submissionId} --wait`);
2467
+ info(`Check premiums with: ${cliInvocation()} quote status ${session.submissionId} --wait`);
2211
2468
  return;
2212
2469
  }
2213
2470
  await waitAndPrint(session.submissionId, Number(options.timeout) * 6e4 || 6e5, !!options.json);
@@ -2236,22 +2493,25 @@ function addInstantQuoteCommands(quote) {
2236
2493
  }
2237
2494
  if (submitted.status !== "submitted") {
2238
2495
  info("Sent to a broker for these coverages.");
2239
- info(`Check it: delegance quote status ${submissionId}`);
2496
+ info(`Check it: ${cliInvocation()} quote status ${submissionId}`);
2240
2497
  return;
2241
2498
  }
2242
2499
  if (options.wait === false) {
2243
- info(`Check premiums with: delegance quote status ${submissionId} --wait`);
2500
+ info(`Check premiums with: ${cliInvocation()} quote status ${submissionId} --wait`);
2244
2501
  return;
2245
2502
  }
2246
2503
  await waitAndPrint(submissionId, Number(options.timeout) * 6e4 || 6e5, !!options.json);
2247
2504
  } catch (err) {
2248
- const guardLines = activeRequestLines(err, "<list>");
2505
+ const guardLines = activeRequestLines(err, "<list>", {
2506
+ answersFile: options.answers,
2507
+ submit: { submissionId, sessionVersion: String(options.sessionVersion) }
2508
+ });
2249
2509
  if (guardLines) {
2250
2510
  error("Nothing was sent.");
2251
2511
  guardLines.forEach((l) => options.json ? console.error(l) : info(l));
2252
2512
  process.exit(1);
2253
2513
  }
2254
- console.error(`Before trying again, check whether it went through: delegance quote status ${submissionId}`);
2514
+ console.error(`Before trying again, check whether it went through: ${cliInvocation()} quote status ${submissionId}`);
2255
2515
  failWith("Submit failed", err);
2256
2516
  }
2257
2517
  });
@@ -2287,7 +2547,7 @@ async function waitAndPrint(submissionId, timeoutMs, asJson) {
2287
2547
  spinner?.stop();
2288
2548
  if (asJson) json(status);
2289
2549
  else printQuoteTable(status);
2290
- if (!status.allCarriersResolved && !asJson) info(`Some carriers are still working. Check again: delegance quote status ${submissionId} --wait`);
2550
+ if (!status.allCarriersResolved && !asJson) info(`Some carriers are still working. Check again: ${cliInvocation()} quote status ${submissionId} --wait`);
2291
2551
  } catch (err) {
2292
2552
  spinner?.fail("Could not read the quote");
2293
2553
  failWith("API error", err);
@@ -2400,13 +2660,13 @@ function createQuoteCommand() {
2400
2660
  }
2401
2661
  console.log();
2402
2662
  info(`Queue IDs: ${result.queueIds.join(", ")}`);
2403
- info('Use "delegance quote list" to check status');
2663
+ info(`Use "${cliInvocation()} quote list" to check status`);
2404
2664
  }
2405
2665
  } catch (err) {
2406
2666
  spinner.fail("Failed to submit quote request");
2407
2667
  if (err instanceof import_sdk5.NotImplementedError) {
2408
2668
  error(QUOTE_SUBMISSION_UNAVAILABLE);
2409
- info("For an instant quote from the terminal: delegance quote start --coverage gl");
2669
+ info(`For an instant quote from the terminal: ${cliInvocation()} quote start --coverage gl`);
2410
2670
  info(`Or start a quote at ${PORTAL_URL}`);
2411
2671
  process.exit(1);
2412
2672
  }
@@ -2564,7 +2824,7 @@ function createPolicyCommand() {
2564
2824
  ["Carrier", "Type", "Policy #", "Expiry", "Status", "Premium"],
2565
2825
  policies.map((p) => [
2566
2826
  p.carrier || "Unknown",
2567
- p.policyType || p.name || "-",
2827
+ (p.policyType ? coverageName(p.policyType) : p.name) || "-",
2568
2828
  p.policyNumber || "-",
2569
2829
  p.expiryDate ? formatDate(p.expiryDate) : "-",
2570
2830
  formatPolicyStatus(p.isActive, p.daysUntilExpiry),
@@ -2598,21 +2858,21 @@ function createPolicyCommand() {
2598
2858
  if (urgent.length > 0) {
2599
2859
  warn(`\u26A0\uFE0F Expiring within 7 days (${urgent.length}):`);
2600
2860
  for (const p of urgent) {
2601
- console.log(` - ${p.carrier} ${p.policyType || p.name} - expires ${formatDate(p.expiryDate)}`);
2861
+ console.log(` - ${p.carrier} ${p.policyType ? coverageName(p.policyType) : p.name} - expires ${formatDate(p.expiryDate)}`);
2602
2862
  }
2603
2863
  console.log();
2604
2864
  }
2605
2865
  if (soon.length > 0) {
2606
2866
  info(`\u{1F4C5} Expiring within 30 days (${soon.length}):`);
2607
2867
  for (const p of soon) {
2608
- console.log(` - ${p.carrier} ${p.policyType || p.name} - expires ${formatDate(p.expiryDate)}`);
2868
+ console.log(` - ${p.carrier} ${p.policyType ? coverageName(p.policyType) : p.name} - expires ${formatDate(p.expiryDate)}`);
2609
2869
  }
2610
2870
  console.log();
2611
2871
  }
2612
2872
  if (later.length > 0) {
2613
2873
  console.log(`\u{1F4C6} Expiring later (${later.length}):`);
2614
2874
  for (const p of later) {
2615
- console.log(` - ${p.carrier} ${p.policyType || p.name} - ${p.daysUntilExpiry} days`);
2875
+ console.log(` - ${p.carrier} ${p.policyType ? coverageName(p.policyType) : p.name} - ${p.daysUntilExpiry} days`);
2616
2876
  }
2617
2877
  }
2618
2878
  }
@@ -2636,11 +2896,11 @@ function createPolicyCommand() {
2636
2896
  } else {
2637
2897
  const { policy: p, coverages } = found;
2638
2898
  console.log();
2639
- header(`${p.carrier} - ${p.policyType || p.name}`);
2899
+ header(`${p.carrier} - ${p.policyType ? coverageName(p.policyType) : p.name}`);
2640
2900
  console.log();
2641
2901
  console.log(` Policy #: ${p.policyNumber || "N/A"}`);
2642
2902
  console.log(` Carrier: ${p.carrier}`);
2643
- console.log(` Type: ${p.policyType || "N/A"}`);
2903
+ console.log(` Type: ${p.policyType ? coverageName(p.policyType) : "N/A"}`);
2644
2904
  console.log(` Effective: ${p.effectiveDate ? formatDate(p.effectiveDate) : "N/A"}`);
2645
2905
  console.log(` Expiry: ${p.expiryDate ? formatDate(p.expiryDate) : "N/A"}`);
2646
2906
  console.log(` Status: ${formatPolicyStatus(p.isActive, p.daysUntilExpiry)}`);
@@ -2691,14 +2951,14 @@ function createPolicyCommand() {
2691
2951
  return;
2692
2952
  }
2693
2953
  if (docs.length === 0) {
2694
- info("No source documents are linked to this policy yet. Upload one with: delegance document upload <file>");
2954
+ info(`No source documents are linked to this policy yet. Upload one with: ${cliInvocation()} document upload <file>`);
2695
2955
  return;
2696
2956
  }
2697
2957
  table(
2698
2958
  ["Document", "File", "Type", "Status", "Added"],
2699
2959
  docs.map((d) => [d.id, d.fileName ?? "-", d.documentType ?? "-", d.status, d.createdAt ? formatDate(d.createdAt) : "-"])
2700
2960
  );
2701
- info("Download one with: delegance document status <documentId>");
2961
+ info(`Download one with: ${cliInvocation()} document status <documentId>`);
2702
2962
  } catch (err) {
2703
2963
  failWith("API error", err);
2704
2964
  }
@@ -2731,9 +2991,9 @@ function createPolicyCommand() {
2731
2991
  await signWithStepUp(client, out.request.id, sig, void 0, void 0);
2732
2992
  } else {
2733
2993
  info(`Sign here: ${out.signatureUrl}`);
2734
- info(`Or sign from here: delegance policy sign ${out.request.id} --signer-name "..." --signer-title "..." --attest`);
2994
+ info(`Or sign from here: ${cliInvocation()} policy sign ${out.request.id} --signer-name "..." --signer-title "..." --attest`);
2735
2995
  }
2736
- info(`Check progress with "delegance policy cancellation ${out.request.id}"`);
2996
+ info(`Check progress with "${cliInvocation()} policy cancellation ${out.request.id}"`);
2737
2997
  } catch (err) {
2738
2998
  spinner.fail("Could not request the cancellation");
2739
2999
  failWith("API error", err);
@@ -2790,7 +3050,7 @@ async function signWithStepUp(client, requestId, sig, stepUpId, presetCode) {
2790
3050
  let code = presetCode;
2791
3051
  if (!code) {
2792
3052
  if (!process.stdin.isTTY) {
2793
- 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>`);
3053
+ 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>`);
2794
3054
  return;
2795
3055
  }
2796
3056
  const answer = await import_inquirer7.default.prompt([{
@@ -2840,7 +3100,7 @@ function createCOICommand() {
2840
3100
  policiesSpinner.stop();
2841
3101
  if (policies.length === 0) {
2842
3102
  error("No active policies found");
2843
- info('Upload policy documents first with "delegance doc upload"');
3103
+ info(`Upload policy documents first with "${cliInvocation()} doc upload"`);
2844
3104
  process.exit(1);
2845
3105
  }
2846
3106
  const answers = await import_inquirer8.default.prompt([
@@ -2849,7 +3109,7 @@ function createCOICommand() {
2849
3109
  name: "selectedPolicies",
2850
3110
  message: "Select policies to include:",
2851
3111
  choices: policies.map((p) => ({
2852
- name: `${p.carrier} - ${p.policyType || p.name} (${p.policyNumber || "No #"})`,
3112
+ name: `${p.carrier} - ${p.policyType ? coverageName(p.policyType) : p.name} (${p.policyNumber || "No #"})`,
2853
3113
  value: p.id,
2854
3114
  checked: policyIds.includes(p.id)
2855
3115
  })),
@@ -2936,7 +3196,7 @@ function createCOICommand() {
2936
3196
  console.log();
2937
3197
  console.log("Policies included:");
2938
3198
  for (const p of result.policiesIncluded) {
2939
- console.log(` - ${p.carrier} (${p.policyType})`);
3199
+ console.log(` - ${p.carrier} (${coverageName(p.policyType)})`);
2940
3200
  }
2941
3201
  }
2942
3202
  } catch (err) {
@@ -2952,7 +3212,7 @@ function createCOICommand() {
2952
3212
  spinner.succeed(`Found ${count} COIs`);
2953
3213
  if (cois.length === 0) {
2954
3214
  info("No COIs generated yet");
2955
- info('Generate one with "delegance coi generate --interactive"');
3215
+ info(`Generate one with "${cliInvocation()} coi generate --interactive"`);
2956
3216
  return;
2957
3217
  }
2958
3218
  if (options.json) {
@@ -3029,7 +3289,7 @@ function createSOVCommand() {
3029
3289
  info(`SOV ID: ${result.sovId}`);
3030
3290
  info(`Status: ${result.status}`);
3031
3291
  if (!options.wait) {
3032
- info('Use "delegance sov status <id>" to check parsing progress');
3292
+ info(`Use "${cliInvocation()} sov status <id>" to check parsing progress`);
3033
3293
  }
3034
3294
  }
3035
3295
  } catch (err) {
@@ -3048,7 +3308,7 @@ function createSOVCommand() {
3048
3308
  spinner.succeed(`Found ${count} SOVs`);
3049
3309
  if (sovs.length === 0) {
3050
3310
  info("No SOVs found");
3051
- info('Upload one with "delegance sov upload schedule.xlsx"');
3311
+ info(`Upload one with "${cliInvocation()} sov upload schedule.xlsx"`);
3052
3312
  return;
3053
3313
  }
3054
3314
  if (options.json) {
@@ -3212,7 +3472,7 @@ function createAppetiteCommand() {
3212
3472
  if (!options.wait) {
3213
3473
  spinner.succeed(`Match queued: ${start.jobId}`);
3214
3474
  if (options.json) json(start);
3215
- else info(`Check it with "delegance appetite status ${start.jobId}"`);
3475
+ else info(`Check it with "${cliInvocation()} appetite status ${start.jobId}"`);
3216
3476
  return;
3217
3477
  }
3218
3478
  spinner.text = `Matching appetite (about ${start.estimatedSeconds}s)...`;
@@ -3358,7 +3618,7 @@ function createKnowledgeCommand() {
3358
3618
  );
3359
3619
  }
3360
3620
  if (pagination.hasMore && pagination.nextCursor) {
3361
- info(`More: delegance knowledge notecards --cursor ${pagination.nextCursor}`);
3621
+ info(`More: ${cliInvocation()} knowledge notecards --cursor ${pagination.nextCursor}`);
3362
3622
  }
3363
3623
  } catch (err) {
3364
3624
  spinner.fail("Failed to list notecards");
@@ -3482,7 +3742,7 @@ function createOnboardingCommand() {
3482
3742
  const result = await client.onboarding.requestVerification();
3483
3743
  spinner.succeed(`Verification sent to ${result.sentTo}`);
3484
3744
  if (options.json) json(result);
3485
- else info('Open the link in that email, then check progress with "delegance onboarding state"');
3745
+ else info(`Open the link in that email, then check progress with "${cliInvocation()} onboarding state"`);
3486
3746
  } catch (err) {
3487
3747
  spinner.fail("Failed to request verification");
3488
3748
  failWith("API error", err);
@@ -3607,6 +3867,11 @@ var import_ora16 = __toESM(require("ora"));
3607
3867
  var import_crypto3 = require("crypto");
3608
3868
  var import_sdk6 = require("@delegance/sdk");
3609
3869
  var KEYS_PORTAL_URL = `${PORTAL_URL}/portal/settings/api-keys`;
3870
+ function parseExpiresInDays(raw) {
3871
+ if (raw === void 0 || raw === "") return void 0;
3872
+ if (raw.trim().toLowerCase() === "never") return "never";
3873
+ return parseInt(raw, 10);
3874
+ }
3610
3875
  function parseScopes(raw) {
3611
3876
  const parts = (Array.isArray(raw) ? raw : [raw ?? "read,write"]).flatMap((p) => p.split(/[\s,]+/)).map((p) => p.trim()).filter(Boolean);
3612
3877
  const unknown = parts.filter((p) => !import_sdk6.API_KEY_SCOPES.includes(p));
@@ -3615,8 +3880,12 @@ function parseScopes(raw) {
3615
3880
  }
3616
3881
  return Array.from(new Set(parts));
3617
3882
  }
3618
- function replacementExpiryDays(expiresAt, now = /* @__PURE__ */ new Date()) {
3619
- if (!expiresAt) return void 0;
3883
+ var EXPIRING_SCOPES = /* @__PURE__ */ new Set(["write", "admin", "claims:write"]);
3884
+ function isReadOnlyScopeSet(scopes) {
3885
+ return !scopes.some((s) => EXPIRING_SCOPES.has(s));
3886
+ }
3887
+ function replacementExpiryDays(expiresAt, now = /* @__PURE__ */ new Date(), scopes = []) {
3888
+ if (!expiresAt) return isReadOnlyScopeSet(scopes) ? "never" : void 0;
3620
3889
  const ms = new Date(expiresAt).getTime() - now.getTime();
3621
3890
  if (!Number.isFinite(ms)) throw new Error(`Cannot read the old key's expiry "${expiresAt}"; not rotating`);
3622
3891
  const days = Math.ceil(ms / (24 * 60 * 60 * 1e3));
@@ -3665,14 +3934,14 @@ function createKeysCommand() {
3665
3934
  ])
3666
3935
  );
3667
3936
  if (pagination?.hasMore && pagination.nextCursor) {
3668
- info(`More keys: delegance keys list --cursor ${pagination.nextCursor}`);
3937
+ info(`More keys: ${cliInvocation()} keys list --cursor ${pagination.nextCursor}`);
3669
3938
  }
3670
3939
  } catch (err) {
3671
3940
  spinner.fail("Failed to list API keys");
3672
3941
  failWith("API error", err);
3673
3942
  }
3674
3943
  });
3675
- 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) => {
3944
+ 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) => {
3676
3945
  let scopes;
3677
3946
  try {
3678
3947
  scopes = parseScopes(options.scopes);
@@ -3687,7 +3956,7 @@ function createKeysCommand() {
3687
3956
  {
3688
3957
  name,
3689
3958
  scopes,
3690
- expiresInDays: options.expiresInDays ? parseInt(options.expiresInDays) : void 0
3959
+ expiresInDays: parseExpiresInDays(options.expiresInDays)
3691
3960
  },
3692
3961
  { idempotencyKey: (0, import_crypto3.randomUUID)() }
3693
3962
  );
@@ -3722,7 +3991,7 @@ function createKeysCommand() {
3722
3991
  {
3723
3992
  name: `${current2.name} (rotated)`,
3724
3993
  scopes: current2.scopes,
3725
- expiresInDays: replacementExpiryDays(current2.expiresAt)
3994
+ expiresInDays: replacementExpiryDays(current2.expiresAt, /* @__PURE__ */ new Date(), current2.scopes)
3726
3995
  },
3727
3996
  { idempotencyKey: (0, import_crypto3.randomUUID)() }
3728
3997
  );
@@ -3733,6 +4002,9 @@ function createKeysCommand() {
3733
4002
  }
3734
4003
  printCreatedKey(created);
3735
4004
  console.log();
4005
+ if (!current2.expiresAt && !isReadOnlyScopeSet(current2.scopes)) {
4006
+ warn("The old key never expired. Keys that can write must expire now, so the new key lasts 90 days.");
4007
+ }
3736
4008
  warn(`The old key ${current2.prefix} is still active.`);
3737
4009
  info(`Switch your integrations to the new key, then revoke the old one at ${KEYS_PORTAL_URL}`);
3738
4010
  } catch (err) {
@@ -3824,7 +4096,7 @@ function createConfigCommand() {
3824
4096
  currentConfig.clear();
3825
4097
  clearCredentials();
3826
4098
  success("Configuration reset to defaults");
3827
- info('You will need to run "delegance auth login" again');
4099
+ info(`You will need to run "${cliInvocation()} auth login" again`);
3828
4100
  });
3829
4101
  config2.command("env").description("Show environment information").action(() => {
3830
4102
  header("Environment");
@@ -3850,7 +4122,7 @@ function createConfigCommand() {
3850
4122
  info("No profiles configured");
3851
4123
  info("Profiles allow you to switch between different accounts/environments");
3852
4124
  console.log();
3853
- info("Example: delegance config set-profile production --url https://portal.delegancebrokerage.com");
4125
+ info(`Example: ${cliInvocation()} config set-profile production --url https://portal.delegancebrokerage.com`);
3854
4126
  } else {
3855
4127
  for (const [name, profile] of Object.entries(profiles)) {
3856
4128
  const isActive = name === activeProfile;
@@ -3866,7 +4138,7 @@ function createConfigCommand() {
3866
4138
  const profiles = currentConfig.get("profiles") || {};
3867
4139
  if (!profiles[name] && name !== "default") {
3868
4140
  error(`Profile "${name}" not found`);
3869
- info("Create it with: delegance config set-profile <name> --url <base-url>");
4141
+ info(`Create it with: ${cliInvocation()} config set-profile <name> --url <base-url>`);
3870
4142
  process.exit(1);
3871
4143
  }
3872
4144
  currentConfig.set("activeProfile", name);
@@ -3897,7 +4169,7 @@ var import_inquirer10 = __toESM(require("inquirer"));
3897
4169
  var import_sdk7 = require("@delegance/sdk");
3898
4170
  var TYPES = ["bug", "idea", "question"];
3899
4171
  var MESSAGE_MAX = 500;
3900
- var USAGE = 'delegance feedback "what happened" [--type bug|idea|question] [--include-last]';
4172
+ var USAGE = `${cliInvocation()} feedback "what happened" [--type bug|idea|question] [--include-last]`;
3901
4173
  function feedbackInputMode(o) {
3902
4174
  if (o.message && o.message.trim()) return "given";
3903
4175
  return o.isTTY ? "prompt" : "usage_error";
@@ -3948,10 +4220,40 @@ function createFeedbackCommand() {
3948
4220
  });
3949
4221
  }
3950
4222
 
4223
+ // src/utils/checkbox-prompt.ts
4224
+ var import_inquirer11 = __toESM(require("inquirer"));
4225
+ var import_chalk3 = __toESM(require("chalk"));
4226
+ var CHECKBOX_HINT = "(space to select, Enter to continue)";
4227
+ var registered = false;
4228
+ function minimalCheckboxPrompt(Base) {
4229
+ return class MinimalCheckboxPrompt extends Base {
4230
+ constructor(...args) {
4231
+ super(...args);
4232
+ this.dontShowHints = true;
4233
+ }
4234
+ getQuestion() {
4235
+ const question = super.getQuestion();
4236
+ return this.status === "answered" ? question : `${question}${import_chalk3.default.dim(CHECKBOX_HINT)} `;
4237
+ }
4238
+ onAllKey() {
4239
+ }
4240
+ onInverseKey() {
4241
+ }
4242
+ };
4243
+ }
4244
+ function registerMinimalCheckbox() {
4245
+ if (registered) return;
4246
+ const prompts = import_inquirer11.default.prompt.prompts;
4247
+ const Base = prompts?.checkbox;
4248
+ if (!Base) return;
4249
+ import_inquirer11.default.registerPrompt("checkbox", minimalCheckboxPrompt(Base));
4250
+ registered = true;
4251
+ }
4252
+
3951
4253
  // src/commands/commerce.ts
3952
4254
  var import_commander18 = require("commander");
3953
4255
  var fs7 = __toESM(require("fs"));
3954
- var import_inquirer11 = __toESM(require("inquirer"));
4256
+ var import_inquirer12 = __toESM(require("inquirer"));
3955
4257
  var import_ora17 = __toESM(require("ora"));
3956
4258
  var import_sdk8 = require("@delegance/sdk");
3957
4259
  function formatCents(cents2, currency = "usd") {
@@ -3979,9 +4281,29 @@ function describeBindResult(r) {
3979
4281
  lines.push(r.next);
3980
4282
  return lines;
3981
4283
  }
4284
+ function exactDollars(cents2) {
4285
+ return `$${(cents2 / 100).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
4286
+ }
4287
+ function describeFinancing(f) {
4288
+ if (!f || !f.available) return [];
4289
+ const lines = [];
4290
+ if (f.checkoutUrl) {
4291
+ lines.push(`Pay over time with ${f.lender}: ${f.checkoutUrl}`);
4292
+ } else {
4293
+ lines.push(`Financing with ${f.lender} opens once your broker confirms the final premium.`);
4294
+ }
4295
+ const t = f.terms;
4296
+ if (t && t.aprBps !== null && t.downPaymentCents !== null && t.installmentCents !== null && t.numberOfInstallments !== null) {
4297
+ lines.push(
4298
+ `Lender terms: ${(t.aprBps / 100).toFixed(2)}% APR, ${exactDollars(t.downPaymentCents)} down, ${t.numberOfInstallments} payments of ${exactDollars(t.installmentCents)}.`
4299
+ );
4300
+ }
4301
+ lines.push(f.disclosure);
4302
+ return lines;
4303
+ }
3982
4304
  async function askCode() {
3983
4305
  if (!process.stdin.isTTY) return null;
3984
- const answer = await import_inquirer11.default.prompt([{
4306
+ const answer = await import_inquirer12.default.prompt([{
3985
4307
  type: "input",
3986
4308
  name: "code",
3987
4309
  message: "Code from your email:",
@@ -3994,7 +4316,7 @@ function createBindCommand() {
3994
4316
  const client = getClient();
3995
4317
  let attest = options.attest === true;
3996
4318
  if (!attest && process.stdin.isTTY && !options.json) {
3997
- const a = await import_inquirer11.default.prompt([{
4319
+ const a = await import_inquirer12.default.prompt([{
3998
4320
  type: "confirm",
3999
4321
  name: "ok",
4000
4322
  message: "Are the answers on this application accurate? Binding relies on them.",
@@ -4002,7 +4324,7 @@ function createBindCommand() {
4002
4324
  }]);
4003
4325
  attest = a.ok === true;
4004
4326
  if (!attest) {
4005
- warn('Not bound. Fix the answers with "delegance quote start", then bind again.');
4327
+ warn(`Not bound. Fix the answers with "${cliInvocation()} quote start", then bind again.`);
4006
4328
  return;
4007
4329
  }
4008
4330
  }
@@ -4018,7 +4340,7 @@ function createBindCommand() {
4018
4340
  info(`We emailed a 6-digit code to ${r.sentTo}. It expires in 10 minutes.`);
4019
4341
  const code = options.code ? String(options.code) : await askCode();
4020
4342
  if (!code) {
4021
- warn(`Finish with: delegance bind ${submissionId} ${offerId} --attest --step-up ${stepUpId} --code <code>`);
4343
+ warn(`Finish with: ${cliInvocation()} bind ${submissionId} ${offerId} --attest --step-up ${stepUpId} --code <code>`);
4022
4344
  return;
4023
4345
  }
4024
4346
  r = await client.instantQuotes.bindWithStepUp(submissionId, offerId, { ...attest ? { attest: true } : {}, stepUpId, code });
@@ -4032,9 +4354,10 @@ function createBindCommand() {
4032
4354
  return;
4033
4355
  }
4034
4356
  if (r.existing) warn(`A bind for this coverage is already open (${r.carrierName}). Showing it.`);
4035
- else if (r.tier !== "A") success(`Bind requested: ${r.carrierName} ${r.coverage}${r.premium === null ? "" : ` at ${formatCurrency(r.premium)}/yr`}`);
4357
+ else if (r.tier !== "A") success(`Bind requested: ${r.carrierName} ${coverageName(r.coverage)}${r.premium === null ? "" : ` at ${formatCurrency(r.premium)}/yr`}`);
4036
4358
  keyValue({ "Bind request": r.bindRequestId, Status: r.status });
4037
4359
  describeBindResult(r).forEach((l) => info(l));
4360
+ describeFinancing(r.financing).forEach((l) => info(l));
4038
4361
  } catch (err) {
4039
4362
  spinner?.stop();
4040
4363
  if (err instanceof import_sdk8.DeleganceError && [400, 403, 409].includes(err.statusCode ?? 0)) {
@@ -4075,7 +4398,7 @@ function createBillingCommand() {
4075
4398
  payments.map((p) => [p.id, formatCents(p.amount, p.currency), p.status, p.dueDate ? formatDate(p.dueDate) : "-", p.description ?? "-"])
4076
4399
  );
4077
4400
  keyValue({ "Open": `${formatCents(sum.openCents)} (${sum.openCount})`, "Paid": formatCents(sum.paidCents) });
4078
- if (sum.openCount > 0) info("Pay one with: delegance pay <paymentId>");
4401
+ if (sum.openCount > 0) info(`Pay one with: ${cliInvocation()} pay <paymentId>`);
4079
4402
  } catch (err) {
4080
4403
  failWith("API error", err);
4081
4404
  }
@@ -4100,7 +4423,7 @@ function createPayCommand() {
4100
4423
  payments.map((p) => [p.id, formatCents(p.amount, p.currency), p.description ?? "", p.payable ? `${p.status} (payable)` : p.status, p.dueDate ? formatDate(p.dueDate) : "-"])
4101
4424
  );
4102
4425
  const next = payments.find((p) => p.payable);
4103
- if (next) info(`Pay it: delegance pay ${next.id}`);
4426
+ if (next) info(`Pay it: ${cliInvocation()} pay ${next.id}`);
4104
4427
  return;
4105
4428
  }
4106
4429
  const { checkoutUrl } = await client.payments.checkout(paymentId);
@@ -4130,14 +4453,14 @@ function bondStartLines(r, ctx = {}) {
4130
4453
  out.push(` ${str(q.key)}: ${str(q.label)}${q.required ? " (required)" : ""}${opts}`);
4131
4454
  });
4132
4455
  }
4133
- out.push(`Answer with: delegance bond answer ${str(r.session_id)} --answers answers.json`);
4456
+ out.push(`Answer with: ${cliInvocation()} bond answer ${str(r.session_id)} --answers answers.json`);
4134
4457
  return out;
4135
4458
  }
4136
4459
  if (Array.isArray(r.candidates) && r.candidates.length) {
4137
4460
  out.push("That name fits more than one bond. Rerun with the exact name:");
4138
4461
  const rawState = (ctx.state ?? "").trim();
4139
4462
  const state = !rawState ? null : /^[A-Za-z]{2}$/.test(rawState) ? rawState.toUpperCase() : shellQuote(rawState);
4140
- r.candidates.forEach((name) => out.push(state ? ` delegance bond quote --state ${state} --bond ${shellQuote(str(name))}` : ` --bond ${shellQuote(str(name))}`));
4463
+ r.candidates.forEach((name) => out.push(state ? ` ${cliInvocation()} bond quote --state ${state} --bond ${shellQuote(str(name))}` : ` --bond ${shellQuote(str(name))}`));
4141
4464
  return out;
4142
4465
  }
4143
4466
  if (r.needsAmount) {
@@ -4192,7 +4515,7 @@ function createBondCommand() {
4192
4515
  if (options.json) json(r);
4193
4516
  else {
4194
4517
  console.log(JSON.stringify(r, null, 2));
4195
- info(`Check it: delegance bond status ${sessionId}`);
4518
+ info(`Check it: ${cliInvocation()} bond status ${sessionId}`);
4196
4519
  }
4197
4520
  } catch (err) {
4198
4521
  failWith("Could not submit the answers", err);
@@ -4269,6 +4592,7 @@ function createClaimCommand() {
4269
4592
 
4270
4593
  // src/program.ts
4271
4594
  function createProgram() {
4595
+ registerMinimalCheckbox();
4272
4596
  const program2 = new import_commander19.Command();
4273
4597
  program2.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", () => {
4274
4598
  migrateLegacyConfigKey();
@@ -4303,9 +4627,9 @@ function createProgram() {
4303
4627
  var program = createProgram();
4304
4628
  installLastCommandRecorder(program);
4305
4629
  program.on("command:*", () => {
4306
- console.error(import_chalk3.default.red(`Unknown command: ${program.args.join(" ")}`));
4630
+ console.error(import_chalk4.default.red(`Unknown command: ${program.args.join(" ")}`));
4307
4631
  console.log();
4308
- console.log('Run "delegance --help" for a list of available commands.');
4632
+ console.log(`Run "${cliInvocation()} --help" for a list of available commands.`);
4309
4633
  process.exit(1);
4310
4634
  });
4311
4635
  if (process.argv.length === 2) {