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.
- package/dist/index.js +75 -6
- 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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
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"
|
|
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"
|
|
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"
|
|
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
|
|
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.
|
|
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
|
-
{
|
|
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.";
|