Cairn desktop client — Windows, macOS and Linux from one Go codebase. Phase 1: sync engine core.
Find a file
Nikola Somborski 5ed3204163
All checks were successful
ci / test (push) Successful in 18s
interop / integration (push) Successful in 53s
fix(watch): report a truncation that kqueue raises as NOTE_ATTRIB alone
The watcher dropped every Chmod-only event. On kqueue a truncation goes
through setattr and raises only NOTE_ATTRIB, so on macOS truncate and
ftruncate changed a file's content with no event, and only the periodic
rescan caught it.

Where the backend is kqueue, the watcher now records each watched file's
size and modification time before its folder's watch is added, and on
every event after. An attribute-only event is reported when either one
moved, or when the file was never seen; it is still dropped when both
are unchanged, as for a mode change or the extended attributes macOS
updates on open. inotify reports a truncation as a write, so on Linux
Chmod-only events are still dropped outright and no stamps are kept.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Nikola Somborski <Nsomborski1995@gmail.com>
2026-09-14 07:09:29 +02:00
.forgejo/workflows fix(ci): keep a killed interop run's test files and processes reclaimable 2026-09-11 22:36:38 +02:00
build/icons feat(frontend): design system, mark states and screen designs 2026-09-14 05:02:36 +02:00
cmd/cairnsync fix(sync): refuse a pass when one side lists nothing but files were synced 2026-09-11 22:29:46 +02:00
docs docs: main-window mockup as the visual target for the design system 2026-09-10 18:30:50 +00:00
frontend feat(frontend): design system, mark states and screen designs 2026-09-14 05:02:36 +02:00
internal fix(watch): report a truncation that kqueue raises as NOTE_ATTRIB alone 2026-09-14 07:09:29 +02:00
test/integration fix(integration): leave the client's request body to the proxy's server 2026-09-11 18:45:00 +02:00
.gitignore Initial commit 2026-09-10 17:10:21 +00:00
CLAUDE.md docs: CLAUDE.md lists the phase-1 hand-off amendments on #22, #23, #25, #26 2026-09-11 03:55:28 +02:00
go.mod feat(watch): debounced recursive filesystem watcher 2026-09-14 06:32:13 +02:00
go.sum feat(watch): debounced recursive filesystem watcher 2026-09-14 06:32:13 +02:00
LICENSE chore: scaffold module, GPLv3 licence, CI 2026-09-10 21:01:12 +02:00
README.md docs: README with status, layout, tests, DCO and licence 2026-09-11 02:39:01 +02:00

cairn-desktop

The desktop sync client for Cairn, a self-hosted file server. Windows, macOS and Linux are built from one Go codebase.

Status

Phase 1 of 4 (phase-1-engine): the three-way sync engine core, in pure Go, in-memory and property-tested. The real WebDAV remote, the real filesystem and the CLI arrive in phase 2, the desktop app in phase 3, and files-on-demand in phase 4. Nothing ships before v1.0, at the end of phase 4.

Layout

internal/sync/    the three-way sync engine: no OS, network or UI imports (arch_test.go enforces it)
internal/vfs/     filesystem interface + in-memory implementation
internal/remote/  Cairn server interface + in-memory implementation
internal/state/   SQLite store of last-synced state (pure-Go driver)

Running the tests

CGO_ENABLED=0 go test ./...

You need Go 1.25 or newer. CGO_ENABLED=0 always applies, so no dependency may require cgo. CI runs go vet, then the tests, then prints coverage.

Contributing

Every commit needs a DCO sign-off: git commit -s. Read CLAUDE.md first: it holds the constraints, the workflow and the order of work. The full design is in docs/design-spec.md.

Licence

GPLv3. See LICENSE.