@rankture/cli 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rankture
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,637 @@
1
+ # @rankture/cli
2
+
3
+ > SEO audit tool for developers — check your sites before deploy
4
+
5
+ A fast, offline-first SEO checker that runs on your local files. Supports 15+ file types including HTML, JSX/TSX, Vue, Svelte, Astro, Markdown, and template engines. Perfect for CI/CD pipelines, pre-commit hooks, or manual checks before deployment.
6
+
7
+ ## Supported File Types
8
+
9
+ | Type | Extensions | Metadata Extraction |
10
+ |------|------------|---------------------|
11
+ | **HTML** | `.html`, `.htm` | Full SEO checks including viewport, canonical |
12
+ | **Astro** | `.astro` | Frontmatter `title`, `description`; `<Image>` component |
13
+ | **React/Next.js** | `.jsx`, `.tsx` | `export const metadata`, `<Head>`, `<Image>`, `<Link>` |
14
+ | **Vue/Nuxt** | `.vue` | `useSeoMeta()`, `useHead()`, `definePageMeta()`, `<NuxtImg>`, `<NuxtLink>` |
15
+ | **Svelte/SvelteKit** | `.svelte` | `<svelte:head>`, Svelte syntax stripped |
16
+ | **Markdown** | `.md`, `.mdx` | Frontmatter, heading/image/link conversion |
17
+ | **Nunjucks** | `.njk` | Block tags stripped, variables marked as dynamic |
18
+ | **EJS** | `.ejs` | Scriptlets stripped, expressions marked as dynamic |
19
+ | **Handlebars** | `.hbs` | Block helpers stripped, expressions marked as dynamic |
20
+ | **Pug** | `.pug` | Basic tag extraction (h1-h6, img, a, title, meta) |
21
+ | **Liquid** | `.liquid` | Shopify/11ty support, schema blocks stripped |
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ # Global install
27
+ npm install -g @rankture/cli
28
+
29
+ # Or use with npx (no install)
30
+ npx @rankture/cli check ./dist
31
+
32
+ # Or add to your project
33
+ npm install --save-dev @rankture/cli
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ```bash
39
+ # Check your built site (HTML output)
40
+ rankture check ./dist
41
+
42
+ # Check source files directly
43
+ rankture check ./src/pages
44
+ rankture check ./src/content
45
+
46
+ # Check with JSON output
47
+ rankture check ./dist --format json
48
+
49
+ # Fail build on critical issues
50
+ rankture check ./dist --fail-on critical
51
+
52
+ # Write report to file
53
+ rankture check ./dist --format json --output seo-report.json
54
+ ```
55
+
56
+ ## Commands
57
+
58
+ ### `check <path>`
59
+
60
+ Run SEO checks on local files.
61
+
62
+ ```bash
63
+ rankture check ./dist # Built HTML
64
+ rankture check ./src/pages # Astro/Next.js pages
65
+ rankture check ./src/content # Markdown content
66
+ rankture check ./index.html # Single file
67
+ rankture check ./pages/index.vue # Vue component
68
+ rankture check ./dist --watch # Watch mode - re-run on changes
69
+ rankture check ./src --changed # Only check git changed files
70
+ rankture check ./src --staged # Only check git staged files (pre-commit)
71
+ ```
72
+
73
+ **Options:**
74
+
75
+ | Option | Description | Default |
76
+ |--------|-------------|---------|
77
+ | `-f, --format <format>` | Output format: `terminal`, `json`, `html` | `terminal` |
78
+ | `-o, --output <file>` | Write output to file | stdout |
79
+ | `--fail-on <level>` | Exit code 1 on: `none`, `critical`, `warning`, `any` | `none` |
80
+ | `--ignore <patterns...>` | Glob patterns to ignore | `[]` |
81
+ | `--config <file>` | Config file path | - |
82
+ | `-w, --watch` | Watch for file changes and re-run checks | `false` |
83
+ | `--changed` | Only check files changed in git (staged + unstaged) | `false` |
84
+ | `--staged` | Only check git staged files (for pre-commit hooks) | `false` |
85
+
86
+ **Output Formats:**
87
+
88
+ ```bash
89
+ # Terminal output (default) - colorful, human-readable
90
+ rankture check ./dist
91
+
92
+ # JSON output - for programmatic processing
93
+ rankture check ./dist -f json -o seo-report.json
94
+
95
+ # HTML output - visual report to open in browser
96
+ rankture check ./dist -f html -o seo-report.html
97
+ ```
98
+
99
+ ### `init`
100
+
101
+ Create a `rankture.config.json` configuration file.
102
+
103
+ ```bash
104
+ rankture init # Create config file
105
+ rankture init --force # Overwrite existing config
106
+ ```
107
+
108
+ ### `validate <type> <file>`
109
+
110
+ Validate SEO assets like sitemaps, robots.txt, or schema.
111
+
112
+ ```bash
113
+ rankture validate sitemap ./public/sitemap.xml
114
+ rankture validate robots ./public/robots.txt
115
+ rankture validate schema ./schema.json # Coming soon
116
+ ```
117
+
118
+ **Robots.txt Validation:**
119
+ - User-agent directive presence
120
+ - Sitemap directive presence
121
+ - Valid directive syntax
122
+ - Disallow/Allow path format
123
+ - Crawl-delay values
124
+ - Common mistakes (blocking all, blocking important paths)
125
+
126
+ **Sitemap.xml Validation:**
127
+ - Valid XML structure
128
+ - Required `<loc>` tags for all URLs
129
+ - Valid URL formats
130
+ - Optional tag validation (`<lastmod>`, `<changefreq>`, `<priority>`)
131
+ - File size warnings (Google limit: 50MB, 50,000 URLs)
132
+ - URL accessibility sampling
133
+
134
+ ### `audit <url>` (Coming Soon)
135
+
136
+ Audit a live URL with optional Pro features.
137
+
138
+ ```bash
139
+ rankture audit https://example.com
140
+ rankture audit https://example.com --api-key YOUR_KEY --sync
141
+ ```
142
+
143
+ ## Checks Performed
144
+
145
+ The CLI runs **21 offline checks** across 5 categories:
146
+
147
+ ### Technical SEO (HTML only)
148
+ - ✓ Viewport meta tag*
149
+ - ✓ Language attribute*
150
+ - ✓ Canonical URL*
151
+ - ✓ Robots meta tag
152
+
153
+ *Skipped for source files since these are typically in layouts
154
+
155
+ ### On-Page SEO (All files)
156
+ - ✓ Title tag (exists, length, uniqueness)
157
+ - ✓ Meta description (exists, length)
158
+ - ✓ Single H1 tag
159
+ - ✓ Heading hierarchy (no skipped levels)
160
+ - ✓ Image alt text
161
+ - ✓ Internal link validity
162
+
163
+ ### Structured Data (HTML only)
164
+ - ✓ JSON-LD presence
165
+ - ✓ Schema.org validation
166
+ - ✓ Speakable schema (voice/AI assistant optimization)
167
+ - ✓ Offer/Product schema (pricing, discounts, availability)
168
+ - ✓ FAQ schema (question/answer structured data)
169
+ - ✓ HowTo schema (step-by-step instructions)
170
+
171
+ ### Social / Open Graph (HTML only)
172
+ - ✓ og:title, og:description, og:image
173
+ - ✓ og:type, og:url
174
+ - ✓ twitter:card, twitter:title, twitter:description, twitter:image
175
+
176
+ ### Accessibility (HTML only)
177
+ - ✓ Skip navigation link
178
+ - ✓ Main landmark (`<main>`)
179
+ - ✓ Navigation landmark (`<nav>`)
180
+ - ✓ Buttons with accessible names
181
+ - ✓ Links with accessible names
182
+ - ✓ Form inputs with labels
183
+ - ✓ Positive tabindex anti-pattern
184
+ - ✓ Focus outline removal
185
+ - ✓ Autoplay video with audio
186
+ - ✓ Color contrast (basic check)
187
+
188
+ ## AI & Voice Optimization
189
+
190
+ The CLI includes specialized checks for AI assistants and voice search readiness:
191
+
192
+ ### Speakable Schema
193
+ Validates that pages have `SpeakableSpecification` schema for voice assistants (Google Assistant, Alexa, Siri):
194
+
195
+ ```html
196
+ <script type="application/ld+json">
197
+ {
198
+ "@type": "WebPage",
199
+ "speakable": {
200
+ "@type": "SpeakableSpecification",
201
+ "cssSelector": [".speakable-intro", ".speakable-faq"]
202
+ }
203
+ }
204
+ </script>
205
+ ```
206
+
207
+ ### Offer/Product Schema
208
+ Validates pricing and product information for rich results:
209
+
210
+ ```html
211
+ <script type="application/ld+json">
212
+ {
213
+ "@type": "Product",
214
+ "offers": {
215
+ "@type": "Offer",
216
+ "price": "29.00",
217
+ "priceCurrency": "USD",
218
+ "availability": "https://schema.org/InStock"
219
+ }
220
+ }
221
+ </script>
222
+ ```
223
+
224
+ ### FAQ Schema
225
+ Validates FAQ structured data for featured snippets:
226
+
227
+ ```html
228
+ <script type="application/ld+json">
229
+ {
230
+ "@type": "FAQPage",
231
+ "mainEntity": [
232
+ {
233
+ "@type": "Question",
234
+ "name": "What is SEO?",
235
+ "acceptedAnswer": {
236
+ "@type": "Answer",
237
+ "text": "SEO stands for Search Engine Optimization..."
238
+ }
239
+ }
240
+ ]
241
+ }
242
+ </script>
243
+ ```
244
+
245
+ ### HowTo Schema
246
+ Validates step-by-step instructions for rich results:
247
+
248
+ ```html
249
+ <script type="application/ld+json">
250
+ {
251
+ "@type": "HowTo",
252
+ "name": "How to optimize your website",
253
+ "step": [
254
+ { "@type": "HowToStep", "text": "Run an SEO audit" },
255
+ { "@type": "HowToStep", "text": "Fix critical issues" }
256
+ ]
257
+ }
258
+ </script>
259
+ ```
260
+
261
+ ## Source File Intelligence
262
+
263
+ When checking source files (`.astro`, `.tsx`, `.md`, etc.), the CLI:
264
+
265
+ ### Metadata Extraction
266
+ - **Astro frontmatter** - Reads `title` and `description` from YAML frontmatter
267
+ - **Next.js `metadata`** - Parses `export const metadata: Metadata = { ... }`
268
+ - **Vue composables** - Extracts from `useSeoMeta()`, `useHead()`, `definePageMeta()`
269
+ - **Svelte head** - Reads title and meta from `<svelte:head>` block
270
+
271
+ ### Component Normalization
272
+ - **Image components** - `<Image>`, `<NuxtImg>`, `<Picture>` → `<img>` for alt text checking
273
+ - **Link components** - `<Link>`, `<NuxtLink>` → `<a>` for internal link checking
274
+ - **JSX curly braces** - Converts `{variable}` to `[dynamic]` markers
275
+
276
+ ### Template Engines
277
+ - **Nunjucks** - Strips `{% %}` blocks, marks `{{ }}` as dynamic
278
+ - **EJS** - Strips `<% %>` scriptlets, marks `<%= %>` as dynamic
279
+ - **Liquid** - Strips `{% %}` tags and `{% schema %}` blocks
280
+ - **Handlebars** - Strips `{{# }}` helpers, marks `{{ }}` as dynamic
281
+
282
+ ### Smart Check Handling
283
+ - **Skips layout checks** - Doesn't flag missing viewport/canonical/lang (handled by layouts)
284
+ - **Preserves content checks** - Still validates title, description, headings, images, links
285
+
286
+ ## Framework-Specific Examples
287
+
288
+ ### Next.js (App Router)
289
+
290
+ ```bash
291
+ # Check your pages
292
+ rankture check ./app
293
+ ```
294
+
295
+ The CLI extracts metadata from:
296
+ ```tsx
297
+ // app/page.tsx
298
+ export const metadata: Metadata = {
299
+ title: 'Home Page',
300
+ description: 'Welcome to our site',
301
+ };
302
+ ```
303
+
304
+ ### Astro
305
+
306
+ ```bash
307
+ # Check pages and content
308
+ rankture check ./src/pages ./src/content
309
+ ```
310
+
311
+ Extracts frontmatter:
312
+ ```astro
313
+ ---
314
+ title: "Blog Post Title"
315
+ description: "Post description for SEO"
316
+ ---
317
+ ```
318
+
319
+ ### Nuxt 3
320
+
321
+ ```bash
322
+ # Check pages
323
+ rankture check ./pages
324
+ ```
325
+
326
+ Extracts from composables:
327
+ ```vue
328
+ <script setup>
329
+ useSeoMeta({
330
+ title: 'Page Title',
331
+ description: 'Page description',
332
+ });
333
+ </script>
334
+ ```
335
+
336
+ ### SvelteKit
337
+
338
+ ```bash
339
+ # Check routes
340
+ rankture check ./src/routes
341
+ ```
342
+
343
+ Extracts from `<svelte:head>`:
344
+ ```svelte
345
+ <svelte:head>
346
+ <title>Page Title</title>
347
+ <meta name="description" content="Description" />
348
+ </svelte:head>
349
+ ```
350
+
351
+ ### Markdown/MDX (Content Collections)
352
+
353
+ ```bash
354
+ # Check content directory
355
+ rankture check ./content ./src/content
356
+ ```
357
+
358
+ Extracts frontmatter and converts syntax:
359
+ ```md
360
+ ---
361
+ title: "Article Title"
362
+ description: "Article description"
363
+ ---
364
+
365
+ # Main Heading
366
+
367
+ ![Alt text](./image.jpg)
368
+ [Link text](/page)
369
+ ```
370
+
371
+ ## CI/CD Integration
372
+
373
+ ### GitHub Actions
374
+
375
+ ```yaml
376
+ name: SEO Check
377
+ on: [push, pull_request]
378
+
379
+ jobs:
380
+ seo:
381
+ runs-on: ubuntu-latest
382
+ steps:
383
+ - uses: actions/checkout@v4
384
+ - uses: actions/setup-node@v4
385
+ with:
386
+ node-version: '20'
387
+
388
+ - name: Build site
389
+ run: npm run build
390
+
391
+ - name: Run SEO checks
392
+ run: npx @rankture/cli check ./dist --fail-on critical
393
+ ```
394
+
395
+ ### GitLab CI
396
+
397
+ ```yaml
398
+ seo_check:
399
+ stage: test
400
+ script:
401
+ - npm run build
402
+ - npx @rankture/cli check ./dist --fail-on critical
403
+ ```
404
+
405
+ ### Pre-commit Hook
406
+
407
+ ```bash
408
+ # package.json
409
+ {
410
+ "scripts": {
411
+ "seo:check": "rankture check ./dist --fail-on warning"
412
+ },
413
+ "husky": {
414
+ "hooks": {
415
+ "pre-commit": "npm run build && npm run seo:check"
416
+ }
417
+ }
418
+ }
419
+ ```
420
+
421
+ ## Programmatic API
422
+
423
+ Use the CLI as a library in your Node.js projects:
424
+
425
+ ```typescript
426
+ import { checkPage, checkPages } from '@rankture/cli';
427
+
428
+ // Check a single page
429
+ const html = '<html>...</html>';
430
+ const report = await checkPage(html, 'https://example.com');
431
+
432
+ console.log(report.summary.score); // 85
433
+ console.log(report.summary.critical); // 0
434
+ console.log(report.results); // Array of CheckResult
435
+
436
+ // Check multiple pages
437
+ const pages = [
438
+ { html: '<html>...</html>', url: 'https://example.com' },
439
+ { html: '<html>...</html>', url: 'https://example.com/about' },
440
+ ];
441
+ const fullReport = await checkPages(pages);
442
+
443
+ console.log(fullReport.summary.totalPages); // 2
444
+ console.log(fullReport.summary.score); // 82 (average)
445
+ ```
446
+
447
+ ### Individual Checks
448
+
449
+ ```typescript
450
+ import { parseHtml, checkMetaTags, checkHeadings, checkImages } from '@rankture/cli';
451
+
452
+ const html = '<html>...</html>';
453
+ const parsed = parseHtml(html, 'https://example.com');
454
+
455
+ // Run individual checks
456
+ const metaResults = checkMetaTags(parsed);
457
+ const headingResults = checkHeadings(parsed);
458
+ const imageResults = checkImages(parsed);
459
+ ```
460
+
461
+ ## Configuration
462
+
463
+ Create a `rankture.config.json` in your project root:
464
+
465
+ ```json
466
+ {
467
+ "ignore": [
468
+ "**/404.html",
469
+ "**/500.html",
470
+ "**/_*.html"
471
+ ],
472
+ "checks": {
473
+ "title-length": { "min": 30, "max": 60 },
474
+ "meta-description-length": { "min": 120, "max": 160 },
475
+ "h1-count": { "expected": 1 }
476
+ },
477
+ "failOn": "critical"
478
+ }
479
+ ```
480
+
481
+ ## Output Formats
482
+
483
+ ### Terminal (default)
484
+
485
+ ```
486
+ 🔍 Checking 5 HTML files...
487
+
488
+ ✓ index.html (18/20 passed)
489
+ ✗ [critical] Missing meta description
490
+ ✗ [warning] Image missing alt text: hero.jpg
491
+
492
+ ✓ about.html (20/20 passed)
493
+ All checks passed!
494
+
495
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
496
+
497
+ 📊 Summary
498
+ Pages: 5
499
+ Score: 92/100
500
+ Passed: 95
501
+ Failed: 5 (2 critical, 3 warnings)
502
+ ```
503
+
504
+ ### JSON
505
+
506
+ ```json
507
+ {
508
+ "summary": {
509
+ "totalPages": 5,
510
+ "score": 92,
511
+ "passed": 95,
512
+ "failed": 5,
513
+ "critical": 2,
514
+ "warnings": 3
515
+ },
516
+ "pages": [
517
+ {
518
+ "url": "file://./dist/index.html",
519
+ "results": [...]
520
+ }
521
+ ],
522
+ "timestamp": "2025-01-15T10:30:00Z"
523
+ }
524
+ ```
525
+
526
+ ## CI/CD Integration
527
+
528
+ ### GitHub Actions
529
+
530
+ ```yaml
531
+ # .github/workflows/seo-check.yml
532
+ name: SEO Check
533
+
534
+ on:
535
+ pull_request:
536
+ branches: [main]
537
+
538
+ jobs:
539
+ seo:
540
+ runs-on: ubuntu-latest
541
+ steps:
542
+ - uses: actions/checkout@v4
543
+ with:
544
+ fetch-depth: 0 # Required for --changed mode
545
+
546
+ - uses: actions/setup-node@v4
547
+ with:
548
+ node-version: '20'
549
+
550
+ - name: Build site
551
+ run: npm run build
552
+
553
+ # Option 1: Check only changed files (fast)
554
+ - name: SEO Check (changed files)
555
+ run: npx @rankture/cli check ./dist --changed --fail-on critical
556
+
557
+ # Option 2: Full check on all files
558
+ - name: SEO Check (full)
559
+ run: npx @rankture/cli check ./dist --fail-on critical
560
+ ```
561
+
562
+ ### Pre-commit Hook (with Husky)
563
+
564
+ ```bash
565
+ # .husky/pre-commit
566
+ #!/bin/sh
567
+ npx @rankture/cli check ./src/pages --staged --fail-on critical
568
+ ```
569
+
570
+ ### GitLab CI
571
+
572
+ ```yaml
573
+ seo-check:
574
+ stage: test
575
+ script:
576
+ - npm run build
577
+ - npx @rankture/cli check ./dist --fail-on critical
578
+ only:
579
+ - merge_requests
580
+ ```
581
+
582
+ ### Generate HTML Report
583
+
584
+ ```yaml
585
+ # In GitHub Actions
586
+ - name: Generate SEO Report
587
+ run: npx @rankture/cli check ./dist -f html -o seo-report.html
588
+
589
+ - name: Upload Report
590
+ uses: actions/upload-artifact@v4
591
+ with:
592
+ name: seo-report
593
+ path: seo-report.html
594
+ ```
595
+
596
+ ## Pro Features (API Key Required)
597
+
598
+ With a [Rankture Pro](https://rankture.com/pricing/) subscription, unlock:
599
+
600
+ - 🌐 **Live URL auditing** - Check live sites, not just static files
601
+ - 📱 **Mobile & desktop** - Separate audits for each viewport
602
+ - 🔗 **Broken link checking** - HTTP validation of all links
603
+ - ⚡ **Core Web Vitals** - LCP, CLS, FID/INP metrics
604
+ - 📊 **Dashboard sync** - Track progress over time
605
+ - 🤖 **AI suggestions** - Intelligent fix recommendations
606
+ - 📄 **PDF reports** - Branded reports for clients
607
+
608
+ ```bash
609
+ rankture audit https://example.com --api-key YOUR_KEY --sync
610
+ ```
611
+
612
+ Get your API key at [rankture.com/dashboard/settings](https://rankture.com/dashboard/settings/)
613
+
614
+ ## Comparison: Free vs Pro
615
+
616
+ | Feature | Free CLI | Pro (API Key) |
617
+ |---------|----------|---------------|
618
+ | Offline HTML checks | ✅ | ✅ |
619
+ | JSON/Terminal output | ✅ | ✅ |
620
+ | CI/CD integration | ✅ | ✅ |
621
+ | Live URL auditing | ❌ | ✅ |
622
+ | Mobile/Desktop audits | ❌ | ✅ |
623
+ | Broken link checking | ❌ | ✅ |
624
+ | Core Web Vitals | ❌ | ✅ |
625
+ | Dashboard sync | ❌ | ✅ |
626
+ | AI suggestions | ❌ | ✅ |
627
+ | PDF reports | ❌ | ✅ |
628
+
629
+ ## Related
630
+
631
+ - [Rankture](https://rankture.com) - Full SEO audit SaaS
632
+ - [Free SEO Audit](https://rankture.com/free-seo-audit/) - One-time free audit
633
+ - [Rankture Blog](https://rankture.com/blog/) - SEO tips and guides
634
+
635
+ ## License
636
+
637
+ MIT © [Rankture](https://rankture.com)
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }