This commit is contained in:
Andras Schmelczer 2026-01-12 22:42:29 +00:00 • committed by GitHub
commit afc96005ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
91 changed files with 6230 additions and 9161 deletions

View file

@ -23,14 +23,19 @@ jobs:
- name: Setup Node.js environment - name: Setup Node.js environment
uses: actions/setup-node@v4.2.0 uses: actions/setup-node@v4.2.0
with: with:
node-version: "22.x" node-version: "25.x"
check-latest: true check-latest: true
- name: Setup Rust toolchain - name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable uses: dtolnay/rust-toolchain@stable
with: with:
toolchain: "1.89.0" toolchain: "1.92.0"
components: clippy, rustfmt components: clippy, rustfmt
- name: Install Task
uses: arduino/setup-task@v2
with:
version: 3.x
- name: Lint & test - name: Lint & test
run: scripts/check.sh run: task check

View file

@ -5,8 +5,8 @@ on:
branches: branches:
- main - main
paths: paths:
- 'docs/**' - "docs/**"
- '.github/workflows/deploy-docs.yml' - ".github/workflows/deploy-docs.yml"
workflow_dispatch: workflow_dispatch:
permissions: permissions:
@ -28,18 +28,22 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Node - name: Setup Node.js environment
uses: actions/setup-node@v4 uses: actions/setup-node@v4.2.0
with: with:
node-version: 22 node-version: "25.x"
cache: npm check-latest: true
cache-dependency-path: docs/package-lock.json
- name: Install Task
uses: arduino/setup-task@v2
with:
version: 3.x
- name: Setup Pages - name: Setup Pages
uses: actions/configure-pages@v4 uses: actions/configure-pages@v4
- name: Build docs - name: Build docs
run: scripts/build-docs.sh run: task docs:check
- name: Upload artifact - name: Upload artifact
uses: actions/upload-pages-artifact@v3 uses: actions/upload-pages-artifact@v3

View file

@ -6,7 +6,7 @@ on:
pull_request: pull_request:
branches: ["main"] branches: ["main"]
schedule: schedule:
- cron: '0 * * * *' - cron: "0 * * * *"
workflow_dispatch: workflow_dispatch:
concurrency: concurrency:
@ -28,21 +28,22 @@ jobs:
- name: Setup Node.js environment - name: Setup Node.js environment
uses: actions/setup-node@v4.2.0 uses: actions/setup-node@v4.2.0
with: with:
node-version: "22.x" node-version: "25.x"
check-latest: true check-latest: true
- name: Setup Rust toolchain - name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable uses: dtolnay/rust-toolchain@stable
with: with:
toolchain: "1.89.0" toolchain: "1.92.0"
components: clippy, rustfmt components: clippy, rustfmt
- name: Setup rust - name: Install Task
run: | uses: arduino/setup-task@v2
which sqlx || cargo install sqlx-cli with:
cd sync-server version: 3.x
sqlx database create --database-url sqlite://db.sqlite3
sqlx migrate run --source src/app_state/database/migrations --database-url sqlite://db.sqlite3 - name: Setup database
run: task db:setup
- name: E2E tests - name: E2E tests
run: | run: |
@ -51,7 +52,7 @@ jobs:
SERVER_PID=$! SERVER_PID=$!
cd .. cd ..
scripts/e2e.sh 8 task e2e -- 8
EXIT_CODE=$? EXIT_CODE=$?
kill $SERVER_PID 2>/dev/null || true kill $SERVER_PID 2>/dev/null || true
@ -69,4 +70,4 @@ jobs:
- name: Cleanup - name: Cleanup
if: always() if: always()
run: scripts/clean-up.sh run: task clean

View file

@ -19,28 +19,30 @@ jobs:
- name: Setup Node.js environment - name: Setup Node.js environment
uses: actions/setup-node@v4.2.0 uses: actions/setup-node@v4.2.0
with: with:
node-version: "22.x" node-version: "25.x"
check-latest: true check-latest: true
- name: Build plugin
run: |
cd frontend
npm ci
npm run build
- name: Setup Rust toolchain - name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable uses: dtolnay/rust-toolchain@stable
with: with:
toolchain: "1.89.0" toolchain: "1.92.0"
components: clippy, rustfmt components: clippy, rustfmt
- name: Install Task
uses: arduino/setup-task@v2
with:
version: 3.x
- name: Install cross-compilation tools - name: Install cross-compilation tools
run: | run: |
apt update apt update
apt install -y gcc-aarch64-linux-gnu musl-tools gcc-mingw-w64-x86-64 apt install -y gcc-aarch64-linux-gnu musl-tools gcc-mingw-w64-x86-64
- name: Build Linux and Windows binaries - name: Build frontend
run: ./scripts/build-sync-server-binaries.sh run: task frontend:build
- name: Build binaries
run: task release:build-binaries
- name: Create release - name: Create release
env: env:

View file

@ -5,6 +5,6 @@
"**/dist": true, "**/dist": true,
"**/node_modules": true, "**/node_modules": true,
"**/.sqlx": true, "**/.sqlx": true,
"**/target": true, "**/target": true
}, }
} }

240
CLAUDE.md
View file

@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview ## Project Overview
VaultLink is a self-hosted Obsidian plugin for real-time collaborative file syncing. The project consists of a Rust-based sync server and a TypeScript frontend with three main components: an Obsidian plugin, a sync client library, and a test client. VaultLink is a self-hosted Obsidian plugin for real-time collaborative file syncing. The project consists of a Rust-based sync server and a TypeScript frontend with four main components: an Obsidian plugin, a sync client library, a test client, and a standalone CLI client.
## Architecture ## Architecture
@ -13,98 +13,234 @@ VaultLink is a self-hosted Obsidian plugin for real-time collaborative file sync
- **sync-server/**: Rust-based WebSocket server with SQLite database for document versioning and real-time synchronization - **sync-server/**: Rust-based WebSocket server with SQLite database for document versioning and real-time synchronization
- **frontend/sync-client/**: TypeScript library providing core sync functionality, WebSocket management, and file operations - **frontend/sync-client/**: TypeScript library providing core sync functionality, WebSocket management, and file operations
- **frontend/obsidian-plugin/**: Obsidian plugin that integrates the sync client with Obsidian's API - **frontend/obsidian-plugin/**: Obsidian plugin that integrates the sync client with Obsidian's API
- **frontend/test-client/**: CLI testing tool for the sync functionality - **frontend/test-client/**: CLI testing tool for simulating multiple concurrent users
- **frontend/local-client-cli/**: Standalone CLI for VaultLink sync client
### Key Technologies ### Key Technologies
- **Backend**: Rust with Axum framework, SQLite with SQLx, WebSockets for real-time sync - **Backend**: Rust with Axum framework, SQLite with SQLx, WebSockets for real-time sync
- **Frontend**: TypeScript, Webpack for bundling, Jest for testing - **Frontend**: TypeScript, Webpack for bundling, Node.js native test runner
- **Sync Algorithm**: Uses reconcile-text library for operational transformation - **Sync Algorithm**: Uses reconcile-text library for operational transformation
### Architectural Patterns
**Server Architecture:**
- `AppState`: Central state container holding `Database`, `Cursors`, and `Broadcasts`
- `Database`: SQLite-backed document versioning with SQLx for compile-time query verification
- `Broadcasts`: WebSocket broadcast system for real-time updates to connected clients
- `Cursors`: Tracks user cursor positions across documents with background cleanup task
**Client Architecture:**
- `SyncClient`: Main entry point, orchestrates all sync operations
- `SyncService`: HTTP API client for CRUD operations on documents
- `WebSocketManager`: Manages WebSocket connection and real-time updates
- `Syncer`: Coordinates file synchronization between local filesystem and server
- `CursorTracker`: Manages local and remote cursor positions
- `Database`: Client-side document metadata cache
- `FileOperations`: Abstraction layer for filesystem operations
**Dual-Bundle Strategy:**
The sync-client builds two separate bundles:
- `sync-client.web.js`: Browser-compatible UMD bundle (excludes `ws` package)
- `sync-client.node.js`: Node.js CommonJS bundle with WebSocket support
## Development Commands ## Development Commands
### Server Development This project uses [Taskfile](https://taskfile.dev/) for task automation. Run `task --list` to see all available tasks.
### Initial Setup
**Taskfile:**
```bash
# Install Task (https://taskfile.dev/installation/)
# macOS
brew install go-task
# Linux
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
# Or via npm
npm install -g @go-task/cli
```
**Node.js (requires version 25):**
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install 25
nvm use 25
nvm alias default 25 # Optional: set as system default
```
**Rust:**
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
cargo install sqlx-cli cargo-machete cargo-edit cargo-insta
```
**Frontend:**
```bash
task frontend:install
```
### Common Tasks (Taskfile)
```bash
task check # Full CI check (lint, test, format). Run before pushing.
task check:fix # Same as above but auto-fixes issues
task e2e -- 8 # E2E tests with 8 concurrent clients
task clean # Clean logs and database files
task update-api-types # Update TypeScript bindings from Rust types
task release:bump -- patch # Bump version (patch|minor|major)
```
### Server Tasks
```bash
task rust:run # Start development server
task rust:test # Run all Rust tests
task rust:clippy # Lint Rust code
task rust:clippy-fix # Auto-fix clippy warnings
task rust:fmt # Format Rust code
task rust:fmt-check # Check Rust formatting
task rust:machete # Detect unused dependencies
```
### Frontend Tasks
```bash
task frontend:dev # Start development mode
task frontend:build # Build all workspaces
task frontend:test # Run all frontend tests
task frontend:lint # Lint and format TypeScript
```
### Database Tasks
```bash
task db:setup # Create and migrate database
task db:reset # Reset database (delete and recreate)
task db:prepare # Prepare SQLx offline data
task db:add-migration NAME=<migration_name> # Add new migration
```
### Documentation Tasks
```bash
task docs:check # Build and check documentation
task docs:dev # Start documentation dev server
```
### Direct Commands (Alternative)
If you prefer not to use Taskfile, these commands work directly:
**Server:**
```bash ```bash
cd sync-server cd sync-server
cargo run config-e2e.yml # Start development server cargo run config-e2e.yml # Start development server
cargo test --verbose # Run Rust tests cargo test --verbose # Run all Rust tests
cargo clippy --all-targets --all-features # Lint Rust code cargo clippy --all-targets --all-features # Lint
cargo clippy --all-targets --all-features --fix --allow-dirty --allow-staged # Auto-fix clippy warnings cargo fmt --all # Format
cargo fmt --all -- --check # Check Rust formatting
cargo fmt --all # Auto-format Rust code
cargo machete --with-metadata # Detect unused dependencies
``` ```
### Frontend Development **Frontend:**
```bash ```bash
cd frontend cd frontend
npm run dev # Start development mode (watches sync-client and obsidian-plugin) npm run dev # Development mode
npm run build # Build all workspaces npm run build # Build all workspaces
npm run test # Run all tests npm run test # Run tests
npm run lint # Lint and format TypeScript code npm run lint # Lint and format
``` ```
### Database Setup (Development) **Database:**
```bash ```bash
cd sync-server cd sync-server
sqlx database create --database-url sqlite://db.sqlite3 sqlx database create --database-url sqlite://db.sqlite3
sqlx migrate run --source src/app_state/database/migrations --database-url sqlite://db.sqlite3 sqlx migrate run --source src/app_state/database/migrations --database-url sqlite://db.sqlite3
cargo sqlx prepare --workspace
``` ```
### Initial Setup
```bash
# Install required cargo tools
cargo install sqlx-cli cargo-machete cargo-edit
```
### Scripts
- `scripts/check.sh`: Full CI check (builds, lints, tests both server and frontend)
- `scripts/check.sh --fix`: Same as above but auto-fixes linting and formatting issues
- `scripts/e2e.sh`: End-to-end testing
- `scripts/clean-up.sh`: Clean logs and database files
- `scripts/bump-version.sh patch`: Publish new version
- `scripts/update-api-types.sh`: Update TypeScript bindings from Rust types
## Code Structure ## Code Structure
### Workspace Configuration ### Workspace Configuration
The frontend uses npm workspaces with four packages: The frontend uses npm workspaces with four packages:
- `sync-client`: Core synchronization logic
- `sync-client`: Core synchronization logic (builds dual bundles for web and Node.js)
- `obsidian-plugin`: Obsidian-specific integration - `obsidian-plugin`: Obsidian-specific integration
- `test-client`: Testing utilities - `test-client`: Testing utilities for E2E tests
- `local-client-cli`: Standalone CLI for VaultLink sync client - `local-client-cli`: Standalone CLI for VaultLink sync client
### Type Generation ### Type Generation and API Updates
Rust structs generate TypeScript types via ts-rs crate, stored in `sync-server/bindings/` and used by frontend packages.
### Key Files Rust structs generate TypeScript types via ts-rs crate:
- `sync-server/src/`: Rust server implementation with WebSocket handlers
- `frontend/sync-client/src/sync-client.ts`: Main sync client entry point 1. Rust structs annotated with `#[derive(TS)]` export to `sync-server/bindings/`
- `frontend/obsidian-plugin/src/vault-link-plugin.ts`: Main Obsidian plugin class 2. Run `task update-api-types` to copy bindings to `frontend/sync-client/src/services/types/`
- `frontend/sync-client/src/services/sync-service.ts`: Core synchronization logic 3. Frontend imports these types for type-safe API communication
### Important Implementation Details
**SQLx Compile-Time Verification:**
- SQLx verifies SQL queries at compile time against the database schema
- Run `cargo sqlx prepare --workspace` after schema changes to update `.sqlx/` directory
- CI builds require prepared query metadata to avoid needing a live database
## Testing ## Testing
### Running Tests ### Running Tests
- Server: `cargo test --verbose`
- Frontend: `npm run test` (runs Jest across all workspaces) ```bash
- E2E: `scripts/e2e.sh` task rust:test # All Rust tests
task frontend:test # All frontend tests
task e2e -- 8 # E2E with 8 concurrent clients
task clean # Clean up after tests
```
Or use direct commands:
```bash
cd sync-server && cargo test --verbose # Rust tests
cd frontend && npm run test # Frontend tests
```
### Test Structure ### Test Structure
- Rust: Unit tests alongside source files
- TypeScript: `.test.ts` files using Jest
- E2E: Uses test-client to simulate multiple concurrent users
## Code Style - **Rust**: Unit tests alongside source files, uses `cargo-insta` for snapshot testing
- **TypeScript**: `.test.ts` files using Node.js native test runner (not Jest)
- **E2E**: Uses `test-client` to simulate multiple concurrent users with random operations
## Code Style and Formatting
### Rust ### Rust
- Uses extensive Clippy lints (see Cargo.toml)
- Follows pedantic linting rules - Extensive Clippy lints (see `Cargo.toml`)
- Pedantic linting rules enabled
- Forbids unsafe code - Forbids unsafe code
- Uses cargo fmt with default settings - Uses `rustfmt.toml` for formatting configuration (4 spaces, Unix line endings)
- Run `cargo fmt --all` to format
### TypeScript ### TypeScript
- Prettier configuration: 4-space tabs, trailing commas removed, LF line endings
- ESLint with unused imports plugin - **Prettier**: 4-space indentation, no trailing commas, LF line endings
- Consistent across all three frontend packages - **YAML/Markdown override**: 2-space indentation (via prettier config)
- **ESLint**: Strict rules with unused imports detection
- Configuration in `frontend/package.json`
- Run `npm run lint` to format and fix issues
### EditorConfig
- `.editorconfig` at project root defines baseline formatting rules
- `rustfmt.toml` and Prettier config explicitly mirror these settings
- Both formatters enforce: 4-space indent (2 for YAML/MD), LF endings, final newline, trim trailing whitespace

View file

@ -8,12 +8,12 @@
## Develop ## Develop
### Install [nvm](https://github.com/nvm-sh/nvm) ### Set up Node.JS 25 with [nvm](https://github.com/nvm-sh/nvm)
- `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash` - `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash`
- `nvm install 22` - `nvm install 25`
- `nvm use 22` - `nvm use 25`
- Optionally set the system-wide default: `nvm alias default 22` - Optionally, set the system-wide default: `nvm alias default 25`
### Set up Rust ### Set up Rust
@ -77,3 +77,10 @@ And to clean up the logs & database files, run `scripts/clean-up.sh`
## Projects ## Projects
- [Sync server](./sync-server/README.md) - [Sync server](./sync-server/README.md)
a create that has been processed by the server but got lost on the way back will create a 2nd doc if it gets edited

96
Taskfile.yml Normal file
View file

@ -0,0 +1,96 @@
version: "3"
vars:
NODE_VERSION: "25"
includes:
rust:
taskfile: ./taskfiles/rust.yml
dir: ./sync-server
frontend:
taskfile: ./taskfiles/frontend.yml
dir: ./frontend
db:
taskfile: ./taskfiles/database.yml
dir: ./sync-server
e2e:
taskfile: ./taskfiles/e2e.yml
docs:
taskfile: ./taskfiles/docs.yml
dir: ./docs
release:
taskfile: ./taskfiles/release.yml
tasks:
check:
desc: Run all checks (lint, test, format)
cmds:
- task: check-node
- task: db:setup
- task: rust:test
- task: rust:lint
- task: update-api-types
- task: frontend:install
- task: frontend:build
- task: frontend:test
- task: frontend:lint
- task: format
- task: check-clean
check:fix:
desc: Run all checks with auto-fix enabled
cmds:
- task: check-node
- task: db:setup
- task: rust:test
- task: rust:lint-fix
- task: update-api-types
- task: frontend:install
- task: frontend:build
- task: frontend:test
- task: frontend:lint
- task: format
check-node:
internal: true
silent: true
preconditions:
- sh: node -v | grep -q "^v{{.NODE_VERSION}}"
msg: "Node.js {{.NODE_VERSION}} required (found: $(node -v))"
cmds:
- echo "Node.js {{.NODE_VERSION}} confirmed"
check-clean:
internal: true
preconditions:
- sh: test -z "$(git status --porcelain)"
msg: |
Working directory not clean after linting:
$(git status --porcelain)
format:
desc: Format all files with Prettier
dir: "{{.ROOT_DIR}}"
cmds:
- npx -C frontend prettier --write "**/*.{ts,js,json,md,yml,yaml}"
update-api-types:
desc: Update TypeScript bindings from Rust types
cmds:
- rm -rf sync-server/bindings
- task: rust:export-bindings
- cp -r sync-server/bindings/* frontend/sync-client/src/services/types/
- cd frontend && npm run lint
- task: format
clean:
desc: Clean up logs and databases
cmds:
- rm -rf sync-server/databases logs
e2e:
desc: Run E2E tests (usage - task e2e -- 8)
cmds:
- task: e2e:run
vars:
PROCESS_COUNT: "{{.CLI_ARGS}}"

View file

@ -2,12 +2,7 @@
"version": "0.2", "version": "0.2",
"language": "en-GB", "language": "en-GB",
"dictionaries": ["en-gb"], "dictionaries": ["en-gb"],
"ignorePaths": [ "ignorePaths": ["node_modules", ".vitepress/dist", ".vitepress/cache", "package-lock.json"],
"node_modules",
".vitepress/dist",
".vitepress/cache",
"package-lock.json"
],
"words": [ "words": [
"VaultLink", "VaultLink",
"Obsidian", "Obsidian",

View file

@ -361,11 +361,11 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "upload_file", "type": "upload_file",
"path": "notes/example.md", "path": "notes/example.md",
"content": "File content here...", "content": "File content here...",
"base_version": 10, "base_version": 10,
"timestamp": "2024-01-01T12:00:00Z" "timestamp": "2024-01-01T12:00:00Z"
} }
``` ```
@ -373,8 +373,8 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "download_file", "type": "download_file",
"path": "notes/example.md" "path": "notes/example.md"
} }
``` ```
@ -382,8 +382,8 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "delete_file", "type": "delete_file",
"path": "notes/old.md" "path": "notes/old.md"
} }
``` ```
@ -391,8 +391,8 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "list_files", "type": "list_files",
"since_version": 0 "since_version": 0
} }
``` ```
@ -402,11 +402,11 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "file_updated", "type": "file_updated",
"path": "notes/example.md", "path": "notes/example.md",
"version": 11, "version": 11,
"size": 1024, "size": 1024,
"hash": "abc123..." "hash": "abc123..."
} }
``` ```
@ -414,10 +414,10 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "file_content", "type": "file_content",
"path": "notes/example.md", "path": "notes/example.md",
"content": "Updated content...", "content": "Updated content...",
"version": 11 "version": 11
} }
``` ```
@ -425,9 +425,9 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "file_deleted", "type": "file_deleted",
"path": "notes/old.md", "path": "notes/old.md",
"version": 12 "version": 12
} }
``` ```
@ -435,9 +435,9 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "sync_complete", "type": "sync_complete",
"total_files": 150, "total_files": 150,
"current_version": 200 "current_version": 200
} }
``` ```
@ -445,9 +445,9 @@ VALUES (?, ?, ?);
```json ```json
{ {
"type": "error", "type": "error",
"message": "File too large", "message": "File too large",
"code": "FILE_TOO_LARGE" "code": "FILE_TOO_LARGE"
} }
``` ```

View file

@ -53,7 +53,7 @@ Central authority for synchronisation. Rust + Axum framework.
**Technology**: **Technology**:
- **Language**: Rust 1.89+ - **Language**: Rust 1.92+
- **Framework**: Axum (async web framework) - **Framework**: Axum (async web framework)
- **Database**: SQLite with SQLx - **Database**: SQLite with SQLx
- **Protocol**: WebSockets for real-time communication - **Protocol**: WebSockets for real-time communication

View file

@ -243,9 +243,9 @@ users:
2. Client sends authentication message: 2. Client sends authentication message:
```json ```json
{ {
"type": "auth", "type": "auth",
"token": "user-token", "token": "user-token",
"vault": "vault-name" "vault": "vault-name"
} }
``` ```
3. Server validates: 3. Server validates:

View file

@ -75,7 +75,7 @@ chmod +x sync_server-linux-x86_64
### Build from Source ### Build from Source
Requirements: Rust 1.89.0+, SQLite development headers, SQLx CLI Requirements: Rust 1.92.0+, SQLite development headers, SQLx CLI
```bash ```bash
# Clone the repository # Clone the repository

5960
docs/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
FROM node:22-slim AS builder FROM node:25-slim AS builder
WORKDIR /build WORKDIR /build
@ -7,7 +7,7 @@ COPY . .
RUN npm ci RUN npm ci
RUN npm run build RUN npm run build
FROM node:22-alpine FROM node:25-alpine
LABEL org.opencontainers.image.title="VaultLink Local CLI" LABEL org.opencontainers.image.title="VaultLink Local CLI"
LABEL org.opencontainers.image.description="Standalone CLI for VaultLink sync client" LABEL org.opencontainers.image.description="Standalone CLI for VaultLink sync client"

View file

@ -47,24 +47,24 @@ vaultlink \
### Required ### Required
| Option | Description | | Option | Description |
|--------|-------------| | ------------------------- | --------------------------------------------- |
| `-l, --local-path <path>` | Local directory to sync | | `-l, --local-path <path>` | Local directory to sync |
| `-r, --remote-uri <uri>` | Remote server WebSocket URI (ws:// or wss://) | | `-r, --remote-uri <uri>` | Remote server WebSocket URI (ws:// or wss://) |
| `-t, --token <token>` | Authentication token | | `-t, --token <token>` | Authentication token |
| `-v, --vault-name <name>` | Vault name on server | | `-v, --vault-name <name>` | Vault name on server |
### Optional ### Optional
| Option | Default | Description | | Option | Default | Description |
|--------|---------|-------------| | ------------------------------------ | ------- | -------------------------------------- |
| `--sync-concurrency <number>` | `1` | Concurrent sync operations | | `--sync-concurrency <number>` | `1` | Concurrent sync operations |
| `--max-file-size-mb <number>` | `10` | Maximum file size in MB | | `--max-file-size-mb <number>` | `10` | Maximum file size in MB |
| `--ignore-pattern <pattern>` | - | Glob pattern to ignore (repeatable) | | `--ignore-pattern <pattern>` | - | Glob pattern to ignore (repeatable) |
| `--websocket-retry-interval-ms <ms>` | `3500` | WebSocket reconnection interval | | `--websocket-retry-interval-ms <ms>` | `3500` | WebSocket reconnection interval |
| `--log-level <level>` | `INFO` | Log level: DEBUG, INFO, WARNING, ERROR | | `--log-level <level>` | `INFO` | Log level: DEBUG, INFO, WARNING, ERROR |
| `-h, --help` | - | Show help | | `-h, --help` | - | Show help |
| `-V, --version` | - | Show version | | `-V, --version` | - | Show version |
### Auto-Ignored Patterns ### Auto-Ignored Patterns
@ -74,11 +74,13 @@ vaultlink \
### Examples ### Examples
Basic usage: Basic usage:
```bash ```bash
vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default
``` ```
With ignore patterns: With ignore patterns:
```bash ```bash
vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default \ vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default \
--ignore-pattern "*.tmp" \ --ignore-pattern "*.tmp" \
@ -87,6 +89,7 @@ vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default \
``` ```
With debug logging: With debug logging:
```bash ```bash
vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default \ vaultlink -l ./vault -r wss://sync.example.com -t token123 -v default \
--log-level DEBUG --log-level DEBUG
@ -176,6 +179,7 @@ services:
## Development ## Development
Build: Build:
```bash ```bash
npm run build npm run build
# or from the parent folder, run # or from the parent folder, run
@ -183,11 +187,13 @@ docker build -f local-client-cli/Dockerfile .
``` ```
Test: Test:
```bash ```bash
npm test npm test
``` ```
Docker build: Docker build:
```bash ```bash
cd frontend cd frontend
docker build -f local-client-cli/Dockerfile -t vault-link-cli:test . docker build -f local-client-cli/Dockerfile -t vault-link-cli:test .

View file

@ -11,18 +11,16 @@
"build": "webpack --mode production", "build": "webpack --mode production",
"test": "tsx --test 'src/**/*.test.ts'" "test": "tsx --test 'src/**/*.test.ts'"
}, },
"dependencies": {
"commander": "^14.0.2",
"watcher": "^2.3.1"
},
"devDependencies": { "devDependencies": {
"@types/node": "^24.8.1", "commander": "^14.0.2",
"watcher": "^2.3.1",
"@types/node": "^25.0.2",
"sync-client": "file:../sync-client", "sync-client": "file:../sync-client",
"ts-loader": "^9.5.2", "ts-loader": "^9.5.4",
"tslib": "2.8.1", "tslib": "2.8.1",
"tsx": "^4.20.6", "tsx": "^4.21.0",
"typescript": "5.8.3", "typescript": "5.9.3",
"webpack": "^5.99.9", "webpack": "^5.103.0",
"webpack-cli": "^6.0.1" "webpack-cli": "^6.0.1"
} }
} }

View file

@ -106,8 +106,8 @@ export class FileWatcher {
} }
/** /**
* Convert a native platform path to forward slashes * Convert a native platform path to forward slashes
*/ */
private toUnixPath(nativePath: string): string { private toUnixPath(nativePath: string): string {
if (path.sep === "\\") { if (path.sep === "\\") {
return nativePath.replace(/\\/g, "/"); return nativePath.replace(/\\/g, "/");

View file

@ -185,8 +185,8 @@ export class NodeFileSystemOperations implements FileSystemOperations {
} }
/** /**
* Convert a forward-slash path to native platform path separators * Convert a forward-slash path to native platform path separators
*/ */
private toNativePath(relativePath: string): string { private toNativePath(relativePath: string): string {
if (path.sep === "\\") { if (path.sep === "\\") {
return relativePath.replace(/\//g, "\\"); return relativePath.replace(/\//g, "\\");
@ -195,8 +195,8 @@ export class NodeFileSystemOperations implements FileSystemOperations {
} }
/** /**
* Convert a native platform path to forward slashes * Convert a native platform path to forward slashes
*/ */
private toUnixPath(nativePath: string): string { private toUnixPath(nativePath: string): string {
if (path.sep === "\\") { if (path.sep === "\\") {
return nativePath.replace(/\\/g, "/"); return nativePath.replace(/\\/g, "/");

View file

@ -18,7 +18,5 @@
"declarationMap": true, "declarationMap": true,
"sourceMap": true "sourceMap": true
}, },
"exclude": [ "exclude": ["dist"]
"dist"
]
} }

Some files were not shown because too many files have changed in this diff Show more