Skip to content
Merged
Show file tree
Hide file tree
Changes from 36 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
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
/dotnet-tui/ @busec0 @kristopherjohnson
/dotnet-winforms/ @busec0 @kristopherjohnson
/flutter_app/ @pvditto @teodorciuraru
/go-tui/ @kristopherjohnson
/java-spring/ @phatblat @busec0
/java-server/ @russhwolf @phatblat @busec0
/javascript-tui/ @konstantinbe @pvditto @teodorciuraru
/javascript-web/ @konstantinbe @pvditto @teodorciuraru
Expand Down
2 changes: 2 additions & 0 deletions go-tui/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[{*.go,*.go2}]
indent_style = tab
5 changes: 5 additions & 0 deletions go-tui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ditto-tasks-termui
go-tui
*.log
*.out
go-sdk/
81 changes: 81 additions & 0 deletions go-tui/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Makefile for Ditto QuickStart Go TUI Tasks application

# Display help information
.PHONY: help
help:
@echo "Ditto Go TUI Tasks Application"
@echo ""
@echo "Available targets:"
@echo " build - Build the FFI library and application"
@echo " run - Build and run the application"
@echo " run-go - Run directly with 'go run'"
@echo " clean - Remove build artifacts"
@echo " help - Show this help message"
@echo ""
@echo "Note: Ensure .env file exists with proper Ditto configuration"

GO=go

# Ditto SDK version and platform detection
#DITTO_SDK_VERSION ?= 5.0.0-go-preview.1
DITTO_SDK_VERSION ?= 5.0.0-experimental-go-publish.10
PLATFORM := $(shell uname -s | tr '[:upper:]' '[:lower:]')
ARCH := $(shell uname -m)

# Determine Ditto SDK platform string
ifeq ($(PLATFORM),linux)
DITTO_PLATFORM = linux-$(ARCH)
else ifeq ($(PLATFORM),darwin)
DITTO_PLATFORM = macos-aarch64

# avoid version mismatch warnings when linking
export MACOSX_DEPLOYMENT_TARGET := 11.0
export CGO_CFLAGS := -mmacosx-version-min=11.0
export CGO_LDFLAGS := -mmacosx-version-min=11.0
else
$(error Unsupported platform: $(PLATFORM))
endif

DITTO_SDK_URL = "https://software.ditto.live/go-$(DITTO_PLATFORM)/Ditto/$(DITTO_SDK_VERSION)/libs/libdittoffi-$(DITTO_PLATFORM).tar.gz"

# Build the application
.PHONY: build
build: go-sdk ditto-tasks-termui

ditto-tasks-termui: main.go redirect_unix.go redirect_windows.go widgets.go Makefile go.mod go.sum
@echo "Building ditto-tasks-termui..."
$(GO) mod tidy
$(GO) build -o ditto-tasks-termui -ldflags='-extldflags "-L./go-sdk"'

.PHONY: go-sdk
go-sdk: ## Downloads and installs the Ditto Go SDK library to go-sdk directory
@ if [ ! -f go-sdk/libdittoffi.so ] && [ ! -f go-sdk/libdittoffi.dylib ] ; then \
echo "📥 Downloading Ditto Go SDK v$(DITTO_SDK_VERSION) for $(DITTO_PLATFORM) $(DITTO_SDK_URL)..."; \
mkdir -p go-sdk; \
if curl -L -f $(DITTO_SDK_URL) | tar xz --strip-components=0 -C go-sdk/; then \
echo "✅ Ditto Go SDK v$(DITTO_SDK_VERSION) installed successfully"; \
else \
echo "❌ Failed to download SDK for $(DITTO_PLATFORM)"; \
fi; \
else \
echo "✅ Ditto Go SDK already installed"; \
fi

# Run the application (built binary)
.PHONY: build
run: build
@echo "Running ditto-tasks-termui..."
LD_LIBRARY_PATH="$$(pwd)/go-sdk" DYLD_LIBRARY_PATH="$$(pwd)/go-sdk" ./ditto-tasks-termui 2>/dev/null

# Run directly with Go
.PHONY: run-go
run-go:
@echo "Running ditto tasks-termui with go run..."
LD_LIBRARY_PATH="$$(pwd)/go-sdk" DYLD_LIBRARY_PATH="$$(pwd)/go-sdk" $(GO) run main.go 2>/dev/null

# Clean build artifacts
.PHONY: clean
clean:
@echo "Cleaning ditto-tasks-termui and build artifacts..."
rm -f ditto-tasks-termui
rm -rf go-sdk
139 changes: 139 additions & 0 deletions go-tui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# 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

Create a `.env` file in this directory with your Ditto credentials:

```bash
# Create .env file
cat > .env << 'EOF'
DITTO_APP_ID=your-app-id
DITTO_PLAYGROUND_TOKEN=your-playground-token
DITTO_AUTH_URL=https://your-app-id.cloud.ditto.live
EOF
```

Alternatively, you can set these as environment variables:

```bash
export DITTO_APP_ID="your-app-id"
export DITTO_PLAYGROUND_TOKEN="your-playground-token"
export DITTO_AUTH_URL="https://your-app-id.cloud.ditto.live"
```

## Building

From this directory (`go-tui`):

```bash
# Using the Makefile
make build

# Or build directly with Go
go build -o ditto-tasks-termui
```


## Running

**Note:** the Ditto Go SDK `libdittoffi.so` (Linux) or `libdittoffi.dylib`
shared library must be present and in one of the directories searched by the
system's dynamic linker to run the application. This is handled automatically
by `make run`. If you use one of the other options, you may need to perform
additional steps. See the [Go SDK Install Guide](https://docs.ditto.live/sdk/latest/install-guides/go)
for details.

Run the quickstart app with the following command:


```bash
# Using the Makefile (which will download the shared library and set shared-library load paths automatically)
make run
```

```bash
# Run the executable that was created via make build
./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


## Troubleshooting

### Logs

To find errors and messages that are not printed to the TUI display, check the application logs.
Logs are output to `/tmp/ditto-tasks-termui.log`.

### libdittoffi Library not found

If you get a library loading error, ensure that the `libdittoffi.so` (Linux) or
`libdittoffi.dylib` (macOS) shared library is present and that `LD_LIBRARY_PATH`
(Linux) or `DYLD_LIBRARY_PATH` (macOS) is set appropriately.

### Environment variables not found

The app looks for a `.env` file in the current directory. Ensure it exists with
all required variables set, or export them as environment variables.

### 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://github.com/getditto/ditto-go-sdk) for edge sync
- Channels for async communication between Ditto observers and the UI

## Architecture

The app follows an event-driven architecture:
- Direct event loop handling keyboard input
- Table widget for displaying tasks (similar to Rust's ratatui)
- Manual text input handling for create/edit modes
- Async updates from Ditto observers via Go channels
- Real-time sync with other Ditto peers running the same app
22 changes: 22 additions & 0 deletions go-tui/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module github.com/getditto/quickstart/go-tui/ditto-tasks-termui

go 1.24.0

require (
github.com/getditto/ditto-go-sdk/v5 v5.0.0-experimental-go-publish.10
github.com/gizak/termui/v3 v3.1.0
github.com/google/uuid v1.6.0
github.com/joho/godotenv v1.5.1
golang.org/x/sys v0.37.0
golang.org/x/term v0.36.0
)

require (
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/nsf/termbox-go v1.1.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
)
30 changes: 30 additions & 0 deletions go-tui/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/getditto/ditto-go-sdk/v5 v5.0.0-experimental-go-publish.10 h1:yXmgeTUVdVY/pBBW35cFBWA7xFEr2aPQ4LjatIRdid8=
github.com/getditto/ditto-go-sdk/v5 v5.0.0-experimental-go-publish.10/go.mod h1:LFVfgkbjAENnhaxjd4rUfOUVOH7BC3yEuKCo1Ps/Kbg=
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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY=
github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
Loading
Loading