diff --git a/.github/cla/cla.md b/.github/cla/cla.md
new file mode 100644
index 00000000..c0e2a890
--- /dev/null
+++ b/.github/cla/cla.md
@@ -0,0 +1,42 @@
+# Stroke Contributor License Agreement
+
+By signing this CLA, you agree to the following terms:
+
+## Grant of License
+
+You grant **Stroke / Nischal Dahal** (the "Project") a perpetual, worldwide,
+non-exclusive, no-charge, royalty-free, irrevocable license to:
+
+- Reproduce, prepare derivative works of, publicly display, publicly perform,
+ sublicense, and distribute your contributions and any derivative works.
+- Re-license your contributions under any license, including proprietary and
+ commercial licenses, at the Project's sole discretion.
+
+## Representations
+
+You represent that:
+
+1. You are legally entitled to grant the above license.
+2. Each of your contributions is your original creation, or you have sufficient
+ rights to submit it under this agreement.
+3. Your contributions do not violate any third-party intellectual property rights.
+4. If your employer has rights over your contributions, you have their written
+ permission to contribute under these terms, or your employer has signed a
+ Corporate CLA with the Project.
+
+## No Warranty
+
+Your contributions are provided on an **"AS IS" basis**, without warranties or
+conditions of any kind.
+
+## What this means in practice
+
+- You keep your copyright. The CLA grants the Project a license, not ownership.
+- Your code will be available under the MIT license in the public repo.
+- The Project may also include your code in a commercial Pro build under a
+ separate proprietary license. This is necessary to sustain the project.
+- You will be credited in the project's contributor list.
+
+---
+
+*This CLA is based on the Apache Foundation Individual CLA, adapted for Stroke.*
diff --git a/.github/cla/signatures.json b/.github/cla/signatures.json
new file mode 100644
index 00000000..6d978e7e
--- /dev/null
+++ b/.github/cla/signatures.json
@@ -0,0 +1,3 @@
+{
+ "signedContributors": []
+}
diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml
new file mode 100644
index 00000000..e06bd81e
--- /dev/null
+++ b/.github/workflows/cla.yml
@@ -0,0 +1,38 @@
+name: CLA Assistant
+
+on:
+ issue_comment:
+ types: [created]
+ pull_request_target:
+ types: [opened, closed, synchronize]
+
+permissions:
+ actions: write
+ contents: write
+ pull-requests: write
+ statuses: write
+
+jobs:
+ cla-assistant:
+ runs-on: ubuntu-latest
+ if: |
+ (github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') ||
+ (github.event_name == 'pull_request_target')
+ steps:
+ - name: CLA assistant
+ uses: contributor-assistant/github-action@v2.6.1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # Personal access token with repo scope — add as a repo secret named
+ # PERSONAL_ACCESS_TOKEN so signatures can be committed back to the repo.
+ PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
+ with:
+ # Signatures are stored in this file in the default branch.
+ path-to-signatures: '.github/cla/signatures.json'
+ # The CLA document contributors will be asked to read.
+ path-to-document: 'https://github.com/${{ github.repository }}/blob/master/.github/cla/cla.md'
+ # The comment added to PRs asking contributors to sign.
+ custom-pr-sign-comment: >
+ I have read the CLA Document and I hereby sign the CLA
+ # Allowlist — bots and the repo owner don't need to sign.
+ allowlist: bot,broisnischal
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..38de1483
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+MIT License
+
+Copyright (c) 2024 Stroke Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+---
+
+NOTICE: Certain features of this software ("Pro Features") are not covered by
+the MIT License above and are subject to a separate commercial license. Pro
+Features are clearly identified in the application and include: AI assistant,
+Dashboard, ORM Runner, Security, Logs, Charts, Diagrams, Schema Timeline,
+Data Diff, Extensions, and SQL Notebooks. Use of Pro Features in production
+requires a valid Stroke Pro license. See https://stroke.click/pricing for details.
diff --git a/README.md b/README.md
index ca42d98d..921e95bb 100644
--- a/README.md
+++ b/README.md
@@ -2,53 +2,188 @@
# Stroke
-**A fast, modern desktop database client.**
+**A fast, minimal desktop database client.**
-Connect to PostgreSQL, MySQL, SQLite, Turso/LibSQL, and Cloudflare D1 — browse schemas, edit data inline, write SQL, visualize, and let AI tools talk to your database through a built-in MCP server.
+Connect to PostgreSQL, MySQL, SQLite, Turso/LibSQL, Cloudflare D1, and more —
+browse schemas, edit data, write SQL, visualize, and let AI tools talk to your database through a built-in MCP server.
-[Download](#install) · [Features](#features) · [Build from source](#build-from-source) · [Website](https://stroke.app)
+[Download](#install) · [Features](#features) · [Build from source](#build-from-source) · [Website](https://stroke.click)
---
+## Why Stroke
+
+Built with **Rust + Svelte** — a native backend paired with a reactive UI — so the app is snappy, memory-efficient, and never feels like a browser tab.
+
+- **Under 40 MB memory** at runtime
+- **Handles millions of rows** without slowing down
+- **Keyboard-first** — every feature is reachable without a mouse
+- **Read-only mode** — safely browse production without risking accidental writes
+- **Extensions** — expand functionality with plugins
+- **Themes** — dark and light, out of the box
+
+---
+
## Supported databases
| Database | Notes |
|----------|-------|
| **PostgreSQL** | Full schema, enums, sequences, triggers, indexes |
-| **MySQL** | Standard host/port connections |
+| **MySQL / MariaDB** | Standard host/port connections |
| **SQLite** | Local file or `:memory:` |
| **Turso / LibSQL** | Serverless SQLite at the edge |
-| **Cloudflare D1** | Connect via OAuth or API token |
+| **Cloudflare D1** | OAuth or API token |
+| **CockroachDB** | PostgreSQL-compatible |
+| **Neon** | Serverless Postgres |
+| **Supabase** | Postgres-based backend |
+| **PlanetScale** | MySQL-compatible serverless |
+
+Connect directly or through an **SSH tunnel** for databases behind a bastion host or private network.
---
## Features
-- **Schema explorer** — tables, views, materialized views, and foreign tables with live row counts, plus an index browser.
-- **Data grid** — paginated browsing, resizable columns (saved per table), column show/hide, multi-column sort, full-text search, and a visual filter builder.
-- **Inline editing** — type-aware editors for text, numbers, booleans, enums, dates, UUIDs, and JSON. Insert and delete rows with smart defaults.
-- **Row inspector** — view any row in formatted, JSON, or preview mode.
-- **Foreign keys** — click a value to jump to the referenced table with the filter applied.
-- **SQL console** — Monaco editor with syntax highlighting, schema-aware autocomplete, formatting, execution time, and CSV/JSON export.
-- **Query history & saved queries** — every query is saved automatically; bookmark the ones you keep.
-- **Schema diagrams** — auto-generated ERDs of your tables and relationships.
-- **Charts & dashboards** — turn query results into charts and pin them to a dashboard.
-- **ORM runner** — run and preview ORM-style queries.
-- **Docker launch** — spin up a local Postgres or MySQL container in one click.
-- **Backup & restore** — export and import your data.
-- **AI chat** — an assistant with direct access to your database that runs queries, explains schemas, generates SQL, and renders diagrams (works with any OpenAI-compatible API).
-- **MCP server** — expose your database to Claude, Cursor, and other MCP clients (see below).
-- **Command palette** — `Cmd/Ctrl+K` to jump anywhere instantly.
+### Data grid
+
+- Paginated browsing with configurable page size
+- Resizable columns, saved per table
+- Pin columns to keep them in view while scrolling
+- Show/hide columns
+- Reset column width to default
+- Column statistics — min, max, avg, nulls, distinct count
+- Multi-column sort
+- Full-text search and visual filter builder
+- Click any foreign-key value to jump to the referenced row
+
+**Cell right-click menu**
+
+Open, Edit, Copy, Filter by value, Exclude this value, Set NULL, Expand, Select row, Delete row
+Copy row as → JSON · CSV · Plain text · Markdown table · INSERT statement
+
+**Column header right-click menu**
+
+Sort ascending · Sort descending · Filter by this column · Pin column · Hide column · Reset column width · Column stats
+
+### Inline editing
+
+Edit text, numbers, booleans, enums, dates, UUIDs, and JSON in place.
+Insert rows with smart defaults. Delete rows. Set any cell to NULL in one action.
+
+### Row inspector
+
+View any row in formatted, raw JSON, or preview mode.
+
+### Schema explorer
+
+- Tables, views, materialized views, and foreign tables
+- Live row counts in the sidebar
+- Index browser
+- View DDL for any object
+
+**Table right-click menu**
+
+Copy name · Close tab · Pin table · Deselect · View DDL · Export as SQL · Export data · Generate test data · Truncate table · Drop table
+
+### SQL console
+
+- Syntax highlighting and schema-aware autocomplete
+- Query formatting and execution time
+- CSV and JSON export
+- Automatic query history — everything is saved
+- Saved queries — bookmark the ones you keep
+- SQL Notebooks (`.sqlnb`) — multi-cell notebooks for documenting and replaying query sequences
+
+### Quick access
+
+Open the quick-access screen to jump anywhere in one keystroke:
+
+| | |
+|--|--|
+| **SQL** | Console with history and saved queries |
+| **Dashboard** | Pinned charts and saved views |
+| **AI** | AI chat assistant |
+| **ORM** | ORM query runner |
+| **Schema** | Schema and index explorer |
+| **Security** | Roles, grants, and privilege viewer |
+| **Logs** | Query and audit logs |
+| **Charts** | Turn query results into charts |
+| **Diagrams** | Auto-generated ERDs |
+| **Timeline** | Schema drift detection across snapshots |
+| **Data Diff** | Row-level diff between snapshots or queries |
+| **Extensions** | Install and manage plugins |
+| **Connect** | Manage and switch connections |
+
+### Charts & dashboards
+
+Turn any query result into a chart and pin it to a dashboard.
+
+### Schema diagrams
+
+Auto-generated entity-relationship diagrams (ERDs) built from your live schema.
+
+### Schema timeline
+
+Track schema changes over time. See exactly what columns, indexes, or constraints were added or removed between snapshots.
+
+### Data diff
+
+Compare two query results or table snapshots row-by-row — added, removed, and modified rows are highlighted clearly.
+
+### ORM runner
+
+Write ORM-style queries, preview the generated SQL, and run them against the connected database.
+
+### Security viewer
+
+Inspect roles, grants, and privileges — see who can read or write what, at a glance.
+
+### Status bar
+
+Active connection, database name, row counts, query execution time, and connection health — always visible at the bottom.
+
+### Docker launch
+
+Spin up a local Postgres or MySQL container in one click without leaving the app.
+
+### Backup & restore
+
+Export and import data as SQL dumps or CSV.
+
+### Extensions
+
+Install community and first-party extensions to add new panels, query tools, or integrations.
+
+### Read-only mode
+
+Lock any connection so writes are blocked entirely — safe for browsing production.
+
+### AI chat
+
+An AI assistant with direct database access that runs queries, explains schemas, generates SQL, and renders diagrams and charts inline.
+Works with any OpenAI-compatible API — configure a base URL, model, and API key in **Settings**.
+
+### MCP server
+
+Stroke ships a built-in **Model Context Protocol** server so Claude, Cursor, and other MCP clients can query your database directly.
+
+1. Open **Settings → MCP Server**
+2. Click **Start**
+3. Copy the one-click config for your AI tool
+
+Uses a stable bearer token — configure once and it just works.
+
+### Command palette
+
+`Cmd/Ctrl+K` — type anything (table name, feature, shortcut) to jump there instantly.
---
## Install
-### Recommended: package managers (no warnings)
-
-The smoothest, warning-free way to install on macOS and Windows:
+### Recommended: package managers
**macOS** — [Homebrew](https://brew.sh)
@@ -63,11 +198,9 @@ scoop bucket add stroke https://github.com/broisnischal/stroke
scoop install stroke
```
-These handle the OS security prompts for you, so the app just opens.
-
### Or download directly
-Grab the installer for your platform from the [Releases](https://github.com/broisnischal/stroke/releases) page.
+Grab the installer from the [Releases](https://github.com/broisnischal/stroke/releases) page.
| Platform | File |
|----------|------|
@@ -77,15 +210,13 @@ Grab the installer for your platform from the [Releases](https://github.com/broi
| Linux (Debian/Ubuntu) | `stroke_x.x.x_amd64.deb` |
| Linux (AppImage) | `stroke_x.x.x_amd64.AppImage` |
-**macOS** — open the `.dmg`, drag **Stroke** to Applications. Stroke is ad-hoc signed (no paid Apple cert), so on first launch macOS may say it's from an unidentified developer or "damaged". Fix it once with:
+**macOS** — open the `.dmg`, drag Stroke to Applications. If macOS blocks it on first launch:
```bash
xattr -cr /Applications/Stroke.app
```
-…then open normally. (The Homebrew install above does this for you.)
-
-**Windows** — run the `.exe` installer. It's unsigned, so SmartScreen shows "Windows protected your PC" — click **More info → Run anyway**. (The Scoop install above avoids this.)
+**Windows** — run the `.exe`. If SmartScreen shows a warning, click **More info → Run anyway**. (Scoop skips this.)
**Linux (Debian/Ubuntu)**
@@ -104,28 +235,15 @@ chmod +x stroke_*_amd64.AppImage
## Connecting
-Pick a database type on the connection screen and fill in the details. Hit **Test connection** to verify, then **Connect**.
-
-- **PostgreSQL / MySQL** — host, port, database, user, password (optional SSL). You can also paste a full connection string and click **Parse**.
-- **SQLite** — point to a `.db`/`.sqlite` file, or use an in-memory database.
-- **Turso / LibSQL** — enter the database URL and (optionally) an auth token.
-- **Cloudflare D1** — sign in with Cloudflare, or enter Account ID, Database ID, and an API token manually.
-
-Connections are saved locally, and Stroke reopens your last one on launch.
-
----
-
-## AI & MCP server
-
-Configure any OpenAI-compatible provider (OpenAI, Mistral, Ollama, …) in **Settings** with a base URL, model, and API key to enable AI chat and SQL suggestions.
-
-To connect external AI tools, Stroke ships a built-in **Model Context Protocol** server:
+Pick a database type and fill in your credentials. Hit **Test connection**, then **Connect**.
-1. Open **Settings → MCP Server**.
-2. Click **Start**.
-3. Copy the one-click config for Claude or Cursor into your tool's config.
+- **PostgreSQL / MySQL** — host, port, database, user, password, optional SSL. Paste a full connection string and click **Parse** to fill the form automatically.
+- **SQLite** — point to a `.db`/`.sqlite` file, or use `:memory:`.
+- **Turso / LibSQL** — database URL and optional auth token.
+- **Cloudflare D1** — sign in with Cloudflare, or enter Account ID, Database ID, and an API token.
+- **SSH tunnel** — any connection type can go through an SSH tunnel for databases in private networks.
-The server uses a stable bearer token, so you only configure it once.
+Connections are saved locally. Stroke reopens your last connection on launch.
---
@@ -134,11 +252,14 @@ The server uses a stable bearer token, so you only configure it once.
| Shortcut | Action |
|----------|--------|
| `Cmd/Ctrl+K` | Command palette |
+| `Ctrl+T` | Quick access |
| `Cmd/Ctrl+Shift+D` | Table data view |
| `Cmd/Ctrl+Shift+S` | SQL console |
| `Cmd/Ctrl+Shift+A` | AI chat |
| `Cmd/Ctrl+Enter` | Run SQL query |
| `Cmd/Ctrl+⌥+←/→` | Switch tabs |
+| `Ctrl+B` | Toggle sidebar |
+| `Ctrl+W` | Close tab |
| `Cmd/Ctrl+?` | Show all shortcuts |
---
@@ -151,17 +272,17 @@ Requires [Node.js](https://nodejs.org) 18+ and the [Rust toolchain](https://rust
git clone https://github.com/broisnischal/stroke
cd stroke
npm install
-npm run tauri # run in dev
-npm run tauri:build # build a release binary
+npm run tauri # dev
+npm run tauri:build # release binary
```
-**Arch Linux** — the AppImage step can fail due to a linker quirk. Build only the `.deb`:
+**Arch Linux** — build `.deb` only to avoid an AppImage linker issue:
```bash
npm run tauri:build -- --bundles deb
```
-…or use the included helper for AppImage on Arch:
+Or use the included Arch helper:
```bash
npm run tauri:build:arch
diff --git a/index.html b/index.html
index 84ee77c5..7652a17f 100644
--- a/index.html
+++ b/index.html
@@ -3,12 +3,13 @@