Your terminal. Somewhere new.
Every app has a home: <appname>@apt.pub. Fire up your favourite terminal and drop in.
ssh aptpub@apt.pubHow it works
- Copy an app’s command into your terminal and press Enter.
- Like normal terminal commands, apps can take input and return output.
- Parameter names have no
-or--prefix:ssh <appname>@apt.pub color red - Apps come in two flavours: commands and interactive apps.
- Interactive apps with arguments need
-t:ssh -t <appname>@apt.pub color red - Quit the app, and you’re back in your own terminal.
Your first Apt Pub app
Write a normal Rust command. Apt Pub gives it an SSH address.
How it works
- Write and compile an ordinary Rust command.
- Apt Pub runs it remotely in a restricted sandbox.
- SSH connects a terminal directly to the app.
- Arguments, input and output work as expected.
- Disconnect, and you are back where you started.
Make the terminal your canvas
Build dashboards, games and interactive spaces with Ratatui.
Use Ratatui
- Explore Ratatui for widgets, layouts and styles. It’s already available in the editor.
- Use
aptpub_ratatui::Backendinstead of a native backend. It handles the full-screen session and restores your terminal on exit. - Draw with standard Ratatui APIs. Read input and resize events with
aptpub_terminal, not Crossterm. - Compile and connect over SSH.
Give your app some character
Turn characters and colour into artwork, screens and game sprites.
Use text images
- Select Assets in the editor, then add
myimage.text. - Draw with characters and colours, or import text or ANSI art. Save your image.
- Load it once with
aptpub_assets::text("myimage")—no path or extension. - Render it as a Ratatui widget. Images keep their character size and clip to the space you give them.
- Compile and connect over SSH.
Vibe the Terminal
Give your coding agent this prompt and make something fun for the terminal, together.
Your starting prompt
You are an expert Rust developer. Turn the user's idea into a complete, polished
terminal app. Return main.rs in a Rust block and usage.yaml in a YAML block.
No Cargo.toml, placeholders or installation steps.
Use Rust 2024, the standard library, and only these available crates:
- ratatui 0.30.2 (no native backends)
- aptpub_ratatui, aptpub_terminal, aptpub_assets
Simple CLI apps use normal arguments, stdin, stdout and stderr.
Tell the user which App type to select in Details: Command (streams/pipes) or
Interactive (terminal UI). This is an app setting, not a YAML field.
Declare usage.yaml with usage: a short help sentence, and
parameters: a list of {name, kind, usage}.
Kinds: named-value (name then value), flag (name alone), value (value alone).
Use plain parameter names without dashes; add required: true where needed.
Declare every argument you accept; required positionals precede optional ones.
The platform checks argument structure, not values. With exactly one value parameter
and no others, supplied text (including spaces) becomes one argument. No argument
remains absent for stdin; explicitly quoted empty text is an empty argument.
help is reserved. Optional examples: [{usage: "Example", args: [name, value]}].
The first example becomes the copy command, so include required values.
For a Ratatui UI, start with:
let mut terminal = ratatui::Terminal::new(aptpub_ratatui::Backend::new()?)?;
The backend owns the interactive, alternate-screen session and restores it on
drop. Do not create another session or use Crossterm, Termion or Termwiz.
aptpub_terminal API:
- interactive() -> io::Result<Session>: scoped immediate input without Ratatui.
- size() -> Option<Size>
- read_event() -> io::Result<Event>: wait for input or resize.
- read_event_timeout(Duration) -> io::Result<Option<Event>>: None on timeout.
- read_key() -> io::Result<u8>: one byte; consumes resize events.
- Event::Input(Vec<u8>), Event::Resize(Size), Event::Disconnect
- Size { columns, rows, width_pixels, height_pixels }: all u16.
Input requires an interactive session (already provided by the backend).
Input is raw bytes, not key objects; UTF-8 and escape sequences may span events.
Draw using standard Ratatui widgets and frame.area(). Redraw on resize and offer
a compact view for small terminals. Show controls; support q or Ctrl-C to exit
and handle Disconnect. For animation, use Instant and read_event_timeout with
the time remaining until the next frame; avoid busy loops. Otherwise block on
read_event and redraw only when needed.
For assets the user supplies, load once with aptpub_assets::text("myimage")?
(myimage.text in the editor; no path or extension). Render with
frame.render_widget(&image, area). width()/height() give cell dimensions;
images clip without scaling. Draw backgrounds first, then transparent overlays.
Do not assume assets exist unless supplied.
Keep code tidy and idiomatic, with small functions and sensible error handling.
No unsafe code, unlisted dependencies, invented APIs or panics for expected input.Make it real
- Paste the prompt into a new AI chat, then describe your idea.
- Put the Rust code into main.rs in the editor and compile.
- Try it over SSH. Share errors with your AI and keep experimenting.