Skip to main content

max / mnw-cli

git clone https://makenot.work/git/max/mnw-cli.git git clone git@ssh.makenot.work:max/mnw-cli.git
Name Size
/ deploy/
/ docs/
/ src/
/ tests/
· .gitignore 8 B
· Cargo.lock 110.1 KB
· Cargo.toml 462 B
· README.md 4.9 KB

README

mnw-cli

SSH-based CLI and TUI for the Makenotwork creator platform. Authenticates via SSH key fingerprint, provides an interactive terminal UI for managing projects, and supports non-interactive commands for scripting.

Prerequisites

  • Rust (stable toolchain, 2024 edition)
  • Cross-compilation (for deployment): zig, cargo-zigbuild, x86_64-unknown-linux-gnu target

Build and Run

# Local development (needs MNW server running on localhost:3000)
cargo run

# Run with custom port
SSH_PORT=2222 MNW_API_URL=http://localhost:3000 MNW_SERVICE_TOKEN=<token> cargo run

# Cross-compile for production
cargo zigbuild --release --target x86_64-unknown-linux-gnu

Architecture

mnw-cli is an SSH server built on russh. Each connection spawns an independent handler that authenticates via SSH key fingerprint lookup against the MNW API, then dispatches to either the interactive TUI or a non-interactive command.

LayerModulesRole
SSHssh/handler.rs, ssh/mod.rsConnection handling, public key auth, channel dispatch
TUItui/mod.rs + 9 screen modulesInteractive terminal UI via ratatui
Commandscommands.rsNon-interactive text output for scripting
APIapi.rsHTTP client for MNW internal API (50+ methods)
SFTPssh/sftp.rsFile upload handling with per-user staging
Gitssh/git.rsGit proxy (upload-pack, receive-pack) via subprocess
Stagingstaging.rs1 GB per-user upload quota, 24h TTL auto-cleanup

Authentication

  1. Client presents SSH public key
  2. Server computes SHA-256 fingerprint
  3. Calls MNW internal API to look up the fingerprint
  4. Returns user info (username, creator tier, suspended status)
  5. Suspended users are rejected at auth stage

Interactive TUI

Connect via ssh cli.makenot.work for a full terminal interface with these screens:

ScreenFeatures
HomeProject list, revenue/sales/follower stats with period comparison
ProjectItems in a project, publish/unpublish, navigation
UploadSFTP staged files, metadata editor, S3 presigned upload flow
ItemItem details, versions, edit fields, delete
BlogBlog posts, create with markdown, publish/draft toggle
PromoPromo codes, create with discount %, delete
KeysLicense keys, generate, revoke
AnalyticsTimeseries revenue, period comparison, top projects
SettingsSSH keys, storage usage, profile info

Navigation: vim keys (h/j/k/l), Enter to select, q/Esc to go back, Tab to switch sections.

Non-Interactive Commands

ssh cli.makenot.work projects              # List projects (table format)
ssh cli.makenot.work projects --json       # JSON output for scripting
ssh cli.makenot.work analytics             # Revenue stats (7d default)
ssh cli.makenot.work analytics --range=30  # 30-day analytics
ssh cli.makenot.work transactions          # Recent transactions
ssh cli.makenot.work export sales          # Export sales as CSV
ssh cli.makenot.work promo list            # List promo codes
ssh cli.makenot.work promo create CODE 20  # Create 20% discount code
ssh cli.makenot.work blog list SLUG        # List blog posts for a project
ssh cli.makenot.work help                  # Show all commands

All commands support --json for machine-readable output.

File Upload Flow

  1. Upload file via SFTP to the SSH server
  2. File lands in per-user staging directory (1 GB quota)
  3. TUI shows staged files with type classification
  4. Fill in metadata (title, project, price)
  5. Server gets presigned S3 URL, uploads file, confirms with MNW API
  6. Staging directory auto-cleaned on 24-hour TTL

Configuration

VariableDefaultPurpose
SSH_PORT2222SSH listen port
MNW_API_URLhttp://localhost:3000MNW server base URL
MNW_SERVICE_TOKEN(required)Bearer token for internal API
SSH_HOST_KEYhost_ed25519Path to host key (auto-generated if missing)
STAGING_DIR/var/lib/mnw-cli/stagingPer-user upload staging
GIT_SUDO_USERgitSystem user for git subprocess ops

Deployment

./deploy/deploy.sh              # Full: build + upload + config + restart
./deploy/deploy.sh --quick      # Build + binary + restart
./deploy/deploy.sh --config     # Config files only

Deploys to hetzner (100.120.174.96) as a systemd service with security hardening (ProtectSystem=strict, PrivateTmp, NoNewPrivileges).

Key Paths

WhatWhere
SSH server + authsrc/ssh/handler.rs
TUI app state + event loopsrc/tui/mod.rs
API client (50+ methods)src/api.rs
Non-interactive commandssrc/commands.rs
SFTP + stagingsrc/ssh/sftp.rs, src/staging.rs
Git proxysrc/ssh/git.rs
Deploy scriptdeploy/deploy.sh
systemd unitdeploy/mnw-cli.service

License

PolyForm Noncommercial 1.0.0