@delegance/cli 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,17 +27,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  var import_chalk4 = __toESM(require("chalk"));
28
28
 
29
29
  // src/program.ts
30
- var import_commander19 = require("commander");
30
+ var import_commander20 = require("commander");
31
31
 
32
32
  // src/version.ts
33
- var CLI_VERSION = "0.2.2";
33
+ var CLI_VERSION = "0.3.0";
34
34
 
35
35
  // src/commands/auth.ts
36
36
  var os4 = __toESM(require("os"));
37
- var import_commander2 = require("commander");
38
- var import_inquirer2 = __toESM(require("inquirer"));
37
+ var import_commander3 = require("commander");
38
+ var import_inquirer3 = __toESM(require("inquirer"));
39
39
  var import_ora2 = __toESM(require("ora"));
40
- var import_sdk3 = require("@delegance/sdk");
40
+ var import_sdk4 = require("@delegance/sdk");
41
41
 
42
42
  // src/utils/config.ts
43
43
  var import_conf = __toESM(require("conf"));
@@ -502,10 +502,10 @@ function openInBrowser(url, platform = process.platform) {
502
502
 
503
503
  // src/commands/signup.ts
504
504
  var import_crypto = require("crypto");
505
- var import_commander = require("commander");
506
- var import_inquirer = __toESM(require("inquirer"));
505
+ var import_commander2 = require("commander");
506
+ var import_inquirer2 = __toESM(require("inquirer"));
507
507
  var import_ora = __toESM(require("ora"));
508
- var import_sdk2 = require("@delegance/sdk");
508
+ var import_sdk3 = require("@delegance/sdk");
509
509
 
510
510
  // src/utils/pending-signup.ts
511
511
  var fs3 = __toESM(require("fs"));
@@ -546,6 +546,82 @@ function clearPendingSignup(home) {
546
546
  }
547
547
  }
548
548
 
549
+ // src/commands/terms.ts
550
+ var import_commander = require("commander");
551
+ var import_inquirer = __toESM(require("inquirer"));
552
+ var import_sdk2 = require("@delegance/sdk");
553
+ function termsAcceptRefusal(prompted) {
554
+ if (!prompted) {
555
+ return { kind: "error", message: `No prompt to answer. Read the Terms, then run "${cliCommand("terms accept --yes")}".` };
556
+ }
557
+ return { kind: "warn", message: "Not accepted. You can still quote; binding needs the current Terms." };
558
+ }
559
+ function termsLines(t) {
560
+ return [
561
+ `Delegance Terms of Service (version ${t.version}): ${t.termsUrl}`,
562
+ `Privacy Policy: ${t.privacyUrl}`,
563
+ ...t.summaries
564
+ ];
565
+ }
566
+ async function confirmTerms(t, opts) {
567
+ termsLines(t).forEach((l) => (opts.print ?? info)(l));
568
+ if (opts.flag) return true;
569
+ if (!opts.interactive) return false;
570
+ const ask = opts.ask ?? (async () => {
571
+ const a = await import_inquirer.default.prompt([{
572
+ type: "confirm",
573
+ name: "ok",
574
+ message: "Do you accept the Terms of Service and Privacy Policy?",
575
+ default: false
576
+ }]);
577
+ return a.ok === true;
578
+ });
579
+ return ask();
580
+ }
581
+ function createTermsCommand() {
582
+ const cmd = new import_commander.Command("terms").description("Show the Delegance Terms of Service, or accept the current version").option("--json", "Output as JSON").action(async (options) => {
583
+ try {
584
+ const t = await (0, import_sdk2.createSignup)({ baseUrl: getBaseUrl() }).getTerms();
585
+ if (options.json) {
586
+ json(t);
587
+ return;
588
+ }
589
+ termsLines(t).forEach((l) => info(l));
590
+ info(`Broker review before you bind: ${t.brokerReview.command}, or email ${t.brokerReview.email}`);
591
+ } catch (err) {
592
+ failWith("Could not load the Terms", err);
593
+ }
594
+ });
595
+ cmd.command("accept").description("Accept the current Terms of Service for your account (a bind can require it)").option("-y, --yes", "Accept without the prompt (you have read the Terms)").option("--json", "Output as JSON").action(async (options) => {
596
+ const client = getClient();
597
+ try {
598
+ const t = await client.terms.get();
599
+ const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY) && !options.json;
600
+ const ok = await confirmTerms(t, {
601
+ flag: options.yes === true,
602
+ interactive,
603
+ // --json keeps stdout to one JSON document; the Terms still print, on stderr.
604
+ ...options.json ? { print: (l) => console.error(l) } : {}
605
+ });
606
+ if (!ok) {
607
+ const refusal = termsAcceptRefusal(interactive);
608
+ if (refusal.kind === "error") error(refusal.message);
609
+ else warn(refusal.message);
610
+ process.exit(1);
611
+ }
612
+ const r = await client.terms.accept(t.version);
613
+ if (options.json) {
614
+ json(r);
615
+ return;
616
+ }
617
+ success(`Accepted the Terms of Service, version ${r.version}.`);
618
+ } catch (err) {
619
+ failWith("Could not record your acceptance", err);
620
+ }
621
+ });
622
+ return cmd;
623
+ }
624
+
549
625
  // src/commands/signup.ts
550
626
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
551
627
  var COMPANY_SIZES = ["0", "1", "2-10", "11-25", "26-50", "51-100", "100-499", "500+"];
@@ -570,8 +646,44 @@ function addressProblem(a) {
570
646
  if (!/^\d{5}(-\d{4})?$/.test(a.zip.trim())) return "ZIP must be 5 digits (or ZIP+4).";
571
647
  return null;
572
648
  }
649
+ var TERMS_REASONS = /* @__PURE__ */ new Set(["terms_not_accepted", "terms_version_outdated"]);
650
+ function isTermsRefusal(err) {
651
+ return err instanceof import_sdk3.DeleganceError && TERMS_REASONS.has(String(err.reason ?? ""));
652
+ }
653
+ async function loadSignupTerms(get) {
654
+ try {
655
+ return await get();
656
+ } catch (err) {
657
+ if (err instanceof import_sdk3.DeleganceError && err.statusCode === 404) return null;
658
+ throw err;
659
+ }
660
+ }
661
+ async function loadSignupTermsOrExit(baseUrl) {
662
+ try {
663
+ return await loadSignupTerms(() => (0, import_sdk3.createSignup)({ baseUrl }).getTerms());
664
+ } catch (err) {
665
+ failWith("Could not load the Terms of Service", err);
666
+ }
667
+ }
668
+ function nonInteractiveMissing(options, terms) {
669
+ const missing = missingSignupFields(options);
670
+ if (terms && options.acceptTerms !== true) missing.push("--accept-terms");
671
+ return missing;
672
+ }
673
+ async function acceptTermsOrExit(baseUrl, flag, preloaded) {
674
+ const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
675
+ const terms = preloaded === void 0 ? await loadSignupTermsOrExit(baseUrl) : preloaded;
676
+ if (!terms) return "";
677
+ const ok = await confirmTerms(terms, { flag, interactive });
678
+ if (!ok) {
679
+ if (interactive) warn("Not signed up. Delegance needs your acceptance of the Terms and Privacy Policy to open an account.");
680
+ else error("No terminal to ask in. Read the Terms and Privacy Policy above, then pass --accept-terms.");
681
+ process.exit(1);
682
+ }
683
+ return terms.version;
684
+ }
573
685
  function exchangeRefusal(err) {
574
- if (!(err instanceof import_sdk2.DeleganceError)) return null;
686
+ if (!(err instanceof import_sdk3.DeleganceError)) return null;
575
687
  switch (err.reason) {
576
688
  case "account_exists":
577
689
  return `This email already has a Delegance account, so signup did not attach it to a new one. Sign in and create a key at ${PORTAL_URL}/portal/settings/api-keys`;
@@ -585,19 +697,21 @@ function exchangeRefusal(err) {
585
697
  }
586
698
  async function ensureEnrolled(pending) {
587
699
  if (pending.enrollmentId) return pending;
588
- const signup = (0, import_sdk2.createSignup)({ baseUrl: pending.baseUrl });
700
+ const signup = (0, import_sdk3.createSignup)({ baseUrl: pending.baseUrl });
589
701
  const hash = (0, import_crypto.createHash)("sha256").update(pending.deviceSecret).digest("hex");
590
702
  const enrollment = await signup.enroll(pending.bootstrapKey, {
591
703
  deviceSecretHash: hash,
592
704
  firstName: pending.firstName ?? "",
593
- lastName: pending.lastName ?? ""
705
+ lastName: pending.lastName ?? "",
706
+ termsAccepted: true,
707
+ termsVersion: pending.termsVersion ?? ""
594
708
  });
595
709
  const next = { ...pending, enrollmentId: enrollment.enrollmentId, verificationSent: false };
596
710
  savePendingSignup(next);
597
711
  return sendVerification(next);
598
712
  }
599
713
  async function sendVerification(pending) {
600
- await (0, import_sdk2.createSignup)({ baseUrl: pending.baseUrl }).requestVerification(pending.bootstrapKey);
714
+ await (0, import_sdk3.createSignup)({ baseUrl: pending.baseUrl }).requestVerification(pending.bootstrapKey);
601
715
  const next = { ...pending, verificationSent: true };
602
716
  savePendingSignup(next);
603
717
  return next;
@@ -614,7 +728,7 @@ function storeOrPrintKey(apiKey, store = storeApiKey) {
614
728
  }
615
729
  }
616
730
  async function waitAndStore(pending, timeoutMs) {
617
- const signup = (0, import_sdk2.createSignup)({ baseUrl: pending.baseUrl });
731
+ const signup = (0, import_sdk3.createSignup)({ baseUrl: pending.baseUrl });
618
732
  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();
619
733
  const started = Date.now();
620
734
  try {
@@ -665,21 +779,24 @@ function signupPrompts(options, interactive) {
665
779
  return all.filter((q) => q.when !== false).map(({ when: _when, ...q }) => q);
666
780
  }
667
781
  function createSignupCommand() {
668
- return new import_commander.Command("signup").description("Create a Delegance account and get an API key, from the terminal").option("-e, --email <email>", "Your work email (the confirm link goes here)").option("-b, --business <name>", "Business name").option("--first <name>", "Your first name").option("--last <name>", "Your last name").option("-i, --industry <industry>", 'What the business does, e.g. "commercial bakery"').option("--size <size>", `Employees: ${COMPANY_SIZES.join(", ")}`).option("-w, --website <url>", "Website (full URL)").option("--street <street>", "Business street address").option("--city <city>", "City").option("--state <state>", "State, 2-letter code (carriers quote by state)").option("--zip <zip>", "ZIP code").option("-d, --description <text>", "A sentence on what the business does (helps carriers classify it)").option("--timeout <minutes>", "How long to wait for the email click", "15").option("--no-wait", 'Send the email and exit; collect later with "delegance verify"').action(async (options) => {
782
+ return new import_commander2.Command("signup").description("Create a Delegance account and get an API key, from the terminal").option("-e, --email <email>", "Your work email (the confirm link goes here)").option("-b, --business <name>", "Business name").option("--first <name>", "Your first name").option("--last <name>", "Your last name").option("-i, --industry <industry>", 'What the business does, e.g. "commercial bakery"').option("--size <size>", `Employees: ${COMPANY_SIZES.join(", ")}`).option("-w, --website <url>", "Website (full URL)").option("--street <street>", "Business street address").option("--city <city>", "City").option("--state <state>", "State, 2-letter code (carriers quote by state)").option("--zip <zip>", "ZIP code").option("-d, --description <text>", "A sentence on what the business does (helps carriers classify it)").option("--accept-terms", "Accept the Terms of Service and Privacy Policy (shown before the account is created)").option("--timeout <minutes>", "How long to wait for the email click", "15").option("--no-wait", 'Send the email and exit; collect later with "delegance verify"').action(async (options) => {
669
783
  const existing = loadPendingSignup();
670
784
  if (existing) {
671
785
  warn(`A signup for ${existing.email} is already waiting for its email confirmation.`);
672
786
  info(`Run "${cliInvocation()} verify" to finish it, or "${cliInvocation()} verify --cancel" to start over.`);
673
787
  process.exit(1);
674
788
  }
789
+ const baseUrl = getBaseUrl();
790
+ let preloadedTerms;
675
791
  if (!(process.stdin.isTTY && process.stdout.isTTY)) {
676
- const missing = missingSignupFields(options);
792
+ preloadedTerms = await loadSignupTermsOrExit(baseUrl);
793
+ const missing = nonInteractiveMissing(options, preloadedTerms);
677
794
  if (missing.length) {
678
795
  error(`No terminal to ask in. Missing: ${missing.join(" ")}`);
679
796
  process.exit(1);
680
797
  }
681
798
  }
682
- const answers = await import_inquirer.default.prompt(signupPrompts(options, Boolean(process.stdin.isTTY && process.stdout.isTTY)));
799
+ const answers = await import_inquirer2.default.prompt(signupPrompts(options, Boolean(process.stdin.isTTY && process.stdout.isTTY)));
683
800
  const address = {
684
801
  street: String(options.street ?? answers.street).trim(),
685
802
  city: String(options.city ?? answers.city).trim(),
@@ -702,8 +819,8 @@ function createSignupCommand() {
702
819
  error(`--size must be one of: ${COMPANY_SIZES.join(", ")}`);
703
820
  process.exit(1);
704
821
  }
705
- const baseUrl = getBaseUrl();
706
- const signup = (0, import_sdk2.createSignup)({ baseUrl });
822
+ const termsVersion = await acceptTermsOrExit(baseUrl, options.acceptTerms === true, preloadedTerms);
823
+ const signup = (0, import_sdk3.createSignup)({ baseUrl });
707
824
  const spinner = (0, import_ora.default)("Creating your account...").start();
708
825
  try {
709
826
  const account = await signup.createAccount({
@@ -715,7 +832,7 @@ function createSignupCommand() {
715
832
  ...description ? { description } : {},
716
833
  ...options.website ? { website: options.website } : {}
717
834
  });
718
- const device = (0, import_sdk2.newDeviceSecret)();
835
+ const device = (0, import_sdk3.newDeviceSecret)();
719
836
  let pending = {
720
837
  enrollmentId: "",
721
838
  deviceSecret: device.secret,
@@ -724,6 +841,7 @@ function createSignupCommand() {
724
841
  email,
725
842
  firstName: String(options.first ?? answers.first).trim(),
726
843
  lastName: String(options.last ?? answers.last).trim(),
844
+ termsVersion,
727
845
  baseUrl,
728
846
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
729
847
  };
@@ -745,14 +863,14 @@ function createSignupCommand() {
745
863
  });
746
864
  }
747
865
  function resendFailureMessage(err) {
748
- if (err instanceof import_sdk2.DeleganceError && (err.statusCode === 401 || err.statusCode === 403)) {
866
+ if (err instanceof import_sdk3.DeleganceError && (err.statusCode === 401 || err.statusCode === 403)) {
749
867
  return "Your email is already confirmed, so there is nothing to re-send. Collecting your key now.";
750
868
  }
751
869
  const why = err instanceof Error ? err.message : String(err);
752
870
  return `Could not re-send the email (${why}). Still waiting for the link you already have.`;
753
871
  }
754
872
  function createVerifyCommand() {
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) => {
873
+ return new import_commander2.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("--accept-terms", "Accept the Terms of Service, if this signup has not recorded an acceptance yet").option("--timeout <minutes>", "How long to wait", "15").action(async (options) => {
756
874
  const pending = loadPendingSignup();
757
875
  if (!pending) {
758
876
  info(`No signup is waiting on this machine. Start one with "${cliInvocation()} signup".`);
@@ -772,8 +890,21 @@ function createVerifyCommand() {
772
890
  failWith("Could not send the confirm email", err);
773
891
  }
774
892
  } else if (!pending.enrollmentId) {
893
+ let toEnroll = pending;
894
+ if (!pending.termsVersion) {
895
+ toEnroll = { ...pending, termsVersion: await acceptTermsOrExit(pending.baseUrl, options.acceptTerms === true) };
896
+ savePendingSignup(toEnroll);
897
+ }
775
898
  try {
776
- resumed = await ensureEnrolled(pending);
899
+ try {
900
+ resumed = await ensureEnrolled(toEnroll);
901
+ } catch (err) {
902
+ if (!isTermsRefusal(err)) throw err;
903
+ warn("The Terms of Service changed since this signup started. Review them again.");
904
+ toEnroll = { ...toEnroll, termsVersion: await acceptTermsOrExit(pending.baseUrl, options.acceptTerms === true) };
905
+ savePendingSignup(toEnroll);
906
+ resumed = await ensureEnrolled(toEnroll);
907
+ }
777
908
  success(`Finished setting up the signup. We emailed a confirm link to ${pending.email}.`);
778
909
  } catch (err) {
779
910
  failWith("Could not finish the signup", err);
@@ -781,7 +912,7 @@ function createVerifyCommand() {
781
912
  }
782
913
  if (options.resend && resumed === pending) {
783
914
  try {
784
- await (0, import_sdk2.createSignup)({ baseUrl: pending.baseUrl }).requestVerification(pending.bootstrapKey);
915
+ await (0, import_sdk3.createSignup)({ baseUrl: pending.baseUrl }).requestVerification(pending.bootstrapKey);
785
916
  success(`Sent the confirm link to ${pending.email} again.`);
786
917
  } catch (err) {
787
918
  info(resendFailureMessage(err));
@@ -812,7 +943,7 @@ function describeExpiry(expiresAt, now = /* @__PURE__ */ new Date()) {
812
943
  return `${date} (in ${days} day${days === 1 ? "" : "s"})`;
813
944
  }
814
945
  function deviceLoginRefusal(err) {
815
- if (!(err instanceof import_sdk3.DeleganceError)) return null;
946
+ if (!(err instanceof import_sdk4.DeleganceError)) return null;
816
947
  switch (err.reason) {
817
948
  case "access_denied":
818
949
  return "The request was denied in the portal. Nothing was stored.";
@@ -825,14 +956,14 @@ function deviceLoginRefusal(err) {
825
956
  }
826
957
  }
827
958
  function notAvailable(err) {
828
- return err instanceof import_sdk3.DeleganceError && (err.statusCode === 404 || err.reason === "not_available");
959
+ return err instanceof import_sdk4.DeleganceError && (err.statusCode === 404 || err.reason === "not_available");
829
960
  }
830
961
  function pasteFallbackHint() {
831
962
  info(`Create a key at ${PORTAL_URL}/portal/settings/api-keys, then run "${cliInvocation()} auth login --key <key>".`);
832
963
  }
833
964
  async function readKeyInfo(apiKey, timeoutMs = 5e3) {
834
965
  try {
835
- const client = new import_sdk3.DeleganceClient({ apiKey, baseUrl: getBaseUrl(), timeout: timeoutMs, retries: 0 });
966
+ const client = new import_sdk4.DeleganceClient({ apiKey, baseUrl: getBaseUrl(), timeout: timeoutMs, retries: 0 });
836
967
  return await client.auth.keyInfo();
837
968
  } catch {
838
969
  return null;
@@ -853,7 +984,7 @@ async function loginWithKey(apiKey, skipVerify) {
853
984
  }
854
985
  const spinner = (0, import_ora2.default)("Verifying API key...").start();
855
986
  try {
856
- const client = new import_sdk3.DeleganceClient({ apiKey, baseUrl: getBaseUrl() });
987
+ const client = new import_sdk4.DeleganceClient({ apiKey, baseUrl: getBaseUrl() });
857
988
  const isValid = await client.verifyApiKey();
858
989
  if (!isValid) {
859
990
  spinner.fail("API key verification failed");
@@ -874,8 +1005,8 @@ async function loginWithKey(apiKey, skipVerify) {
874
1005
  }
875
1006
  }
876
1007
  async function loginWithBrowser(openBrowser) {
877
- const login = (0, import_sdk3.createDeviceLogin)({ baseUrl: getBaseUrl() });
878
- const device = (0, import_sdk3.newDeviceSecret)();
1008
+ const login = (0, import_sdk4.createDeviceLogin)({ baseUrl: getBaseUrl() });
1009
+ const device = (0, import_sdk4.newDeviceSecret)();
879
1010
  let start;
880
1011
  try {
881
1012
  start = await login.start({ deviceSecretHash: device.hash, deviceName: defaultDeviceName() });
@@ -929,7 +1060,7 @@ async function loginWithBrowser(openBrowser) {
929
1060
  }
930
1061
  }
931
1062
  function createAuthCommand() {
932
- const auth = new import_commander2.Command("auth").description("Manage authentication");
1063
+ const auth = new import_commander3.Command("auth").description("Manage authentication");
933
1064
  auth.command("login").description("Sign in: approve this terminal in the portal, or store an API key").option("-k, --key <apiKey>", "Store this API key instead of signing in with the browser").option("--paste", "Prompt for an API key instead of signing in with the browser").option("--no-browser", "Print the approval link without opening a browser").option("--skip-verify", "With --key or --paste: store without verification (useful when API is not reachable)").action(async (options) => {
934
1065
  try {
935
1066
  if (options.key) {
@@ -937,7 +1068,7 @@ function createAuthCommand() {
937
1068
  return;
938
1069
  }
939
1070
  if (options.paste) {
940
- const answers = await import_inquirer2.default.prompt([
1071
+ const answers = await import_inquirer3.default.prompt([
941
1072
  {
942
1073
  type: "password",
943
1074
  name: "apiKey",
@@ -972,13 +1103,13 @@ function createAuthCommand() {
972
1103
  let origin = null;
973
1104
  let refused = null;
974
1105
  try {
975
- const client = new import_sdk3.DeleganceClient({ apiKey, baseUrl: getBaseUrl(), timeout: 5e3, retries: 0 });
1106
+ const client = new import_sdk4.DeleganceClient({ apiKey, baseUrl: getBaseUrl(), timeout: 5e3, retries: 0 });
976
1107
  const keyInfo = await client.auth.keyInfo();
977
1108
  origin = keyInfo.origin;
978
1109
  expiryLine = describeExpiry(keyInfo.expiresAt);
979
1110
  if (!fromEnv) setStoredKeyExpiry(keyInfo.expiresAt);
980
1111
  } catch (err) {
981
- if (err instanceof import_sdk3.DeleganceError && err.statusCode === 401) {
1112
+ if (err instanceof import_sdk4.DeleganceError && err.statusCode === 401) {
982
1113
  refused = err.reason === "key_expired" ? "Your API key expired" : err.reason === "key_membership_revoked" ? "Your API key was revoked: its user is no longer an active member of the company" : "Your API key was rejected by the server";
983
1114
  expiryLine = err.reason === "key_expired" ? "Expired" : "Not valid";
984
1115
  }
@@ -1008,13 +1139,13 @@ function createAuthCommand() {
1008
1139
  }
1009
1140
  const spinner = (0, import_ora2.default)("Refreshing your key...").start();
1010
1141
  try {
1011
- const client = new import_sdk3.DeleganceClient({ apiKey, baseUrl: getBaseUrl() });
1142
+ const client = new import_sdk4.DeleganceClient({ apiKey, baseUrl: getBaseUrl() });
1012
1143
  const { expiresAt } = await client.auth.refresh();
1013
1144
  if (!process.env.DELEGANCE_API_KEY) setStoredKeyExpiry(expiresAt);
1014
1145
  spinner.succeed(`Key refreshed. Expires ${describeExpiry(expiresAt)}.`);
1015
1146
  } catch (err) {
1016
1147
  spinner.stop();
1017
- if (err instanceof import_sdk3.DeleganceError && err.reason === "not_refreshable") {
1148
+ if (err instanceof import_sdk4.DeleganceError && err.reason === "not_refreshable") {
1018
1149
  info("This key came from the portal and keeps the expiry it was created with. Nothing changed.");
1019
1150
  return;
1020
1151
  }
@@ -1031,7 +1162,7 @@ function createAuthCommand() {
1031
1162
  return;
1032
1163
  }
1033
1164
  if (!options.force) {
1034
- const { confirm } = await import_inquirer2.default.prompt([
1165
+ const { confirm } = await import_inquirer3.default.prompt([
1035
1166
  {
1036
1167
  type: "confirm",
1037
1168
  name: "confirm",
@@ -1061,7 +1192,7 @@ function createAuthCommand() {
1061
1192
  }
1062
1193
  const spinner = (0, import_ora2.default)("Fetching account info...").start();
1063
1194
  try {
1064
- const client = new import_sdk3.DeleganceClient({
1195
+ const client = new import_sdk4.DeleganceClient({
1065
1196
  apiKey,
1066
1197
  baseUrl: getBaseUrl()
1067
1198
  });
@@ -1089,11 +1220,11 @@ function createAuthCommand() {
1089
1220
  }
1090
1221
 
1091
1222
  // src/commands/company.ts
1092
- var import_commander3 = require("commander");
1093
- var import_inquirer3 = __toESM(require("inquirer"));
1223
+ var import_commander4 = require("commander");
1224
+ var import_inquirer4 = __toESM(require("inquirer"));
1094
1225
  var import_ora3 = __toESM(require("ora"));
1095
1226
  function createCompanyCommand() {
1096
- const company = new import_commander3.Command("company").alias("companies").description("Manage companies");
1227
+ const company = new import_commander4.Command("company").alias("companies").description("Manage companies");
1097
1228
  company.command("list").description("List companies").option("--include-created", "Include companies created via this API key").option("--json", "Output as JSON").action(async (options) => {
1098
1229
  const client = getClient();
1099
1230
  const spinner = (0, import_ora3.default)("Fetching companies...").start();
@@ -1129,7 +1260,7 @@ function createCompanyCommand() {
1129
1260
  company.command("create").description("Create a new company").option("-n, --name <name>", "Company name").option("-i, --industry <industry>", "Industry").option("-s, --size <size>", "Company size (1, 2-10, 11-25, 26-50, 51-100, 100-499, 500+)").option("-e, --email <email>", "Contact email").option("--fein <fein>", "FEIN (XX-XXXXXXX)").option("--website <url>", "Website URL").option("--external-id <id>", "External ID for deduplication").option("--interactive", "Interactive mode with prompts").option("--json", "Output as JSON").action(async (options) => {
1130
1261
  let companyData;
1131
1262
  if (options.interactive || !options.name && !options.industry) {
1132
- const answers = await import_inquirer3.default.prompt([
1263
+ const answers = await import_inquirer4.default.prompt([
1133
1264
  {
1134
1265
  type: "input",
1135
1266
  name: "name",
@@ -1275,7 +1406,7 @@ function createCompanyCommand() {
1275
1406
  }
1276
1407
 
1277
1408
  // src/commands/document.ts
1278
- var import_commander4 = require("commander");
1409
+ var import_commander5 = require("commander");
1279
1410
  var import_ora4 = __toESM(require("ora"));
1280
1411
  var fs4 = __toESM(require("fs"));
1281
1412
  var path4 = __toESM(require("path"));
@@ -1286,7 +1417,7 @@ function extractionOutcome(status) {
1286
1417
  return "pending";
1287
1418
  }
1288
1419
  function createDocumentCommand() {
1289
- const doc = new import_commander4.Command("doc").alias("docs").alias("document").alias("documents").description("Manage documents");
1420
+ const doc = new import_commander5.Command("doc").alias("docs").alias("document").alias("documents").description("Manage documents");
1290
1421
  doc.command("upload <files...>").description("Upload one or more documents").option("-c, --company <id>", "Company ID (or use default)").option("-t, --type <type>", "Document type (policy, loss_run, financial_statement, sov, application, certificate, endorsement, bor, other)").option("--external-id <id>", "External ID for reference").option("-w, --wait", "Wait for extraction to complete").option("--timeout <ms>", "Timeout for waiting (default: 120000)", "120000").option("--json", "Output as JSON").action(async (filePatterns, options) => {
1291
1422
  const companyId = getCompanyId(options);
1292
1423
  const client = getClient();
@@ -1564,11 +1695,11 @@ function createDocumentCommand() {
1564
1695
  }
1565
1696
 
1566
1697
  // src/commands/chat.ts
1567
- var import_commander5 = require("commander");
1698
+ var import_commander6 = require("commander");
1568
1699
  var import_ora5 = __toESM(require("ora"));
1569
- var import_inquirer4 = __toESM(require("inquirer"));
1700
+ var import_inquirer5 = __toESM(require("inquirer"));
1570
1701
  function createChatCommand() {
1571
- const chat = new import_commander5.Command("ask").alias("chat").description("Ask the Orin insurance assistant a question");
1702
+ const chat = new import_commander6.Command("ask").alias("chat").description("Ask the Orin insurance assistant a question");
1572
1703
  chat.command("query <question...>").alias("q").description("Ask a single question").option("-c, --conversation <id>", "Continue a previous conversation").option("--json", "Output as JSON").action(async (questionParts, options) => {
1573
1704
  const question = questionParts.join(" ");
1574
1705
  const client = getClient();
@@ -1604,7 +1735,7 @@ function createChatCommand() {
1604
1735
  console.log('Type your questions. Enter "exit" or "quit" to end the session.');
1605
1736
  console.log();
1606
1737
  while (true) {
1607
- const { question } = await import_inquirer4.default.prompt([
1738
+ const { question } = await import_inquirer5.default.prompt([
1608
1739
  {
1609
1740
  type: "input",
1610
1741
  name: "question",
@@ -1664,18 +1795,18 @@ function createChatCommand() {
1664
1795
  }
1665
1796
 
1666
1797
  // src/commands/quote.ts
1667
- var import_commander6 = require("commander");
1798
+ var import_commander7 = require("commander");
1668
1799
  var import_ora7 = __toESM(require("ora"));
1669
- var import_inquirer6 = __toESM(require("inquirer"));
1670
- var import_sdk5 = require("@delegance/sdk");
1800
+ var import_inquirer7 = __toESM(require("inquirer"));
1801
+ var import_sdk6 = require("@delegance/sdk");
1671
1802
 
1672
1803
  // src/commands/instant-quote.ts
1673
1804
  var fs5 = __toESM(require("fs"));
1674
1805
  var import_crypto2 = require("crypto");
1675
1806
  var import_chalk2 = __toESM(require("chalk"));
1676
- var import_inquirer5 = __toESM(require("inquirer"));
1807
+ var import_inquirer6 = __toESM(require("inquirer"));
1677
1808
  var import_ora6 = __toESM(require("ora"));
1678
- var import_sdk4 = require("@delegance/sdk");
1809
+ var import_sdk5 = require("@delegance/sdk");
1679
1810
 
1680
1811
  // src/utils/coverage-names.ts
1681
1812
  var NAMES = {
@@ -2014,16 +2145,11 @@ var DEMO_STATUS = {
2014
2145
  };
2015
2146
 
2016
2147
  // src/commands/instant-quote.ts
2017
- function shellArg(value) {
2018
- return /^[\w@%+=:,./-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
2019
- }
2020
- function activeRequestLines(err, coverageFlag, ctx = {}) {
2021
- if (!(err instanceof import_sdk4.DeleganceError) || err.statusCode !== 409 || !err.body) return null;
2148
+ function activeRequestLines(err, coverageFlag) {
2149
+ if (!(err instanceof import_sdk5.DeleganceError) || err.statusCode !== 409 || !err.body) return null;
2022
2150
  const { body } = err;
2023
2151
  const code = body.message;
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;
2152
+ const requote = `${cliInvocation()} quote start --coverage ${coverageFlag} --replace`;
2027
2153
  if (code === "active_request_exists") {
2028
2154
  const active = Array.isArray(body.active) ? body.active : [];
2029
2155
  const first = active[0];
@@ -2031,7 +2157,7 @@ function activeRequestLines(err, coverageFlag, ctx = {}) {
2031
2157
  const carriers = Array.isArray(first?.carriers) ? first.carriers.map((c) => `${c.carrierId}${c.state ? ` (${c.state.toLowerCase()})` : ""}`).join(", ") : "";
2032
2158
  return [
2033
2159
  `Already with carriers${id ? `: ${id}` : ""}${carriers ? `, ${carriers}` : ""}.`,
2034
- `Check it: ${id ? `${cliInvocation()} quote status ${id}` : `${cliInvocation()} quote status <id>`} Replace it: ${replaceCmd}`
2160
+ `Check it: ${id ? `${cliInvocation()} quote status ${id}` : `${cliInvocation()} quote status <id>`} Replace it: ${requote}`
2035
2161
  ];
2036
2162
  }
2037
2163
  if (code === "replace_conflict") {
@@ -2083,7 +2209,7 @@ async function askOne(q, answers, fallback) {
2083
2209
  }
2084
2210
  };
2085
2211
  }
2086
- const { v } = await import_inquirer5.default.prompt([prompt]);
2212
+ const { v } = await import_inquirer6.default.prompt([prompt]);
2087
2213
  const c = coerceAnswer(q, v);
2088
2214
  if (c.ok && c.value !== void 0) answers[q.id] = c.value;
2089
2215
  }
@@ -2094,7 +2220,7 @@ async function askQuestions(questions, answers = {}) {
2094
2220
  const round = planQuestionRound(questions, answers, handled);
2095
2221
  if (round.confirm.length + round.checklist.length + round.ask.length === 0) break;
2096
2222
  if (round.confirm.length) {
2097
- const { keep } = await import_inquirer5.default.prompt([
2223
+ const { keep } = await import_inquirer6.default.prompt([
2098
2224
  {
2099
2225
  type: "checkbox",
2100
2226
  name: "keep",
@@ -2123,7 +2249,7 @@ async function askQuestions(questions, answers = {}) {
2123
2249
  }
2124
2250
  }
2125
2251
  if (round.checklist.length) {
2126
- const { yes } = await import_inquirer5.default.prompt([
2252
+ const { yes } = await import_inquirer6.default.prompt([
2127
2253
  {
2128
2254
  type: "checkbox",
2129
2255
  name: "yes",
@@ -2134,7 +2260,7 @@ async function askQuestions(questions, answers = {}) {
2134
2260
  ]);
2135
2261
  const yn = checklistAnswers(round.checklist, yes);
2136
2262
  const yesCount = Object.values(yn).filter((v) => v === "yes").length;
2137
- const { ok } = await import_inquirer5.default.prompt([
2263
+ const { ok } = await import_inquirer6.default.prompt([
2138
2264
  { type: "confirm", name: "ok", message: `Yes to ${yesCount}, No to ${round.checklist.length - yesCount}. Correct?`, default: true }
2139
2265
  ]);
2140
2266
  if (ok) {
@@ -2168,7 +2294,7 @@ async function runBrokerHandoff(submissionId, instantAnswers, opts) {
2168
2294
  try {
2169
2295
  plan = await client.instantQuotes.brokerHandoffQuestions(submissionId, instantAnswers);
2170
2296
  } catch (err) {
2171
- if (err instanceof import_sdk4.DeleganceError && err.statusCode === 503) {
2297
+ if (err instanceof import_sdk5.DeleganceError && err.statusCode === 503) {
2172
2298
  say("A broker can still market it: reply to the confirmation email, or start in the portal.");
2173
2299
  return;
2174
2300
  }
@@ -2434,7 +2560,7 @@ function addInstantQuoteCommands(quote) {
2434
2560
  ...options.replace ? { replace: true } : {}
2435
2561
  });
2436
2562
  } catch (err) {
2437
- const guardLines = activeRequestLines(err, String(options.coverage), { answersFile: options.answers });
2563
+ const guardLines = activeRequestLines(err, String(options.coverage));
2438
2564
  if (guardLines) {
2439
2565
  submitSpinner.fail("Nothing was sent.");
2440
2566
  guardLines.forEach((l) => options.json ? console.error(l) : info(l));
@@ -2502,10 +2628,7 @@ function addInstantQuoteCommands(quote) {
2502
2628
  }
2503
2629
  await waitAndPrint(submissionId, Number(options.timeout) * 6e4 || 6e5, !!options.json);
2504
2630
  } catch (err) {
2505
- const guardLines = activeRequestLines(err, "<list>", {
2506
- answersFile: options.answers,
2507
- submit: { submissionId, sessionVersion: String(options.sessionVersion) }
2508
- });
2631
+ const guardLines = activeRequestLines(err, "<list>");
2509
2632
  if (guardLines) {
2510
2633
  error("Nothing was sent.");
2511
2634
  guardLines.forEach((l) => options.json ? console.error(l) : info(l));
@@ -2557,7 +2680,7 @@ async function waitAndPrint(submissionId, timeoutMs, asJson) {
2557
2680
  // src/commands/quote.ts
2558
2681
  var QUOTE_SUBMISSION_UNAVAILABLE = "Quote submission via API isn't available yet";
2559
2682
  function createQuoteCommand() {
2560
- const quote = new import_commander6.Command("quote").alias("quotes").description("Request and manage insurance quotes");
2683
+ const quote = new import_commander7.Command("quote").alias("quotes").description("Request and manage insurance quotes");
2561
2684
  quote.command("carriers").description("List available carriers for quoting").option("--json", "Output as JSON").action(async (options) => {
2562
2685
  const client = getClient();
2563
2686
  const spinner = (0, import_ora7.default)("Fetching carriers...").start();
@@ -2604,7 +2727,7 @@ function createQuoteCommand() {
2604
2727
  process.exit(1);
2605
2728
  }
2606
2729
  if (options.interactive || carrierIds.length === 0 && !options.all) {
2607
- const { selectedCarriers } = await import_inquirer6.default.prompt([
2730
+ const { selectedCarriers } = await import_inquirer7.default.prompt([
2608
2731
  {
2609
2732
  type: "checkbox",
2610
2733
  name: "selectedCarriers",
@@ -2664,7 +2787,7 @@ function createQuoteCommand() {
2664
2787
  }
2665
2788
  } catch (err) {
2666
2789
  spinner.fail("Failed to submit quote request");
2667
- if (err instanceof import_sdk5.NotImplementedError) {
2790
+ if (err instanceof import_sdk6.NotImplementedError) {
2668
2791
  error(QUOTE_SUBMISSION_UNAVAILABLE);
2669
2792
  info(`For an instant quote from the terminal: ${cliInvocation()} quote start --coverage gl`);
2670
2793
  info(`Or start a quote at ${PORTAL_URL}`);
@@ -2797,11 +2920,11 @@ function formatQuoteStatus(status) {
2797
2920
  }
2798
2921
 
2799
2922
  // src/commands/policy.ts
2800
- var import_commander7 = require("commander");
2801
- var import_inquirer7 = __toESM(require("inquirer"));
2923
+ var import_commander8 = require("commander");
2924
+ var import_inquirer8 = __toESM(require("inquirer"));
2802
2925
  var import_ora8 = __toESM(require("ora"));
2803
2926
  function createPolicyCommand() {
2804
- const policy = new import_commander7.Command("policy").alias("policies").description("Manage insurance policies");
2927
+ const policy = new import_commander8.Command("policy").alias("policies").description("Manage insurance policies");
2805
2928
  policy.command("list").alias("ls").description("List all policies").option("-s, --status <status>", "Filter by status (active, expired, all)", "active").option("-t, --type <type>", "Filter by policy type").option("-l, --limit <n>", "Maximum results", "50").option("--json", "Output as JSON").action(async (options) => {
2806
2929
  const client = getClient();
2807
2930
  const spinner = (0, import_ora8.default)("Fetching policies...").start();
@@ -3053,7 +3176,7 @@ async function signWithStepUp(client, requestId, sig, stepUpId, presetCode) {
3053
3176
  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>`);
3054
3177
  return;
3055
3178
  }
3056
- const answer = await import_inquirer7.default.prompt([{
3179
+ const answer = await import_inquirer8.default.prompt([{
3057
3180
  type: "input",
3058
3181
  name: "code",
3059
3182
  message: "Code from your email:",
@@ -3080,11 +3203,11 @@ function formatPolicyStatus(isActive, daysUntilExpiry) {
3080
3203
  }
3081
3204
 
3082
3205
  // src/commands/coi.ts
3083
- var import_commander8 = require("commander");
3206
+ var import_commander9 = require("commander");
3084
3207
  var import_ora9 = __toESM(require("ora"));
3085
- var import_inquirer8 = __toESM(require("inquirer"));
3208
+ var import_inquirer9 = __toESM(require("inquirer"));
3086
3209
  function createCOICommand() {
3087
- const coi = new import_commander8.Command("coi").description("Generate and manage Certificates of Insurance");
3210
+ const coi = new import_commander9.Command("coi").description("Generate and manage Certificates of Insurance");
3088
3211
  coi.command("generate").alias("create").description("Generate a Certificate of Insurance").option("-p, --policies <ids...>", "Policy IDs to include").option("-n, --holder-name <name>", "Certificate holder name").option("-a, --holder-address <address>", "Certificate holder address").option("--city <city>", "Certificate holder city").option("--state <state>", "Certificate holder state (2-letter)").option("--zip <zip>", "Certificate holder ZIP").option("-t, --type <type>", "Certificate type (additional_insured, certificate_holder)", "certificate_holder").option("-i, --interactive", "Interactive mode").option("--json", "Output as JSON").action(async (options) => {
3089
3212
  const client = getClient();
3090
3213
  let policyIds = options.policies || [];
@@ -3103,7 +3226,7 @@ function createCOICommand() {
3103
3226
  info(`Upload policy documents first with "${cliInvocation()} doc upload"`);
3104
3227
  process.exit(1);
3105
3228
  }
3106
- const answers = await import_inquirer8.default.prompt([
3229
+ const answers = await import_inquirer9.default.prompt([
3107
3230
  {
3108
3231
  type: "checkbox",
3109
3232
  name: "selectedPolicies",
@@ -3239,12 +3362,12 @@ function createCOICommand() {
3239
3362
  }
3240
3363
 
3241
3364
  // src/commands/sov.ts
3242
- var import_commander9 = require("commander");
3365
+ var import_commander10 = require("commander");
3243
3366
  var import_ora10 = __toESM(require("ora"));
3244
3367
  var import_fs = __toESM(require("fs"));
3245
3368
  var import_path = __toESM(require("path"));
3246
3369
  function createSOVCommand() {
3247
- const sov = new import_commander9.Command("sov").description("Manage Schedules of Values (property schedules)");
3370
+ const sov = new import_commander10.Command("sov").description("Manage Schedules of Values (property schedules)");
3248
3371
  sov.command("upload <file>").description("Upload a Schedule of Values file").option("-l, --line <line>", "Line of business (property, inland_marine, etc)", "property").option("--effective <date>", "Effective date (YYYY-MM-DD)").option("--expiration <date>", "Expiration date (YYYY-MM-DD)").option("-w, --wait", "Wait for parsing to complete").option("--json", "Output as JSON").action(async (file, options) => {
3249
3372
  const client = getClient();
3250
3373
  const filePath = import_path.default.resolve(file);
@@ -3402,7 +3525,7 @@ function showSOVDetails(s) {
3402
3525
  }
3403
3526
 
3404
3527
  // src/commands/appetite.ts
3405
- var import_commander10 = require("commander");
3528
+ var import_commander11 = require("commander");
3406
3529
  var import_ora11 = __toESM(require("ora"));
3407
3530
  function num(value) {
3408
3531
  if (value === void 0) return void 0;
@@ -3450,7 +3573,7 @@ function printResult(result) {
3450
3573
  for (const w of result.warnings) warn(w);
3451
3574
  }
3452
3575
  function createAppetiteCommand() {
3453
- const appetite = new import_commander10.Command("appetite").description("Check which carriers will write a risk");
3576
+ const appetite = new import_commander11.Command("appetite").description("Check which carriers will write a risk");
3454
3577
  appetite.command("match").description("Match a business to carrier appetite").requiredOption("-s, --state <state>", "Two-letter state code").option("-i, --industry <industry>", 'Industry, e.g. "bakery"').option("-d, --description <text>", "What the business does").option("--naics <code>", "NAICS code").option("--sic <code>", "SIC code").option("-c, --coverage <types>", "Comma-separated coverage types, e.g. general_liability,workers_comp").option("--carriers <names>", "Comma-separated carriers to limit the match to").option("--market-size <size>", '"Small Business" or "Middle Market"').option("--revenue <usd>", "Annual revenue").option("--payroll <usd>", "Annual payroll").option("--property-value <usd>", "Total property value").option("--min-fit <fit>", "Raise the quality floor: possible or strong").option("--top <n>", "Maximum matches (1-50)").option("--no-wait", "Return the job id instead of waiting for a cold match").option("--timeout <ms>", "How long to wait for a cold match", "120000").option("--json", "Output as JSON").action(async (options) => {
3455
3578
  const input = buildMatchInput(options);
3456
3579
  const timeoutMs = positiveInt(options.timeout, "--timeout");
@@ -3511,7 +3634,7 @@ function createAppetiteCommand() {
3511
3634
  }
3512
3635
 
3513
3636
  // src/commands/lead.ts
3514
- var import_commander11 = require("commander");
3637
+ var import_commander12 = require("commander");
3515
3638
  var import_ora12 = __toESM(require("ora"));
3516
3639
  function buildLeadInput(options) {
3517
3640
  const input = {
@@ -3542,7 +3665,7 @@ function buildLeadInput(options) {
3542
3665
  return input;
3543
3666
  }
3544
3667
  function createLeadCommand() {
3545
- const lead = new import_commander11.Command("lead").alias("leads").description("Send prospect businesses to Delegance");
3668
+ const lead = new import_commander12.Command("lead").alias("leads").description("Send prospect businesses to Delegance");
3546
3669
  lead.command("create").description("Create a lead (idempotent on --external-id and contact email)").requiredOption("-n, --name <name>", "Business name").requiredOption("-e, --email <email>", "Contact email").option("--legal-name <name>", "Legal name, if different").option("-i, --industry <industry>", "Industry").option("-p, --phone <phone>", "Contact phone").option("-w, --website <url>", "Website (full URL)").option("--size <size>", "Company size").option("-d, --description <text>", "What the business does").option("--naics <code>", "NAICS code").option("--sic <code>", "SIC code").option("-s, --state <state>", "Two-letter state code").option("--street <street>", "Street address").option("--suite <suite>", "Suite").option("--city <city>", "City").option("--address-state <state>", "Address state (defaults to --state)").option("--zip <zip>", "ZIP code").option("--external-id <id>", "Your id for this lead").option("--source <source>", "Lead source label").option("--notes <notes>", "Notes for the broker").option("--json", "Output as JSON").action(async (options) => {
3547
3670
  const input = buildLeadInput(options);
3548
3671
  if (input.address && (!input.address.street || !input.address.city || !input.address.state || !input.address.zip)) {
@@ -3565,11 +3688,11 @@ function createLeadCommand() {
3565
3688
  }
3566
3689
 
3567
3690
  // src/commands/knowledge.ts
3568
- var import_commander12 = require("commander");
3691
+ var import_commander13 = require("commander");
3569
3692
  var import_ora13 = __toESM(require("ora"));
3570
3693
  var SEARCH_TYPES = ["notecard", "document_chunk"];
3571
3694
  function createKnowledgeCommand() {
3572
- const knowledge = new import_commander12.Command("knowledge").alias("kb").description("Search notecards and document facts");
3695
+ const knowledge = new import_commander13.Command("knowledge").alias("kb").description("Search notecards and document facts");
3573
3696
  knowledge.command("search <query...>").description("Search notecards and document text").option("-t, --type <type>", `Limit to one result type (${SEARCH_TYPES.join(", ")})`).option("-l, --limit <n>", "Maximum results", "10").option("--json", "Output as JSON").action(async (queryParts, options) => {
3574
3697
  const client = getClient();
3575
3698
  const query = queryParts.join(" ");
@@ -3671,7 +3794,7 @@ function createKnowledgeCommand() {
3671
3794
  }
3672
3795
 
3673
3796
  // src/commands/onboarding.ts
3674
- var import_commander13 = require("commander");
3797
+ var import_commander14 = require("commander");
3675
3798
  var import_ora14 = __toESM(require("ora"));
3676
3799
  var ONBOARDING_STATES = [
3677
3800
  "created",
@@ -3681,7 +3804,7 @@ var ONBOARDING_STATES = [
3681
3804
  "ready"
3682
3805
  ];
3683
3806
  function createOnboardingCommand() {
3684
- const onboarding = new import_commander13.Command("onboarding").alias("onboard").description("Check account setup and onboarding state");
3807
+ const onboarding = new import_commander14.Command("onboarding").alias("onboard").description("Check account setup and onboarding state");
3685
3808
  onboarding.command("status").description("Show the setup checklist and the next step").option("--json", "Output as JSON").action(async (options) => {
3686
3809
  const client = getClient();
3687
3810
  const spinner = (0, import_ora14.default)("Fetching onboarding status...").start();
@@ -3772,7 +3895,7 @@ function createOnboardingCommand() {
3772
3895
  }
3773
3896
 
3774
3897
  // src/commands/usage.ts
3775
- var import_commander14 = require("commander");
3898
+ var import_commander15 = require("commander");
3776
3899
  var import_ora15 = __toESM(require("ora"));
3777
3900
  function isoDay(daysAgo, now = /* @__PURE__ */ new Date()) {
3778
3901
  const d = new Date(now.getTime() - daysAgo * 24 * 60 * 60 * 1e3);
@@ -3782,7 +3905,7 @@ function cents(n) {
3782
3905
  return `$${(n / 100).toFixed(2)}`;
3783
3906
  }
3784
3907
  function createUsageCommand() {
3785
- const usage = new import_commander14.Command("usage").description("Show API usage, billing, and rate limits");
3908
+ const usage = new import_commander15.Command("usage").description("Show API usage, billing, and rate limits");
3786
3909
  usage.command("summary").description("Usage for the current billing period").option("--json", "Output as JSON").action(async (options) => {
3787
3910
  const client = getClient();
3788
3911
  const spinner = (0, import_ora15.default)("Fetching usage summary...").start();
@@ -3862,10 +3985,10 @@ function createUsageCommand() {
3862
3985
  }
3863
3986
 
3864
3987
  // src/commands/keys.ts
3865
- var import_commander15 = require("commander");
3988
+ var import_commander16 = require("commander");
3866
3989
  var import_ora16 = __toESM(require("ora"));
3867
3990
  var import_crypto3 = require("crypto");
3868
- var import_sdk6 = require("@delegance/sdk");
3991
+ var import_sdk7 = require("@delegance/sdk");
3869
3992
  var KEYS_PORTAL_URL = `${PORTAL_URL}/portal/settings/api-keys`;
3870
3993
  function parseExpiresInDays(raw) {
3871
3994
  if (raw === void 0 || raw === "") return void 0;
@@ -3874,9 +3997,9 @@ function parseExpiresInDays(raw) {
3874
3997
  }
3875
3998
  function parseScopes(raw) {
3876
3999
  const parts = (Array.isArray(raw) ? raw : [raw ?? "read,write"]).flatMap((p) => p.split(/[\s,]+/)).map((p) => p.trim()).filter(Boolean);
3877
- const unknown = parts.filter((p) => !import_sdk6.API_KEY_SCOPES.includes(p));
4000
+ const unknown = parts.filter((p) => !import_sdk7.API_KEY_SCOPES.includes(p));
3878
4001
  if (unknown.length > 0) {
3879
- throw new Error(`Unknown scope(s): ${unknown.join(", ")}. Allowed: ${import_sdk6.API_KEY_SCOPES.join(", ")}`);
4002
+ throw new Error(`Unknown scope(s): ${unknown.join(", ")}. Allowed: ${import_sdk7.API_KEY_SCOPES.join(", ")}`);
3880
4003
  }
3881
4004
  return Array.from(new Set(parts));
3882
4005
  }
@@ -3905,7 +4028,7 @@ function printCreatedKey(created) {
3905
4028
  console.log(` ${created.key}`);
3906
4029
  }
3907
4030
  function createKeysCommand() {
3908
- const keys = new import_commander15.Command("keys").alias("api-keys").description("Manage API keys");
4031
+ const keys = new import_commander16.Command("keys").alias("api-keys").description("Manage API keys");
3909
4032
  keys.command("list").alias("ls").description("List API keys for your company").option("-l, --limit <n>", "Maximum results", "50").option("--cursor <cursor>", "Page cursor from a previous list").option("--json", "Output as JSON").action(async (options) => {
3910
4033
  const client = getClient();
3911
4034
  const spinner = (0, import_ora16.default)("Fetching API keys...").start();
@@ -3941,7 +4064,7 @@ function createKeysCommand() {
3941
4064
  failWith("API error", err);
3942
4065
  }
3943
4066
  });
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) => {
4067
+ keys.command("create <name>").description("Create an API key (needs a key with the admin scope)").option("-s, --scopes <scopes>", `Comma-separated scopes (${import_sdk7.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) => {
3945
4068
  let scopes;
3946
4069
  try {
3947
4070
  scopes = parseScopes(options.scopes);
@@ -4020,7 +4143,7 @@ function createKeysCommand() {
4020
4143
  spinner.succeed("API key revoked");
4021
4144
  } catch (err) {
4022
4145
  spinner.fail("Failed to revoke API key");
4023
- if (err instanceof import_sdk6.AuthenticationError) {
4146
+ if (err instanceof import_sdk7.AuthenticationError) {
4024
4147
  error("Revoking a key needs a signed-in portal session today");
4025
4148
  info(`Revoke it at ${KEYS_PORTAL_URL}`);
4026
4149
  process.exit(1);
@@ -4032,10 +4155,10 @@ function createKeysCommand() {
4032
4155
  }
4033
4156
 
4034
4157
  // src/commands/config.ts
4035
- var import_commander16 = require("commander");
4036
- var import_inquirer9 = __toESM(require("inquirer"));
4158
+ var import_commander17 = require("commander");
4159
+ var import_inquirer10 = __toESM(require("inquirer"));
4037
4160
  function createConfigCommand() {
4038
- const config2 = new import_commander16.Command("config").description("Manage CLI configuration");
4161
+ const config2 = new import_commander17.Command("config").description("Manage CLI configuration");
4039
4162
  config2.command("show").alias("list").description("Show current configuration").option("--json", "Output as JSON").action((options) => {
4040
4163
  const currentConfig = getConfig();
4041
4164
  const apiKey = getApiKey();
@@ -4079,7 +4202,7 @@ function createConfigCommand() {
4079
4202
  });
4080
4203
  config2.command("reset").description("Reset all configuration to defaults").option("-f, --force", "Skip confirmation").action(async (options) => {
4081
4204
  if (!options.force) {
4082
- const { confirm } = await import_inquirer9.default.prompt([
4205
+ const { confirm } = await import_inquirer10.default.prompt([
4083
4206
  {
4084
4207
  type: "confirm",
4085
4208
  name: "confirm",
@@ -4164,9 +4287,9 @@ function createConfigCommand() {
4164
4287
  }
4165
4288
 
4166
4289
  // src/commands/feedback.ts
4167
- var import_commander17 = require("commander");
4168
- var import_inquirer10 = __toESM(require("inquirer"));
4169
- var import_sdk7 = require("@delegance/sdk");
4290
+ var import_commander18 = require("commander");
4291
+ var import_inquirer11 = __toESM(require("inquirer"));
4292
+ var import_sdk8 = require("@delegance/sdk");
4170
4293
  var TYPES = ["bug", "idea", "question"];
4171
4294
  var MESSAGE_MAX = 500;
4172
4295
  var USAGE = `${cliInvocation()} feedback "what happened" [--type bug|idea|question] [--include-last]`;
@@ -4183,7 +4306,7 @@ function buildFeedbackContext(last) {
4183
4306
  ctx.at = last.at;
4184
4307
  }
4185
4308
  ctx.cliVersion = CLI_VERSION;
4186
- ctx.sdkVersion = import_sdk7.SDK_VERSION;
4309
+ ctx.sdkVersion = import_sdk8.SDK_VERSION;
4187
4310
  return ctx;
4188
4311
  }
4189
4312
  function usageError(message) {
@@ -4192,14 +4315,14 @@ function usageError(message) {
4192
4315
  process.exit(2);
4193
4316
  }
4194
4317
  function createFeedbackCommand() {
4195
- return new import_commander17.Command("feedback").alias("bug").description("Report a bug, an idea, or a question to Delegance").argument("[message...]", "What happened (asked for when left out on a terminal)").option("-t, --type <type>", "bug, idea, or question", "bug").option("--include-last", "Attach the last command name, exit code, trace id, and CLI/SDK versions (never its arguments)").option("--json", "Output as JSON").action(async (words, options) => {
4318
+ return new import_commander18.Command("feedback").alias("bug").description("Report a bug, an idea, or a question to Delegance").argument("[message...]", "What happened (asked for when left out on a terminal)").option("-t, --type <type>", "bug, idea, or question", "bug").option("--include-last", "Attach the last command name, exit code, trace id, and CLI/SDK versions (never its arguments)").option("--json", "Output as JSON").action(async (words, options) => {
4196
4319
  const type = String(options.type ?? "bug").toLowerCase();
4197
4320
  if (!TYPES.includes(type)) usageError(`--type must be bug, idea, or question, got "${options.type}"`);
4198
4321
  let message = (words ?? []).join(" ").trim();
4199
4322
  const mode = feedbackInputMode({ message, isTTY: Boolean(process.stdin.isTTY && process.stdout.isTTY) });
4200
4323
  if (mode === "usage_error") usageError(`Say what happened: ${USAGE}`);
4201
4324
  if (mode === "prompt") {
4202
- const answer = await import_inquirer10.default.prompt([
4325
+ const answer = await import_inquirer11.default.prompt([
4203
4326
  { type: "input", name: "message", message: type === "bug" ? "What went wrong?" : "What would you like to tell us?" }
4204
4327
  ]);
4205
4328
  message = String(answer.message ?? "").trim();
@@ -4221,7 +4344,7 @@ function createFeedbackCommand() {
4221
4344
  }
4222
4345
 
4223
4346
  // src/utils/checkbox-prompt.ts
4224
- var import_inquirer11 = __toESM(require("inquirer"));
4347
+ var import_inquirer12 = __toESM(require("inquirer"));
4225
4348
  var import_chalk3 = __toESM(require("chalk"));
4226
4349
  var CHECKBOX_HINT = "(space to select, Enter to continue)";
4227
4350
  var registered = false;
@@ -4243,19 +4366,19 @@ function minimalCheckboxPrompt(Base) {
4243
4366
  }
4244
4367
  function registerMinimalCheckbox() {
4245
4368
  if (registered) return;
4246
- const prompts = import_inquirer11.default.prompt.prompts;
4369
+ const prompts = import_inquirer12.default.prompt.prompts;
4247
4370
  const Base = prompts?.checkbox;
4248
4371
  if (!Base) return;
4249
- import_inquirer11.default.registerPrompt("checkbox", minimalCheckboxPrompt(Base));
4372
+ import_inquirer12.default.registerPrompt("checkbox", minimalCheckboxPrompt(Base));
4250
4373
  registered = true;
4251
4374
  }
4252
4375
 
4253
4376
  // src/commands/commerce.ts
4254
- var import_commander18 = require("commander");
4377
+ var import_commander19 = require("commander");
4255
4378
  var fs7 = __toESM(require("fs"));
4256
- var import_inquirer12 = __toESM(require("inquirer"));
4379
+ var import_inquirer13 = __toESM(require("inquirer"));
4257
4380
  var import_ora17 = __toESM(require("ora"));
4258
- var import_sdk8 = require("@delegance/sdk");
4381
+ var import_sdk9 = require("@delegance/sdk");
4259
4382
  function formatCents(cents2, currency = "usd") {
4260
4383
  return currency.toLowerCase() === "usd" ? formatCurrency(cents2 / 100) : `${(cents2 / 100).toFixed(2)} ${currency.toUpperCase()}`;
4261
4384
  }
@@ -4281,6 +4404,35 @@ function describeBindResult(r) {
4281
4404
  lines.push(r.next);
4282
4405
  return lines;
4283
4406
  }
4407
+ var BROKER_REVIEW_EMAIL = "support@delegancebrokerage.com";
4408
+ function selfDirectedAckLines(submissionId, offerId) {
4409
+ return [
4410
+ "This is a self-directed placement: Delegance binds the coverage you chose and does not advise on whether it fits your needs (Terms Section 9A).",
4411
+ `Want a licensed broker to review it first? Run: ${cliInvocation()} bind ${submissionId} ${offerId} --broker-review`
4412
+ ];
4413
+ }
4414
+ function brokerReviewMailto(submissionId, offerId) {
4415
+ const subject = encodeURIComponent(`Broker review before bind: submission ${submissionId}, offer ${offerId}`);
4416
+ return `mailto:${BROKER_REVIEW_EMAIL}?subject=${subject}`;
4417
+ }
4418
+ function brokerReviewLines(submissionId, offerId) {
4419
+ return [
4420
+ "Nothing was bound, and no review has been requested yet.",
4421
+ `To request a review by a licensed Delegance broker, send an email to ${BROKER_REVIEW_EMAIL}`,
4422
+ `naming submission ${submissionId} and offer ${offerId}: ${brokerReviewMailto(submissionId, offerId)}`,
4423
+ "Wait for the broker to reply before you bind. A reviewed placement is not self-directed."
4424
+ ];
4425
+ }
4426
+ function brokerReviewResult(submissionId, offerId) {
4427
+ return {
4428
+ bound: false,
4429
+ reviewRequested: false,
4430
+ submissionId,
4431
+ offerId,
4432
+ brokerReview: { email: BROKER_REVIEW_EMAIL, mailto: brokerReviewMailto(submissionId, offerId) },
4433
+ message: brokerReviewLines(submissionId, offerId)
4434
+ };
4435
+ }
4284
4436
  function exactDollars(cents2) {
4285
4437
  return `$${(cents2 / 100).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
4286
4438
  }
@@ -4303,7 +4455,7 @@ function describeFinancing(f) {
4303
4455
  }
4304
4456
  async function askCode() {
4305
4457
  if (!process.stdin.isTTY) return null;
4306
- const answer = await import_inquirer12.default.prompt([{
4458
+ const answer = await import_inquirer13.default.prompt([{
4307
4459
  type: "input",
4308
4460
  name: "code",
4309
4461
  message: "Code from your email:",
@@ -4312,11 +4464,19 @@ async function askCode() {
4312
4464
  return String(answer.code).trim();
4313
4465
  }
4314
4466
  function createBindCommand() {
4315
- return new import_commander18.Command("bind").description('Bind one offer from "quote status": the carrier checkout when the carrier offers it, otherwise a broker review').argument("<submissionId>", "The quote submission id").argument("<offerId>", "The offer id from the quote table").option("--attest", "Confirm the application answers are accurate (asked interactively when omitted)").option("--step-up <id>", "Finish an earlier attempt: the stepUpId the code email belongs to").option("--code <code>", "The 6-digit code from the email").option("--json", "Output as JSON").action(async (submissionId, offerId, options) => {
4467
+ return new import_commander19.Command("bind").description('Bind one offer from "quote status": the carrier checkout when the carrier offers it, otherwise a broker review').argument("<submissionId>", "The quote submission id").argument("<offerId>", "The offer id from the quote table").option("--attest", "Confirm the application answers are accurate (asked interactively when omitted)").option("--broker-review", "Do not bind; ask a licensed broker to review this coverage first").option("--step-up <id>", "Finish an earlier attempt: the stepUpId the code email belongs to").option("--code <code>", "The 6-digit code from the email").option("--json", "Output as JSON").action(async (submissionId, offerId, options) => {
4468
+ if (options.brokerReview) {
4469
+ if (options.json) json(brokerReviewResult(submissionId, offerId));
4470
+ else brokerReviewLines(submissionId, offerId).forEach((l) => info(l));
4471
+ return;
4472
+ }
4316
4473
  const client = getClient();
4474
+ const ack = selfDirectedAckLines(submissionId, offerId);
4475
+ if (options.json) ack.forEach((l) => console.error(l));
4476
+ else ack.forEach((l) => info(l));
4317
4477
  let attest = options.attest === true;
4318
4478
  if (!attest && process.stdin.isTTY && !options.json) {
4319
- const a = await import_inquirer12.default.prompt([{
4479
+ const a = await import_inquirer13.default.prompt([{
4320
4480
  type: "confirm",
4321
4481
  name: "ok",
4322
4482
  message: "Are the answers on this application accurate? Binding relies on them.",
@@ -4350,7 +4510,7 @@ function createBindCommand() {
4350
4510
  }
4351
4511
  }
4352
4512
  if (options.json) {
4353
- json(r);
4513
+ json({ ...r, selfDirected: true, disclosure: ack[0] });
4354
4514
  return;
4355
4515
  }
4356
4516
  if (r.existing) warn(`A bind for this coverage is already open (${r.carrierName}). Showing it.`);
@@ -4360,7 +4520,7 @@ function createBindCommand() {
4360
4520
  describeFinancing(r.financing).forEach((l) => info(l));
4361
4521
  } catch (err) {
4362
4522
  spinner?.stop();
4363
- if (err instanceof import_sdk8.DeleganceError && [400, 403, 409].includes(err.statusCode ?? 0)) {
4523
+ if (err instanceof import_sdk9.DeleganceError && [400, 403, 409].includes(err.statusCode ?? 0)) {
4364
4524
  error(err.message);
4365
4525
  process.exit(1);
4366
4526
  }
@@ -4381,7 +4541,7 @@ function summarizeBilling(payments) {
4381
4541
  return { openCents, paidCents, openCount };
4382
4542
  }
4383
4543
  function createBillingCommand() {
4384
- return new import_commander18.Command("billing").description("What you owe and what you paid: every premium payment request on the account").option("--json", "Output as JSON").action(async (options) => {
4544
+ return new import_commander19.Command("billing").description("What you owe and what you paid: every premium payment request on the account").option("--json", "Output as JSON").action(async (options) => {
4385
4545
  try {
4386
4546
  const payments = await getClient().payments.list();
4387
4547
  const sum = summarizeBilling(payments);
@@ -4405,7 +4565,7 @@ function createBillingCommand() {
4405
4565
  });
4406
4566
  }
4407
4567
  function createPayCommand() {
4408
- return new import_commander18.Command("pay").description("Pay a premium: list payment requests, or get a checkout link for one").argument("[paymentId]", "Payment request to pay (omit to list them)").option("--json", "Output as JSON").action(async (paymentId, options) => {
4568
+ return new import_commander19.Command("pay").description("Pay a premium: list payment requests, or get a checkout link for one").argument("[paymentId]", "Payment request to pay (omit to list them)").option("--json", "Output as JSON").action(async (paymentId, options) => {
4409
4569
  const client = getClient();
4410
4570
  try {
4411
4571
  if (!paymentId) {
@@ -4490,7 +4650,7 @@ function bondStartLines(r, ctx = {}) {
4490
4650
  return out;
4491
4651
  }
4492
4652
  function createBondCommand() {
4493
- const bond = new import_commander18.Command("bond").alias("bonds").description("Surety bond quotes");
4653
+ const bond = new import_commander19.Command("bond").alias("bonds").description("Surety bond quotes");
4494
4654
  bond.command("quote").description("Start a bond quote and list its questions").requiredOption("-s, --state <state>", "Two-letter state, e.g. TX").option("-b, --bond <name>", 'Bond name or keyword, e.g. "notary", "contractor license"').option("--entity-id <id>", "Exact bond id, when you have it").option("--contract-amount <amount>", "Contract value, for contract bonds").option("--bond-amount <amount>", "Bond penal sum").option("--json", "Output as JSON").action(async (options) => {
4495
4655
  try {
4496
4656
  const r = await getClient().bonds.start({
@@ -4536,7 +4696,7 @@ function createBondCommand() {
4536
4696
  return bond;
4537
4697
  }
4538
4698
  function createClaimCommand() {
4539
- const claim = new import_commander18.Command("claim").alias("claims").description("File and track claims");
4699
+ const claim = new import_commander19.Command("claim").alias("claims").description("File and track claims");
4540
4700
  claim.command("file").description("File a claim. The first time, accept the claims disclaimer in the portal").option("-d, --description <text>", "What happened (visible in shell history; prefer --description-file)").option("--description-file <file>", "Read what happened from a file, or - for stdin").option("--date <yyyy-mm-dd>", "When it happened").option("--policy <id>", "Policy id, if you know it").option("--json", "Output as JSON").action(async (options) => {
4541
4701
  let description = options.description;
4542
4702
  if (options.descriptionFile) {
@@ -4560,7 +4720,7 @@ function createClaimCommand() {
4560
4720
  success(r.message);
4561
4721
  keyValue({ Claim: r.claimId, Status: r.status, Portal: r.portalUrl });
4562
4722
  } catch (err) {
4563
- if (err instanceof import_sdk8.DeleganceError && err.reason === "gate_not_acknowledged") {
4723
+ if (err instanceof import_sdk9.DeleganceError && err.reason === "gate_not_acknowledged") {
4564
4724
  error("Accept the claims disclaimer once in the portal, then file again. It cannot be accepted for you.");
4565
4725
  info(String(err.body?.portalUrl ?? ""));
4566
4726
  process.exit(1);
@@ -4593,7 +4753,7 @@ function createClaimCommand() {
4593
4753
  // src/program.ts
4594
4754
  function createProgram() {
4595
4755
  registerMinimalCheckbox();
4596
- const program2 = new import_commander19.Command();
4756
+ const program2 = new import_commander20.Command();
4597
4757
  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", () => {
4598
4758
  migrateLegacyConfigKey();
4599
4759
  });
@@ -4619,6 +4779,7 @@ function createProgram() {
4619
4779
  program2.addCommand(createBondCommand());
4620
4780
  program2.addCommand(createClaimCommand());
4621
4781
  program2.addCommand(createFeedbackCommand());
4782
+ program2.addCommand(createTermsCommand());
4622
4783
  program2.addCommand(createConfigCommand());
4623
4784
  return program2;
4624
4785
  }