Development
Prerequisites
- Node.js 20+
- Rust (latest stable)
- Tauri prerequisites
Setup
# Clone the repo
git clone https://github.com/sorenwacker/nodus.git
cd nodus
# Install dependencies
npm install
# Start development server
make dev
Commands
| Command | Description |
|---|---|
make dev |
Start development server |
npm test |
Run tests |
npm run lint |
Lint code |
npm run build |
Build frontend |
npm run tauri build |
Build for production |
cargo test |
Run Rust tests (in src-tauri/) |
cargo clippy |
Lint Rust code |
Project Structure
nodus/
├── src/ # Vue frontend
│ ├── canvas/ # Canvas rendering (DOM, SVG, Canvas 2D)
│ ├── components/ # Vue components
│ ├── composables/ # Vue composables
│ ├── stores/ # Pinia state management
│ ├── llm/ # LLM integration
│ └── lib/ # Utility libraries
├── src-tauri/ # Rust backend
│ └── src/
│ ├── database.rs # SQLite operations
│ ├── watcher.rs # File system watcher
│ └── commands.rs # Tauri commands
└── docs/ # Documentation
Tech Stack
| Layer | Technology |
|---|---|
| Desktop | Tauri v2 |
| Frontend | Vue 3 + TypeScript |
| Canvas | DOM cards, SVG edges, and a 2D canvas above the level-of-detail threshold |
| Database | SQLite via sqlx |
| Math | Typst WASM |
Logging
The application uses a structured logging system with namespace prefixes.
Log Levels
| Environment | Default Level | Shows |
|---|---|---|
| Development | info |
info, warn, error |
| Production | warn |
warn, error |
Namespaces
| Logger | Prefix | Usage |
|---|---|---|
appLogger |
[Nodus] |
General application logs |
storeLogger |
[Store] |
Pinia store operations |
canvasLogger |
[Canvas] |
Canvas rendering |
agentLogger |
[Agent] |
LLM agent operations |
Usage
import { storeLogger } from '../lib/logger'
storeLogger.debug('Verbose debugging info') // Only in development
storeLogger.info('General information') // Development only
storeLogger.warn('Warning message') // Always shown
storeLogger.error('Error occurred', error) // Always shown
Known dependency advisory
glib 0.18 carries a medium-severity unsoundness advisory (VariantStrIter). It
cannot be upgraded from this repository: Tauri 2.11.5, the latest release, pins
it transitively through gtk 0.18 and muda. Nodus contains no direct glib
usage and never calls the affected API, and the issue is Linux-only. The alert is
dismissed as tolerable risk and should be revisited when Tauri's gtk stack moves
to glib 0.20.
Release signing
Two independent signatures matter, and neither is configured in this repository because both require credentials the maintainer holds.
Update signatures (required for auto-update)
The updater refuses any payload whose signature does not verify, so the release pipeline needs a keypair:
npm run tauri signer generate -- -w ~/.nodus-updater.key- Put the public key in
src-tauri/tauri.conf.jsonunderplugins.updater.pubkey, replacing the placeholder. - Add the private key and its password as the repository secrets
TAURI_SIGNING_PRIVATE_KEYandTAURI_SIGNING_PRIVATE_KEY_PASSWORD.
Until the keypair exists, bundle.createUpdaterArtifacts stays false and
plugins.updater.pubkey stays empty. A placeholder public key is worse than no
key: Tauri finds it, demands the matching private key, and fails the build.
Set both when you add the key:
bundle.createUpdaterArtifactstotrueplugins.updater.pubkeyto the generated public key
The release then publishes a signed latest.json; without them it publishes
installers only, and the in-app update check stays silent.
Distribution signatures (removes the install warnings)
Unsigned builds are the largest avoidable loss of users: macOS reports an unidentified developer and Windows SmartScreen warns before the first run.
- macOS needs an Apple Developer account. Add
APPLE_CERTIFICATE,APPLE_CERTIFICATE_PASSWORD,APPLE_SIGNING_IDENTITY,APPLE_ID,APPLE_PASSWORDandAPPLE_TEAM_IDas repository secrets, then add the same names to theenvblock of the release job. Add them together: declaring the variables while the secrets are unset makestauri-actionattempt a certificate import with an empty value, which fails the macOS build. - Windows needs a code-signing certificate; set
bundle.windows.certificateThumbprintintauri.conf.json, or supply the certificate to the signing step.