Skip to content

Commit ba64c36

Browse files
committed
Website: Add llms.txt, sitemap, etc for agent a11y
- Add `/llms.txt` and `/llms-full.txt` as build-time Astro endpoints (same pattern as rss.xml.ts). Blog list, version, and download URLs are auto-maintained; product description and pricing are string templates. - Add Schema.org JSON-LD: Organization (all pages), SoftwareApplication (landing), FAQPage (pricing), BlogPosting (blog posts). - Add @astrojs/sitemap for auto-generated sitemap-index.xml.
1 parent 1a2621a commit ba64c36

9 files changed

Lines changed: 382 additions & 0 deletions

File tree

apps/website/astro.config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
import { defineConfig } from 'astro/config'
33
import tailwindcss from '@tailwindcss/vite'
44
import rehypeExternalLinks from 'rehype-external-links'
5+
import sitemap from '@astrojs/sitemap'
56

67
// https://astro.build/config
78
export default defineConfig({
89
site: 'https://getcmdr.com',
910
output: 'static',
11+
integrations: [sitemap()],
1012
server: {
1113
port: parseInt(process.env.PORT || '4321'),
1214
},

apps/website/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
},
2020
"dependencies": {
2121
"@astrojs/rss": "4.0.15",
22+
"@astrojs/sitemap": "^3.7.0",
2223
"@resvg/resvg-js": "2.6.2",
2324
"@tailwindcss/vite": "^4.2.1",
2425
"astro": "^5.18.0",

apps/website/src/layouts/BlogLayout.astro

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,35 @@ const formattedDate = new Date(date).toLocaleDateString('en-US', {
1818
month: 'long',
1919
day: 'numeric',
2020
})
21+
22+
const blogPostingSchema: Record<string, unknown> = {
23+
'@context': 'https://schema.org',
24+
'@type': 'BlogPosting',
25+
headline: title,
26+
description: description,
27+
datePublished: date,
28+
author: {
29+
'@type': 'Organization',
30+
name: 'Cmdr',
31+
url: 'https://getcmdr.com',
32+
},
33+
publisher: {
34+
'@type': 'Organization',
35+
name: 'Cmdr',
36+
url: 'https://getcmdr.com',
37+
logo: 'https://getcmdr.com/logo-512.png',
38+
},
39+
url: Astro.url.href,
40+
}
41+
if (ogImage) {
42+
blogPostingSchema.image = new URL(ogImage, Astro.site).href
43+
}
2144
---
2245

2346
<Layout title={`${title} — Cmdr blog`} description={description} ogImage={ogImage}>
2447
<Header />
2548
<main class="mx-auto max-w-3xl px-6 pt-32 pb-24">
49+
<script type="application/ld+json" set:html={JSON.stringify(blogPostingSchema)} />
2650
<header class="mb-12">
2751
<time class="text-sm text-[var(--color-text-tertiary)]" datetime={date}>
2852
{formattedDate}

apps/website/src/layouts/Layout.astro

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ const {
6565

6666
<title>{title}</title>
6767

68+
<!-- Organization structured data -->
69+
<script
70+
type="application/ld+json"
71+
set:html={JSON.stringify({
72+
'@context': 'https://schema.org',
73+
'@type': 'Organization',
74+
name: 'Cmdr',
75+
url: 'https://getcmdr.com',
76+
logo: 'https://getcmdr.com/logo-512.png',
77+
sameAs: ['https://github.com/vdavid/cmdr'],
78+
})}
79+
/>
80+
6881
{/* Umami analytics — self-hosted, cookieless */}
6982
{
7083
import.meta.env.PUBLIC_UMAMI_WEBSITE_ID && (

apps/website/src/pages/index.astro

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,28 @@ import Hero from '../components/Hero.astro'
55
import Features from '../components/Features.astro'
66
import Download from '../components/Download.astro'
77
import Footer from '../components/Footer.astro'
8+
import { version } from '../lib/release'
9+
10+
const softwareApplicationSchema = {
11+
'@context': 'https://schema.org',
12+
'@type': 'SoftwareApplication',
13+
name: 'Cmdr',
14+
applicationCategory: 'UtilitiesApplication',
15+
operatingSystem: 'macOS',
16+
offers: {
17+
'@type': 'Offer',
18+
price: '0',
19+
priceCurrency: 'USD',
20+
},
21+
softwareVersion: version,
22+
url: 'https://getcmdr.com',
23+
}
824
---
925

1026
<Layout title="Cmdr — The AI-native file manager" forceDark>
1127
<Header />
1228
<main>
29+
<script type="application/ld+json" set:html={JSON.stringify(softwareApplicationSchema)} />
1330
<Hero />
1431
<Features />
1532
<Download />
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import type { APIContext } from 'astro'
2+
import { getCollection } from 'astro:content'
3+
import { version, dmgUrls } from '../lib/release'
4+
import latestRelease from '../../public/latest.json'
5+
6+
export async function GET(context: APIContext) {
7+
const site = context.site!.origin
8+
const posts = await getCollection('blog')
9+
const sortedPosts = posts.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
10+
11+
const blogLines = sortedPosts
12+
.map((post) => `- [${post.data.title}](${site}/blog/${post.id}/): ${post.data.description}`)
13+
.join('\n')
14+
15+
const releaseNotes = latestRelease.notes
16+
.replace(/\[([a-f0-9]{7})\]\(https:\/\/github\.com\/[^)]+\)/g, '$1')
17+
.replace(/, [a-f0-9]{7}(, [a-f0-9]{7})*/g, '')
18+
.replace(/\(([a-f0-9]{7})\)/g, '')
19+
.replace(/ +/g, ' ')
20+
.trim()
21+
22+
const body = `# Cmdr
23+
24+
> The AI-native file manager for power users who want superpowers.
25+
26+
Cmdr is an extremely fast, keyboard-driven, two-pane file manager for macOS (Linux in alpha), built with Rust, Tauri 2, and Svelte 5. It lets you rename files with natural language, search by describing what you're looking for, and organize hundreds of files with a single command. Free forever for personal use, source-available under BSL 1.1.
27+
28+
Current version: ${version}
29+
Release date: ${latestRelease.pub_date.split('T')[0]}
30+
31+
## Key links
32+
33+
- [Download (Apple Silicon)](${dmgUrls.aarch64}): DMG installer for Apple Silicon Macs
34+
- [Download (Intel)](${dmgUrls.x86_64}): DMG installer for Intel Macs
35+
- [Download (Universal)](${dmgUrls.universal}): DMG installer that works on both architectures
36+
- [Pricing](${site}/pricing/): Free for personal use, commercial from $59/year
37+
- [Blog](${site}/blog/): Updates and news
38+
- [Changelog](${site}/changelog/): Release notes
39+
- [Roadmap](${site}/roadmap/): What's coming next
40+
- [GitHub](https://github.com/vdavid/cmdr): Source code and issues
41+
- [RSS feed](${site}/rss.xml): Subscribe to blog updates
42+
- [Privacy policy](${site}/privacy-policy/): How we handle your data
43+
- [Terms and conditions](${site}/terms-and-conditions/): Terms of use
44+
- [Refund policy](${site}/refund/): 30-day, no-questions-asked refunds
45+
- [llms.txt](${site}/llms.txt): Concise version of this document
46+
47+
## Features
48+
49+
### AI-powered features
50+
51+
- **Natural language rename**: Type "make these lowercase and add date prefix" and watch it happen. No regex, no scripts, just words. Cmdr understands your intent and renames files accordingly.
52+
- **Smart search**: Find files by describing them in plain English: "that PDF contract from last month" or "screenshots with error messages." No need to remember exact file names.
53+
- **AI batch operations**: Organize hundreds of files with a single command. Tell Cmdr to "sort these into folders by project name" and it figures out the rest.
54+
55+
### Core features
56+
57+
- **Keyboard-first**: Navigate, select, copy, move without touching your mouse. Every action has a keyboard shortcut, and you can customize them all.
58+
- **Blazing fast**: Built with Rust for native performance. Handles folders with 50,000+ files effortlessly. Startup is near-instant.
59+
- **Two-pane layout**: See source and destination side by side. The classic dual-pane layout that professional file managers have used for decades.
60+
- **Tabs**: Multiple tabs per pane with pinning, persistence, and per-tab sorting.
61+
- **File viewer**: Built-in viewer for text files with search, syntax highlighting, and support for very large files.
62+
- **Drive indexing**: Index your drives for fast search with an efficient integer-keyed database schema.
63+
- **Clipboard**: Full clipboard support with Finder interop. Copy, cut, and paste files between Cmdr and Finder.
64+
- **Delete and trash**: Trash by default, permanent delete with confirmation. Batch operations with progress and cancellation.
65+
- **Network shares**: Connect to SMB network shares with saved credentials, mDNS discovery, and timeout protection.
66+
- **Disk space display**: See free space per volume in the status bar and volume dropdown.
67+
- **Custom tooltips**: Glass-effect tooltips with shortcut badges and smart positioning.
68+
- **Accent color**: Choose between macOS system accent or Cmdr gold, with optional gold folder icons.
69+
- **Command palette**: Quick access to every action in the app.
70+
71+
## Tech stack
72+
73+
- **Rust**: Backend logic, file operations, IPC commands, and drive indexing
74+
- **Tauri 2**: Native desktop framework bridging Rust and the web frontend
75+
- **Svelte 5**: Reactive frontend with TypeScript strict mode
76+
- **Tailwind v4**: Styling with CSS-first configuration
77+
- **SQLite**: Drive indexing with integer-keyed schema for efficient storage
78+
- **Ed25519**: License key signing and verification
79+
80+
## Pricing
81+
82+
### Personal (free forever)
83+
84+
- All features included
85+
- Unlimited machines
86+
- Automatic updates
87+
- No commercial use
88+
89+
### Supporter ($10 one-time)
90+
91+
- Everything in Personal
92+
- "Supporter" badge in the app
93+
- No commercial use
94+
95+
### Commercial ($59/year)
96+
97+
- All features included
98+
- Commercial use allowed
99+
- Per user, unlimited machines
100+
- Auto-renews annually
101+
- Discounted from $79 for the first 1,000 licenses
102+
103+
### Perpetual ($199 one-time)
104+
105+
- All features included
106+
- Commercial use allowed
107+
- Per user, unlimited machines
108+
- Three years of updates included
109+
- Keep using your version forever after updates expire
110+
- Renew updates at a reduced rate
111+
112+
## Frequently asked questions
113+
114+
### What counts as "commercial use"?
115+
116+
If you're using Cmdr as part of your job (employment, freelancing, consulting), that's commercial use. Side projects, open source work, and personal file management are all fine without a commercial license.
117+
118+
### Can I use it on multiple machines?
119+
120+
Yes! Use Cmdr on as many machines as you like. Laptop, desktop, remote debugging rig, whatever. Your license is per user, not per machine.
121+
122+
### What's the difference between subscription and perpetual?
123+
124+
Subscription ($59/year) auto-renews annually and always includes the latest updates. Perpetual ($199) is a one-time purchase that includes three years of updates. After that, you can keep using your current version forever or renew updates at a reduced rate.
125+
126+
### Can I see the source code?
127+
128+
Yes! Cmdr is source-available on GitHub at https://github.com/vdavid/cmdr. You can view, learn from, and modify the code. The license (BSL 1.1) converts to AGPL-3.0 after three years.
129+
130+
### What if I regret the purchase?
131+
132+
We offer a 30-day, no-questions-asked refund. Send an email and we'll sort it out.
133+
134+
### Do you offer team licenses?
135+
136+
Each person needs their own license. For teams of five or more, email legal@getcmdr.com for volume pricing.
137+
138+
## System requirements
139+
140+
- **macOS**: Apple Silicon (M1 and later) and Intel. Separate DMG installers for each architecture, plus a universal build.
141+
- **Linux**: Alpha support. Volumes via /proc/mounts, file ops with reflink support, trash via FreeDesktop spec, inotify file watching, native file icons via freedesktop-icons.
142+
143+
## License
144+
145+
BSL 1.1 (Business Source License). Source-available: you can view, learn from, and modify the code. The license converts to AGPL-3.0 after three years. See the GitHub repository for full license text.
146+
147+
## Latest release notes (v${version})
148+
149+
${releaseNotes}
150+
151+
## Blog posts
152+
153+
${blogLines}
154+
`
155+
156+
return new Response(body, {
157+
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
158+
})
159+
}

apps/website/src/pages/llms.txt.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import type { APIContext } from 'astro'
2+
import { getCollection } from 'astro:content'
3+
import { version, dmgUrls } from '../lib/release'
4+
5+
export async function GET(context: APIContext) {
6+
const site = context.site!.origin
7+
const posts = await getCollection('blog')
8+
const sortedPosts = posts.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
9+
10+
const blogLines = sortedPosts
11+
.map((post) => `- [${post.data.title}](${site}/blog/${post.id}/): ${post.data.description}`)
12+
.join('\n')
13+
14+
const body = `# Cmdr
15+
16+
> The AI-native file manager for power users who want superpowers.
17+
18+
Cmdr is an extremely fast, keyboard-driven, two-pane file manager for macOS, built with Rust, Tauri 2, and Svelte 5. It lets you rename files with natural language, search by describing what you're looking for, and organize hundreds of files with a single command. Free forever for personal use, source-available under BSL 1.1.
19+
20+
Current version: ${version}
21+
22+
## Key links
23+
24+
- [Download (Apple Silicon)](${dmgUrls.aarch64}): DMG installer for Apple Silicon Macs
25+
- [Download (Intel)](${dmgUrls.x86_64}): DMG installer for Intel Macs
26+
- [Pricing](${site}/pricing/): Free for personal use, commercial from $59/year
27+
- [Blog](${site}/blog/): Updates and news
28+
- [Changelog](${site}/changelog/): Release notes
29+
- [Roadmap](${site}/roadmap/): What's coming next
30+
- [GitHub](https://github.com/vdavid/cmdr): Source code and issues
31+
- [RSS feed](${site}/rss.xml): Subscribe to blog updates
32+
33+
## Features
34+
35+
- **Natural language rename**: Type "make these lowercase and add date prefix" and watch it happen. No regex, no scripts.
36+
- **Smart search**: Find files by describing them: "that PDF contract from last month" or "screenshots with error messages."
37+
- **AI batch operations**: Organize hundreds of files with a single command. "Sort these into folders by project name."
38+
- **Keyboard-first**: Navigate, select, copy, move without touching your mouse.
39+
- **Blazing fast**: Built with Rust for native performance. Handles folders with 50,000+ files effortlessly.
40+
- **Two-pane layout**: See source and destination side by side. The classic layout that works.
41+
42+
## Pricing
43+
44+
- **Personal**: Free forever. All features, unlimited machines, automatic updates. No commercial use.
45+
- **Supporter**: $10 one-time. Everything in Personal plus a "Supporter" badge in the app.
46+
- **Commercial**: $59/year (discounted from $79 for first 1,000 licenses). All features, commercial use, per user, unlimited machines.
47+
- **Perpetual**: $199 one-time. All features, commercial use, per user, unlimited machines, three years of updates.
48+
49+
## System requirements
50+
51+
- macOS (Apple Silicon and Intel)
52+
- Linux support in alpha
53+
54+
## License
55+
56+
BSL 1.1 (source-available). Converts to AGPL-3.0 after three years.
57+
58+
## Blog posts
59+
60+
${blogLines}
61+
`
62+
63+
return new Response(body, {
64+
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
65+
})
66+
}

apps/website/src/pages/pricing.astro

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,60 @@ const isPaddleConfigured = paddleConfig.clientToken !== ''
194194
</div>
195195

196196
<!-- FAQ Section -->
197+
<script type="application/ld+json" set:html={JSON.stringify({
198+
"@context": "https://schema.org",
199+
"@type": "FAQPage",
200+
"mainEntity": [
201+
{
202+
"@type": "Question",
203+
"name": "What counts as \"commercial use\"?",
204+
"acceptedAnswer": {
205+
"@type": "Answer",
206+
"text": "If you're using Cmdr as part of your job (employment, freelancing, consulting), that's commercial use. Side projects, open source work, and personal file management are all fine without a commercial license.",
207+
},
208+
},
209+
{
210+
"@type": "Question",
211+
"name": "Can I use it on multiple machines?",
212+
"acceptedAnswer": {
213+
"@type": "Answer",
214+
"text": "Yes! Use Cmdr on as many machines as you like — laptop, desktop, remote debugging rig, whatever. Just make sure you're the one using your license.",
215+
},
216+
},
217+
{
218+
"@type": "Question",
219+
"name": "What's the difference between subscription and perpetual?",
220+
"acceptedAnswer": {
221+
"@type": "Answer",
222+
"text": "Subscription ($59/year) auto-renews annually and always includes the latest updates. Perpetual ($199) is a one-time purchase that includes 3 years of updates — after that, you can keep using your current version forever or renew updates at a reduced rate.",
223+
},
224+
},
225+
{
226+
"@type": "Question",
227+
"name": "Can I see the source code?",
228+
"acceptedAnswer": {
229+
"@type": "Answer",
230+
"text": "Yes! Cmdr is source-available on GitHub. You can view, learn from, and modify the code. The license (BSL 1.1) converts to AGPL-3.0 after 3 years.",
231+
},
232+
},
233+
{
234+
"@type": "Question",
235+
"name": "What if I regret the purchase?",
236+
"acceptedAnswer": {
237+
"@type": "Answer",
238+
"text": "We offer a 30-day, no-questions-asked refund. Just email us and we'll sort it out.",
239+
},
240+
},
241+
{
242+
"@type": "Question",
243+
"name": "Do you offer team licenses?",
244+
"acceptedAnswer": {
245+
"@type": "Answer",
246+
"text": "Each person needs their own license. For teams of 5+, email us at legal@getcmdr.com for volume pricing.",
247+
},
248+
},
249+
],
250+
})} />
197251
<section>
198252
<h2 class="mb-8 text-center text-2xl font-bold text-[var(--color-text-primary)]">
199253
Frequently asked questions

0 commit comments

Comments
 (0)