3.7 KiB
This file provides guidance to Claude Code (claude.ai/code), Cursor, and any other Agentic coding tools when working with code in this repository.
Project Overview
This codebase is the beginning of a pretty ambitious project to build a personal server runtime/overlay OS. The idea is that users should be able to have a conceptual personal server operating system that is instantiated on several nodes that all communicate with each other and share personal documents in a decentralized way. A node might be a smartphone, a desktop or laptop PC, a browser extension, a headless server running in a cloud; and a user can have arbitrarily many nodes. Personal data could be files like PDF documents, music/video files; but also things like "how many minutes into this podcast did I listen to", "how long into this youtube video did I watch", "which Twitter/X/BlueSky/Mastodon feeds have I read and/or archived", etc.
This project is inspired by Urbit, and in particular the Urbit concept of a planet with subordinate moons - each node in this system is effectively a moon, without any central planet. Like in Urbit, each node has an individual cryptographic keypair to sign and encrypt messages; but also nodes have access to a global keypair that signifies ownership of the node at large. Eventually, different sets of nodes should be able to communicate with each other in an encrypted and authenticated way.
Project Status
This project is currently experimental. There are no backwards compatibility constraints — breaking changes to serialization formats, database schemas, wire protocols, key derivation salts, and CLI interfaces are all acceptable.
Build Commands
- Android:
./gradlew buildor./gradlew assemble - Rust:
just build-rustorcd rust && cargo build --target aarch64-linux-android --release - Run tests:
- Kotlin:
./gradlew test(unit tests),./gradlew connectedAndroidTest(instrumented) - Rust:
cargo nextest runin therustdirectory
- Kotlin:
- Run single test:
./gradlew test --tests "ExampleUnitTest.testName"
Code Style
- Errors: Use typed errors with meaningful messages. In rust, prefer
thiserror. - the justfile codifies recipes that run standard Rust and Kotlin formatters (just fmt-kotlin, just fmt-rust). Run these tools to keep code formatted on every commit.
- don't generate code that has fully-qualified type names (e.g.
documents::Artifacts::new()); instead prefer touse documents::Artifacts,Artifacts::new() - Naming: camelCase for variables/functions, PascalCase for classes/interfaces
- Architecture: Jetpack Compose for UI, JNI for Rust integration
- Types: Use explicit types for public APIs, leverage type inference for local variables
- Slint: Prefer to create components built out of functional subcomponents with meaningful names, instead of long components with no internal structure. Prefer to define named constants instead of using the same color, spacing, etc. values in-situ. Don't define default values for properties unless necessary. Prefer to create text elements that have copy-able text; as of Slint 1.16 the best way to do this is by using the TextInput component with read-only: true.
- When displaying hex-encoded hashes, do not truncate the hash
VCS Workflow
- This project uses Jujutsu (jj) with a git backend. Prefer
jjcommands overgitwhen the checkout is a Jujutsu repo (check for.jj/directory). If only git is available (e.g. a plain git clone), git commands are fine. - Prefer small, self-contained commits over large monolithic ones
- Each commit should represent a single logical change
- Use as many individual commits as necessary to implement a feature
- This makes code review easier and enables cleaner git history/bisection