Skip to content

Commit 273d6fe

Browse files
committed
initial commit
0 parents  commit 273d6fe

49 files changed

Lines changed: 12747 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint-frontend:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Setup Node.js
16+
uses: actions/setup-node@v4
17+
with:
18+
node-version: 22
19+
cache: npm
20+
21+
- name: Install dependencies
22+
run: npm ci
23+
24+
- name: Type check
25+
run: npx tsc --noEmit
26+
27+
test-rust:
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v4
31+
32+
- name: Install Rust stable
33+
uses: dtolnay/rust-toolchain@stable
34+
with:
35+
components: clippy, rustfmt
36+
37+
- name: Rust cache
38+
uses: swatinem/rust-cache@v2
39+
with:
40+
workspaces: "./src-tauri -> target"
41+
42+
- name: Install Linux dependencies
43+
run: |
44+
sudo apt-get update
45+
sudo apt-get install -y \
46+
libwebkit2gtk-4.1-dev \
47+
libgtk-3-dev \
48+
libayatana-appindicator3-dev \
49+
librsvg2-dev \
50+
libssl-dev
51+
52+
- name: Check formatting
53+
working-directory: src-tauri
54+
run: cargo fmt --check
55+
56+
- name: Clippy
57+
working-directory: src-tauri
58+
run: cargo clippy -- -D warnings
59+
60+
- name: Run tests
61+
working-directory: src-tauri
62+
run: cargo test
63+
64+
build-check:
65+
needs: [lint-frontend, test-rust]
66+
strategy:
67+
fail-fast: false
68+
matrix:
69+
platform: [macos-latest, ubuntu-22.04, windows-latest]
70+
runs-on: ${{ matrix.platform }}
71+
steps:
72+
- uses: actions/checkout@v4
73+
74+
- name: Install Rust stable
75+
uses: dtolnay/rust-toolchain@stable
76+
77+
- name: Rust cache
78+
uses: swatinem/rust-cache@v2
79+
with:
80+
workspaces: "./src-tauri -> target"
81+
82+
- name: Install Linux dependencies
83+
if: matrix.platform == 'ubuntu-22.04'
84+
run: |
85+
sudo apt-get update
86+
sudo apt-get install -y \
87+
libwebkit2gtk-4.1-dev \
88+
libgtk-3-dev \
89+
libayatana-appindicator3-dev \
90+
librsvg2-dev \
91+
libssl-dev
92+
93+
- name: Setup Node.js
94+
uses: actions/setup-node@v4
95+
with:
96+
node-version: 22
97+
cache: npm
98+
99+
- name: Install frontend dependencies
100+
run: npm ci
101+
102+
- name: Build Tauri app
103+
uses: tauri-apps/tauri-action@v0
104+
env:
105+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
106+
with:
107+
args: ""

.github/workflows/release.yml

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
workflow_dispatch:
8+
9+
jobs:
10+
create-release:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
outputs:
15+
release_id: ${{ steps.create_release.outputs.id }}
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Create GitHub Release
20+
id: create_release
21+
uses: actions/create-release@v1
22+
env:
23+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24+
with:
25+
tag_name: ${{ github.ref_name }}
26+
release_name: DotEnv Vault ${{ github.ref_name }}
27+
draft: true
28+
prerelease: false
29+
body: |
30+
## What's New
31+
32+
See the [full changelog](https://github.com/${{ github.repository }}/compare/.../${{ github.ref_name }}).
33+
34+
## Downloads
35+
36+
| Platform | File |
37+
|----------|------|
38+
| macOS (Apple Silicon) | `.dmg` |
39+
| macOS (Intel) | `.dmg` |
40+
| Windows | `.msi` / `.exe` |
41+
| Linux (Debian/Ubuntu) | `.deb` |
42+
| Linux (AppImage) | `.AppImage` |
43+
44+
build:
45+
needs: create-release
46+
permissions:
47+
contents: write
48+
strategy:
49+
fail-fast: false
50+
matrix:
51+
include:
52+
- platform: macos-latest
53+
args: --target aarch64-apple-darwin
54+
rust_target: aarch64-apple-darwin
55+
- platform: macos-latest
56+
args: --target x86_64-apple-darwin
57+
rust_target: x86_64-apple-darwin
58+
- platform: ubuntu-22.04
59+
args: ""
60+
rust_target: ""
61+
- platform: windows-latest
62+
args: ""
63+
rust_target: ""
64+
65+
runs-on: ${{ matrix.platform }}
66+
steps:
67+
- uses: actions/checkout@v4
68+
69+
- name: Install Rust stable
70+
uses: dtolnay/rust-toolchain@stable
71+
with:
72+
targets: ${{ matrix.rust_target }}
73+
74+
- name: Rust cache
75+
uses: swatinem/rust-cache@v2
76+
with:
77+
workspaces: "./src-tauri -> target"
78+
79+
- name: Install Linux dependencies
80+
if: matrix.platform == 'ubuntu-22.04'
81+
run: |
82+
sudo apt-get update
83+
sudo apt-get install -y \
84+
libwebkit2gtk-4.1-dev \
85+
libgtk-3-dev \
86+
libayatana-appindicator3-dev \
87+
librsvg2-dev \
88+
libssl-dev \
89+
patchelf
90+
91+
- name: Setup Node.js
92+
uses: actions/setup-node@v4
93+
with:
94+
node-version: 22
95+
cache: npm
96+
97+
- name: Install frontend dependencies
98+
run: npm ci
99+
100+
- name: Build Tauri app
101+
uses: tauri-apps/tauri-action@v0
102+
env:
103+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
104+
with:
105+
releaseId: ${{ needs.create-release.outputs.release_id }}
106+
args: ${{ matrix.args }}
107+
108+
publish-release:
109+
runs-on: ubuntu-latest
110+
needs: [create-release, build]
111+
permissions:
112+
contents: write
113+
steps:
114+
- name: Publish release
115+
uses: actions/github-script@v7
116+
with:
117+
script: |
118+
github.rest.repos.updateRelease({
119+
owner: context.repo.owner,
120+
repo: context.repo.repo,
121+
release_id: '${{ needs.create-release.outputs.release_id }}',
122+
draft: false,
123+
});

.gitignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Build output
5+
dist/
6+
src-tauri/target/
7+
8+
# Environment files (ironic, but correct)
9+
.env
10+
.env.*
11+
12+
# IDE
13+
.vscode/
14+
.idea/
15+
*.swp
16+
*.swo
17+
*~
18+
19+
# OS
20+
.DS_Store
21+
Thumbs.db
22+
23+
# Logs
24+
*.log
25+
npm-debug.log*
26+
27+
# Tauri
28+
src-tauri/gen/
29+
30+
# SQLite database (user data, never commit)
31+
*.db
32+
*.db-journal
33+
*.db-wal

CLAUDE.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code when working with this repository.
4+
5+
## Project Overview
6+
7+
DotEnv Vault is a **Tauri 2.x desktop app** that discovers, catalogs, compares, and encrypts `.env` files across all your projects. It scans root directories, finds projects, parses their env files, and stores everything in an encrypted local SQLite vault.
8+
9+
## Commands
10+
11+
```bash
12+
npm install # Install frontend dependencies
13+
npm run tauri dev # Start Tauri development (requires Rust toolchain)
14+
npm run tauri build # Production build
15+
npm run dev # Start Vite dev server only (frontend)
16+
npm run build # Build frontend only
17+
```
18+
19+
### Prerequisites
20+
21+
- **Rust** (stable, via rustup)
22+
- **Node.js** ≥ 18
23+
- **Tauri CLI**: `cargo install tauri-cli` (or use `npx tauri`)
24+
- **System deps** (Linux): `libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libssl-dev`
25+
26+
## Tech Stack
27+
28+
- **Shell**: Tauri 2.x (Rust backend, webview frontend)
29+
- **Backend**: Rust with rusqlite, aes-gcm, argon2, walkdir, notify
30+
- **Frontend**: React 19 + TypeScript + Tailwind CSS v4 + React Router v7
31+
- **Storage**: SQLite (via rusqlite with bundled feature)
32+
- **Encryption**: AES-256-GCM + Argon2id key derivation
33+
34+
## Architecture
35+
36+
### Rust Backend (`src-tauri/src/`)
37+
38+
```
39+
src-tauri/src/
40+
├── main.rs # Entry point
41+
├── lib.rs # Tauri app setup, state management
42+
├── commands.rs # All #[tauri::command] handlers
43+
├── db/
44+
│ ├── mod.rs # Database struct, all CRUD operations
45+
│ └── schema.rs # SQLite CREATE TABLE statements
46+
├── parser/
47+
│ └── mod.rs # .env file parser + tier detection + ecosystem detection
48+
├── scanner/
49+
│ └── mod.rs # Recursive filesystem scanner, project discovery
50+
├── crypto/
51+
│ └── mod.rs # AES-256-GCM encryption, Argon2id key derivation, vault state
52+
├── watcher/
53+
│ └── mod.rs # File system watcher (notify crate)
54+
└── search/
55+
└── mod.rs # Search filters + fuzzy matching
56+
```
57+
58+
### React Frontend (`src/`)
59+
60+
```
61+
src/
62+
├── main.tsx # React entry point
63+
├── App.tsx # Root component: routing, vault state, keyboard shortcuts
64+
├── index.css # Tailwind v4 @theme tokens (design system)
65+
├── lib/
66+
│ └── tauri.ts # Type definitions + invoke wrappers for all Tauri commands
67+
├── hooks/
68+
│ └── useVault.ts # Vault state management hook
69+
├── components/
70+
│ ├── Sidebar.tsx # Navigation sidebar with roots/projects tree
71+
│ ├── Header.tsx # Top bar with search trigger + scan button
72+
│ ├── SearchPalette.tsx # Cmd+K search palette
73+
│ └── TierBadge.tsx # Color-coded environment tier badge
74+
└── pages/
75+
├── SetupScreen.tsx # First-time master password creation
76+
├── UnlockScreen.tsx # Vault unlock screen
77+
├── ProjectsPage.tsx # Overview dashboard with all projects
78+
├── ProjectDetailPage.tsx # Single project: env hierarchy tree + file table
79+
├── EnvFilePage.tsx # Env file variables with masked/reveal values
80+
├── ComparisonPage.tsx # Cross-environment comparison matrix
81+
└── SettingsPage.tsx # Vault settings, password change, export
82+
```
83+
84+
### Design System
85+
86+
Uses Tailwind v4's `@theme` directive. Key tokens:
87+
- `bg-bg` (#09090B) — main background
88+
- `bg-surface` (#18181B) — cards/panels
89+
- `bg-surface-2` (#27272A) — hover states
90+
- `text-accent` (#6366F1) — indigo accent
91+
- `text-green/yellow/red` — status colors
92+
- `font-ui` — Inter/system sans-serif
93+
- `font-code` — JetBrains Mono
94+
95+
### Tauri Command Surface
96+
97+
All frontend-to-backend calls go through `src/lib/tauri.ts` which wraps `invoke()` with typed APIs. Commands are registered in `lib.rs` via `generate_handler![]`.
98+
99+
### Key Design Decisions
100+
101+
- **Values encrypted, keys plaintext**: Variable names are stored unencrypted for instant search and comparison. Only secret values are AES-256-GCM encrypted.
102+
- **Vault state in OnceLock**: The encryption key lives in a process-global `OnceLock<Mutex<VaultState>>` so it's accessible across commands without being part of Tauri's managed state serialization.
103+
- **Stable project IDs**: Projects are identified by UUID, matched by (root_path, name) on re-scan to avoid duplication.
104+
- **Non-blocking scan**: Scanning runs in Tauri's command thread pool. The file watcher uses a separate thread.

0 commit comments

Comments
 (0)