SolarOS

SolarOS 4.6.8 manual · app

SolarOS Embedded Apps

This document covers foreground applications registered in SolarOS. Availability depends on the selected firmware flavor and board capabilities. The apps command shows the app set compiled into the running image.

Exit behavior:

agent

Native Responses/Chat-Completions LLM client and SolarOS agent control plane. It streams model text directly to the active shell and exposes typed system-status, storage-listing, job-listing, display-discovery, and optional Python/Lua execution tools. agent tools shows risk, policy, and runtime availability.

Configure the full endpoint and model, then ask a question:

agent config endpoint https://api.openai.com/v1/responses
agent config model gpt-model
agent config key api-key
agent config reasoning medium
agent config tools confirm
agent config max-tools 16
agent
agent list
agent resume SLOT
agent ask How much memory is free on this device?
agent script python -c "print(6 * 7)"
agent script lua /script.lua argument

Bare agent and agent new open a new foreground prompt loop. Completed turns are saved, and agent list plus agent resume SLOT restore a selected transcript after leaving the app or rebooting. agent delete SLOT removes one conversation without changing provider credentials. Responses uses its saved provider continuation ID; Chat Completions uses bounded local history. Slots are 1 to 3 on internal flash or 1 to 8 on SD; the oldest is reused when full. agent ask performs one unsaved request but likewise waits for Esc or the app-exit key after completion, so display-shell output is not immediately replaced by the shell screen.

Use agent config key clear for an endpoint that does not require bearer authentication. agent status shows configuration, request counters, HTTP status, reasoning effort, duration, traffic, and internal-RAM/PSRAM measurements from the last request. The API key itself is never printed. A Chat-Completions-compatible endpoint can still be configured explicitly.

The agent permits 16 sequential tool calls by default, followed by a separately reserved final provider turn. agent config max-tools COUNT stores a per-request limit from 1 through 32 in NVS. The final turn advertises no tools after that budget is consumed, so the model concludes from the collected results instead of failing on one more tool request. Output is bounded to 16 KiB, protocol buffers and queues prefer PSRAM, and the foreground worker uses a declared 16 KiB internal stack. Full builds can reuse that worker for bounded Python or Lua source/file execution. The manual script path captures at most 4095 output bytes, has a 30-second deadline, and supports cancellation with Esc or the app-exit key. Model-generated source is capped at 640 bytes and captures 383 output bytes.

The storage registry includes bounded listing, sensitive text-file reads, and text-file replacement. Reads and writes are capped at 3072 bytes and paths below .ssh are unavailable to protect SSH identity files.

The default confirm policy runs read-only tools automatically and shows the exact arguments of sensitive, mutating, disruptive, and script calls before waiting for a local y/N decision. off disables tools, readonly excludes all protected risk classes, and explicit all allows every available tool without prompting. See Native Agent Service for the provider contract and current limits.

Controls:

aplay

Play audio files through the board audio output. WAV and MP3 are supported when the audio package is compiled and the board has audio hardware.

Usage:

aplay [-v volume] file.wav|file.mp3

Controls:

arecord

Record microphone input to a WAV file. This requires the audio package and board microphone hardware.

Usage:

arecord [-d seconds] file.wav

Controls:

calc

Scientific calculator and function plotter. On a graphical display, calc opens an expression list beside a Cartesian plot. From UART, USB CDC, Telnet, or any other text-only shell, the same command opens a scientific REPL without the plot pane. calc --text forces that REPL even when graphics are available.

The expression engine supports +, -, *, /, %, powers with ^, parentheses, scientific notation, and implicit multiplication such as 2pi or 2(x + 1). Built-ins include sin, cos, tan, their inverse functions, sqrt, abs, exp, ln, log, floor, ceil, round, min, max, pow, and atan2. Trigonometric input is in radians; rad(degrees) and deg(radians) convert explicitly. Constants are pi and e.

Rows can hold scalar calculations, variables, one-argument functions, or plots:

a = 2
f(x) = sin(x) / x
f(pi / a)
y = f(x)

For a one-off shell calculation, use:

calc -e "sqrt(2)^2"

Text REPL commands:

Graphical controls:

chat

Two-pane provider-neutral conversation client. The left pane lists gateway and radio conversations, the right pane shows bounded shared history, and the bottom line is the message/command input. It opens and remains useful offline; network or radio transport jobs connect independently.

Usage:

chat [gateway|meshcore|link|conversation-id]

With no selector, Chat opens a unified view and initially selects the newest unread conversation. A provider name filters the list. A decimal conversation ID opens exactly that conversation.

The background gateway-sync job owns the gateway transport connection, retries, and joined-channel replay. The shared messaging service owns queued outbound messages and gateway-sync consumes only gateway requests. Start it explicitly with job start gateway-sync, just like email-sync. Closing or suspending chat does not disconnect an already-running synchronizer. Incoming messages remain in the shared bounded messaging store and publish bounded notifications to the universal inbox; reopening the app replays retained conversations from every provider. With SD storage, full messages are retained under /.messages/messages.bin. On internal flash, Chat restores the compact message copy already retained in /.inbox/messages.bin, so it consumes no second flash ring. Both backends deduplicate transport replays by stable message identity and keep linked Inbox read state aligned.

Unlike email-sync, gateway-sync takes no interval argument: it waits for Wi-Fi and reconnects with exponential backoff while remaining in the running state.

Gateway setup and room lifecycle use gateway status, gateway configure, gateway connect, gateway disconnect, gateway rooms, gateway join, gateway leave, and gateway delete. Gateway synchronization runs only under the gateway-sync job name.

Conversation rows show provider, unread, and security state. Outbound rows show queued/sending/sent/delivered/failed state. Use /new CONTACT_ID to open a direct conversation with the contact's preferred endpoint. Sending to a discovered endpoint asks for a second Enter confirmation; blocked endpoints cannot be messaged.

The conversation header reports the selected provider's state. Gateway uses disconnected, connecting, and connected; connectionless MeshCore and Link providers use stopped, starting, ready, and error.

In-app commands:

/help
/new contact-id
/status
/quit

Controls:

clock

Full-screen graphical seven-segment clock, alarm countdown, and stopwatch.

Usage:

clock
clock -a mm:ss
clock -s

Controls:

com

Serial terminal for a bidirectional byte-stream port. Display-keyboard or port-shell input is forwarded to the selected port, and received bytes are drawn in the active terminal. The port may be a UART or a virtual port such as a peer-bound SolarOS Link stream.

Usage:

com [--autobaud] [--hex] [port]

The port defaults to uart0. For example, com gps connects to an existing runtime UART bus named gps, while com vser0 opens a Link stream previously created with link stream create. The selected port remains claimed by the app until the session exits. com works from both display and port shells; when launched from a port shell, its terminal output is returned through that same port. The input/output shell port and selected COM port must be different.

--autobaud is available only for UART buses. It samples the RX signal for three seconds before opening the terminal. Send a repeating 0x55 or 0xaa pattern during that interval. A reliable measurement is matched to a standard UART rate and applied to the current bus connection without overwriting the saved baud setting. UART input forwarding begins when sampling completes. If measurement fails, the configured rate is kept.

--hex displays received bytes as eight-byte offset, hexadecimal, and ASCII rows instead of interpreting them as terminal text. Both options can be used together.

Examples:

com --hex gps
com --autobaud --hex uart0
com vser0

Controls:

curl

HTTP client for quick text downloads and diagnostics. It can print response data to the terminal or save it to a file.

Usage:

curl [-L] [-o file] URL

Controls:

help

Foreground browser for the package-aware SolarOS manual. The foldable tree groups the topics compiled for the current firmware and shows whether it is using the embedded copy or a verified downloaded revision.

Usage:

help
help agent

Controls:

The maintenance forms help status, help update, and help reset remain shell operations. SD-capable builds show terminal-width-aware progress while downloading and extracting one exact-version signed manual archive.

edit

Text editor for files on mounted storage. It supports cursor navigation, selection, clipboard operations, text-size changes, and syntax highlighting for known source files. The editor supports files up to 256 KiB on boards with PSRAM and 32 KiB on boards without PSRAM. Use hexedit for binary files.

Usage:

edit <file>

Controls:

hexedit

Two-pane binary editor for files on mounted storage. Each row shows a file offset, hexadecimal bytes, and their synchronized printable ASCII view. The number of bytes per row adapts to the terminal width. It uses the same 256 KiB PSRAM and 32 KiB internal-memory limits as edit.

Usage:

hexedit <file>

Controls:

files

File manager inspired by Midnight Commander. Its normal mode provides two panes for copy, move, delete, and launch workflows on mounted storage. Launcher mode provides a minimal single-pane application menu suitable for a startup script.

Usage:

files [--launcher] [path]

files --launcher hides dot-prefixed entries, removes the message and function key bars, and expands one pane to the bottom of the terminal. Launcher mode is read-only: navigate with the arrows, open with Enter, refresh with r, move to the parent with Backspace, and exit with q or the app-exit key. To make a directory the startup menu, add a line such as this to /.shell/startup:

files --launcher /apps

File associations come from the installed app registry. Only apps compiled in the active firmware can be selected. Associations include images to view, WAV/MP3 to aplay, CSV to sheet, Python and Lua scripts to their runtimes, documents to reader (or writer when Reader is unavailable), and .gb ROMs to gameboy. Unknown files fall back to less or edit. A .sh file runs through the built-in SolarOS shell. In launcher mode, documents associated with Reader open as reader --pager for row-aware page navigation.

Controls:

contacts

Provider-neutral address book for gateway and MeshCore identities. Contacts can carry multiple provider endpoints while retaining trust independently for each endpoint. A signed MeshCore advert creates a discovered endpoint: the signature proves possession of the advertised key, not the human identity behind it.

Open the searchable TUI:

contacts

The list is grouped by trust and provider. Press / to search, Enter to view the selected endpoint addresses, capabilities, last-seen times, and bounded provider metadata summary, and Esc or q to leave.

Use the shell surface for mutations:

contacts status
contacts list [all|discovered|trusted|blocked]
contacts show CONTACT_ID
contacts rename CONTACT_ID NAME
contacts trust CONTACT_ID [ENDPOINT_ID]
contacts block CONTACT_ID [ENDPOINT_ID]
contacts remove CONTACT_ID
contacts link TARGET_CONTACT_ID SOURCE_CONTACT_ID

Contact and endpoint identifiers autocomplete from live service snapshots. Linking moves the source endpoints to the target contact and removes the source record. When the 64-contact store is full, SolarOS may evict the oldest unpinned contact whose endpoints are all still discovered; trusted and blocked records are never automatically evicted.

The versioned store is CRC checked, uses two alternating headers and data copies, remains below 24 KiB, and normally lives at /.contacts/contacts.bin. If storage is unavailable, Contacts remains usable in volatile mode and contacts status reports the storage error.

inbox

Universal incoming-message browser for pages, chat notifications, mail, and other background producers. It reads the same shared inbox that supplies the status-bar unread count. Messages and read state survive reboot in the bounded /.inbox/messages.bin store; the service retains at most 64 entries and keeps the file below 32 KB even when internal flash is the only storage.

Each list item occupies exactly one terminal row: unread/priority markers, local reception date and time, a compact source (chat/general, email, or pocsag), and as much of the message body preview as fits the screen.

Optional notification sound is disabled by default. Press s in the Inbox or use inbox notify on, inbox notify off, or inbox notify test; the setting is persistent and is available only on boards with audio output.

Usage:

inbox

Controls:

email

Receive-only IMAPS client for the configured mailbox. The app shows the provider-specific message list while every newly synchronized message is also published to the universal inbox and its shared status-bar unread counter.

Configure and synchronize the account before opening the app:

wifi on
email configure imaps://imap.example.com user@example.com app-password INBOX
email sync
email

Controls:

The account configuration persists in NVS. The local message list is volatile and keeps the newest 32 synchronized messages. This first version displays a best-effort text preview; MIME attachments, encoded headers, sending, and server-side read flags are not implemented yet.

io

Interactive expansion I/O manager. Its default Layout view presents the board's connectors in their physical arrangement, followed by the existing pin, named-bus, and resource-claim views. It uses the same ownership and validation services as the gpio, i2c, spi, uart, onewire, and expansion commands.

Usage:

io

Controls:

invaders

Graphical arcade shooter.

Usage:

invaders

Controls:

gameboy

Experimental original Game Boy (DMG) emulator for the Waveshare ESP32-S3-RLCD-4.2 and the full-PAL Freenove ESP32-WROVER v3.0 target. It is included in the retro and rover-retro flavors. The application loads a user-supplied ROM into PSRAM, renders its four shades as a 320x288 dithered image, and writes battery-backed cartridge RAM beside the ROM as a .sav file. Game Boy Color-only ROMs and ROMs larger than 4 MiB are rejected.

The emulator runs the core independently from the relatively expensive RLCD update. It keeps Peanut-GB's hot state and up to two 16 KiB ROM banks in internal RAM when the SolarOS reserve permits, skips alternate core-rendered frames by default, and presents the newest frame once per three emulated frames. On the Waveshare display, a dedicated monochrome presentation path rotates and streams the frame in one controller write sequence. On Rover, a direct byte-aligned conversion copies XBM rows into the inactive PAL scanout buffer and swaps it at a field boundary; the 320x288 image is centered in the 384x288 canvas and reaches the top and bottom edges. Runtime logs report emulation and presentation rates separately.

Audio rendering runs in its own bounded worker and holds exclusive speaker output while Game Boy is active. RLCD presentation runs independently at about 20 Hz, temporarily requests the panel's 25.5 Hz HPM profile, and drops stale frames instead of blocking emulation. Pausing, suspending, or exiting the app stops the synth and restores the previous display and audio policies. These audio and HPM behaviors apply to the Waveshare retro build. The Rover build deliberately compiles Game Boy without sound because PAL scanout owns I2S0. Its 320x200 composite safe-area mode is too short for the 320x288 Game Boy canvas and is not supported by rover-retro.

Usage:

gameboy <file.gb>

Controls:

Game Boy reads the generic SolarOS held-key state. BLE keyboards, fixed board buttons, gpio-keys, joysticks, and ADC D-pads therefore remain active until release, and combinations such as diagonal movement or direction plus A/B work simultaneously. USB HID usages preserve the physical Z/X positions across keyboard layouts. Character-only inputs such as port-shell input retain the short button-pulse fallback.

less

Terminal pager for text files. It preserves original text layout and is useful for quick file inspection.

Usage:

less <file>

Controls:

logic

On-device logic analyzer waveform viewer. It displays the latest capture made by the shared logic analyzer service or the SUMP job. With pin arguments it makes a new local capture before opening the viewer.

Usage:

logic
logic <pin[,pin...]> [rate-hz] [samples] [trigger=<pin>]

Examples:

logic
logic 1,2,3,17
logic 1,2 500000 8192
logic 1,2,3,17 10000 4096 trigger=1

trigger=<pin> waits for the next rising or falling edge on that runtime-safe GPIO before sampling. The trigger pin may be one of the captured data pins, as in the last example, or a separate GPIO that is not displayed as a channel.

Controls:

The app is compiled only for boards with graphics and runtime-safe GPIOs. While the SUMP job is running, the app remains a viewer and automatically reloads captures received from the host.

lua

Embedded Lua runtime. It can run an interactive REPL or execute .lua scripts from storage. Lua scripts can use SolarOS service bindings when the selected firmware includes the corresponding packages.

Usage:

lua
lua file.lua [args...]

Controls:

notes

Markdown-backed checklist and category manager. It stores unchecked and checked items and supports one level of category folding.

Usage:

notes [file.md]

Controls:

plot

Graphical plotter for DAQ CSV files and live scalar streams. It is compatible with CSV generated by the daq job.

Usage:

plot <scalar-stream...> [--rate ms]
plot -f <file.csv> [column...]

Examples:

plot temperature humidity --rate 1000
plot -f /logs/env.csv temperature humidity

--rate is a best-effort live sampling interval in milliseconds. Rates below 25 ms request faster runtime ticks while the screen redraws no more often than once every 25 ms, so fast acquisition does not force an equally fast display refresh.

Controls:

playground

Browse the configured community catalog as a foldable category tree, search applications, and install, update, uninstall, or run Python and Lua scripts.

Usage:

playground
playground search QUERY...
playground install APP-ID [auto|flash|sd]
playground run APP-ID [ARG...]
playground delete
playground refresh
playground reload
playground source [repository-or-catalog-url|reset]
playground storage [flash|sd]

Press / to search, Enter to open an application, and use the actions shown in the bottom bar. Press i on an application in the catalog tree or details page to install it, and u to uninstall it after confirmation. Packages are verified by size and SHA-256 and installed under /playground/ on the permanently configured flash or sd storage. Community scripts run with the normal permissions of their runtime and are not sandboxed.

Catalog and application files are stored under /playground/ on the selected filesystem. playground delete recursively removes that entire directory, clears the loaded catalog from memory, and also removes the legacy hidden .solar/playground directory when present. Source and storage preferences are retained.

The shell subcommands use the local catalog: refresh downloads and saves it, reload loads that saved copy without network access, search prints matches, install downloads and verifies an application by ID, and run launches an installed ID directly through its declared Python or Lua runtime without creating a Playground session. Tab completes installed catalog IDs after playground install and playground run. Arguments after the application ID are forwarded unchanged to the selected Python or Lua script. For example, playground run qr-share --file /notes/wifi.txt passes both options to QR Share. Opening the TUI reloads the saved catalog automatically and does not refresh it. At the top-level catalog tree, Esc, q, and the app-exit key exit Playground.

playground storage shows the persistent catalog and default application storage. Set it with playground storage flash or playground storage sd. Without a saved preference, Playground selects SD when it is mounted and flash otherwise. Omitting the install target, or specifying auto, uses the selected setting.

See Playground for controls, storage layout, source selection, and the trust model.

python

Embedded MicroPython runtime. It can run an interactive REPL, .py scripts, or .mpy files from storage. Python scripts can use SolarOS service bindings when the selected firmware includes the corresponding packages.

Usage:

python
python file.py [args...]
python file.mpy [args...]

Controls:

reader

Graphical document reader for plain text, Markdown, and EPUB. It remembers reading position and zoom per opened file when storage is available.

Usage:

reader [--pager] <file.txt|file.md|file.epub|man:topic>

With --pager, Up and Down page instead of scrolling one layout row. Each forward page starts with the final visible row from the previous page, so mixed font sizes and wrapped Markdown retain a precise reading overlap.

Controls:

writer

Resumable graphical Markdown editor for PSRAM display boards. Inactive blocks are formatted like reader; the block containing the cursor and every block touched by a selection show their exact Markdown source. edit remains the portable text editor for port shells and boards without graphics or PSRAM.

Usage:

writer [file.md]

Without a path, Writer opens an untitled document and asks for a path on the first save. Existing files larger than 256 KiB are rejected without changing them. Saves use a synced same-directory staging file, backup rename, verified replacement, and rollback. Cursor, scroll anchor, and zoom metadata plus idle recovery snapshots live centrally under /.writer or the active persistent storage root. Writer offers a differing recovery snapshot when the document is opened again. Recovery uses R to recover, D to discard the snapshot, or C to cancel; the unsaved-changes dialog similarly uses S, D, and C.

Controls:

scp

SCP file transfer over SSH. It supports password or key authentication through the shared SSH transport and host lookup/known-host storage. When user@ is omitted, SCP uses the NVS-backed SolarOS identity user.

Usage:

scp [-P port] local [user@]host:remote
scp [-P port] local [user@]host:
scp [-P port] [user@]host:remote local
scp [-P port] [user@]host:remote-glob dir
scp [-P port] [user@]host:remote

Remote download paths can use * or ?. The local target must be an existing directory for remote wildcard downloads.

SCP runs inline in the shell. Its progress and result remain in the terminal scrollback, and usage errors or a completed transfer return directly to the prompt.

Controls:

sheet

CSV viewer for small data tables. It is intended as a companion to daq logs and simple spreadsheet-like inspection.

Usage:

sheet <file.csv>

Controls:

ssh

Interactive SSH client. It supports password and key authentication, known hosts, hostname lookup through /.ssh/hosts, UTF-8 text, VT-style controls, and remote full-screen terminal applications. When user@ is omitted, SSH uses the NVS-backed SolarOS identity user.

Usage:

ssh [user@]host [port]

SSH runs inline in the shell, so connection output remains in the terminal scrollback and disconnecting returns directly to the prompt. Remote terminal control sequences still work, including full-screen applications.

Controls:

telnet

Telnet client for classic TCP terminal sessions. It supports basic Telnet option negotiation, terminal type reporting, window size reporting, and raw mode.

Usage:

telnet host [port]
telnet -r host [port]

Controls:

view

Graphical image viewer. It supports the image formats compiled into the current firmware, including common PNG/JPEG/GIF/WebP paths and automatic animated GIF playback when the media package is enabled.

Usage:

view [-fit|-actual] <image>

Controls:

web

Simple graphical web browser for lightweight HTML pages. It shares document and image rendering infrastructure with reader where possible.

Usage:

web http://host/
web https://host/path

Controls:

Quick reference

Use apps to list applications installed in the current firmware. Start an app by entering its name and arguments. Use the app-exit key to return to the shell; resumable applications can also be switched through sessions. This page is the complete usage and controls reference for foreground applications.