Tauri + SolidJS desktop app for controlling the Manafish ROV. Rust backend in
src-tauri/, TypeScript/SolidJS frontend in src/. Consumes the
@manafishrov/ui component library.
- Bun + TypeScript, Vite, SolidJS, TanStack Router/Form
- Tauri v2 (Rust)
- Tailwind v4, oxlint, oxfmt
- Vitest
- Nix flake for the dev shell (
nix developor direnv)
src/— UI:components/,features/,routes/,stores/,lib/,tauri/src-tauri/— Rust backend (system access, ROV comms)src-yolo/— experimental sandbox; not shippedmessages/,i18n.inlang/— Paraglide translationspublic/,app-icon.png— static assets
- Install:
bun install - Dev (full app):
bun run tauri dev - Dev (frontend only):
bun run dev - Build:
bun run tauri build
bun run fmt:check # frontend
bun run lint # frontend (oxlint, type-aware)
bun run fmt:rs:check # rust
bun run lint:rs # rust (clippy)
bun run test # vitestAuto-fix variants: fmt, lint:fix, fmt:rs, lint:rs:fix.
- Never access OS/hardware from the frontend — go through Tauri commands in
src/tauri/and Rust handlers insrc-tauri/src/. - Keep concerns separated: data → store → feature → component.
- Match existing patterns. Don't add dependencies without reason.
- Name wrapper components that build around an
@manafishrov/uiprimitive with the primitive component name at the end, e.g.SubmitButton,InfoTextInput,ShutdownAlertDialog, orFruitSelect. - Use strict types; never
as any,@ts-ignore, or@ts-expect-error. - Never commit secrets or hardcode local paths.
- Don't push without being asked. CI runs on push to
main.
Never cut a release without being explicitly asked, and confirm the version and release notes back to the user before doing anything.
- Releases for
appare independent offirmware. Do not match versions. - Bump all of these to the same version in one commit:
src-tauri/Cargo.toml→[package] versionsrc-tauri/Cargo.lock(regenerated bycargo build/cargo update -p manafish)src-tauri/tauri.conf.json→"version"src-tauri/com.manafishrov.manafish.metainfo.xml→ add a new<release>entry (required for Flathub; the AppStream listing reads it)
- Commit message:
chore(release): vX.Y.Z. - Tag:
git tag vX.Y.Zthengit push --tags— pushing the tag triggers.github/workflows/build.yamlwhich builds macOS/Linux/Windows artifacts and creates a draft GitHub release. Edit and publish manually. - Pre-releases use
vX.Y.Z-rc.N(or similar) and are auto-marked prerelease.
Linux packages bundle a custom WebKitGTK built with ENABLE_WEB_RTC (distro
builds compile it out, which leaves RTCPeerConnection undefined and breaks
the live video feed). The release workflow builds it automatically via
.github/workflows/build-webkitgtk.yaml when the
ghcr.io/manafishrov/webkitgtk-webrtc package is missing the version tag
(one-time ~4h per version), then reuses the published tarballs. The package
must be set to public visibility (one-time, GitHub UI) so it can be pulled
anonymously.
To bump the WebKitGTK version (new release or CVE), update it in both:
.github/workflows/build.yaml→webkitgtkjobwith: version.github/workflows/build-webkitgtk.yaml→workflow_dispatchinput default
The next release tag rebuilds and bundles it automatically.
Workflow before tagging: confirm the bumped version with the user, confirm the release notes text, then commit, tag, push.
Conventional Commits, focused on why.
<type>(<scope>): <subject>
[body explaining why, ~72 char wrap]
- Types:
feat,fix,refactor,perf,docs,chore,ci,build,revert.chore(deps)reserved for Renovate. - Scopes:
frontend,tauri,ui,i18n,routes,stores,flake,ci. - Subject: imperative, lowercase, ≤72 chars, no period.
- Body when the why isn't obvious from the subject.
If you change scripts, add a top-level directory, swap a tool, or alter the quality gates — update this file in the same commit.