sproutkit-code 1.0.0 → 1.1.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 +75 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -79738,6 +79738,13 @@ var require_builder = __commonJS({
79738
79738
  const pattern = new RegExp(`https?:\\/\\/[^\\s"'\`)]*(${STOCK_HOSTS.map((h) => h.replace(/\./g, "\\.")).join("|")})[^\\s"'\`)]*`, "gi");
79739
79739
  return code.replace(pattern, "");
79740
79740
  }
79741
+ function demoBanner(businessName) {
79742
+ const esc = (v) => v.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
79743
+ const label = `Preview site for ${esc(businessName)}`;
79744
+ return `<div id="sproutkit-demo-banner" role="note" style="all:initial;display:block;box-sizing:border-box;width:100%;background:#1f2937;color:#f9fafb;font-family:ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;font-size:13px;line-height:1.4;padding:10px 16px;text-align:center;letter-spacing:.01em">
79745
+ <strong style="all:unset;font-weight:600">DEMO</strong> \xB7 ${label} \u2014 not licensed for live use. Built with <a href="https://sproutkit.app" style="all:unset;color:#a7f3d0;text-decoration:underline;cursor:pointer">Sproutkit</a>. Contact us to go live with your own domain.
79746
+ </div>`;
79747
+ }
79741
79748
  function snapshotDir(leadId) {
79742
79749
  return path3.join((0, runtime_1.userDataDir)(), "data", "sites", String(leadId));
79743
79750
  }
@@ -80311,7 +80318,7 @@ ${prompt}` : prompt;
80311
80318
  onProgress("Deploying to Vercel...");
80312
80319
  const indexHtml = `<!DOCTYPE html>
80313
80320
  <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${lead.name}</title></head>
80314
- <body style="margin:0"><div id="root"></div><script type="module" src="/src/main.jsx"></script></body></html>`;
80321
+ <body style="margin:0">${demoBanner(lead.name)}<div id="root"></div><script type="module" src="/src/main.jsx"></script></body></html>`;
80315
80322
  const mainJsx = `import { StrictMode } from 'react';
80316
80323
  import { createRoot } from 'react-dom/client';
80317
80324
  import App from './App.jsx';
@@ -80506,7 +80513,7 @@ export default defineConfig({ plugins: [react()] });`;
80506
80513
  { source: "/book/", destination: "/book/index.html" }
80507
80514
  ]
80508
80515
  });
80509
- const indexHtmlCms = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${lead.name}</title></head><body style="margin:0"><div id="root"></div><script type="module" src="/src/main.jsx"></script></body></html>`;
80516
+ const indexHtmlCms = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${lead.name}</title></head><body style="margin:0">${demoBanner(lead.name)}<div id="root"></div><script type="module" src="/src/main.jsx"></script></body></html>`;
80510
80517
  const mainJsxCms = `import { StrictMode } from 'react';
80511
80518
  import { createRoot } from 'react-dom/client';
80512
80519
  import App from './App.jsx';
@@ -80583,7 +80590,7 @@ export default defineConfig({ plugins: [react()] });`;
80583
80590
  snapshot[appJsxIndex] = { ...snapshot[appJsxIndex], data: modifiedApp };
80584
80591
  saveSnapshot(lead.id, snapshot);
80585
80592
  const files = snapshot.map((f) => ({ file: f.file, data: f.data, encoding: f.encoding }));
80586
- const indexHtml = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${lead.name}</title></head><body style="margin:0"><div id="root"></div><script type="module" src="/src/main.jsx"></script></body></html>`;
80593
+ const indexHtml = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${lead.name}</title></head><body style="margin:0">${demoBanner(lead.name)}<div id="root"></div><script type="module" src="/src/main.jsx"></script></body></html>`;
80587
80594
  const mainJsx = `import { StrictMode } from 'react';
80588
80595
  import { createRoot } from 'react-dom/client';
80589
80596
  import App from './App.jsx';
@@ -93130,6 +93137,11 @@ var require_chat_tools = __commonJS({
93130
93137
  type: "array",
93131
93138
  items: { type: "number" },
93132
93139
  description: "Specific lead ids to prepare. Omit to prepare every lead that has a site built but hasn't been contacted yet (status 'site_built')."
93140
+ },
93141
+ channel: {
93142
+ type: "string",
93143
+ enum: ["whatsapp", "sms"],
93144
+ description: "Messaging channel for leads that have a phone: 'whatsapp' opens WhatsApp, 'sms' opens the device's Messages app (Messages on macOS, Phone Link on Windows). Omit to use the saved preference."
93133
93145
  }
93134
93146
  }
93135
93147
  },
@@ -93481,7 +93493,8 @@ Interested?`;
93481
93493
  };
93482
93494
  }
93483
93495
  const channelRow = db2.get("SELECT value FROM settings WHERE key = ?", ["outreach_channel"]);
93484
- const channel = channelRow?.value || "whatsapp";
93496
+ const requested = String(input.channel ?? "").toLowerCase();
93497
+ const channel = requested === "sms" || requested === "whatsapp" ? requested : channelRow?.value || "whatsapp";
93485
93498
  const template = outreachTemplate(db2);
93486
93499
  const smtp = (0, email_1.smtpFromSettings)((k) => getDecryptedSetting(k));
93487
93500
  const emailSubject = getDecryptedSetting("outreach_email_subject") || "A free demo website for {name}";
@@ -94661,7 +94674,7 @@ var require_package2 = __commonJS({
94661
94674
  "package.json"(exports2, module2) {
94662
94675
  module2.exports = {
94663
94676
  name: "sproutkit-code",
94664
- version: "1.0.0",
94677
+ version: "1.1.0",
94665
94678
  description: "Sproutkit in your terminal \u2014 find leads, build sites, run outreach, all via chat.",
94666
94679
  bin: {
94667
94680
  sproutkit: "./dist/index.js"
@@ -95757,7 +95770,10 @@ async function cmdOutreach(argv) {
95757
95770
  const ids = String(flags.ids ?? "").split(",").map((s) => Number(s.trim())).filter((n) => !Number.isNaN(n) && n > 0);
95758
95771
  const result = await runTool(
95759
95772
  "prepare_outreach",
95760
- { ids: ids.length ? ids : void 0 },
95773
+ {
95774
+ ids: ids.length ? ids : void 0,
95775
+ channel: flags.channel ? String(flags.channel).toLowerCase() : void 0
95776
+ },
95761
95777
  makeCtx({ json })
95762
95778
  );
95763
95779
  if (json) {
@@ -96281,6 +96297,59 @@ async function main() {
96281
96297
  }
96282
96298
  if (arg === "find" || arg === "list" || arg === "build" || arg === "build-all" || arg === "regenerate" || arg === "cms" || arg === "book" || arg === "outreach" || arg === "pipeline") {
96283
96299
  const subArgs = process.argv.slice(3);
96300
+ if (subArgs.includes("--help") || subArgs.includes("-h")) {
96301
+ const USAGE = {
96302
+ find: [
96303
+ 'sproutkit find "<area>" --categories "barber shop,cafe"',
96304
+ " --max <n> max leads to save (default 25)",
96305
+ " --radius <m> search radius in metres (default 10000)",
96306
+ " --json machine-readable output"
96307
+ ],
96308
+ list: [
96309
+ "sproutkit list [--status <s>] [--city <c>] [--limit <n>] [--json]",
96310
+ " statuses: discovered, site_built, contacted, replied, won, dead"
96311
+ ],
96312
+ build: [
96313
+ "sproutkit build <leadId> [options]",
96314
+ ' --instructions "\u2026" tailor the design/content',
96315
+ " --cms include the editable CMS",
96316
+ " --multipage real Home/Services/About/Contact pages",
96317
+ " --skip-qa skip the post-build review (faster, lower quality)"
96318
+ ],
96319
+ "build-all": [
96320
+ "sproutkit build-all [--ids 3,5] [--concurrency 3] [--json]",
96321
+ " builds every unbuilt lead unless --ids is given; press q to stop"
96322
+ ],
96323
+ regenerate: [
96324
+ 'sproutkit regenerate <leadId> --instructions "what to change"',
96325
+ " --multipage rebuild as a multipage site"
96326
+ ],
96327
+ cms: ["sproutkit cms <leadId>", " adds the editable CMS to a site we already built"],
96328
+ book: [
96329
+ "sproutkit book <leadId> [options]",
96330
+ " --standalone booking site on its OWN url (client already has a site)",
96331
+ " --archetype <type> slots | reservation | enquiry",
96332
+ ' --instructions "\u2026" e.g. "45-min slots, add beard trim \xA312"',
96333
+ " --email <addr> owner email for booking notifications"
96334
+ ],
96335
+ outreach: [
96336
+ "sproutkit outreach [--ids 3,5] [--channel sms|whatsapp] [--json]",
96337
+ " Per lead: phone -> a messaging link you open; no phone -> emailed (needs SMTP).",
96338
+ " Moves reached leads to Contacted. Targets every lead with a built site",
96339
+ " unless --ids is given."
96340
+ ],
96341
+ pipeline: [
96342
+ "sproutkit pipeline x3 [--book] [--limit 10] [--ids 3,5] [--json]",
96343
+ " build -> (booking) -> outreach for many clients concurrently (max 4)",
96344
+ " press q to stop after in-flight clients finish"
96345
+ ]
96346
+ };
96347
+ say();
96348
+ for (const line of USAGE[arg] ?? [`sproutkit ${arg}`]) say(" " + line);
96349
+ say();
96350
+ closeTty();
96351
+ return;
96352
+ }
96284
96353
  const lic2 = await check();
96285
96354
  if (lic2.status !== "active") {
96286
96355
  const msg = lic2.status === "offline_grace_expired" ? "Licence check offline and grace expired \u2014 reconnect and retry." : "No active licence. Run 'sproutkit setup' first.";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sproutkit-code",
3
- "version": "1.0.0",
3
+ "version": "1.1.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"