git-paid 2.1.7 → 2.1.9

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/lib/pseo.js CHANGED
@@ -74,7 +74,7 @@ function renderTopicSpecificSection(pageSlug, cleanName, domain) {
74
74
  <td><strong>Launch Pass</strong> <span class="pill emerald" style="margin-left:6px;">Recommended</span></td>
75
75
  <td><strong>$29</strong> (one-time)</td>
76
76
  <td>1 project domain</td>
77
- <td>All 85 prefilled directory launch links + CSV export, 1-click <code>.zip</code> Launch Bundle with 25 static HTML SEO routes (<code>npx git-paid fix</code>), dedicated <code>&lt;domain&gt;-bot@postbuild.dev</code> verification inbox (30-day retention), and CLI/MCP key.</td>
77
+ <td>All 85 directory &amp; community launch links + CSV export, 1-click <code>.zip</code> Launch Bundle with 25 static HTML SEO starter templates (<code>npx git-paid fix</code>), dedicated <code>&lt;domain&gt;-bot@postbuild.dev</code> verification inbox (30-day retention), and CLI/MCP key.</td>
78
78
  </tr>
79
79
  <tr>
80
80
  <td><strong>Done-For-You &amp; Studio</strong></td>
@@ -123,7 +123,7 @@ function renderTopicSpecificSection(pageSlug, cleanName, domain) {
123
123
  <tr>
124
124
  <td><strong>Directory Launch Queue</strong></td>
125
125
  <td>Manual spreadsheet copy-pasting &amp; personal inbox clutter</td>
126
- <td>85 curated directories ranked by DR with prefilled UTM links + dedicated <code>postbuild-bot@postbuild.dev</code> inbox</td>
126
+ <td>85 curated directories &amp; launch channels ranked by DR + dedicated <code>postbuild-bot@postbuild.dev</code> inbox</td>
127
127
  </tr>
128
128
  </tbody>
129
129
  </table>
@@ -165,7 +165,7 @@ function renderTopicSpecificSection(pageSlug, cleanName, domain) {
165
165
  <td><strong>${escapeHtml(cleanName)} (<code>npx git-paid</code>)</strong></td>
166
166
  <td><strong>$29 one-time</strong> (Launch Pass)</td>
167
167
  <td>Dedicated <code>&lt;domain&gt;-bot@postbuild.dev</code></td>
168
- <td>Generates <code>robots.txt</code>, <code>sitemap.xml</code>, <code>llms.txt</code>, JSON-LD &amp; 25 HTML routes</td>
168
+ <td>Generates <code>robots.txt</code>, <code>sitemap.xml</code>, <code>llms.txt</code>, JSON-LD &amp; 25 HTML starter templates</td>
169
169
  </tr>
170
170
  </tbody>
171
171
  </table>
@@ -187,7 +187,7 @@ export function renderSinglePseoPage(page, allPages = [], options = {}) {
187
187
 
188
188
  const fullTitle = `${title} — ${categoryLabel} | ${cleanName}`;
189
189
  const canonicalUrl = `${origin}${page.path}`;
190
- const metaDescription = `${categoryLabel} for ${page.keyword}. Audit your live URL, generate robots.txt, sitemap.xml, llms.txt, and prepare 85 prefilled directory submissions with npx git-paid.`;
190
+ const metaDescription = `${categoryLabel} for ${page.keyword}. Audit your live URL, generate robots.txt, sitemap.xml, llms.txt, and prepare 85 directory & community submissions with npx git-paid.`;
191
191
 
192
192
  const relatedPages = allPages.filter((p) => p.path !== page.path).slice(0, 8);
193
193
  const topicSection = renderTopicSpecificSection(pageSlug, cleanName, domain);
@@ -229,7 +229,7 @@ export function renderSinglePseoPage(page, allPages = [], options = {}) {
229
229
  name: `How does ${cleanName} help with ${page.keyword}?`,
230
230
  acceptedAnswer: {
231
231
  "@type": "Answer",
232
- text: `By running npx git-paid on your live URL, ${cleanName} audits 8 technical SEO and AI crawler signals, writes missing robots.txt, sitemap.xml, llms.txt, and 25 static HTML routes to your repo, and prepares 85 prefilled directory submission links with a dedicated @postbuild.dev verification inbox.`
232
+ text: `By running npx git-paid on your live URL, ${cleanName} audits 8 technical SEO and AI crawler signals, writes missing robots.txt, sitemap.xml, llms.txt, and 25 static HTML starter templates, and prepares 85 directory & community submission links with a dedicated @postbuild.dev verification inbox.`
233
233
  }
234
234
  },
235
235
  {
@@ -237,7 +237,7 @@ export function renderSinglePseoPage(page, allPages = [], options = {}) {
237
237
  name: `What is included in the $29 Launch Pass vs. the free audit?`,
238
238
  acceptedAnswer: {
239
239
  "@type": "Answer",
240
- text: `The free audit checks your live URL and provides copy-paste snippets plus a 5-directory preview. The $29 one-time Launch Pass unlocks all 85 prefilled directory links, CSV/JSON exports, repo file generation via npx git-paid fix, and your dedicated @postbuild.dev verification inbox with a 14-day refund guarantee.`
240
+ text: `The free audit checks your live URL and provides copy-paste snippets plus a 5-directory preview. The $29 one-time Launch Pass unlocks all 85 directory & community links, CSV/JSON exports, repo file generation via npx git-paid fix, and your dedicated @postbuild.dev verification inbox with a 14-day refund guarantee.`
241
241
  }
242
242
  }
243
243
  ]
@@ -593,9 +593,9 @@ export function renderSinglePseoPage(page, allPages = [], options = {}) {
593
593
  </thead>
594
594
  <tbody>
595
595
  <tr>
596
- <td><strong>85-Directory Submission Links &amp; UTMs</strong></td>
596
+ <td><strong>85-Directory &amp; Community Launch Links</strong></td>
597
597
  <td>~14 hours of repetitive copy-pasting &amp; URL tagging</td>
598
- <td>85 prefilled submission URLs + CSV export ready in seconds</td>
598
+ <td>URL auto-prefill + 1-click copy launch kit + CSV export ready in seconds</td>
599
599
  </tr>
600
600
  <tr>
601
601
  <td><strong>Directory Verification Emails &amp; OTPs</strong></td>
@@ -638,7 +638,7 @@ export function renderSinglePseoPage(page, allPages = [], options = {}) {
638
638
 
639
639
  <footer class="site-footer">
640
640
  <div>
641
- <strong>postbuild.dev</strong> (<code>git-paid</code> v2.1.6) — Post-build SEO, directory launch kit &amp; verification inbox.
641
+ <strong>postbuild.dev</strong> (<code>git-paid</code> v2.1.9) — Post-build SEO, directory launch kit &amp; verification inbox.
642
642
  </div>
643
643
  <div style="display:flex;gap:14px;flex-wrap:wrap;">
644
644
  <a href="/">Home &amp; Audit</a>
@@ -683,6 +683,8 @@ export function renderBuyerStarterPseoPage(page, allPages = [], options = {}) {
683
683
  const tagline =
684
684
  rawTagline &&
685
685
  rawTagline.toLowerCase() !== prodName.toLowerCase() &&
686
+ rawTagline.toLowerCase() !== cleanDomain.toLowerCase() &&
687
+ !rawTagline.toLowerCase().includes(`on ${cleanDomain}`) &&
686
688
  !rawTagline.toLowerCase().includes(`(${cleanDomain})`)
687
689
  ? rawTagline
688
690
  : "";
@@ -690,7 +692,7 @@ export function renderBuyerStarterPseoPage(page, allPages = [], options = {}) {
690
692
  const shortPitch = String(options.shortPitch || options.description || "").trim();
691
693
  const summaryText =
692
694
  shortPitch ||
693
- `${prodName} is available at ${cleanOrig}. Customize this starter draft with your specific product workflows, screenshots, and customer examples before publishing.`;
695
+ `${prodName} is available at ${cleanOrig}. Customize this starter template with your specific product workflows, screenshots, and customer examples before publishing.`;
694
696
 
695
697
  const cats =
696
698
  Array.isArray(options.categories) && options.categories.length > 0
@@ -698,16 +700,17 @@ export function renderBuyerStarterPseoPage(page, allPages = [], options = {}) {
698
700
  : "Web Application";
699
701
 
700
702
  const metaDesc = `${cleanHeading}. ${summaryText}`.slice(0, 158).trim();
701
- const ogImgUrl = options.ogImage || `${cleanOrig}/og-card.svg`;
702
- const related = (allPages || []).filter((p) => p.path !== page.path).slice(0, 5);
703
- const headingTopic = cleanHeading
703
+ const ogImgUrl = options.ogImage || `${cleanOrig}/og-card.png`;
704
+ const strippedCandidate = cleanHeading
704
705
  .replace(new RegExp(`^${prodName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*[—–:-]?\\s*`, "i"), "")
705
- .trim() || cleanHeading;
706
+ .trim();
707
+ const headingTopic =
708
+ !strippedCandidate || /^vs\./i.test(strippedCandidate) ? cleanHeading : strippedCandidate;
706
709
 
707
710
  const hasFaqSchema = String(page.schemaType || page.kd || "").includes("FAQPage");
708
711
  const faqItems = [
709
712
  {
710
- q: `What is covered in this ${headingTopic} guide?`,
713
+ q: `What is covered in "${cleanHeading}"?`,
711
714
  a: `${summaryText}`
712
715
  },
713
716
  {
@@ -748,21 +751,20 @@ export function renderBuyerStarterPseoPage(page, allPages = [], options = {}) {
748
751
  let bodySectionHtml = "";
749
752
  if (cat === "Comparison" || cat === "Walkthrough") {
750
753
  bodySectionHtml = ` <section class="card">
751
- <h2>Evaluation Criteria: ${escapeHtml(headingTopic)}</h2>
752
- <p>Use the worksheet below when comparing <strong>${escapeHtml(prodName)}</strong> against existing internal workflows:</p>
754
+ <h2>Evaluation Worksheet: ${escapeHtml(cleanHeading)}</h2>
755
+ <p>Customize this comparison table with your product's specific differentiators before removing <code>noindex</code>:</p>
753
756
  <table class="cmp-table">
754
- <thead><tr><th>Criterion</th><th>${escapeHtml(prodName)} (${escapeHtml(cleanDomain)})</th><th>Current / Baseline Process</th></tr></thead>
757
+ <thead><tr><th>Criterion</th><th>${escapeHtml(prodName)}</th><th>Current / Baseline Process</th></tr></thead>
755
758
  <tbody>
756
- <tr><td><strong>Primary Scope</strong></td><td>${escapeHtml(tagline || prodName)}</td><td>Document current team baseline</td></tr>
757
- <tr><td><strong>Overview</strong></td><td>${escapeHtml(summaryText)}</td><td>Record current steps and handoffs</td></tr>
758
- <tr><td><strong>Direct Access</strong></td><td><a href="${escapeHtml(cleanOrig)}">${escapeHtml(cleanOrig)}</a></td><td>Internal docs / spreadsheets</td></tr>
759
+ <tr><td><strong>Core Focus</strong></td><td>${escapeHtml(tagline || summaryText)}</td><td>Document current team baseline</td></tr>
760
+ <tr><td><strong>Workflow Setup</strong></td><td>Available at <a href="${escapeHtml(cleanOrig)}">${escapeHtml(cleanOrig)}</a></td><td>Record current steps and handoffs</td></tr>
759
761
  </tbody>
760
762
  </table>
761
763
  </section>`;
762
764
  } else if (cat === "Calculator") {
763
765
  bodySectionHtml = ` <section class="card">
764
766
  <h2>Workflow Time Worksheet — ${escapeHtml(headingTopic)}</h2>
765
- <p>Enter your team's monthly frequency and average minutes per task to estimate total monthly time spent on this workflow:</p>
767
+ <p>Customize the default inputs below for your users before removing <code>noindex</code> and publishing:</p>
766
768
  <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;padding:18px;margin-top:12px;">
767
769
  <label style="display:block;font-weight:600;margin-bottom:6px;">Monthly runs: <span id="runsVal">10 runs/mo</span></label>
768
770
  <input id="runsInput" type="range" min="1" max="60" value="10" style="width:100%;margin-bottom:12px;" oninput="var r=parseInt(this.value,10)||1;var m=parseInt(document.getElementById('minsInput').value,10)||15;document.getElementById('runsVal').textContent=r+' runs/mo';document.getElementById('hrsTotal').textContent=((r*m)/60).toFixed(1)+' hrs/mo';" />
@@ -776,21 +778,22 @@ export function renderBuyerStarterPseoPage(page, allPages = [], options = {}) {
776
778
  </section>`;
777
779
  } else {
778
780
  bodySectionHtml = ` <section class="card">
779
- <h2>Key Notes: ${escapeHtml(headingTopic)}</h2>
781
+ <h2>Implementation Outline: ${escapeHtml(headingTopic)}</h2>
780
782
  <ul style="padding-left:20px;margin:12px 0;">
781
- <li style="margin-bottom:10px;"><strong>Objective:</strong> Define how ${escapeHtml(prodName)} fits into your ${escapeHtml(headingTopic.toLowerCase())} workflow.</li>
783
+ <li style="margin-bottom:10px;"><strong>Topic Scope:</strong> ${escapeHtml(cleanHeading)} (${escapeHtml(cat)}).</li>
782
784
  <li style="margin-bottom:10px;"><strong>Live Environment:</strong> Visit <a href="${escapeHtml(cleanOrig)}">${escapeHtml(cleanOrig)}</a> to inspect current features and setup options.</li>
783
- <li style="margin-bottom:10px;"><strong>Customization Note:</strong> Replace this starter section with your product's specific steps, screenshots, or code examples before publishing.</li>
785
+ <li style="margin-bottom:10px;"><strong>Editorial Step:</strong> Add your product's concrete steps, screenshots, and pricing, then remove <code>&lt;meta name="robots" content="noindex" /&gt;</code> in <code>&lt;head&gt;</code> when ready to index.</li>
784
786
  </ul>
785
787
  </section>`;
786
788
  }
787
789
 
788
790
  return `<!DOCTYPE html>
789
- <!-- Starter SEO draft for ${escapeHtml(cleanDomain)} (${escapeHtml(page.path)}). Review and customize with your product details before publishing to production. -->
791
+ <!-- Starter SEO template for ${escapeHtml(cleanDomain)} (${escapeHtml(page.path)}). Includes <meta name="robots" content="noindex" /> by default so unedited drafts are never indexed. Customize and remove noindex before publishing. -->
790
792
  <html lang="en">
791
793
  <head>
792
794
  <meta charset="UTF-8" />
793
795
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
796
+ <meta name="robots" content="noindex" />
794
797
  <title>${escapeHtml(pageTitle)}</title>
795
798
  <meta name="description" content="${escapeHtml(metaDesc)}" />
796
799
  <link rel="canonical" href="${escapeHtml(canonicalUrl)}" />
@@ -804,7 +807,7 @@ export function renderBuyerStarterPseoPage(page, allPages = [], options = {}) {
804
807
  <meta name="twitter:description" content="${escapeHtml(metaDesc)}" />
805
808
  <meta name="twitter:image" content="${escapeHtml(ogImgUrl)}" />
806
809
  <script type="application/ld+json">${ldJson}</script>
807
- <style>body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;max-width:880px;margin:0 auto;padding:36px 20px 64px;line-height:1.65;color:#0f172a;background:#f8fafc}.card{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:26px;margin-bottom:20px}.cta{display:inline-block;background:#047857;color:#fff;padding:10px 18px;border-radius:8px;text-decoration:none;font-weight:600}.cmp-table{width:100%;border-collapse:collapse;margin-top:14px;font-size:14px}.cmp-table th,.cmp-table td{border:1px solid #e2e8f0;padding:10px 12px;text-align:left}.cmp-table th{background:#f1f5f9;font-weight:700}.faq-item{border-top:1px solid #e2e8f0;padding-top:14px;margin-top:14px}</style>
810
+ <style>body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;max-width:880px;margin:0 auto;padding:36px 20px 64px;line-height:1.65;color:#0f172a;background:#f8fafc}.card{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:26px;margin-bottom:20px}.draft-note{background:#fffbeb;border:1px solid #fde68a;color:#92400e;border-radius:10px;padding:12px 16px;margin-bottom:18px;font-size:13px}.cta{display:inline-block;background:#047857;color:#fff;padding:10px 18px;border-radius:8px;text-decoration:none;font-weight:600}.cmp-table{width:100%;border-collapse:collapse;margin-top:14px;font-size:14px}.cmp-table th,.cmp-table td{border:1px solid #e2e8f0;padding:10px 12px;text-align:left}.cmp-table th{background:#f1f5f9;font-weight:700}.faq-item{border-top:1px solid #e2e8f0;padding-top:14px;margin-top:14px}</style>
808
811
  </head>
809
812
  <body>
810
813
  <header style="display:flex;justify-content:space-between;align-items:center;margin-bottom:24px;padding-bottom:14px;border-bottom:1px solid #e2e8f0;">
@@ -812,6 +815,9 @@ export function renderBuyerStarterPseoPage(page, allPages = [], options = {}) {
812
815
  <a class="cta" href="${escapeHtml(cleanOrig)}" style="font-size:13px;padding:7px 14px;">Open ${escapeHtml(prodName)} &rarr;</a>
813
816
  </header>
814
817
  <main>
818
+ <div class="draft-note">
819
+ <strong>Starter Draft Template (<code>noindex</code> active):</strong> Customize this page with your product's specific details and remove <code>&lt;meta name="robots" content="noindex" /&gt;</code> before adding this URL to <code>public/sitemap.xml</code>.
820
+ </div>
815
821
  <article class="card">
816
822
  <div style="font-size:12px;font-weight:700;color:#047857;text-transform:uppercase;letter-spacing:0.04em;">${escapeHtml(cat)} &middot; ${escapeHtml(cats)}</div>
817
823
  <h1 style="margin:8px 0 12px;font-size:28px;line-height:1.25;">${escapeHtml(cleanHeading)}</h1>
@@ -828,12 +834,6 @@ ${faqItems.map((f) => ` <div class="faq-item"><h3 style="margin:0 0 6px;fon
828
834
  </section>`
829
835
  : ""
830
836
  }
831
- <section class="card">
832
- <h2>Related ${escapeHtml(prodName)} Guides</h2>
833
- <ul style="padding-left:20px;margin:10px 0;">
834
- ${related.map((r) => ` <li style="margin-bottom:6px;"><a href="${escapeHtml(r.path)}" style="color:#0284c7;text-decoration:none;font-weight:500;">${escapeHtml(r.keyword || r.path)}</a> <span style="color:#64748b;font-size:12px;">(${escapeHtml(r.category || r.volume || "Guide")})</span></li>`).join("\n")}
835
- </ul>
836
- </section>
837
837
  </main>
838
838
  </body>
839
839
  </html>`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-paid",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "description": "git push ships your code. git paid sells it. Autonomous SEO, Paywall, MCP & Directory Launch Agent (www.postbuild.dev).",
5
5
  "type": "module",
6
6
  "main": "bin/git-paid.js",