sproutkit-code 0.13.0 → 0.14.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 +40 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -79756,7 +79756,8 @@ var require_builder = __commonJS({
|
|
|
79756
79756
|
}
|
|
79757
79757
|
}
|
|
79758
79758
|
async function buildAndDeploySite(args) {
|
|
79759
|
-
const { lead, anthropicKey, vercelToken, placesKey, customInstructions, onProgress, includeCms, blobToken, reuseAdminPassword, skipContentExtraction } = args;
|
|
79759
|
+
const { lead, anthropicKey, vercelToken, placesKey, customInstructions, onProgress, includeCms, blobToken, reuseAdminPassword, skipContentExtraction, multipage, pages } = args;
|
|
79760
|
+
const pageList = multipage && (!pages || pages.length === 0) ? ["Home", "Services", "About", "Contact"] : pages ?? [];
|
|
79760
79761
|
if (includeCms && !blobToken) {
|
|
79761
79762
|
throw new Error("CMS is enabled but no Vercel Blob token is set. Add it in Settings \u2192 Vercel Blob token.");
|
|
79762
79763
|
}
|
|
@@ -79913,11 +79914,24 @@ SECTIONS (in this order)
|
|
|
79913
79914
|
6. REVIEWS \u2014 display the real reviews above as testimonial cards with the customer's name and stars
|
|
79914
79915
|
7. CONTACT \u2014 address, phone, hours in a clear card. Map embed NOT required.
|
|
79915
79916
|
8. FOOTER \u2014 simple, business name + address + a final "Built with Sproutkit \xB7 sproutkit.app" line in muted text
|
|
79917
|
+
${multipage ? `
|
|
79918
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
79919
|
+
MULTIPAGE (REQUIRED) \u2014 real separate pages, not one long scroll
|
|
79920
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
79921
|
+
Build a MULTI-PAGE site using react-router-dom's HashRouter (import { HashRouter, Routes, Route, Link, useNavigate } from "react-router-dom"). HashRouter is REQUIRED (not BrowserRouter) so routes work on static hosting without server config.
|
|
79916
79922
|
|
|
79923
|
+
Pages (one <Route> each), with a persistent sticky NAV linking between them via <Link>:
|
|
79924
|
+
${pageList.map((p, i) => ` ${i + 1}. ${p}`).join("\n")}
|
|
79925
|
+
|
|
79926
|
+
- Home: hero + a short intro + 2-3 teaser sections that link through to the other pages.
|
|
79927
|
+
- Distribute the sections above across the pages sensibly (e.g. Services page = full services; About = the about/story + reviews; Contact = address/phone/hours/CTA). Don't cram everything onto Home.
|
|
79928
|
+
- The whole thing is STILL one App.jsx exporting a single default App component that renders <HashRouter>\u2026</HashRouter>. Define each page as a component in the same file.
|
|
79929
|
+
- Nav must be present on every page and highlight the active route. Include the phone/Book CTA in the nav.
|
|
79930
|
+
` : ""}
|
|
79917
79931
|
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
79918
79932
|
TECHNICAL REQUIREMENTS
|
|
79919
79933
|
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
79920
|
-
- Single React component in App.jsx, exported as default
|
|
79934
|
+
- Single React component in App.jsx, exported as default${multipage ? " (it renders <HashRouter> with the pages above; define page components in the same file)" : ""}
|
|
79921
79935
|
- Inline styles ONLY (no Tailwind, no CSS files, no external UI libs)
|
|
79922
79936
|
- Mobile-responsive (test mental model: 375px wide must look great)
|
|
79923
79937
|
- Use this constant for photos: const PHOTOS = REPLACE_PHOTOS;
|
|
@@ -79928,7 +79942,7 @@ TECHNICAL REQUIREMENTS
|
|
|
79928
79942
|
- Phone CTA button: <a href="tel:${lead.phone}">
|
|
79929
79943
|
- WhatsApp option: <a href="https://wa.me/${lead.phone.replace(/[^0-9]/g, "").replace(/^0/, "44")}">
|
|
79930
79944
|
- Final line MUST be: export default App;
|
|
79931
|
-
- Keep it focused: max 350 lines, no unused code
|
|
79945
|
+
- Keep it focused: max ${multipage ? 700 : 350} lines, no unused code
|
|
79932
79946
|
${includeCms ? `
|
|
79933
79947
|
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
79934
79948
|
CMS INTEGRATION (MANDATORY when this brief mentions it)
|
|
@@ -80063,13 +80077,16 @@ ${prompt}` : prompt;
|
|
|
80063
80077
|
import { createRoot } from 'react-dom/client';
|
|
80064
80078
|
import App from './App.jsx';
|
|
80065
80079
|
createRoot(document.getElementById('root')).render(<StrictMode><App /></StrictMode>);`;
|
|
80080
|
+
const baseDeps = { react: "^18.3.1", "react-dom": "^18.3.1" };
|
|
80081
|
+
if (multipage)
|
|
80082
|
+
baseDeps["react-router-dom"] = "^6.26.2";
|
|
80066
80083
|
const packageJson = JSON.stringify({
|
|
80067
80084
|
name: "sprout-demo",
|
|
80068
80085
|
private: true,
|
|
80069
80086
|
version: "0.0.1",
|
|
80070
80087
|
type: "module",
|
|
80071
80088
|
scripts: { build: "vite build", dev: "vite" },
|
|
80072
|
-
dependencies: {
|
|
80089
|
+
dependencies: { ...baseDeps },
|
|
80073
80090
|
devDependencies: { "@vitejs/plugin-react": "^4.3.1", vite: "^5.4.2" }
|
|
80074
80091
|
});
|
|
80075
80092
|
const viteConfig = `import { defineConfig } from 'vite';
|
|
@@ -80086,8 +80103,7 @@ export default defineConfig({ plugins: [react()] });`;
|
|
|
80086
80103
|
type: "module",
|
|
80087
80104
|
scripts: { build: "vite build", dev: "vite" },
|
|
80088
80105
|
dependencies: {
|
|
80089
|
-
|
|
80090
|
-
"react-dom": "^18.3.1",
|
|
80106
|
+
...baseDeps,
|
|
80091
80107
|
"@vercel/blob": "^0.23.4",
|
|
80092
80108
|
bcryptjs: "^2.4.3"
|
|
80093
80109
|
},
|
|
@@ -81126,6 +81142,10 @@ var require_chat_tools = __commonJS({
|
|
|
81126
81142
|
includeCms: {
|
|
81127
81143
|
type: "boolean",
|
|
81128
81144
|
description: "When true, deploy the site WITH a /admin CMS editor on the customer's own domain. The site becomes editable by the business owner via a password. Requires a Vercel Blob token to be configured in Settings. Returns an admin URL + password to hand off."
|
|
81145
|
+
},
|
|
81146
|
+
multipage: {
|
|
81147
|
+
type: "boolean",
|
|
81148
|
+
description: "When true, build a MULTI-PAGE site (Home/Services/About/Contact as real routed pages with a nav) instead of a single long-scroll page. Use when the user asks for a multipage site or a bigger site with separate pages."
|
|
81129
81149
|
}
|
|
81130
81150
|
},
|
|
81131
81151
|
required: ["id"]
|
|
@@ -81254,6 +81274,7 @@ var require_chat_tools = __commonJS({
|
|
|
81254
81274
|
placesKey,
|
|
81255
81275
|
customInstructions: args.instructions,
|
|
81256
81276
|
includeCms: args.includeCms,
|
|
81277
|
+
multipage: args.multipage,
|
|
81257
81278
|
blobToken,
|
|
81258
81279
|
onProgress: (msg) => args.ctx.emitProgress?.({
|
|
81259
81280
|
channel: "sites:progress",
|
|
@@ -81490,6 +81511,7 @@ Interested?`;
|
|
|
81490
81511
|
id,
|
|
81491
81512
|
instructions: input.instructions,
|
|
81492
81513
|
includeCms: !!input.includeCms,
|
|
81514
|
+
multipage: !!input.multipage,
|
|
81493
81515
|
ctx
|
|
81494
81516
|
});
|
|
81495
81517
|
return { ...result, id };
|
|
@@ -81503,7 +81525,12 @@ Interested?`;
|
|
|
81503
81525
|
error: "Please ask the user what they want changed before regenerating \u2014 instructions are required."
|
|
81504
81526
|
};
|
|
81505
81527
|
}
|
|
81506
|
-
const result = await buildSiteForChat({
|
|
81528
|
+
const result = await buildSiteForChat({
|
|
81529
|
+
id,
|
|
81530
|
+
instructions,
|
|
81531
|
+
multipage: !!input.multipage,
|
|
81532
|
+
ctx
|
|
81533
|
+
});
|
|
81507
81534
|
return { ...result, id };
|
|
81508
81535
|
}
|
|
81509
81536
|
case "build_all_sites": {
|
|
@@ -82565,7 +82592,7 @@ var require_package = __commonJS({
|
|
|
82565
82592
|
"package.json"(exports2, module2) {
|
|
82566
82593
|
module2.exports = {
|
|
82567
82594
|
name: "sproutkit-code",
|
|
82568
|
-
version: "0.
|
|
82595
|
+
version: "0.14.0",
|
|
82569
82596
|
description: "Sproutkit in your terminal \u2014 find leads, build sites, run outreach, all via chat.",
|
|
82570
82597
|
bin: {
|
|
82571
82598
|
sproutkit: "./dist/index.js"
|
|
@@ -83714,7 +83741,8 @@ async function cmdBuild(argv) {
|
|
|
83714
83741
|
{
|
|
83715
83742
|
id,
|
|
83716
83743
|
instructions: flags.instructions ? String(flags.instructions) : void 0,
|
|
83717
|
-
includeCms: !!flags.cms
|
|
83744
|
+
includeCms: !!flags.cms,
|
|
83745
|
+
multipage: !!flags.multipage
|
|
83718
83746
|
},
|
|
83719
83747
|
makeCtx({ json, status })
|
|
83720
83748
|
);
|
|
@@ -83784,7 +83812,7 @@ async function cmdRegenerate(argv) {
|
|
|
83784
83812
|
try {
|
|
83785
83813
|
const result = await runTool(
|
|
83786
83814
|
"regenerate_site",
|
|
83787
|
-
{ id, instructions },
|
|
83815
|
+
{ id, instructions, multipage: !!flags.multipage },
|
|
83788
83816
|
makeCtx({ json, status })
|
|
83789
83817
|
);
|
|
83790
83818
|
if (result && result.ok === false) {
|
|
@@ -83961,7 +83989,7 @@ When a request is missing information the command needs, ask a SHORT, STRUCTURED
|
|
|
83961
83989
|
COMMANDS:
|
|
83962
83990
|
- sproutkit find "<area>" --categories "<type>,<type>" --json \u2014 find website-less leads
|
|
83963
83991
|
- sproutkit list --json [--status <s>] [--city <c>] \u2014 list leads (get ids)
|
|
83964
|
-
- sproutkit build <id> --json [--instructions "..."] [--cms]
|
|
83992
|
+
- sproutkit build <id> --json [--instructions "..."] [--cms] [--multipage] \u2014 build a demo site (--multipage = real Home/Services/About/Contact pages, not one scroll)
|
|
83965
83993
|
- sproutkit build-all --json [--ids 3,5] [--concurrency 3] \u2014 build many at once
|
|
83966
83994
|
- sproutkit regenerate <id> --instructions "..." --json \u2014 rebuild an existing site with changes
|
|
83967
83995
|
- sproutkit cms <id> --json \u2014 add the editable CMS on top of the site we built them
|
|
@@ -84220,7 +84248,7 @@ async function main() {
|
|
|
84220
84248
|
say(c.bold(" Commands (type with or without a leading /):"));
|
|
84221
84249
|
say(` ${c.greenBold("find")} "<area>" --categories "cafe,barber" find website-less leads`);
|
|
84222
84250
|
say(` ${c.greenBold("list")} [--status <s>] [--city <c>] list leads (get ids)`);
|
|
84223
|
-
say(` ${c.greenBold("build")} <id> [--instructions "\u2026"] [--cms]
|
|
84251
|
+
say(` ${c.greenBold("build")} <id> [--instructions "\u2026"] [--cms] [--multipage] build a demo site`);
|
|
84224
84252
|
say(` ${c.greenBold("build-all")} [--ids 3,5] [--concurrency 3] build many at once`);
|
|
84225
84253
|
say(` ${c.greenBold("regenerate")} <id> --instructions "\u2026" rebuild a site with changes`);
|
|
84226
84254
|
say(` ${c.greenBold("cms")} <id> add the editable CMS to a built site`);
|