This is the Go rewrite of qtools with TUI support, following the implementation plan in .cursor/plans/go_tools_rewrite_with_tui.plan.md.
-
Phase 1: Foundation & Config Management
- ✅ Go module initialization
- ✅ Directory structure
- ✅ Config system with auto-migration (
internal/config/)paths.go- Path managementconfig.go- Config structsloader.go- Config loading/savingmigrations.go- Migration systemgenerator.go- Default config generation
-
Phase 2: Node Setup
- ✅ Node config types (
internal/node/config_types.go) - ✅ Node config manager (
internal/node/config.go) - ✅ Config operations (
internal/node/config_operations.go) - ✅ Mode detection (
internal/node/mode.go) - ✅ Node setup (
internal/node/setup.go) - ✅ Node commands (
internal/node/commands.go) - ✅ Installation scaffolding (
internal/node/install.go)
- ✅ Node config types (
-
Phase 3: Service Management
- ✅ Service options (
internal/service/options.go) - ✅ Service manager (
internal/service/manager.go) - ✅ Platform detection (
internal/service/platform.go) - ✅ Systemd integration (
internal/service/systemd.go) - ✅ Launchd integration (
internal/service/launchd.go) - ✅ Plist generation (
internal/service/plist.go) - ✅ Worker management (
internal/service/workers.go)
- ✅ Service options (
-
Phase 4: CLI Interface
- ✅ Basic CLI structure with Cobra (
cmd/qtools/main.go) - ✅ Node commands (setup, mode, install)
- ✅ Service commands (start, stop, restart, status)
- ✅ TUI command integration
- ✅ Basic CLI structure with Cobra (
-
Phase 5: TUI Implementation
- ✅ Main TUI app (
internal/tui/app.go) - ✅ Node setup view (
internal/tui/views/node_setup.go) - ✅ Service control view (
internal/tui/views/service_control.go) - ✅ Status view (
internal/tui/views/status.go) - ✅ Log view (
internal/tui/views/log_view.go) - ✅ Components (menu, core input)
- ✅ Log filtering (
internal/log/filters.go,internal/log/viewer.go)
- ✅ Main TUI app (
-
Phase 6: Desktop Integration (Stubs)
- ✅ Messaging stub (
internal/messaging/stub.go) - ✅ Node client (
internal/client/node_client.go)- Binary command support (works when node is stopped)
- gRPC support stub (for when node is running)
- Hybrid approach (tries gRPC first, falls back to binary)
- ✅ Messaging stub (
-
Phase 2: Node Setup
- ⏳ Complete
install.goimplementation (download binaries, create users/groups, etc.)
- ⏳ Complete
-
Phase 4: CLI Interface
- ⏳ Implement actual command handlers (currently stubs)
- ⏳ Log commands
- ⏳ Config commands
-
Phase 6: Desktop Integration
- ⏳ Implement actual Quilibrium Messaging integration
- ⏳ Full gRPC client implementation
- ⏳ Desktop app SDK/examples
cd go-tools
CGO_ENABLED=0 GOOS=linux GOARCH=$(go env GOARCH) go build -o qtools ./cmd/qtoolsUse the helper script to upload local binaries to QStorage and rotate bucket paths:
- Existing objects in
<prefix>/current/are moved to<prefix>/old/<timestamp>/ - New artifacts are uploaded to
<prefix>/current/
cd go-qtools
task build:docker:all
task upload:qstorageYou can also run the script directly:
cd go-qtools
./scripts/upload-qstorage-build.sh \
--bucket <bucket-name> \
--access-key-id <access-key-id> \
--access-key <access-key>Defaults:
- Region:
q-world-1 - Endpoint:
https://qstorage.quilibrium.com - Prefix:
qtools/dev-builds - Artifacts:
dist/qtoolsanddist/qtools-arm64
# CLI
./qtools --help
./qtools node setup --help
./qtools service start --help
# TUI
./qtools tuiYou can run distro-level functional testing against fresh binary builds with Incus:
cd go-qtools
task test:functional:incusWhat this does:
- Builds a fresh
qtoolsbinary (dist/qtools-functional) - Launches Incus containers for Ubuntu LTS and Debian stable
- Optionally runs a lightweight distro (Alpine) in best-effort mode
- Runs
qtools node installand validates installation outcomes:- node directory created
- node binary installed and executable
/usr/local/bin/quilibrium-nodesymlink created and onPATH- qtools config generated
Useful environment variables:
SKIP_BUILD=1to reuse an existing binaryBINARY_PATH=/path/to/qtoolsto test a specific binaryINCLUDE_LIGHTWEIGHT=0to skip lightweight distro checksKEEP_CONTAINERS=1to preserve containers for debugging
Qtools supports shell completion for bash, zsh, fish, and PowerShell.
Automatic installation (recommended):
Simply run qtools completion without arguments. Qtools will:
- Auto-detect your shell
- Prompt you if detection fails
- Install completions permanently
# Auto-detect and install
qtools completion
# Or specify shell explicitly
qtools completion bash
qtools completion zsh
qtools completion fishGenerate completion script (for manual installation):
If you prefer to install manually, use the --generate flag:
# Generate to stdout
qtools completion bash --generate > ~/.local/share/bash-completion/completions/qtools
# Or use the installation script
./scripts/install-completion.sh bashPowerShell:
PowerShell completion requires manual setup:
qtools completion powershell --generate | Out-String | Invoke-Expression
# Or add to profile:
qtools completion powershell --generate | Out-String | Add-Content $PROFILEAfter installation, restart your shell or source the completion file as instructed.
The project follows the structure defined in the plan:
go-tools/
├── cmd/qtools/ # CLI entry point
├── internal/
│ ├── config/ # Config management
│ ├── node/ # Node setup and management
│ ├── s3/ # S3/QStorage client library
│ ├── service/ # Service management
│ ├── log/ # Log viewing and filtering
│ ├── tui/ # TUI implementation
│ ├── messaging/ # Desktop integration stub
│ └── client/ # Node client library
- Dynamic Config System: Auto-migrating config with programmatic defaults
- Manual Mode Default: Opinionated default for better reliability (each worker as separate service)
- Cross-platform: Linux (systemd) and macOS (launchd) support
- TUI Support: Full Bubble Tea-based TUI interface
- Service Management: Complete service control for master and workers
- Log Viewing: Real-time log tailing with filtering support
- QStorage Integration: Fetch credentials and backup to Quilibrium's S3-compatible storage
- Key Migration: Go-native implementation of key data migration from config files
Commands are organized into separate branches:
-
qtools node- All node-related commands:node setup- Setup nodenode install- Complete installationnode download- Download node binarynode update- Update node binarynode config- Node configuration managementnode backup- Backup node data to QStorage (S3)node restore- Restore node data from QStorage (S3)node info- Get node informationnode peer-id- Get peer IDnode balance- Get balancenode seniority- Get senioritynode worker-count- Get worker count
-
qtools qclient- All qclient-related commands:qclient download- Download qclient binary- (More qclient commands coming: transfer, merge, split, coins, account, etc.)
-
Other top-level commands:
qtools service- Service management (start, stop, restart, status)qtools config- Qtools configuration managementqtools toggle- Toggle settings (auto-updates, etc.)qtools util- Utility commands (public-ip, etc.)qtools logs- Log viewing and managementqtools backup- Backup and restore (local/peer)qtools diagnostics- Diagnostic commandsqtools update- Update commandsqtools completion- Shell completionqtools tui- Launch TUI mode
Qtools integrates with Quilibrium's QStorage service (S3-compatible) for backing up and restoring node data.
Before using the backup/restore commands, you need to set up a QStorage (or S3-compatible) account with the following:
- Create a user with programmatic access (access key ID + access key).
- Create a bucket to store your node backups.
- Attach an S3 read/write policy to the user, scoped to the bucket. At minimum the user needs permissions for
s3:GetObject,s3:PutObject,s3:DeleteObject, ands3:ListBucketon the target bucket.
Example S3 policy (adjust your-bucket-name as needed):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::your-bucket-name/*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::your-bucket-name"
}
]
}Tip: Create a dedicated user per node rather than reusing credentials across nodes. This limits the blast radius if a key is compromised.
| Setting | Default Value |
|---|---|
| Region | q-world-1 |
| Endpoint | https://qstorage.quilibrium.com |
These defaults can be overridden per-command via flags or saved in the qtools config.
The S3 bucket mirrors the local $QUIL_NODE_PATH/.config/ directory structure directly:
<bucket>/
├── <prefix>/ # Optional user-provided root prefix
│ ├── config.yml # Node configuration
│ ├── keys.yml # Node keys
│ ├── store/ # Master store data
│ └── worker-store/ # Worker store data
│ ├── 1/ # Worker 1
│ ├── 2/ # Worker 2
│ └── ...
| S3 Path | Local Path |
|---|---|
<prefix>/config.yml |
$QUIL_NODE_PATH/.config/config.yml |
<prefix>/keys.yml |
$QUIL_NODE_PATH/.config/keys.yml |
<prefix>/store/ |
$QUIL_NODE_PATH/.config/store/ |
<prefix>/worker-store/<id>/ |
$QUIL_NODE_PATH/.config/worker-store/<id>/ |
Use qtools node backup to upload node data to a QStorage bucket.
# Backup everything (interactive, prompts for credentials)
qtools node backup
# Backup config files only
qtools node backup --config-files --bucket my-bucket
# Backup master store only
qtools node backup --master --bucket my-bucket
# Backup specific workers only
qtools node backup --worker 1,2,3 --bucket my-bucket
# Backup master + specific workers
qtools node backup --master --worker 1,2 --bucket my-bucket
# Provide all credentials via flags
qtools node backup \
--access-key-id <key-id> \
--access-key <key> \
--account-id <account-id> \
--bucket my-bucketUse qtools node restore to download node data from a QStorage bucket.
# Restore everything (interactive)
qtools node restore
# Restore config files only
qtools node restore --config-files --bucket my-bucket
# Restore keys only (migrate key data into existing/new config)
qtools node restore --config-files --keys-only --bucket my-bucket
# Restore master store only
qtools node restore --master --bucket my-bucket
# Restore specific workers only
qtools node restore --worker 1,2,3 --bucket my-bucket
# Restore master + specific workers
qtools node restore --master --worker 1,2 --bucket my-bucket
# Provide all credentials via flags
qtools node restore \
--access-key-id <key-id> \
--access-key <key> \
--account-id <account-id> \
--bucket my-bucket
# Override default region and endpoint
qtools node restore --bucket my-bucket \
--region us-east-1 \
--endpoint-url https://s3.amazonaws.com--config-files: Only operate on config files (config.yml + keys.yml) rather than the full node data.
--keys-only (modifier for --config-files): Instead of replacing files directly, downloads to a temp directory, creates a fresh default node config (if needed), and migrates only the key data (keys.yml, encryptionKey, peerPrivKey) into the local config. Cleans up temp files afterward.
--master: Only operate on the master store. Can be combined with --worker.
--worker <ids>: Only operate on specific worker store(s). Accepts a comma-separated list of worker IDs (e.g., 1,2,3). Can be combined with --master.
| Flag | Description |
|---|---|
--access-key-id |
QStorage/S3 access key ID |
--access-key |
QStorage/S3 access key |
--account-id |
QStorage/S3 account ID |
--bucket |
S3 bucket name |
--region |
S3 region (default: q-world-1) |
--endpoint-url |
S3 endpoint URL (default: QStorage endpoint) |
--prefix |
Optional root prefix within the bucket |
--config-files |
Only operate on config files |
--keys-only |
Migrate key data only (restore, with --config-files) |
--master |
Only operate on the master store |
--worker |
Only operate on specific worker stores (comma-separated IDs) |
After backup/restore, you'll be prompted to save credentials for future use. Credentials are stored in plain text in the qtools config file under the qstorage section:
qstorage:
access_key_id: "your-key-id"
access_key: "your-access-key"
account_id: "your-account-id"
bucket: "your-bucket"
region: "q-world-1"
endpoint_url: "https://qstorage.quilibrium.com"
prefix: ""✅ All core phases complete! The foundation is fully implemented:
- Config system with auto-migration
- Node setup and management
- Service management (systemd/launchd)
- CLI interface
- TUI interface
- Desktop integration stubs
- Wire up CLI command handlers - Connect service management to CLI commands
- Complete install.go implementation - Download binaries, user/group creation
- Implement actual Quilibrium Messaging integration - Replace stubs with real implementation
- Add comprehensive testing - Unit tests, integration tests
- Add documentation - User guide, API documentation