zerostarter 0.0.12 → 0.0.13-canary.1

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.
@@ -1,29 +1,31 @@
1
1
  #!/usr/bin/env node
2
- import{i as e,n as t,r as n,t as r}from"../convert-HqQouyr9.mjs";import{basename as i,join as a,resolve as o}from"node:path";import{existsSync as s,readdirSync as c}from"node:fs";import{createInterface as l}from"node:readline/promises";import{parseArgs as u}from"node:util";import{execFileSync as d}from"node:child_process";import{randomBytes as f}from"node:crypto";var p={name:`zerostarter`,version:`0.0.12`,description:`Go from zero to a production-ready SaaS, rebranded and ready to ship.`,keywords:[`cli`,`saas`,`scaffold`,`starter`,`template`,`zerostarter`],homepage:`https://github.com/nrjdalal/zerostarter#readme`,bugs:`https://github.com/nrjdalal/zerostarter/issues`,license:`MIT`,author:{name:`Neeraj Dalal`,email:`admin@nrjdalal.com`,url:`https://nrjdalal.com`},repository:`nrjdalal/zerostarter`,funding:`https://github.com/sponsors/nrjdalal`,bin:{zerostarter:`dist/bin/index.mjs`},files:[`dist`],type:`module`,types:`./dist/index.d.mts`,exports:`./dist/index.mjs`,scripts:{build:`tsdown`,"check-types":`tsc --noEmit`,dev:`tsdown --watch`,test:`bun test`},devDependencies:{"@packages/config":`workspace:*`,"@types/bun":`catalog:`,"@types/node":`catalog:`,tsdown:`catalog:`,typescript:`catalog:`}};const m=()=>!!(process.stdin.isTTY&&process.stdout.isTTY),h=(e,t=e)=>process.stdout.isTTY?`\x1b]8;;${e}\x07${t}\x1b]8;;\x07`:e,g=(e,t=process.stdout)=>n=>t.isTTY?`\x1b[${e}m${n}\x1b[0m`:n,_=g(`38;5;208`),v=g(`38;2;63;185;80`),y=g(`38;2;210;153;34`),b=g(`38;2;248;81;73`,process.stderr),x=async(e,t=``)=>{let n=l({input:process.stdin,output:process.stdout});try{return(await n.question(`${e}${t?` (${t})`:``}: `)).trim()||t}finally{n.close()}},S=async(e,t=!0)=>{let n=l({input:process.stdin,output:process.stdout});try{let r=(await n.question(`${e} (${t?`Y/n`:`y/N`}) `)).trim().toLowerCase();return r?r===`y`||r===`yes`:t}finally{n.close()}},C=(e,t,n)=>d(e,t,{cwd:n,encoding:`utf8`,maxBuffer:1<<26,stdio:[`ignore`,`pipe`,`pipe`]}),w=(e,t,n)=>{d(e,t,{cwd:n,stdio:`inherit`})},T=()=>{try{return d(`docker`,[`info`],{stdio:`ignore`}),!0}catch{return!1}},E=r=>{let i=a(r,`.env`);if(!t(i)){let o=a(r,`.env.example`);e(i,t(o)?n(o):``)}return i},D=(e,t)=>{let r=`${t}=`,i=n(e).split(`
3
- `).find(e=>e.startsWith(r));return i?i.slice(r.length).trim():``},O=(t,r,i)=>{let a=`${r}=`,o=n(t).split(`
2
+ import{i as e,n as t,r as n,t as r}from"../convert-qa6VNLLu.mjs";import{basename as i,join as a,resolve as o}from"node:path";import{existsSync as s,readdirSync as c}from"node:fs";import{createInterface as l}from"node:readline/promises";import{parseArgs as u}from"node:util";import{execFileSync as d}from"node:child_process";import{randomBytes as f}from"node:crypto";var p={name:`zerostarter`,version:`0.0.13-canary.1`,description:`Go from zero to a production-ready SaaS, rebranded and ready to ship.`,keywords:[`cli`,`saas`,`scaffold`,`starter`,`template`,`zerostarter`],homepage:`https://github.com/nrjdalal/zerostarter#readme`,bugs:`https://github.com/nrjdalal/zerostarter/issues`,license:`MIT`,author:{name:`Neeraj Dalal`,email:`admin@nrjdalal.com`,url:`https://nrjdalal.com`},repository:`nrjdalal/zerostarter`,funding:`https://github.com/sponsors/nrjdalal`,bin:{zerostarter:`dist/bin/index.mjs`},files:[`dist`],type:`module`,types:`./dist/index.d.mts`,exports:`./dist/index.mjs`,scripts:{build:`tsdown`,"check-types":`tsc --noEmit`,dev:`tsdown --watch`,test:`bun test`},devDependencies:{"@packages/config":`workspace:*`,"@types/bun":`catalog:`,"@types/node":`catalog:`,tsdown:`catalog:`,typescript:`catalog:`}};const m=()=>!!(process.stdin.isTTY&&process.stdout.isTTY),h=(e,t=e)=>process.stdout.isTTY?`\x1b]8;;${e}\x07${t}\x1b]8;;\x07`:e,g=(e,t=process.stdout)=>n=>t.isTTY?`\x1b[${e}m${n}\x1b[0m`:n,_=g(`38;5;208`),v=g(`38;2;63;185;80`),y=g(`38;2;210;153;34`),b=g(`38;2;248;81;73`,process.stderr),x=async(e,t=``)=>{let n=l({input:process.stdin,output:process.stdout});try{return(await n.question(`${e}${t?` (${t})`:``}: `)).trim()||t}finally{n.close()}},S=async(e,t=!0)=>{let n=l({input:process.stdin,output:process.stdout});try{let r=(await n.question(`${e} (${t?`Y/n`:`y/N`}) `)).trim().toLowerCase();return r?r===`y`||r===`yes`:t}finally{n.close()}},C=(e,t,n)=>d(e,t,{cwd:n,encoding:`utf8`,maxBuffer:1<<26,stdio:[`ignore`,`pipe`,`pipe`]}),w=()=>{try{return d(`docker`,[`info`],{stdio:`ignore`}),!0}catch{return!1}},T=r=>{let i=a(r,`.env`);if(!t(i)){let o=a(r,`.env.example`);e(i,t(o)?n(o):``)}return i},E=(e,t)=>{let r=`${t}=`,i=n(e).split(`
3
+ `).find(e=>e.startsWith(r));return i?i.slice(r.length).trim():``},D=(t,r,i)=>{let a=`${r}=`,o=n(t).split(`
4
4
  `),s=o.findIndex(e=>e.startsWith(a));if(s>=0)o[s]=`${a}${i}`;else{for(;o.length&&o[o.length-1]===``;)o.pop();o.push(`${a}${i}`,``)}e(t,o.join(`
5
- `))},k=e=>{let t=E(e);D(t,`BETTER_AUTH_SECRET`)||O(t,`BETTER_AUTH_SECRET`,f(32).toString(`base64`))},A=e=>{let n=a(e,`.env`);return t(n)&&D(n,`POSTGRES_URL`)!==``},j=e=>{let t=C(`bunx`,[`pglaunch@5.5.7`,`-k`],e).match(/postgres(?:ql)?:\/\/[\w.:@\-/%?=&]+/);if(!t)throw Error(`pglaunch did not print a connection URL`);return t[0]},M=e=>{O(E(e),`POSTGRES_URL`,j(e)),w(`bun`,[`run`,`db:migrate`],e)},N=(e,t,n)=>d(e,t,{cwd:n,encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`]}),P=(e,t=`main`)=>{N(`bunx`,[`gitpick@5.4.1`,`https://github.com/nrjdalal/zerostarter/tree/${t}`,e])},F=e=>{N(`bun`,[`install`],e)},I=e=>{N(`git`,[`init`,`-q`,`-b`,`canary`],e)},L=(e,t)=>{N(`git`,[`branch`,t],e)},R=(e,t)=>{N(`git`,[`add`,`-A`],e);try{N(`git`,[`commit`,`--no-verify`,`-q`,`-m`,t],e)}catch{}},z=e=>!s(e)||c(e).filter(e=>e!==`.git`).length===0,B=e=>t(a(e,`packages/config/src/site.ts`)),V=async e=>{let{positionals:n,values:s}=u({allowPositionals:!0,args:e,options:{db:{type:`boolean`},"dry-run":{type:`boolean`},help:{short:`h`,type:`boolean`},yes:{short:`y`,type:`boolean`}}});if(s.help){console.log(`Usage:
6
- $ zerostarter init [dir] [options]
5
+ `))},O=e=>{let t=T(e);E(t,`BETTER_AUTH_SECRET`)||D(t,`BETTER_AUTH_SECRET`,f(32).toString(`base64`))},k=e=>{let n=a(e,`.env`);return t(n)&&E(n,`POSTGRES_URL`)!==``},A=e=>{let t=C(`bunx`,[`pglaunch@5.5.7`,`-k`],e).match(/postgres(?:ql)?:\/\/[\w.:@\-/%?=&]+/);if(!t)throw Error(`pglaunch did not print a connection URL`);return t[0]},j=e=>{D(T(e),`POSTGRES_URL`,A(e)),C(`bun`,[`run`,`db:migrate`],e)},M=(e,t,n)=>d(e,t,{cwd:n,encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`]}),N=(e,t=`main`)=>{M(`bunx`,[`gitpick@5.4.1`,`https://github.com/nrjdalal/zerostarter/tree/${t}`,e])},P=e=>{M(`bun`,[`install`],e)},F=e=>{M(`git`,[`init`,`-q`,`-b`,`canary`],e)},I=(e,t)=>{M(`git`,[`branch`,t],e)},L=(e,t)=>{M(`git`,[`add`,`-A`],e);try{M(`git`,[`commit`,`--no-verify`,`-q`,`-m`,t],e)}catch{}},R=e=>!s(e)||c(e).filter(e=>e!==`.git`).length===0,z=e=>t(a(e,`packages/config/src/site.ts`)),B=async e=>{let{positionals:n,values:s}=u({allowPositionals:!0,args:e,options:{db:{type:`boolean`},"dry-run":{type:`boolean`},help:{short:`h`,type:`boolean`},yes:{short:`y`,type:`boolean`}}});if(s.help){console.log(`Usage:
6
+ $ bunx zerostarter init [dir] [options]
7
7
 
8
8
  Scaffold ZeroStarter into dir (default .) as a fresh product. The author's
9
- content, public assets, and agent skills are left out for you to supply; the
9
+ content and public assets are left out for you to supply; the
10
10
  dir name becomes the project name and site.ts + package.json are rebranded. If
11
11
  the dir already holds a ZeroStarter clone it is used in place; otherwise the
12
12
  latest ZeroStarter is fetched into it first.
13
13
 
14
14
  Options:
15
- -y, --yes Skip prompts; fail instead of prompting when input is needed
15
+ -y, --yes Skip prompts, taking defaults (provisions Postgres when Docker is running)
16
16
  --db Provision a local Postgres (pglaunch) and migrate; needs Docker
17
17
  --dry-run Print the plan without writing anything
18
- -h, --help Display help`);return}let c=m()&&!s.yes,l=n[0]??`.`,d=o(l),f=B(d);if(!f&&!z(d)){if(!c)throw Error(`Target directory is not empty. Pass an empty target dir, for example: zerostarter init my-product`);let e=await x(`Target directory is not empty. New project directory`);if(!e)throw Error(`No directory name provided.`);l=e}let p=o(l),h=i(p),g={name:h};if(s[`dry-run`]){console.log(`zerostarter init (dry run)`),console.log(` target: ${p}`),console.log(` name: ${h}`),console.log(` mode: ${B(p)?`in place`:`fetch first`}`);return}if(f&&c&&!await S(y(`Convert ${p} in place? This rewrites files and commits.`),!1)){console.log(`Aborted.`);return}B(p)||(console.log(`Fetching the latest ZeroStarter ...`),P(p)),t(a(p,`.git`))||(I(p),R(p,`ci(init): scaffold from zerostarter`),L(p,`main`)),console.log(`Removing starter content and rebranding ...`),r(p,g),console.log(`Installing dependencies ...`),F(p),R(p,`ci(init): re-baseline as ${h}`),console.log(`Setting up .env (copied from .env.example, with a generated BETTER_AUTH_SECRET) ...`),k(p);let b=!1,C=T(),w=A(p),E=!1;if(w?s.db&&console.log(y(` --db ignored: POSTGRES_URL is already set in .env.`)):s.db?(E=C,C||console.log(y(` --db ignored: Docker is not running.`))):c&&C&&(E=await S(`Docker detected. Provision a local database and run migrations now?`,!0)),E)try{console.log(`Provisioning a local database with pglaunch and migrating ...`),M(p),b=!0}catch(e){let t=e instanceof Error?e.message:String(e);console.log(y(` Skipped database setup (${t}); set it up later with pglaunch + db:migrate.`))}let D=[[`packages/config/src/site.ts`,`your brand: name, tagline, links`],[`web/next/content`,`your docs and blog`],[`web/next/public`,`your logo and assets`]];console.log(`\n${v(`✓`)} ${h} is ready.\n`),console.log(`Next steps:`),p!==process.cwd()&&console.log(` ${_(`cd ${l}`)}`),b||(console.log(` ${_(`bunx pglaunch -k`)} # start Postgres, set POSTGRES_URL in .env`),console.log(` ${_(`bun run db:migrate`)}`)),console.log(` ${_(`bun run dev`)}`),console.log(`
18
+ -h, --help Display help`);return}let c=m()&&!s.yes,l=n[0]??`.`,d=o(l),f=z(d);if(!f&&!R(d)){if(!c)throw Error(`Directory is not empty. Run it in an empty directory, or pass a project name: bunx zerostarter init <name>`);let e=await x(`Directory isn't empty. Project name`);if(!e)throw Error(`No directory name provided.`);l=e}let p=o(l),h=i(p),g={name:h};if(s[`dry-run`]){console.log(`bunx zerostarter init (dry run)`),console.log(` target: ${p}`),console.log(` name: ${h}`),console.log(` mode: ${z(p)?`in place`:`fetch first`}`);return}if(f&&c&&!await S(y(`Convert ${p} in place? This rewrites files and commits.`),!1)){console.log(`Aborted.`);return}console.log(),z(p)||(console.log(`Fetching the latest ZeroStarter ...`),N(p)),t(a(p,`.git`))||(F(p),L(p,`ci(init): scaffold from zerostarter`),I(p,`main`)),console.log(`Removing starter content and rebranding ...`),r(p,g),console.log(`Installing dependencies ...`),P(p),L(p,`ci(init): re-baseline as ${h}`),O(p);let b=!1,C=w(),T=k(p),E=!1;if(T?s.db&&console.log(y(` --db ignored: POSTGRES_URL is already set in .env.`)):E=s.db?!0:c?await S(`Provision a local Postgres database now?`,C):C,E&&C)try{console.log(`Provisioning a local database with pglaunch and migrating ...`),j(p),b=!0}catch(e){let t=e.stderr,n=t?String(t).trim():e instanceof Error?e.message:String(e);console.log(y(` Database setup failed; set POSTGRES_URL in .env yourself.`)),n&&console.log(y(` ${n}`))}else E&&console.log(y(` Docker isn't running, so the database wasn't provisioned. Set POSTGRES_URL in .env, or start Docker and re-run for automatic setup.`));let D=[[`packages/config/src/site.ts`,`your brand: name, tagline, links`],[`web/next/content`,`your docs and blog`],[`web/next/public`,`your logo and assets`]];console.log(`\n${v(`✓`)} ${h} is ready.\n`),console.log(`Next steps:`),p!==process.cwd()&&console.log(` ${_(`cd ${l}`)}`),b||(console.log(` ${_(`set POSTGRES_URL in .env`)} # your Postgres connection string`),console.log(` ${_(`bun run db:migrate`)}`)),console.log(` ${_(`bun run dev`)}`),console.log(`
19
19
  Push to an empty GitHub repo when ready:`),console.log(` ${_(`git push origin canary`)}`),console.log(`canary becomes the default branch; your next push seeds main and opens the release PR.`),console.log(`
20
- Make it yours:`);for(let[e,t]of D)console.log(` ${e.padEnd(29)} ${t}`)},H=async e=>{console.log(`zerostarter sync is not implemented yet.`),console.log(`Planned: a gitpick overlay of the latest zerostarter onto an existing fork, then a`),console.log(`prune of starter-only artifacts while preserving the fork's product and branding.`)},{author:U,name:W,version:G}=p,K=`Version:
21
- ${W}@${G}
20
+ Make it yours:`);for(let[e,t]of D)console.log(` ${e.padEnd(29)} ${t}`);console.log(b?`
21
+ Everything works out of the box. Try it now; add OAuth or other credentials to .env whenever you like.`:`
22
+ It needs a Postgres database to run: a hosted one like Neon works, or a local Docker one. OAuth and other credentials are optional.`)},V=async e=>{console.log(`zerostarter sync is not implemented yet.`),console.log(`Planned: a gitpick overlay of the latest zerostarter onto an existing fork, then a`),console.log(`prune of starter-only artifacts while preserving the fork's product and branding.`)},{author:H,name:U,version:W}=p,G=`Version:
23
+ ${U}@${W}
22
24
 
23
25
  Go from zero to a production-ready SaaS, rebranded and ready to ship.
24
26
 
25
27
  Usage:
26
- $ ${W} <command> [options]
28
+ $ ${U} <command> [options]
27
29
 
28
30
  Commands:
29
31
  init [dir] Scaffold ZeroStarter into dir (default .) as a fresh product.
@@ -35,4 +37,4 @@ Options:
35
37
  -h, --help Display help
36
38
 
37
39
  Author:
38
- ${U.name} <${U.email}> (${h(U.url)})`;(async()=>{try{let e=process.argv.slice(2),t=e[0],n=e.slice(1);switch(t){case`init`:return await V(n);case`sync`:return await H(n);case void 0:case`-h`:case`--help`:console.log(K);return;case`-v`:case`--version`:console.log(`${W}@${G}`);return;default:console.error(b(`Unknown command: ${t}\n`)),console.log(K),process.exit(1)}}catch(e){console.error(b(e instanceof Error?e.message:String(e))),process.exit(1)}})();export{};
40
+ ${H.name} <${H.email}> (${h(H.url)})`;(async()=>{try{let e=process.argv.slice(2),t=e[0],n=e.slice(1);switch(t){case`init`:return await B(n);case`sync`:return await V(n);case void 0:case`-h`:case`--help`:console.log(G);return;case`-v`:case`--version`:console.log(`${U}@${W}`);return;default:console.error(b(`Unknown command: ${t}\n`)),console.log(G),process.exit(1)}}catch(e){console.error(b(e instanceof Error?e.message:String(e))),process.exit(1)}})();export{};
@@ -25,10 +25,7 @@ export type Site = typeof site
25
25
  export default function Home() {
26
26
  redirect("/waitlist")
27
27
  }
28
- `,g=()=>`# AGENTS.md
29
-
30
- Guidance for AI coding agents working in this repository.
31
- `,_=()=>`---
28
+ `,g=()=>'# AGENTS.md\n\nGuidance for AI coding agents working in this repository.\n\n## Instructions\n\n- ALWAYS: Use `@/` for imports, and follow the `design` skill for UI and styling conventions.\n- ALWAYS: Keep documentation in sync with every change.\n- NEVER: Include "Co-authored-by" in commit messages.\n- NEVER: Use em-dashes (the long dash, U+2014) in code, comments, docs, or copy. Regular hyphens are fine; for a pause or aside, use a comma, colon, or period.\n\n## Skills\n\nCustom skills live in `.agents/skills` (symlinked to `.claude/skills`). Start with the `codebase-map` skill to orient, then load the task skill that fits (`api-endpoint`, `db-migration`, `dev`, `design`, and more).\n',_=()=>`---
32
29
  slug: /docs
33
30
  title: Introduction
34
31
  description: Documentation.
@@ -91,7 +88,7 @@ const docsConfig = {
91
88
  } satisfies DocsConfig
92
89
 
93
90
  export default docsConfig
94
- `,S=(e,...n)=>t(e,...n),C=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`app`,w=[`web/next/content`,`web/next/public`,`.agents/skills`,`.claude/skills`,`.github/skills`],T=[`packages/cli`,`.github/workflows/cli-release.yml`,`.github/audit`,`.github/reviews`,`.infisical.json`,`.github/assets/graph-build.svg`,`.github/assets/cli.tape`,`.github/assets/setup.sh`,`.github/assets/cli.gif`,`.github/FUNDING.yml`,`LICENSE.md`,`CHANGELOG.md`,`bun.lock`,`skills-lock.json`,`web/next/src/app/hire`,`web/next/src/app/resume`,`web/next/src/fonts/caveat-latin-wght-normal.woff2`,`web/next/src/fonts/newsreader-latin-wght-normal.woff2`,`web/next/src/fonts/newsreader-latin-wght-italic.woff2`],E=e=>{let t=new Date,n=t.toISOString().slice(0,10),r=[t.getFullYear(),t.getMonth()+1,t.getDate()].map(e=>String(e).padStart(2,`0`)).join(`-`),i=r<n?r:n;l(S(e,`web/next/content/docs/index.mdx`),_()),l(S(e,`web/next/content/blog/index.mdx`),y(i)),l(S(e,`web/next/content/blog/hello-world.mdx`),b(i)),l(S(e,`web/next/content/console/docs/index.mdx`),v()),l(S(e,`web/next/docs.config.ts`),x()),l(S(e,`web/next/public/.gitkeep`),``),l(S(e,`web/next/src/app/page.tsx`),h()),l(S(e,`AGENTS.md`),g())},D=e=>{let t=p(S(e,`web/next/src/components/navbar/home.tsx`),[[` { href: "/hire", label: "Hire" },
91
+ `,S=(e,...n)=>t(e,...n),C=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`app`,w=[`web/next/content`,`web/next/public`],T=[`packages/cli`,`.github/workflows/cli-release.yml`,`.github/audit`,`.infisical.json`,`.coderabbit.yaml`,`.github/assets/graph-build.svg`,`.github/assets/cli.tape`,`.github/assets/setup.sh`,`.github/assets/cli.gif`,`.github/FUNDING.yml`,`LICENSE.md`,`CHANGELOG.md`,`bun.lock`,`web/next/src/app/hire`,`web/next/src/app/resume`,`web/next/src/fonts/caveat-latin-wght-normal.woff2`,`web/next/src/fonts/newsreader-latin-wght-normal.woff2`,`web/next/src/fonts/newsreader-latin-wght-italic.woff2`],E=e=>{let t=new Date,n=t.toISOString().slice(0,10),r=[t.getFullYear(),t.getMonth()+1,t.getDate()].map(e=>String(e).padStart(2,`0`)).join(`-`),i=r<n?r:n;l(S(e,`web/next/content/docs/index.mdx`),_()),l(S(e,`web/next/content/blog/index.mdx`),y(i)),l(S(e,`web/next/content/blog/hello-world.mdx`),b(i)),l(S(e,`web/next/content/console/docs/index.mdx`),v()),l(S(e,`web/next/docs.config.ts`),x()),l(S(e,`web/next/public/.gitkeep`),``),l(S(e,`web/next/src/app/page.tsx`),h()),l(S(e,`AGENTS.md`),g())},D=e=>{let t=p(S(e,`web/next/src/components/navbar/home.tsx`),[[` { href: "/hire", label: "Hire" },
95
92
  `,``]]),n=p(S(e,`web/next/src/lib/fonts.ts`),[[`
96
93
  export const caveat = localFont({
97
94
  src: "../fonts/caveat-latin-wght-normal.woff2",
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./convert-HqQouyr9.mjs";export{e as convertRepo};
1
+ import{t as e}from"./convert-qa6VNLLu.mjs";export{e as convertRepo};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zerostarter",
3
- "version": "0.0.12",
3
+ "version": "0.0.13-canary.1",
4
4
  "description": "Go from zero to a production-ready SaaS, rebranded and ready to ship.",
5
5
  "keywords": [
6
6
  "cli",