sproutkit-code 1.14.0 → 1.15.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.
Files changed (2) hide show
  1. package/dist/index.js +61 -21
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -407,7 +407,7 @@ var require_db = __commonJS({
407
407
  } catch {
408
408
  }
409
409
  }
410
- for (const col of ["receptionist_id TEXT", "receptionist_url TEXT", "receptionist_price_pence INTEGER"]) {
410
+ for (const col of ["receptionist_id TEXT", "receptionist_url TEXT", "receptionist_price_pence INTEGER", "receptionist_line TEXT"]) {
411
411
  try {
412
412
  db2.exec(`ALTER TABLE leads ADD COLUMN ${col}`);
413
413
  } catch {
@@ -84479,6 +84479,7 @@ var require_pitch_text = __commonJS({
84479
84479
  Object.defineProperty(exports2, "__esModule", { value: true });
84480
84480
  exports2.withVideo = withVideo;
84481
84481
  exports2.withReceptionist = withReceptionist;
84482
+ exports2.prettyNumber = prettyNumber;
84482
84483
  function withVideo(message, videoUrl) {
84483
84484
  if (!videoUrl)
84484
84485
  return message.replace(/\n?[^\n]*\{video\}[^\n]*/g, "");
@@ -84494,12 +84495,13 @@ ${line}`;
84494
84495
  lines.splice(at + 1, 0, "", line);
84495
84496
  return lines.join("\n");
84496
84497
  }
84497
- function withReceptionist(message, url) {
84498
- if (!url)
84498
+ function withReceptionist(message, url, demoNumber, businessName) {
84499
+ const what = demoNumber ? `ring ${prettyNumber(demoNumber)} from your business phone and it'll answer as ${businessName ?? "you"}` : url ? `give it a call here: ${url}` : null;
84500
+ if (!what)
84499
84501
  return message.replace(/\n?[^\n]*\{receptionist\}[^\n]*/g, "");
84500
84502
  if (message.includes("{receptionist}"))
84501
- return message.replace(/\{receptionist\}/g, url);
84502
- const line = `I've also set up an AI receptionist that would answer your calls 24/7. Give it a call: ${url}`;
84503
+ return message.replace(/\{receptionist\}/g, demoNumber ? prettyNumber(demoNumber) : url);
84504
+ const line = `I've also set up an AI receptionist that would answer your calls 24/7 when you can't \u2014 ${what}.`;
84503
84505
  const lines = message.split("\n");
84504
84506
  const at = lines.findIndex((l) => /https?:\/\//.test(l));
84505
84507
  if (at < 0)
@@ -84509,6 +84511,20 @@ ${line}`;
84509
84511
  lines.splice(at + 1, 0, "", line);
84510
84512
  return lines.join("\n");
84511
84513
  }
84514
+ function prettyNumber(e164) {
84515
+ const d = e164.replace(/[^\d+]/g, "");
84516
+ if (d.startsWith("+44")) {
84517
+ const n = "0" + d.slice(3);
84518
+ if (/^0(1\d1|11\d)/.test(n))
84519
+ return `${n.slice(0, 4)} ${n.slice(4, 7)} ${n.slice(7)}`;
84520
+ if (/^02/.test(n))
84521
+ return `${n.slice(0, 3)} ${n.slice(3, 7)} ${n.slice(7)}`;
84522
+ return `${n.slice(0, 5)} ${n.slice(5)}`;
84523
+ }
84524
+ if (d.startsWith("+1") && d.length === 12)
84525
+ return `(${d.slice(2, 5)}) ${d.slice(5, 8)}-${d.slice(8)}`;
84526
+ return e164;
84527
+ }
84512
84528
  }
84513
84529
  });
84514
84530
 
@@ -84696,7 +84712,9 @@ var require_receptionist = __commonJS({
84696
84712
  exports2.buildConfig = buildConfig;
84697
84713
  exports2.createTrial = createTrial;
84698
84714
  exports2.listReceptionists = listReceptionists;
84715
+ exports2.listAll = listAll;
84699
84716
  exports2.activateReceptionist = activateReceptionist;
84717
+ exports2.forwardingSheet = forwardingSheet;
84700
84718
  exports2.removeReceptionist = removeReceptionist;
84701
84719
  var db_1 = require_db();
84702
84720
  var agency_1 = require_agency();
@@ -84826,20 +84844,39 @@ ${source.slice(0, 6e4)}`
84826
84844
  const r = await api("POST", "/api/receptionists", {
84827
84845
  leadRef: String(leadId),
84828
84846
  config,
84829
- ownerEmail
84847
+ ownerEmail,
84848
+ prospectPhones: config.phone ? [config.phone] : []
84830
84849
  });
84831
- (0, db_1.getDb)().run("UPDATE leads SET receptionist_id = ?, receptionist_url = ?, receptionist_price_pence = COALESCE(receptionist_price_pence, 4900) WHERE id = ?", [
84832
- r.receptionist.id,
84833
- r.trialUrl,
84834
- leadId
84835
- ]);
84836
- return { trialUrl: r.trialUrl, id: r.receptionist.id };
84850
+ (0, db_1.getDb)().run("UPDATE leads SET receptionist_id = ?, receptionist_url = ?, receptionist_line = ?, receptionist_price_pence = COALESCE(receptionist_price_pence, 4900) WHERE id = ?", [r.receptionist.id, r.trialUrl, r.demoNumber, leadId]);
84851
+ return { trialUrl: r.trialUrl, id: r.receptionist.id, demoNumber: r.demoNumber };
84837
84852
  }
84838
84853
  async function listReceptionists() {
84839
- return (await api("GET", "/api/receptionists")).receptionists;
84840
- }
84841
- async function activateReceptionist(id, country, ownerEmail) {
84842
- return api("POST", `/api/receptionists/${id}/activate`, { country, ownerEmail });
84854
+ return (await listAll()).receptionists;
84855
+ }
84856
+ async function listAll() {
84857
+ return api("GET", "/api/receptionists");
84858
+ }
84859
+ async function activateReceptionist(id, country, ownerEmail, ownerMobile, emergencies) {
84860
+ return api("POST", `/api/receptionists/${id}/activate`, { country, ownerEmail, ownerMobile, emergencies });
84861
+ }
84862
+ function forwardingSheet(receptionistNumber, country) {
84863
+ const n = receptionistNumber.replace(/[^\d+]/g, "");
84864
+ const lines = [
84865
+ `Send missed calls to your AI receptionist`,
84866
+ ``,
84867
+ `On your business mobile, dial each code and press call. Your phone still rings first \u2014 the receptionist only picks up when you can't.`,
84868
+ ``,
84869
+ `1. When you don't answer: **61*${n}#`,
84870
+ `2. When you're busy: **67*${n}#`,
84871
+ `3. When you have no signal: **62*${n}#`,
84872
+ ``,
84873
+ `Check each one is on: *#61# *#67# *#62#`,
84874
+ `To turn it all off again: ##004#`
84875
+ ];
84876
+ if (country === "US") {
84877
+ lines.push(``, `On Verizon instead: dial *71${n.replace(/^\+1/, "")} (no answer and busy). To turn it off: *73.`);
84878
+ }
84879
+ return lines.join("\n");
84843
84880
  }
84844
84881
  async function removeReceptionist(id, leadId) {
84845
84882
  await api("DELETE", `/api/receptionists/${id}`);
@@ -98371,12 +98408,12 @@ If you'd rather not hear from me again, just reply and let me know.`;
98371
98408
  }
98372
98409
  case "prepare_outreach": {
98373
98410
  const explicit = input.ids;
98374
- const rows = explicit && explicit.length > 0 ? db2.all(`SELECT id, name, phone, email, address, city, site_url, lead_kind, booking_platform, booking_url, pitch_video_url, receptionist_url FROM leads WHERE id IN (${explicit.map(() => "?").join(",")})`, explicit) : db2.all(
98411
+ const rows = explicit && explicit.length > 0 ? db2.all(`SELECT id, name, phone, email, address, city, site_url, lead_kind, booking_platform, booking_url, pitch_video_url, receptionist_url, receptionist_line FROM leads WHERE id IN (${explicit.map(() => "?").join(",")})`, explicit) : db2.all(
98375
98412
  // Eligible = we have something to show them: either a demo site
98376
98413
  // we built (site_url) OR a booking page we built (booking_url).
98377
98414
  // Booking leads never get a site_url, so requiring it silently
98378
98415
  // excluded every one-shot booking customer.
98379
- "SELECT id, name, phone, email, address, city, site_url, lead_kind, booking_platform, booking_url, pitch_video_url, receptionist_url FROM leads WHERE status IN ('site_built','discovered') AND ((site_url IS NOT NULL AND site_url != '') OR (booking_url IS NOT NULL AND booking_url != '')) ORDER BY score DESC NULLS LAST, id DESC",
98416
+ "SELECT id, name, phone, email, address, city, site_url, lead_kind, booking_platform, booking_url, pitch_video_url, receptionist_url, receptionist_line FROM leads WHERE status IN ('site_built','discovered') AND ((site_url IS NOT NULL AND site_url != '') OR (booking_url IS NOT NULL AND booking_url != '')) ORDER BY score DESC NULLS LAST, id DESC",
98380
98417
  []
98381
98418
  );
98382
98419
  const eligible = rows.filter((r) => r.site_url || r.booking_url);
@@ -98408,15 +98445,18 @@ If you'd rather not hear from me again, just reply and let me know.`;
98408
98445
  }
98409
98446
  }
98410
98447
  let receptionistUrl = r.receptionist_url ?? null;
98448
+ let receptionistLine = r.receptionist_line ?? null;
98411
98449
  if (!isBookingLead && !receptionistUrl && r.site_url && getDecryptedSetting("receptionist_auto") === "1") {
98412
98450
  ctx.emitProgress?.({ channel: "outreach:progress", payload: { msg: `Setting up ${r.name}'s AI receptionist\u2026` } });
98413
98451
  try {
98414
- receptionistUrl = (await (0, receptionist_1.createTrial)(r.id)).trialUrl;
98452
+ const t = await (0, receptionist_1.createTrial)(r.id);
98453
+ receptionistUrl = t.trialUrl;
98454
+ receptionistLine = t.demoNumber;
98415
98455
  } catch {
98416
98456
  receptionistUrl = null;
98417
98457
  }
98418
98458
  }
98419
- const message = (0, pitch_text_1.withVideo)((0, pitch_text_1.withReceptionist)((isBookingLead ? bookingTemplate : template).replace(/\{name\}/g, r.name).replace(/\{site_url\}/g, (isBookingLead ? r.booking_url : r.site_url) ?? r.site_url ?? "").replace(/\{booking_how\}/g, r.booking_platform || "WhatsApp/phone"), isBookingLead ? null : receptionistUrl), isBookingLead ? null : videoUrl);
98459
+ const message = (0, pitch_text_1.withVideo)((0, pitch_text_1.withReceptionist)((isBookingLead ? bookingTemplate : template).replace(/\{name\}/g, r.name).replace(/\{site_url\}/g, (isBookingLead ? r.booking_url : r.site_url) ?? r.site_url ?? "").replace(/\{booking_how\}/g, r.booking_platform || "WhatsApp/phone"), isBookingLead ? null : receptionistUrl, isBookingLead ? null : receptionistLine, r.name), isBookingLead ? null : videoUrl);
98420
98460
  const e164 = toE164(r.phone ?? "");
98421
98461
  if (!r.email && smtp && (preferEmail || !e164)) {
98422
98462
  ctx.emitProgress?.({
@@ -100427,7 +100467,7 @@ var require_package2 = __commonJS({
100427
100467
  "package.json"(exports2, module2) {
100428
100468
  module2.exports = {
100429
100469
  name: "sproutkit-code",
100430
- version: "1.14.0",
100470
+ version: "1.15.0",
100431
100471
  description: "Sproutkit in your terminal \u2014 find leads, build sites, run outreach, all via chat.",
100432
100472
  bin: {
100433
100473
  sproutkit: "./dist/index.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sproutkit-code",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "description": "Sproutkit in your terminal — find leads, build sites, run outreach, all via chat.",
5
5
  "bin": {
6
6
  "sproutkit": "./dist/index.js"