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.
Files changed (2) hide show
  1. package/dist/index.js +40 -12
  2. 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: { react: "^18.3.1", "react-dom": "^18.3.1" },
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
- react: "^18.3.1",
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({ id, instructions, ctx });
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.13.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] \u2014 build a demo site
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] build a demo site`);
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`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sproutkit-code",
3
- "version": "0.13.0",
3
+ "version": "0.14.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"