Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0ae11f0
Added a basic go-tui app that mirrors the rust-tui app
bigfish24 Aug 11, 2025
bfeb02a
Added one-liner to run
bigfish24 Aug 11, 2025
b04cd96
feat: migrate go-tui to v5 Config-based Ditto API
kristopherjohnson Aug 12, 2025
44407a3
style: apply go fmt formatting to main.go
kristopherjohnson Aug 12, 2025
2e5f8c4
refactor: apply Go-idiomatic improvements to go-tui
kristopherjohnson Aug 12, 2025
1f56d2d
chore: add .gitignore for go-tui executables
kristopherjohnson Aug 12, 2025
eb3411f
docs: remove go-tui executable references, use only ditto-tasks-termui
kristopherjohnson Aug 12, 2025
dda9498
feat: integrate new Go SDK authentication API
kristopherjohnson Aug 12, 2025
090fe31
fix: update imports for flattened Ditto Go SDK structure
kristopherjohnson Aug 12, 2025
b9818ff
refactor: update config type to DittoConfig
kristopherjohnson Aug 12, 2025
0e4b049
fix: update to use ServerConnect instead of deprecated OnlinePlaygrou…
kristopherjohnson Aug 13, 2025
45c6bf0
refactor: modernize logging and platform support
kristopherjohnson Aug 13, 2025
be2d714
fix: resolve terminal UI display issues and clean up debug code
kristopherjohnson Aug 13, 2025
2c95aee
refactor: remove call to deprecated DisableSyncWithV3
kristopherjohnson Aug 15, 2025
a5b81e9
chore(go-tui): make the path to the Go SDK machine-independent
kristopherjohnson Aug 18, 2025
dfab631
chore(go-tui): remove unnecessary call to `UpdateTransportConfig()`
kristopherjohnson Aug 18, 2025
f04c63e
fix(go-tui): update API calls to match Go SDK v5 interface
kristopherjohnson Aug 21, 2025
fbb05db
fix(go-tui): update ServerConnect to DittoConfigConnectServer
kristopherjohnson Aug 21, 2025
ba11526
fix(go-tui): update sync API calls to use new Sync type methods
kristopherjohnson Aug 21, 2025
6b1dd4d
perf(go-tui): use Items() method instead of iterating GetItem()
kristopherjohnson Aug 22, 2025
451d5b7
chore(go): rename Go quickstart executable to `ditto-tasks-termui`
kristopherjohnson Aug 26, 2025
ba988f6
chore(go): add dsharp-pivotal to CODEOWNERS for go-tui
kristopherjohnson Aug 26, 2025
9e39ddf
go-tui: Use os.DevNull for name of /dev/null
dsharp-pivotal Aug 26, 2025
390fbfc
go-tui: Use channels over Mutex in the App struct
dsharp-pivotal Aug 26, 2025
4f183bc
go-tui: Clear highlight from non-selected rows
dsharp-pivotal Aug 26, 2025
603b78b
go-tui: Shrink the selector and done columns to fixed sizes
dsharp-pivotal Aug 26, 2025
c2fe91d
go-tui: Re-render on terminal resize
dsharp-pivotal Aug 26, 2025
fbcda3c
go-tui: Update input box size
dsharp-pivotal Aug 26, 2025
bee75f1
git-tui: Handle all ui events in handleEvent; fix "q" in edit modes
dsharp-pivotal Aug 27, 2025
7a206cb
resolve CODEOWNERS merge conflicts
kristopherjohnson Nov 3, 2025
78ea368
update go-tui for Go SDK public preview.1
kristopherjohnson Nov 3, 2025
30b8bc5
Delete GO_IMPROVEMENTS.md
kristopherjohnson Nov 3, 2025
75c1e17
use downloaded libraries and Go module
kristopherjohnson Nov 5, 2025
265a72f
Update SDK version to 5.0.0-experimental-go-publish.10
kristopherjohnson Nov 6, 2025
85e06b9
remove `replace` directive
kristopherjohnson Nov 6, 2025
fabfb34
Merge branch 'main' into kj/go-tui
kristopherjohnson Nov 6, 2025
f4e9bd7
Update go-tui/Makefile
kristopherjohnson Nov 6, 2025
e818f70
update to 5.0.0-go-preview.3
kristopherjohnson Nov 17, 2025
a875699
Merge branch 'kj/go-tui' of github.com:getditto/quickstart into kj/go…
kristopherjohnson Nov 17, 2025
e22053f
Apply suggestion from @Copilot
kristopherjohnson Nov 17, 2025
1bb06da
Enable the `ditto.SetMinimumLogLevel()` line which was causing segfau…
kristopherjohnson Nov 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
/dotnet-maui/ @busec0 @phatblat
/dotnet-tui/ @busec0 @phatblat
/flutter_quickstart/ @cameron1024 @teodorciuraru
/go-tui/ @kristopherjohnson
/javascript-tui/ @konstantinbe @pvditto @teodorciuraru
/javascript-web/ @konstantinbe @pvditto @teodorciuraru
/react-native/ @teodorciuraru @kristopherjohnson
Expand Down
144 changes: 144 additions & 0 deletions go-tui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Ditto Go Quickstart App 🚀

This directory contains Ditto's quickstart app for the Go SDK.
This app is a Terminal User Interface (TUI) that allows for creating
a todo list that syncs between multiple peers.

## Getting Started

To get started, you'll first need to create an app in the [Ditto Portal][0]
with the "Online Playground" authentication type. You'll need to find your
AppID and Online Playground Token, Auth URL, and Websocket URL in order to use this quickstart.

[0]: https://portal.ditto.live

From the repo root, copy the `.env.sample` file to `.env`, and fill in the
fields with your AppID, Online Playground Token, Auth URL, and Websocket URL:

```
cp ../../.env.sample ../../.env
```

The `.env` file should look like this (with your fields filled in):

```bash
#!/usr/bin/env bash

# Copy this file from ".env.sample" to ".env", then fill in these values
# A Ditto AppID, Online Playground Token, Auth URL, and Websocket URL can be obtained from https://portal.ditto.live
export DITTO_APP_ID=""
export DITTO_PLAYGROUND_TOKEN=""
export DITTO_AUTH_URL=""
export DITTO_WEBSOCKET_URL=""
```

## Building

Build the FFI library (required for Ditto SDK):
```bash
(cd ../../ditto/sdks/go && make build) && go build -o go-tui main.go && ./go-tui 2>/dev/null
```

Build the application:
```bash
go build -o ditto-tasks-termui
```

## Running

Run the quickstart app with the following command:

```bash
./ditto-tasks-termui 2>/dev/null
```

Or run directly with Go:
```bash
go run main.go 2>/dev/null
```

> NOTE: The `2>/dev/null` is a workaround to silence output on `stderr`, since
> that would interfere with the TUI application. Without it, the screen will
> quickly become garbled due to Ditto's internal logging.

## Controls

- **j/↓**: Move down
- **k/↑**: Move up
- **Enter/Space**: Toggle task completion
- **c**: Create new task
- **e**: Edit selected task
- **d**: Delete selected task
- **q**: Quit application
- **Esc**: Cancel input mode

## Features

- ✅ Create, edit, and delete tasks
- ✅ Mark tasks as complete/incomplete
- ✅ Real-time synchronization across devices
- ✅ Terminal-based interface using termui
- ✅ Cross-platform compatibility with other Ditto quickstart apps

## Data Model

Tasks are stored in a `tasks` collection with the following structure:
```json
{
"_id": "unique-task-id",
"title": "Task description",
"done": false,
"deleted": false
}
```

This matches the data model used by other quickstart apps (Rust, C++, etc.) for cross-platform sync compatibility.

## UI Features

The TUI displays tasks in a table format with:
- Selection indicator (❯❯) for the currently selected task
- Checkboxes showing task status (✅ for done, ☐ for not done)
- Modal overlay for creating and editing tasks
- Keyboard shortcut hints in the status bar

## Troubleshooting

### Library not found
If you get a library loading error, ensure the FFI library is built and available:
```bash
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../ditto/sdks/go/build
```

On macOS, you may need to use `DYLD_LIBRARY_PATH` instead:
```bash
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:../../ditto/sdks/go/build
```

### Environment variables not found
The app looks for `.env` file in parent directories. Ensure it exists in the repository root with all required variables set.

### Garbled screen output
Always run the application with `2>/dev/null` to suppress stderr output that can interfere with the TUI display:
```bash
./ditto-tasks-termui 2>/dev/null
```

## Development

The application uses:
- [termui v3](https://github.com/gizak/termui) for the TUI framework (similar to Rust's ratatui)
- [Ditto Go SDK](https://docs.ditto.live) for real-time sync
- Channels for async communication between Ditto observers and the UI

## Architecture

The app follows an event-driven architecture similar to the Rust TUI implementation:
- Direct event loop handling keyboard input
- Table widget for displaying tasks
- Manual text input handling for create/edit modes
- Async updates from Ditto observers via Go channels

## License

MIT
23 changes: 23 additions & 0 deletions go-tui/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module github.com/getditto/quickstart/go-tui

go 1.23.0

toolchain go1.24.5

require (
github.com/getditto/ditto-go-sdk v0.0.0
github.com/gizak/termui/v3 v3.1.0
github.com/google/uuid v1.6.0
github.com/joho/godotenv v1.5.1
)

replace github.com/getditto/ditto-go-sdk => /Users/kristopherjohnson/work/go-sdk/sdks/go

require (
github.com/fxamacker/cbor/v2 v2.5.0 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/x448/float16 v0.8.4 // indirect
)
28 changes: 28 additions & 0 deletions go-tui/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc=
github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading