zerostarter 0.1.7 → 0.1.8

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 +1 @@
1
- export { };
1
+ export {}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,p as c,r as l,s as u,t as d,u as f}from"../convert-DHRbJrsm.mjs";import{basename as p,delimiter as m,dirname as h,join as g,parse as _,resolve as v}from"node:path";import{existsSync as y,readFileSync as b,readdirSync as ee}from"node:fs";import{spawn as x}from"node:child_process";import{access as te}from"node:fs/promises";import{createInterface as S}from"node:readline/promises";import{randomBytes as C}from"node:crypto";import{parseArgs as ne}from"node:util";import{homedir as w}from"node:os";const T=(e,t,n=process.stdout)=>r=>n.isTTY?`\x1b[${e}m${r}\x1b[${t}m`:r,E=T(`36`,`39`),D=T(`32`,`39`),O=T(`33`,`39`),k=T(`90`,`39`),A=T(`2`,`22`),j=T(`31`,`39`,process.stderr),re=T(`2`,`22`,process.stderr),M=T(`38;5;208`,`39`),N=[`◇`,`◆`],P=(e,t)=>{let n=(e%N.length+N.length)%N.length;return`${E(N[n])} ${t}`},F={barStart:`┌`,bar:`│`,barEnd:`└`,active:`◆`,submit:`◇`,radioOn:`●`,radioOff:`○`,checkboxOn:`◼`,checkboxOff:`◻`,warn:`▲`,error:`■`,barH:`─`,cornerTR:`╮`,connectL:`├`,cornerBL:`╰`,cornerBR:`╯`};var ie=class extends Error{constructor(...e){super(...e),this.name=`SubprocessError`,this.stdout=``,this.stderr=``}};const ae=[`.exe`,`.com`],I=e=>e.replaceAll(/([()\][%!^"`<>&|;, *?])/g,`^$1`),oe=e=>I(I(`"${e.replaceAll(/(\\*)"/g,`$1$1\\"`).replace(/(\\*)$/,`$1$1`)}"`)),se=async(e,t,n)=>{if(ae.some(t=>e.toLowerCase().endsWith(t)))return!0;let r=(n.PATH||n.Path||``).split(m).filter(Boolean).map(e=>e.replace(/^"(.*)"$/,`$1`));try{return await Promise.any([t,...r].flatMap(t=>ae.map(n=>te(`${v(t,e)}${n}`)))),!0}catch{return!1}},ce=async(e,t,n,r=process.platform===`win32`)=>{let i=n.cwd?String(n.cwd):`.`,a=n.env||process.env;return r&&!n.shell&&!await se(e,i,a)?[I(e),t.map(oe),{...n,shell:!0}]:[e,t,n]},L=async(e,t,n,r)=>{let i=[e,...t].join(` `),[a,o,s]=await ce(e,t,n);s.shell&&o.length>0&&(a=[a,...o].join(` `),o=[]);let c=x(a,o,s),l=``,u=``;return new Promise((e,t)=>{let n=(e,n,r)=>{let i=new ie(e,r?{cause:r}:void 0);i.stdout=l,i.stderr=u,i.exitCode=n,t(i)},a=e=>{e.code!==`ERR_STREAM_PREMATURE_CLOSE`&&e.code!==`EPIPE`&&n(`Command failed: ${i}`,void 0,e)};c.stdout&&(c.stdout.setEncoding(`utf8`),c.stdout.on(`data`,e=>{l+=e,r?.(e)}),c.stdout.on(`error`,a)),c.stderr&&(c.stderr.setEncoding(`utf8`),c.stderr.on(`data`,e=>{u+=e,r?.(e)}),c.stderr.on(`error`,a)),c.on(`error`,e=>n(`Command failed: ${i}`,void 0,e)),c.on(`close`,(t,r)=>{if(r)return n(`Command was terminated with ${r}: ${i}`);if(t!==0)return n(`Command failed with exit code ${t}: ${i}`,t??void 0);e({stdout:l,stderr:u})})})},R=async(e,t,n)=>{let{stdout:r}=await L(e,t,{cwd:n,stdio:[`ignore`,`pipe`,`pipe`]});return r},le=async(e,t,n)=>{await L(e,t,{cwd:n,stdio:`inherit`})},z=async(e,t)=>{try{return await L(e,t,{stdio:`ignore`}),!0}catch{return!1}},ue=RegExp(`\x1B\\[[0-9;?]*[a-zA-Z]`,`g`),de=e=>e.replace(ue,``),fe=new WeakSet,pe=e=>{if(process.stderr.write(`\n ${j(e instanceof Error?e.message:String(e))}\n`),!(e instanceof ie)||fe.has(e))return;let t=(e.stderr||e.stdout||``).trim();if(!t)return;let n=de(t).split(`
2
+ import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,p as c,r as l,s as u,t as d,u as f}from"../convert-qIUh5kib.mjs";import{basename as p,delimiter as m,dirname as h,join as g,parse as _,resolve as v}from"node:path";import{existsSync as y,readFileSync as b,readdirSync as ee}from"node:fs";import{spawn as x}from"node:child_process";import{access as te}from"node:fs/promises";import{createInterface as S}from"node:readline/promises";import{randomBytes as C}from"node:crypto";import{parseArgs as ne}from"node:util";import{homedir as w}from"node:os";const T=(e,t,n=process.stdout)=>r=>n.isTTY?`\x1b[${e}m${r}\x1b[${t}m`:r,E=T(`36`,`39`),D=T(`32`,`39`),O=T(`33`,`39`),k=T(`90`,`39`),A=T(`2`,`22`),j=T(`31`,`39`,process.stderr),re=T(`2`,`22`,process.stderr),M=T(`38;5;208`,`39`),N=[`◇`,`◆`],P=(e,t)=>{let n=(e%N.length+N.length)%N.length;return`${E(N[n])} ${t}`},F={barStart:`┌`,bar:`│`,barEnd:`└`,active:`◆`,submit:`◇`,radioOn:`●`,radioOff:`○`,checkboxOn:`◼`,checkboxOff:`◻`,warn:`▲`,error:`■`,barH:`─`,cornerTR:`╮`,connectL:`├`,cornerBL:`╰`,cornerBR:`╯`};var ie=class extends Error{constructor(...e){super(...e),this.name=`SubprocessError`,this.stdout=``,this.stderr=``}};const ae=[`.exe`,`.com`],I=e=>e.replaceAll(/([()\][%!^"`<>&|;, *?])/g,`^$1`),oe=e=>I(I(`"${e.replaceAll(/(\\*)"/g,`$1$1\\"`).replace(/(\\*)$/,`$1$1`)}"`)),se=async(e,t,n)=>{if(ae.some(t=>e.toLowerCase().endsWith(t)))return!0;let r=(n.PATH||n.Path||``).split(m).filter(Boolean).map(e=>e.replace(/^"(.*)"$/,`$1`));try{return await Promise.any([t,...r].flatMap(t=>ae.map(n=>te(`${v(t,e)}${n}`)))),!0}catch{return!1}},ce=async(e,t,n,r=process.platform===`win32`)=>{let i=n.cwd?String(n.cwd):`.`,a=n.env||process.env;return r&&!n.shell&&!await se(e,i,a)?[I(e),t.map(oe),{...n,shell:!0}]:[e,t,n]},L=async(e,t,n,r)=>{let i=[e,...t].join(` `),[a,o,s]=await ce(e,t,n);s.shell&&o.length>0&&(a=[a,...o].join(` `),o=[]);let c=x(a,o,s),l=``,u=``;return new Promise((e,t)=>{let n=(e,n,r)=>{let i=new ie(e,r?{cause:r}:void 0);i.stdout=l,i.stderr=u,i.exitCode=n,t(i)},a=e=>{e.code!==`ERR_STREAM_PREMATURE_CLOSE`&&e.code!==`EPIPE`&&n(`Command failed: ${i}`,void 0,e)};c.stdout&&(c.stdout.setEncoding(`utf8`),c.stdout.on(`data`,e=>{l+=e,r?.(e)}),c.stdout.on(`error`,a)),c.stderr&&(c.stderr.setEncoding(`utf8`),c.stderr.on(`data`,e=>{u+=e,r?.(e)}),c.stderr.on(`error`,a)),c.on(`error`,e=>n(`Command failed: ${i}`,void 0,e)),c.on(`close`,(t,r)=>{if(r)return n(`Command was terminated with ${r}: ${i}`);if(t!==0)return n(`Command failed with exit code ${t}: ${i}`,t??void 0);e({stdout:l,stderr:u})})})},R=async(e,t,n)=>{let{stdout:r}=await L(e,t,{cwd:n,stdio:[`ignore`,`pipe`,`pipe`]});return r},le=async(e,t,n)=>{await L(e,t,{cwd:n,stdio:`inherit`})},z=async(e,t)=>{try{return await L(e,t,{stdio:`ignore`}),!0}catch{return!1}},ue=RegExp(`\x1B\\[[0-9;?]*[a-zA-Z]`,`g`),de=e=>e.replace(ue,``),fe=new WeakSet,pe=e=>{if(process.stderr.write(`\n ${j(e instanceof Error?e.message:String(e))}\n`),!(e instanceof ie)||fe.has(e))return;let t=(e.stderr||e.stdout||``).trim();if(!t)return;let n=de(t).split(`
3
3
  `).map(e=>e.trimEnd()).filter(Boolean).slice(-12);for(let e of n)process.stderr.write(` ${re(e)}\n`)},me=async(e,t,n)=>{let r=process.stdout,i=n.label??``;if(!r.isTTY){i&&r.write(` ${E(F.active)} ${i}\n`),await le(e,t,n.cwd);return}let a=n.lines??3,o=[],s=0,c=0,l=``,u=``,d=()=>(r.columns||80)-1,f=e=>{r.write(e?`\x1B[?7h`:`\x1B[?7l`)},p=()=>{c>0&&(r.write(`[${c}A`),c=0)},m=()=>{p();let e=0;r.write(` ${P(s,i)}\n`),e++;for(let t of o.slice(-a))r.write(` ${k(F.bar)} ${A(t.slice(0,Math.max(0,d()-5)))}\n`),e++;c=e},h=e=>{u+=e,l+=e;let t=l.split(`
4
- `);l=t.pop()??``;for(let e of t)o.push(de(e).replace(/\r/g,``).replace(/\t/g,` `).trimEnd()),m()};m(),f(!1);let g=()=>{f(!0),process.exit(130)};process.once(`SIGINT`,g);let _=setInterval(()=>{s+=1,m()},400),v=()=>{clearInterval(_),process.removeListener(`SIGINT`,g)};try{await L(e,t,{cwd:n.cwd,stdio:[`ignore`,`pipe`,`pipe`]},h)}catch(e){throw v(),p(),f(!0),r.write(u),e&&typeof e==`object`&&fe.add(e),e}v(),p(),f(!0),r.write(` ${E(F.active)} ${n.done??i}\n`);for(let e of o.slice(-a))r.write(` ${k(F.bar)} ${A(e.slice(0,Math.max(0,d()-5)))}\n`)};var he={name:`zerostarter`,version:`0.1.7`,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 B=()=>!!(process.stdin.isTTY&&process.stdout.isTTY),ge=(e,t=e)=>process.stdout.isTTY?`\x1b]8;;${e}\x07${t}\x1b]8;;\x07`:e,V=e=>ge(e,E(e)),H=e=>{process.stdout.write(`\n ${k(F.barStart)} ${e}\n ${k(F.bar)}\n`)},U=e=>{process.stdout.write(` ${k(F.bar)}\n ${k(F.barEnd)} ${e}\n`)},W=(e=`Cancelled`)=>{process.stdout.write(` ${k(F.barEnd)} ${j(e)}\n`)},G=e=>e.replace(RegExp(`\x1B\\[[0-9;?]*[a-zA-Z]`,`g`),``).replace(RegExp(`\x1B\\]8;;.*?\\x07`,`g`),``).length,K=(e,t=``,n=!1)=>{let r=`\n${e}\n`.split(`
4
+ `);l=t.pop()??``;for(let e of t)o.push(de(e).replace(/\r/g,``).replace(/\t/g,` `).trimEnd()),m()};m(),f(!1);let g=()=>{f(!0),process.exit(130)};process.once(`SIGINT`,g);let _=setInterval(()=>{s+=1,m()},400),v=()=>{clearInterval(_),process.removeListener(`SIGINT`,g)};try{await L(e,t,{cwd:n.cwd,stdio:[`ignore`,`pipe`,`pipe`]},h)}catch(e){throw v(),p(),f(!0),r.write(u),e&&typeof e==`object`&&fe.add(e),e}v(),p(),f(!0),r.write(` ${E(F.active)} ${n.done??i}\n`);for(let e of o.slice(-a))r.write(` ${k(F.bar)} ${A(e.slice(0,Math.max(0,d()-5)))}\n`)};var he={name:`zerostarter`,version:`0.1.8`,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 B=()=>!!(process.stdin.isTTY&&process.stdout.isTTY),ge=(e,t=e)=>process.stdout.isTTY?`\x1b]8;;${e}\x07${t}\x1b]8;;\x07`:e,V=e=>ge(e,E(e)),H=e=>{process.stdout.write(`\n ${k(F.barStart)} ${e}\n ${k(F.bar)}\n`)},U=e=>{process.stdout.write(` ${k(F.bar)}\n ${k(F.barEnd)} ${e}\n`)},W=(e=`Cancelled`)=>{process.stdout.write(` ${k(F.barEnd)} ${j(e)}\n`)},G=e=>e.replace(RegExp(`\x1B\\[[0-9;?]*[a-zA-Z]`,`g`),``).replace(RegExp(`\x1B\\]8;;.*?\\x07`,`g`),``).length,K=(e,t=``,n=!1)=>{let r=`\n${e}\n`.split(`
5
5
  `),i=G(t),a=r.reduce((e,t)=>Math.max(e,G(t)),i),o=Math.max(a,54)+2,s=r.map(e=>` ${k(F.bar)} ${e}${` `.repeat(o-G(e))}${k(F.bar)}`).join(`
6
6
  `),c=n?F.cornerBL:F.connectL;process.stdout.write(` ${E(F.active)} ${t} ${k(F.barH.repeat(Math.max(o-i-1,1))+F.cornerTR)}\n${s}\n ${k(c+F.barH.repeat(o+2)+F.cornerBR)}\n`)},q=(e,t=[])=>{process.stdout.write(` ${E(F.active)} ${e}\n`);for(let e of t)process.stdout.write(` ${k(F.bar)} ${e}\n`)},_e=e=>{process.stdout.write(` ${D(F.active)} ${D(e)}\n`)},J=(e,t=[])=>{process.stdout.write(` ${O(F.warn)} ${O(e)}\n`);for(let e of t)process.stdout.write(` ${k(F.bar)} ${O(e)}\n`)},ve=async(e,t,n)=>{let r=process.stdout,i=null;if(r.isTTY){let t=0;r.write(` ${P(0,e)}`),i=setInterval(()=>{t+=1,r.write(`\r\x1b[K ${P(t,e)}`)},400)}try{let e=await n();return i&&clearInterval(i),r.write(r.isTTY?`\r\x1b[K ${E(F.active)} ${t}\n`:` ${E(F.active)} ${t}\n`),e}catch(e){throw i&&clearInterval(i),r.isTTY&&r.write(`\r\x1B[K`),e}},ye=e=>{let t=e?`${D(F.radioOn)} Yes`:A(`${F.radioOff} Yes`),n=e?A(`${F.radioOff} No`):`${D(F.radioOn)} No`;return` ${k(F.bar)} ${t} ${A(`/`)} ${n}`},Y=async(e,t=!0)=>{let n=process.stdout;return B()?new Promise(r=>{let i=t,a=process.stdin,o=Math.max(1,Math.ceil((5+G(e))/(n.columns||80)));n.write(` ${E(F.submit)} ${e}\n`),n.write(ye(i)),a.setRawMode(!0),a.resume(),a.setEncoding(`utf8`);let s=()=>{a.setRawMode(!1),a.pause(),a.removeListener(`data`,u)},c=()=>{n.write(`\r\x1b[K\x1b[${o}A\r\x1b[0J`)},l=()=>{s(),c(),r(i)};function u(t){t===``?(s(),c(),n.write(` ${E(F.submit)} ${A(e)}\n`),W(),process.exit(130)):t===`\r`||t===`
7
7
  `?l():t===`y`||t===`Y`?(i=!0,l()):t===`n`||t===`N`?(i=!1,l()):(t===`\x1B[C`||t===`\x1B[D`||t===`\x1B[A`||t===`\x1B[B`||t===`h`||t===`l`)&&(i=!i,n.write(`\r\x1b[K${ye(i)}`))}a.on(`data`,u)}):(n.write(` ${E(F.active)} ${e} ${A(t?`Yes`:`No`)}\n`),t)},be=async(e,t)=>{if(t.length===0)return[];let n=process.stdout,r=new Set(t.filter(e=>e.checked).map(e=>e.value)),i=()=>t.filter(e=>r.has(e.value)).map(e=>e.label).join(`, `)||`none`;return B()?new Promise(a=>{let o=process.stdin,s=0,c=e=>{let n=t[e],i=r.has(n.value)?D(F.checkboxOn):A(F.checkboxOff),a=e===s?n.label:A(n.label);return` ${k(F.bar)} ${i} ${a}`},l=e=>{e||n.write(`\x1b[${t.length}A`);for(let e=0;e<t.length;e++)n.write(`\r\x1b[K${c(e)}\n`)};n.write(` ${E(F.submit)} ${e}\n`),l(!0),o.setRawMode(!0),o.resume(),o.setEncoding(`utf8`);let u=()=>{o.setRawMode(!1),o.pause(),o.removeListener(`data`,d)};function d(o){if(o===``)u(),n.write(`\x1b[${t.length+1}A\r\x1b[0J ${E(F.submit)} ${A(e)}\n`),W(),process.exit(130);else if(o===`\r`||o===`
@@ -1,5 +1,9 @@
1
1
  import{dirname as e,join as t}from"node:path";import{existsSync as n,mkdirSync as r,readFileSync as i,readdirSync as a,rmSync as o,writeFileSync as s}from"node:fs";const c=e=>{let t=[],n=[],r=!1;for(let i of e.split(`
2
- `)){let e=i.trim();if(e){if(!r&&e.startsWith(`# PRESERVE_ON_SYNC`)){n=e.slice(18).replace(/^\s*-\s*/,``).split(`,`).map(e=>e.trim()).filter(Boolean),r=!0;continue}e.startsWith(`#`)||t.push(e)}}return{excludes:t,preserve:n}},l=e=>n(e),u=e=>i(e,`utf8`),d=(t,n)=>{r(e(t),{recursive:!0}),s(t,n)},f=e=>{o(e,{force:!0,recursive:!0})},p=new Set([`node_modules`,`.next`,`.turbo`,`dist`]),m=(e,n=!0)=>{for(let r of a(e,{withFileTypes:!0})){let i=t(e,r.name);if(r.name===`.git`){if(n)continue;o(i,{force:!0,recursive:!0});continue}r.isDirectory()?p.has(r.name)?o(i,{force:!0,recursive:!0}):(m(i,!1),a(i).length===0&&o(i,{force:!0,recursive:!0})):r.name.startsWith(`.env`)||o(i,{force:!0})}},h=e=>{let n=[];for(let r of a(e,{withFileTypes:!0})){if(r.name===`.git`||p.has(r.name))continue;let i=t(e,r.name);r.isDirectory()?n.push(...h(i)):r.name===`package.json`&&n.push(i)}return n},g=e=>JSON.parse(u(e)),_=(e,t)=>{d(e,`${JSON.stringify(t,null,2)}\n`)},v=(e,t)=>{if(!n(e))return!1;let r=u(e),i=r.replace(t,``);return i===r?!1:(s(e,i),!0)},y=[`homepage`,`bugs`,`license`,`author`,`repository`,`funding`],b=[`name`,`version`,...y],x=(e,t)=>{let n={...e,...t};return Object.keys(n).length>0?n:void 0},S=(e,t)=>{let n=Array.isArray(e)?e:[],r=Array.isArray(t)?t:[];return n.length||r.length?[...new Set([...r,...n])]:void 0},C=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`,`resolutions`,`catalog`,`scripts`,`overrides`],w=(e,t,n)=>{let r={...t};for(let n of Object.keys(e))n in t||(r[n]=e[n]);for(let n of C){let i=x(e[n],t[n]);i&&(r[n]=i)}let i=S(e.workspaces,t.workspaces);if(i&&(r.workspaces=i),n)for(let t of b)t in e?r[t]=e[t]:delete r[t];return r},T={apiDocs:!0,blog:!0,docs:!0,internalDocs:!0,waitlist:!1},E=e=>`// Optional surfaces a fork enables or disables. Typed boolean (not \`as const\`) so a fork can flip them and the runtime gates are not dead code. Off means the routes 404 and the links, nav, sitemap, llms, and search drop the surface. waitlist off makes the home a plain landing page.
2
+ `)){let e=i.trim();if(e){if(!r&&e.startsWith(`# PRESERVE_ON_SYNC`)){n=e.slice(18).replace(/^\s*-\s*/,``).split(`,`).map(e=>e.trim()).filter(Boolean),r=!0;continue}e.startsWith(`#`)||t.push(e)}}return{excludes:t,preserve:n}},l=e=>n(e),u=e=>i(e,`utf8`),d=(t,n)=>{r(e(t),{recursive:!0}),s(t,n)},f=e=>{o(e,{force:!0,recursive:!0})},p=new Set([`node_modules`,`.next`,`.turbo`,`dist`]),m=(e,n=!0)=>{for(let r of a(e,{withFileTypes:!0})){let i=t(e,r.name);if(r.name===`.git`){if(n)continue;o(i,{force:!0,recursive:!0});continue}r.isDirectory()?p.has(r.name)?o(i,{force:!0,recursive:!0}):(m(i,!1),a(i).length===0&&o(i,{force:!0,recursive:!0})):r.name.startsWith(`.env`)||o(i,{force:!0})}},h=e=>{let n=[];for(let r of a(e,{withFileTypes:!0})){if(r.name===`.git`||p.has(r.name))continue;let i=t(e,r.name);r.isDirectory()?n.push(...h(i)):r.name===`package.json`&&n.push(i)}return n},g=e=>JSON.parse(u(e)),_=(e,t)=>{d(e,`${JSON.stringify(t,null,2)}\n`)},v=(e,t)=>{if(!n(e))return!1;let r=u(e),i=r.replace(t,``);return i===r?!1:(s(e,i),!0)},y=[`homepage`,`bugs`,`license`,`author`,`repository`,`funding`],b=[`name`,`version`,...y],x=(e,t)=>{let n={...e,...t};return Object.keys(n).length>0?n:void 0},S=(e,t)=>{let n=Array.isArray(e)?e:[],r=Array.isArray(t)?t:[];return n.length||r.length?[...new Set([...r,...n])]:void 0},C=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`,`resolutions`,`catalog`,`scripts`,`overrides`],w=(e,t,n)=>{let r={...t};for(let n of Object.keys(e))n in t||(r[n]=e[n]);for(let n of C){let i=x(e[n],t[n]);i&&(r[n]=i)}let i=S(e.workspaces,t.workspaces);if(i&&(r.workspaces=i),n)for(let t of b)t in e?r[t]=e[t]:delete r[t];return r},T=`https://github.com/nrjdalal/zerostarter`,E=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`app`,D=(e,t,n)=>e.replaceAll(`ZeroStarter`,n).replaceAll(`zerostarter`,t),O=()=>`> [!CAUTION]
3
+ > Synced from ${T}. If you customize this skill or remove this note, it stops syncing and your fork owns it.`,k=(e,n)=>{let r=t(e,`.agents/skills`);if(!l(r))return;let i=E(n.name);for(let e of a(r,{withFileTypes:!0})){if(!e.isDirectory())continue;let a=t(r,e.name,`SKILL.md`);if(!l(a))continue;let o=u(a).split(`
4
+ `),s=o.indexOf(`---`),c=o.indexOf(`---`,s+1);if(s!==0||c===-1)throw Error(`.agents/skills/${e.name}/SKILL.md has no frontmatter to reconcile (the skill shape drifted). Update packages/cli/src/skills.ts.`);let f=o.slice(s+1,c).map(e=>e.startsWith(`source:`)?`source: ${T}`:D(e,i,n.name));f.some(e=>e.startsWith(`source:`))||f.push(`source: ${T}`);let p=D(o.slice(c+1).join(`
5
+ `),i,n.name).replace(/^\n+/,``);d(a,`---\n${f.join(`
6
+ `)}\n---\n\n${O()}\n\n${p}`)}},A={apiDocs:!0,blog:!0,docs:!0,internalDocs:!0,waitlist:!1},j=e=>`// Optional surfaces a fork enables or disables. Typed boolean (not \`as const\`) so a fork can flip them and the runtime gates are not dead code. Off means the routes 404 and the links, nav, sitemap, llms, and search drop the surface. waitlist off makes the home a plain landing page.
3
7
  export const features = {
4
8
  apiDocs: ${e.apiDocs},
5
9
  blog: ${e.blog},
@@ -8,7 +12,7 @@ export const features = {
8
12
  waitlist: ${e.waitlist},
9
13
  }
10
14
 
11
- export type Feature = keyof typeof features`,D=({name:e},t=T)=>{let n=e.charAt(0).toUpperCase()+e.slice(1);return`// Brand identity for this app: the single source a fork edits to rebrand. web reads it via lib/config.ts.
15
+ export type Feature = keyof typeof features`,M=({name:e},t=A)=>{let n=e.charAt(0).toUpperCase()+e.slice(1);return`// Brand identity for this app: the single source a fork edits to rebrand. web reads it via lib/config.ts.
12
16
  export const site = {
13
17
  name: "${n}",
14
18
  description: "${n} is just getting started. Tell its story here.",
@@ -30,8 +34,8 @@ export const site = {
30
34
 
31
35
  export type Site = typeof site
32
36
 
33
- ${E(t)}
34
- `},O=()=>`import { features, site } from "@packages/config/site"
37
+ ${j(t)}
38
+ `},N=()=>`import { features, site } from "@packages/config/site"
35
39
  import { redirect } from "next/navigation"
36
40
 
37
41
  // Fresh fork: the waitlist capture when the waitlist feature is on, otherwise a plain landing page. Replace this with your real home when ready.
@@ -47,7 +51,7 @@ export default function Home() {
47
51
  </main>
48
52
  )
49
53
  }
50
- `,k=()=>'# 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',A=({name:e})=>`# ${e.charAt(0).toUpperCase()+e.slice(1)}
54
+ `,P=()=>'# 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',F=({name:e})=>`# ${e.charAt(0).toUpperCase()+e.slice(1)}
51
55
 
52
56
  Built on top of [ZeroStarter](https://zerostarter.dev).
53
57
 
@@ -58,7 +62,7 @@ bun run dev
58
62
  \`\`\`
59
63
 
60
64
  This serves named \`.localhost\` dev URLs via portless (\`bunx portless list\` shows them); \`PORTLESS=0 bun run dev\` uses fixed ports instead (web \`:3000\`, api \`:4000\`).
61
- `,j=()=>`---
65
+ `,I=()=>`---
62
66
  slug: /docs
63
67
  title: Introduction
64
68
  description: Documentation.
@@ -67,7 +71,7 @@ description: Documentation.
67
71
  # Introduction
68
72
 
69
73
  This is your documentation home. Start writing, this page is yours.
70
- `,M=()=>`---
74
+ `,L=()=>`---
71
75
  slug: /console/docs
72
76
  title: Introduction
73
77
  description: Internal documentation.
@@ -76,7 +80,7 @@ description: Internal documentation.
76
80
  # Introduction
77
81
 
78
82
  Your team's internal docs live here.
79
- `,N=e=>`---
83
+ `,R=e=>`---
80
84
  title: Blog
81
85
  description: Latest articles and updates
82
86
  createdAt: ${e}
@@ -85,7 +89,7 @@ createdAt: ${e}
85
89
  ## Recent Posts
86
90
 
87
91
  <BlogPostList />
88
- `,P=e=>`---
92
+ `,z=e=>`---
89
93
  title: Hello World
90
94
  description: The first post on your new blog.
91
95
  createdAt: ${e}
@@ -95,7 +99,7 @@ publishedAt: ${e}
95
99
  ## Hello World
96
100
 
97
101
  Your very first post. Replace it with something worth reading.
98
- `,F=()=>`import type { DocsConfig } from "./src/lib/docs"
102
+ `,B=()=>`import type { DocsConfig } from "./src/lib/docs"
99
103
 
100
104
  const docsConfig = {
101
105
  docs: {
@@ -121,4 +125,4 @@ const docsConfig = {
121
125
  } satisfies DocsConfig
122
126
 
123
127
  export default docsConfig
124
- `,I=(e,...n)=>t(e,...n),L=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`app`,R=e=>{let t=I(e,`.gitpickignore`);if(l(t)){for(let n of c(u(t)).excludes){if(/[*?![\]]/.test(n))throw Error(`.gitpickignore entry "${n}" is not a literal path; the in-place converter only supports literal paths (a glob or negation would diverge from gitpick's fetch).`);f(I(e,n))}f(t)}},z=/[ \t]*\{[^}\r\n]*href:[ \t]*["']\/hire["'][^}\r\n]*\},?[ \t]*\r?\n/,B=(e,t)=>{let n=new Date,r=n.toISOString().slice(0,10),i=[n.getFullYear(),n.getMonth()+1,n.getDate()].map(e=>String(e).padStart(2,`0`)).join(`-`),a=i<r?i:r;d(I(e,`web/next/content/docs/index.mdx`),j()),d(I(e,`web/next/content/blog/index.mdx`),N(a)),d(I(e,`web/next/content/blog/hello-world.mdx`),P(a)),d(I(e,`web/next/content/console/docs/index.mdx`),M()),d(I(e,`web/next/docs.config.ts`),F()),d(I(e,`web/next/public/.gitkeep`),``),d(I(e,`web/next/src/app/page.tsx`),O()),d(I(e,`AGENTS.md`),k()),d(I(e,`README.md`),A(t))},V=e=>{let t=I(e,`web/next/src/lib/fonts.ts`),n=I(e,`web/next/src/lib/marketing/fonts.ts`),r=I(e,`web/next/src/components/common/navbar.tsx`);if(v(r,z),l(n))throw Error(`web/next/src/lib/marketing/fonts.ts survived the fork strip (add web/next/src/lib/marketing/ to .gitpickignore).`);if(l(t)&&u(t).includes(`fonts/marketing/`))throw Error(`fonts.ts references fonts/marketing/; author-only marketing fonts must live in the fork-excluded web/next/src/lib/marketing/, not the shared fonts.ts.`);if(l(r)&&/href:\s*["']\/hire["']/.test(u(r)))throw Error(`common/navbar.tsx still has the /hire entry after fixDangling (regex drift). Update packages/cli/src/convert.ts.`)},H=(e,t,n)=>{d(I(e,`packages/config/src/site.ts`),D(t,n));let r=L(t.name),i=I(e,`package.json`),a=g(i);a.name=r,a.version=`0.0.0`;for(let e of y)delete a[e];_(i,a);for(let[t,n]of[[`web/next`,r],[`api/hono`,`api.${r}`]]){let r=I(e,t,`package.json`),i=g(r),a=i.portless;if(!a||typeof a!=`object`||Array.isArray(a))throw Error(`${t}/package.json has no "portless" object to rebrand (the dev-URL setup drifted). Update packages/cli/src/convert.ts.`);let o=a;o.name=n,_(r,i)}},U=(e,t,n=T)=>{R(e),B(e,t),V(e),H(e,t,n)};export{m as a,u as c,d,_ as f,w as i,g as l,V as n,l as o,c as p,T as r,h as s,U as t,f as u};
128
+ `,V=(e,...n)=>t(e,...n),H=e=>{let t=V(e,`.gitpickignore`);if(l(t)){for(let n of c(u(t)).excludes){if(/[*?![\]]/.test(n))throw Error(`.gitpickignore entry "${n}" is not a literal path; the in-place converter only supports literal paths (a glob or negation would diverge from gitpick's fetch).`);f(V(e,n))}f(t)}},U=/[ \t]*\{[^}\r\n]*href:[ \t]*["']\/hire["'][^}\r\n]*\},?[ \t]*\r?\n/,W=(e,t)=>{let n=new Date,r=n.toISOString().slice(0,10),i=[n.getFullYear(),n.getMonth()+1,n.getDate()].map(e=>String(e).padStart(2,`0`)).join(`-`),a=i<r?i:r;d(V(e,`web/next/content/docs/index.mdx`),I()),d(V(e,`web/next/content/blog/index.mdx`),R(a)),d(V(e,`web/next/content/blog/hello-world.mdx`),z(a)),d(V(e,`web/next/content/console/docs/index.mdx`),L()),d(V(e,`web/next/docs.config.ts`),B()),d(V(e,`web/next/public/.gitkeep`),``),d(V(e,`web/next/src/app/page.tsx`),N()),d(V(e,`AGENTS.md`),P()),d(V(e,`README.md`),F(t))},G=e=>{let t=V(e,`web/next/src/lib/fonts.ts`),n=V(e,`web/next/src/lib/marketing/fonts.ts`),r=V(e,`web/next/src/components/common/navbar.tsx`);if(v(r,U),l(n))throw Error(`web/next/src/lib/marketing/fonts.ts survived the fork strip (add web/next/src/lib/marketing/ to .gitpickignore).`);if(l(t)&&u(t).includes(`fonts/marketing/`))throw Error(`fonts.ts references fonts/marketing/; author-only marketing fonts must live in the fork-excluded web/next/src/lib/marketing/, not the shared fonts.ts.`);if(l(r)&&/href:\s*["']\/hire["']/.test(u(r)))throw Error(`common/navbar.tsx still has the /hire entry after fixDangling (regex drift). Update packages/cli/src/convert.ts.`)},K=(e,t,n)=>{d(V(e,`packages/config/src/site.ts`),M(t,n));let r=E(t.name),i=V(e,`package.json`),a=g(i);a.name=r,a.version=`0.0.0`;for(let e of y)delete a[e];_(i,a);for(let[t,n]of[[`web/next`,r],[`api/hono`,`api.${r}`]]){let r=V(e,t,`package.json`),i=g(r),a=i.portless;if(!a||typeof a!=`object`||Array.isArray(a))throw Error(`${t}/package.json has no "portless" object to rebrand (the dev-URL setup drifted). Update packages/cli/src/convert.ts.`);let o=a;o.name=n,_(r,i)}},q=(e,t,n=A)=>{H(e),W(e,t),G(e),K(e,t,n),k(e,t)};export{m as a,u as c,d,_ as f,w as i,g as l,G as n,l as o,c as p,A as r,h as s,q as t,f as u};
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./convert-DHRbJrsm.mjs";export{e as convertRepo};
1
+ import{t as e}from"./convert-qIUh5kib.mjs";export{e as convertRepo};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zerostarter",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Go from zero to a production-ready SaaS, rebranded and ready to ship.",
5
5
  "keywords": [
6
6
  "cli",