hedge-broker 0.2.0 → 0.3.1

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.
Files changed (2) hide show
  1. package/dist/index.js +83 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -565,12 +565,26 @@ function registerSubmissions(program2) {
565
565
  const r = await apiRequest(ctx.client, "GET", `/broker/submissions/${submissionId}/requirements`);
566
566
  if (ctx.json) return printJson(r);
567
567
  process.stdout.write(kv({ insured: r.insured_name, lines: (r.lines || []).join(", "), state: r.state, forms: (r.forms || []).join(", ") }) + "\n");
568
+ if (r.forms?.length) {
569
+ process.stdout.write("(download blanks with: hedge form <form_key>)\n");
570
+ }
568
571
  if (r.markets?.length) {
569
572
  process.stdout.write("\nMarkets:\n" + table(r.markets.map((m) => ({
570
573
  market: m.market_name,
571
574
  ready: m.ready ? "yes" : "no",
572
575
  needs_from_you: (m.needs_from_you || []).join("; ")
573
576
  })), ["market", "ready", "needs_from_you"]) + "\n");
577
+ } else {
578
+ const hint = typeof r.marketing_hint === "string" && r.marketing_hint ? r.marketing_hint : null;
579
+ if (r.marketing_status === "matching") {
580
+ process.stdout.write("\nNo markets yet - " + (hint ?? "Hedge is matching carrier markets now (usually ~5 minutes after finalize); re-run this in a few minutes.") + "\n");
581
+ } else if (r.marketing_status === "not_started") {
582
+ process.stdout.write("\nNo markets yet - " + (hint ?? "run hedge finalize " + submissionId + " to start marketing.") + "\n");
583
+ } else if (r.marketing_status === "no_markets_matched") {
584
+ process.stdout.write("\nNo markets attached - " + (hint ?? "Hedge is reviewing options for this risk and will follow up.") + "\n");
585
+ } else {
586
+ process.stdout.write("\nNo markets yet. If you just finalized, matching usually completes within ~5 minutes - re-run this shortly or use hedge status " + submissionId + ".\n");
587
+ }
574
588
  }
575
589
  if (r.carrier_api_sessions?.length) {
576
590
  process.stdout.write("\nInstant-quote carriers:\n" + table(r.carrier_api_sessions.map((s) => ({
@@ -594,6 +608,8 @@ function registerSubmissions(program2) {
594
608
  status: l.status_label ?? l.status,
595
609
  quote: l.quote_premium ?? ""
596
610
  }))), ["carrier", "line", "status", "quote"]) + "\n");
611
+ } else {
612
+ process.stdout.write("\nNo markets attached yet. Matching usually completes within ~5 minutes of finalize - re-run this shortly (or check hedge requirements " + submissionId + ").\n");
597
613
  }
598
614
  const byStatus = s.status_summary?.by_status;
599
615
  if (byStatus && Object.keys(byStatus).length) {
@@ -617,11 +633,74 @@ function registerSubmissions(program2) {
617
633
  premium: r.premium ?? ""
618
634
  })), ["id", "insured", "lines", "status", "premium"]) + "\n");
619
635
  });
620
- program2.command("finalize <submissionId>").description("Start marketing the submission to carriers").action(async (submissionId) => {
636
+ program2.command("finalize <submissionId>").description("Start marketing the submission to carriers").option("--wait", "poll until markets attach (usually ~5 minutes), then print them").option("--timeout <minutes>", "how long --wait polls before giving up", "8").action(async (submissionId, opts) => {
621
637
  const ctx = makeCtx(program2.opts());
622
638
  const r = await apiRequest(ctx.client, "POST", `/broker/submissions/${submissionId}/finalize`);
623
- if (ctx.json) return printJson(r);
624
- process.stdout.write("Marketing started. Track with: hedge status " + submissionId + "\n");
639
+ if (ctx.json && !opts.wait) return printJson(r);
640
+ if (!opts.wait) {
641
+ const wait = Number(r.typical_wait_seconds) > 0 ? Math.round(Number(r.typical_wait_seconds) / 60) : 5;
642
+ process.stdout.write(
643
+ `Marketing started. Markets usually attach within ~${wait} minutes.
644
+ Track with: hedge status ${submissionId} (or use finalize --wait next time)
645
+ `
646
+ );
647
+ return;
648
+ }
649
+ const timeoutMin = intFlag(opts.timeout, "--timeout");
650
+ const deadline = Date.now() + Math.max(1, timeoutMin) * 6e4;
651
+ process.stdout.write("Marketing started - waiting for markets to attach (usually ~5 minutes)");
652
+ let markets = [];
653
+ while (Date.now() < deadline) {
654
+ await new Promise((resolve) => setTimeout(resolve, 15e3));
655
+ process.stdout.write(".");
656
+ const s = await apiRequest(ctx.client, "GET", `/broker/submissions/${submissionId}`);
657
+ if (s.markets?.length) {
658
+ markets = s.markets;
659
+ break;
660
+ }
661
+ }
662
+ process.stdout.write("\n");
663
+ if (!markets.length) {
664
+ process.stdout.write(
665
+ `Still matching after ${timeoutMin} minutes - this can occasionally take longer.
666
+ Check in with: hedge status ${submissionId} or hedge requirements ${submissionId}
667
+ `
668
+ );
669
+ return;
670
+ }
671
+ const rows = markets.flatMap((m) => (m.lines || []).map((l) => ({
672
+ carrier: m.carrier_name,
673
+ line: l.lob_label ?? l.lob_slug,
674
+ status: l.status_label ?? l.status
675
+ })));
676
+ if (ctx.json) return printJson({ finalize: r, markets });
677
+ process.stdout.write(`Matched ${markets.length} market(s):
678
+
679
+ ` + table(rows, ["carrier", "line", "status"]) + "\n");
680
+ process.stdout.write("\nNext: hedge requirements " + submissionId + " shows what each market still needs from you.\n");
681
+ });
682
+ program2.command("forms [search]").description('Search the blank application-form catalog, e.g. hedge forms "liquor"').action(async (search) => {
683
+ const ctx = makeCtx(program2.opts());
684
+ const rows = await apiRequest(ctx.client, "GET", "/broker/forms", {
685
+ query: { q: search }
686
+ });
687
+ if (ctx.json) return printJson(rows);
688
+ if (!rows.length) {
689
+ process.stdout.write("No forms matched" + (search ? ` "${search}"` : "") + ".\n");
690
+ return;
691
+ }
692
+ process.stdout.write(table(rows.map((f) => ({
693
+ form_key: f.form_key,
694
+ title: f.title ?? "",
695
+ acord: f.is_acord ? "yes" : "",
696
+ pages: f.page_count ?? ""
697
+ })), ["form_key", "title", "acord", "pages"]) + "\n");
698
+ process.stdout.write("\nDownload a blank with: hedge form <form_key>\n");
699
+ });
700
+ program2.command("form <formKey>").description("Download a blank application form by its catalog key (the keys `hedge requirements` lists)").option("-o, --output <file>", "output file (default <formKey>.pdf)").action(async (formKey, opts) => {
701
+ const ctx = makeCtx(program2.opts());
702
+ const out = await downloadRequest(ctx.client, "GET", `/broker/forms/${encodeURIComponent(formKey)}/pdf`, opts.output, `${formKey}.pdf`);
703
+ process.stdout.write("Saved " + out + "\n");
625
704
  });
626
705
  program2.command("documents <submissionId>").description("List a submission's finalized documents (ACORDs, quotes, binders)").action(async (submissionId) => {
627
706
  const ctx = makeCtx(program2.opts());
@@ -794,7 +873,7 @@ function registerQuotes(program2) {
794
873
 
795
874
  // src/index.ts
796
875
  var program = new Command();
797
- program.name("hedge").description("Submit risks to Hedge and track them from your terminal.").version("0.2.0").option("--staging", "use the staging environment").option("--json", "output raw JSON (for scripting)");
876
+ program.name("hedge").description("Submit risks to Hedge and track them from your terminal.").version("0.3.1").option("--staging", "use the staging environment").option("--json", "output raw JSON (for scripting)");
798
877
  registerAuth(program);
799
878
  registerSubmissions(program);
800
879
  registerAppetite(program);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedge-broker",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Command-line tool for the Hedge broker portal. Submit risks, check appetite, track quotes and policies.",
5
5
  "type": "module",
6
6
  "bin": { "hedge": "dist/index.js" },