Skip to content

Commit 06c49cb

Browse files
committed
Switch to BSL license so it's free for individuals
1 parent 7e68c27 commit 06c49cb

17 files changed

Lines changed: 476 additions & 720 deletions

AGENTS.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,9 @@ This is a monorepo with the following structure:
2727
- `/apps/website/` - Marketing website (getcmdr.com)
2828
- Astro + Tailwind v4
2929
- Deployed via Docker + nginx
30-
- Proprietary license
3130
- `/apps/license-server/` - License key generation webhook
3231
- Cloudflare Worker (Hono framework)
3332
- Receives Paddle webhooks, generates Ed25519-signed keys
34-
- Proprietary license
3533
- `/scripts/check/` - Go-based unified check runner (replaces individual scripts)
3634
- `/docs/` - Docs including `style-guide.md`
3735

@@ -111,8 +109,8 @@ See [docs/adr](docs/adr) for all key technical decisions, and the
111109
- **Clippy `--allow-dirty --allow-staged`** is used locally to allow auto-fixes even with uncommitted changes
112110
- **Paddle for payments**: Chosen for MoR model (handles taxes/invoicing), all-inclusive fees. See
113111
[ADR-014](docs/adr/014-payment-provider-paddle.md)
114-
- **AGPL + trial license model**: Source is open (AGPL), official binary has 14-day trial. See
115-
[ADR-015](docs/adr/015-license-model-agpl-trial.md) and [licensing docs](docs/features/licensing.md)
112+
- **BSL license model**: Source-available (BSL 1.1), free for personal use, paid for commercial. See
113+
[ADR-016](docs/adr/016-license-model-bsl.md) and [licensing docs](docs/features/licensing.md)
116114

117115
## MCP
118116

LICENSE

Lines changed: 64 additions & 639 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,33 @@
11
# Cmdr
22

3-
![License](https://img.shields.io/github/license/vdavid/cmdr)
3+
![License](https://img.shields.io/badge/license-BSL--1.1-blue)
44

5-
An extremely fast, keyboard-driven, two-pane file manager written in Rust for folks who miss the golden days of Norton
6-
Commander and Total Commander.
5+
An extremely fast AI-native file manager written in Rust, free forever for personal use on macOS.
76

8-
![cmdr](https://github.com/user-attachments/assets/7827b88d-e0a9-447e-b195-af7216c0fa35)
7+
Cmdr is for folks who love a rock-solid, keyboard-driven, two-pane file manager with a modern UI in 2026.
8+
9+
Give it a try: [Download for macOS](https://getcmdr.com) on the website, or do `brew install cmdr`.
910

11+
![cmdr](https://github.com/user-attachments/assets/7827b88d-e0a9-447e-b195-af7216c0fa35)
1012

1113
## Overview
1214

13-
Cmdr is a desktop file manager that brings back the classic two-pane layout. It's built for speed and keyboard
14-
navigation. If you've ever used Norton Commander, Midnight Commander, or Total Commander, you'll feel right at home.
15+
Cmdr is the first AI-native file manager, written by modern standards with built-in AI to support natural language
16+
search, smart renaming, and auto-organization. Built on the spiritual foundations of `mc` and Total Commander.
1517

1618
Core features:
1719

18-
- **Two-pane layout**: see two directories side by side
19-
- **Keyboard-first navigation**: do everything without touching your mouse
20-
- **Fast file operations**: copy, move, rename, and delete with a few keystrokes
21-
- **Cross-platform**: runs on macOS, Windows, and Linux
20+
- **Two-pane layout**: see two dirs side by side.
21+
- **Keyboard-first**: do anything without touching your mouse, using your familiar shortcuts.
22+
- **Blazing fast file operations**: copy, move, rename, and delete with a few keystrokes
23+
- **AI native**: search, rename, organize like you're in 2026.
2224

2325
## Installation
2426

25-
Download the latest release for your platform from the [Releases](https://github.com/vdavid/cmdr/releases) page.
26-
27-
### macOS
28-
29-
(Downloadable installer coming soon)
27+
Download from [getcmdr.com](https://getcmdr.com) or just do `brew install cmdr`.
3028

31-
### Windows and Linux
32-
33-
Sorry, only macOS for now
29+
Windows and Linux users: sorry, you'll need to wait. The Rust+Tauri stack allows for cross-platform deployment, but the app
30+
uses OS-specific features by nature, so I've only had time to write and test it on macOS for now.
3431

3532
## Usage
3633

@@ -53,21 +50,26 @@ gives it native performance with a modern, responsive UI.
5350

5451
## License
5552

56-
Cmdr is available under a **dual license**:
53+
Cmdr is **source-available** under the [Business Source License 1.1](LICENSE).
54+
55+
### Free for personal use
56+
57+
Use Cmdr for free on any number of machines for personal, non-commercial projects. No nags, no trial timers, no
58+
restrictions.
59+
60+
### Commercial use
5761

58-
### Open source (AGPL-3.0-or-later)
62+
For work projects, you'll need a license:
5963

60-
For open-source projects, personal use, and those who can comply with the
61-
[GNU Affero General Public License v3](https://www.gnu.org/licenses/agpl-3.0.html), Cmdr is free to use, modify, and
62-
distribute. The AGPL requires that if you modify Cmdr and make it available to users over a network, you must also make
63-
your source code available under the same license.
64+
- **$59/year** — subscription, auto-renews
65+
- **$149 one-time** — perpetual license
6466

65-
### Commercial license
67+
Purchase at [getcmdr.com/pricing](https://getcmdr.com/pricing).
6668

67-
For companies and individuals who cannot comply with the AGPL (e.g., you want to use Cmdr in proprietary software, or
68-
you don't want to disclose your source code), a commercial license is available.
69+
### Source code
6970

70-
**Contact**: [veszelovszki@gmail.com](mailto:veszelovszki@gmail.com) for pricing and terms.
71+
The source becomes [AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html) after 3 years (rolling per release). Until
72+
then, you can view, modify, and learn from the code — just not use it commercially without a license.
7173

7274
---
7375

@@ -76,9 +78,9 @@ you don't want to disclose your source code), a commercial license is available.
7678
Contributions are welcome! Report issues and feature requests in the
7779
[issue tracker](https://github.com/vdavid/cmdr/issues).
7880

79-
By submitting a contribution, you agree to license your contribution under the AGPL-3.0-or-later license and grant the
80-
project owner the right to use your contribution under both the AGPL and any commercial license offered for this
81-
project.
81+
By submitting a contribution, you agree to license your contribution under the same terms as the project (BSL 1.1,
82+
converting to AGPL-3.0) and grant the project owner the right to use your contribution under any commercial license
83+
offered for this project.
8284

8385
Happy browsing!
8486

apps/license-server/LICENSE

Lines changed: 0 additions & 6 deletions
This file was deleted.

apps/license-server/README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,16 @@ Then open http://localhost:3333 and click "Buy Cmdr".
103103

104104
## Endpoints
105105

106-
| Method | Path | Description |
107-
| ------ | ----------------- | ------------------------------------------------ |
108-
| `GET` | `/` | Health check |
109-
| `POST` | `/webhook/paddle` | Paddle webhook (generates and emails license) |
110-
| `POST` | `/admin/generate` | Manual license generation (requires auth header) |
106+
| Method | Path | Description |
107+
| ------ | ----------------- | ------------------------------------------------- |
108+
| `GET` | `/` | Health check |
109+
| `POST` | `/webhook/paddle` | Paddle webhook (generates and emails license) |
110+
| `POST` | `/validate` | Validate license key (returns subscription status)|
111+
| `POST` | `/admin/generate` | Manual license generation (requires auth header) |
111112

112113

113114
## Architecture decisions
114115

115116
- See [ADR 014: Payment provider choice](../../docs/adr/014-payment-provider-paddle.md) for why Paddle
116-
- See [ADR 015: License model](../../docs/adr/015-license-model-agpl-trial.md) for the AGPL + trial approach
117+
- See [ADR 016: License model](../../docs/adr/016-license-model-bsl.md) for the BSL license approach
117118
- See [Licensing feature docs](../../docs/features/licensing.md) for the full feature overview

apps/license-server/src/email.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Resend } from 'resend'
2+
import type { LicenseType } from './license'
23

34
interface EmailParams {
45
to: string
@@ -7,10 +8,32 @@ interface EmailParams {
78
productName: string
89
supportEmail: string
910
resendApiKey: string
11+
organizationName?: string
12+
licenseType?: LicenseType
13+
}
14+
15+
function getLicenseDescription(type: LicenseType | undefined, orgName?: string): string {
16+
switch (type) {
17+
case 'supporter':
18+
return 'Your supporter license is valid forever for personal use. Love you! ❤️'
19+
case 'commercial_subscription':
20+
return orgName
21+
? `Your commercial license for ${orgName} is valid for one year and will auto-renew.`
22+
: 'Your commercial license is valid for one year and will auto-renew.'
23+
case 'commercial_perpetual':
24+
return orgName
25+
? `Your perpetual commercial license for ${orgName} is valid forever.`
26+
: 'Your perpetual commercial license is valid forever.'
27+
default:
28+
return 'This is an unknown license type. This is weird. Please contact support.'
29+
}
1030
}
1131

1232
export async function sendLicenseEmail(params: EmailParams): Promise<void> {
1333
const resend = new Resend(params.resendApiKey)
34+
const licenseDescription = getLicenseDescription(params.licenseType, params.organizationName)
35+
const orgLine = params.organizationName ? `<p><strong>Licensed to:</strong> ${params.organizationName}</p>` : ''
36+
const orgLineText = params.organizationName ? `Licensed to: ${params.organizationName}\n` : ''
1437

1538
await resend.emails.send({
1639
from: `${params.productName} <noreply@getcmdr.com>`,
@@ -25,6 +48,7 @@ export async function sendLicenseEmail(params: EmailParams): Promise<void> {
2548
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; }
2649
.license-box { background: #f5f5f5; border-radius: 8px; padding: 20px; margin: 20px 0; font-family: monospace; font-size: 18px; text-align: center; letter-spacing: 2px; }
2750
.footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #eee; font-size: 14px; color: #666; }
51+
.note { background: #e8f4f8; border-left: 4px solid #0ea5e9; padding: 12px 16px; margin: 20px 0; }
2852
</style>
2953
</head>
3054
<body>
@@ -38,14 +62,20 @@ export async function sendLicenseEmail(params: EmailParams): Promise<void> {
3862
${params.licenseKey}
3963
</div>
4064
65+
${orgLine}
66+
4167
<h3>How to activate:</h3>
4268
<ol>
4369
<li>Open ${params.productName}</li>
4470
<li>Go to <strong>Menu → Enter License Key</strong></li>
4571
<li>Paste the key above and click Activate</li>
4672
</ol>
4773
48-
<p>That's it! Your license is valid forever on up to 2 machines.</p>
74+
<p>${licenseDescription}</p>
75+
76+
<div class="note">
77+
<strong>Multiple machines?</strong> Your license lets you run ${params.productName} on multiple machines — like a laptop and desktop for remote debugging — as long as you're the only one using it.
78+
</div>
4979
5080
<div class="footer">
5181
<p>Questions? Just reply to this email or contact <a href="mailto:${params.supportEmail}">${params.supportEmail}</a></p>
@@ -63,12 +93,15 @@ Thanks for purchasing ${params.productName}! Here's your license key:
6393
6494
${params.licenseKey}
6595
96+
${orgLineText}
6697
How to activate:
6798
1. Open ${params.productName}
6899
2. Go to Menu → Enter License Key
69100
3. Paste the key above and click Activate
70101
71-
That's it! Your license is valid forever on up to 2 machines.
102+
${licenseDescription}
103+
104+
Multiple machines? Your license lets you run ${params.productName} on multiple machines — like a laptop and desktop for remote debugging — as long as you're the one using it.
72105
73106
Questions? Contact ${params.supportEmail}
74107

0 commit comments

Comments
 (0)