Skip to content

feat: interactive install script (DIM-645)#1395

Merged
spomichter merged 46 commits intodevfrom
feat/dim-645-interactive-install
Mar 5, 2026
Merged

feat: interactive install script (DIM-645)#1395
spomichter merged 46 commits intodevfrom
feat/dim-645-interactive-install

Conversation

@spomichter
Copy link
Contributor

@spomichter spomichter commented Mar 2, 2026

Problem

Closes DIM-645

DimOS has no guided installation experience. Users must manually follow README steps, install system dependencies, choose between library/dev mode, configure Python environments, and hope they get it right. This is a significant barrier to adoption.

Solution

Added scripts/install.sh — a fully interactive installer powered by gum (charmbracelet's TUI toolkit for shell scripts). The script auto-downloads the gum binary (~4.5MB) and falls back to basic prompts if unavailable.

Features

  • Interactive TUI: arrow-key selection for install mode (library/developer), extras packages, setup method (system packages vs Nix)
  • Smart defaults: detects OS/arch, checks disk space (warns <10GB), skips already-installed apt packages
  • Two setup paths: system packages (apt + uv) or Nix with flake support
  • Safe by design: asks before overwriting existing .venv, Ctrl+C works everywhere (no subshell traps), proper curl-pipe detection (re-execs from temp file for TTY)
  • Post-install verification: optional smoke tests with dimos --simulation and targeted pytest
  • Non-interactive mode: --non-interactive --mode library --extras base,unitree for CI/scripting
  • Cross-platform: Linux x64/arm64, macOS x64/arm64

Files changed

  • scripts/install.sh — the installer (~920 lines)
  • README.md — added Interactive Install section at top of Installation

Breaking Changes

None — this is purely additive. Existing installation methods are unchanged.

How to Test

# Test the installer directly (dry-run mode available)
cd /home/ubuntu/dimos
git fetch origin && git checkout feat/dim-645-interactive-install

# Dry run (shows what would happen without executing)
bash scripts/install.sh --dry-run

# Full interactive run (in a temp directory)
mkdir /tmp/test-install && cd /tmp/test-install
bash /home/ubuntu/dimos/scripts/install.sh

# Non-interactive mode
bash scripts/install.sh --non-interactive --mode library --extras base

# Curl-pipe style (as end users would run it)
curl -fsSL https://raw.githubusercontent.com/dimensionalOS/dimos/feat/dim-645-interactive-install/scripts/install.sh | bash

Contributor License Agreement

  • I have read and approved the CLA

@spomichter spomichter changed the base branch from main to dev March 2, 2026 11:47

# ─── System packages (apt) ───────────────────────────────────────────────────
if command -v apt-get &>/dev/null; then
PKGS="portaudio19-dev git-lfs libturbojpeg python3-dev pre-commit"
Copy link
Contributor

@paul-nechifor paul-nechifor Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no check that these packages were installed by us. We might unintentionally remove packages that people were using before but weren't aware they were using.

Personally, I just wouldn't uninstall system packages.

Also, these are not all the packages which are installed.

@spomichter spomichter marked this pull request as ready for review March 2, 2026 21:55
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@spomichter spomichter changed the title Feat/dim 645 interactive install feat: interactive install script (DIM-645) Mar 2, 2026
# Interactive installer for DimOS — the agentive operating system for generalist robotics.
#
# Usage:
# curl -fsSL https://raw.githubusercontent.com/dimensionalOS/dimos/dev/scripts/install.sh | bash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be dev or main?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dev for now

# ─── ascii banner ─────────────────────────────────────────────────────────────
show_banner() {
if [[ "$NON_INTERACTIVE" == "1" ]] && [[ -z "${DIMOS_SHOW_BANNER:-}" ]]; then return; fi
local banner=' ▇▇▇▇▇▇╗ ▇▇╗▇▇▇╗ ▇▇▇╗▇▇▇▇▇▇▇╗▇▇▇╗ ▇▇╗▇▇▇▇▇▇▇╗▇▇╗ ▇▇▇▇▇▇╗ ▇▇▇╗ ▇▇╗ ▇▇▇▇▇╗ ▇▇╗
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logo doesn't show up right on a Ubuntu 24.04 terminal with a default window size.

Image

printf " %s# real hardware%s\n ROBOT_IP=192.168.1.100 dimos run unitree-go2\n\n" "$DIM" "$RESET"
fi
if [[ "$EXTRAS" == *"sim"* ]] || [[ "$EXTRAS" == "all" ]]; then
printf " %s# MuJoCo + click-nav%s\n dimos --simulation run unitree-go2-click-nav --viewer-backend rerun\n\n" "$DIM" "$RESET"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't click-nav be eventually moved into unitree-go2? Is it worth mentioning unitree-go2-click-nav here?

elif [[ "$uname_s" == "Linux" ]]; then
if grep -qi microsoft /proc/version 2>/dev/null; then DETECTED_OS="wsl"
elif [[ -f /etc/NIXOS ]] || has_cmd nixos-version; then DETECTED_OS="nixos"
else DETECTED_OS="ubuntu"; fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't assume that every os that's not Windows or NixOS is Ubuntu.

The best way to check for systems which use apt-get is grep -Ei 'debian' /etc/os-release. If it doesn't match we should also use die "unsupported operating system"

single-command installer for DimOS that handles system detection,
dependency installation, and uv setup interactively.

supports library mode (uv pip install) and developer mode (git clone
+ uv sync). detects OS (ubuntu/macos/nixos/wsl), GPU (nvidia/apple
silicon/cpu), and python version automatically.

includes --dry-run, --non-interactive, and environment variable
support for CI/automation. configures LCM sysctl buffers and runs
post-install verification.

Closes DIM-645
- Nix detection: detect nix on any OS (not just NixOS), source nix-daemon.sh
- Nix install: offer to install via Determinate Systems installer with flakes
- Nix setup flow: --use-nix / --no-nix flags, DIMOS_USE_NIX / DIMOS_NO_NIX env vars
- Library mode + nix: download flake.nix/lock, init git repo, nix develop --command
- Dev mode + nix: after git clone, uv sync inside nix develop --command
- verify_nix_develop(): checks python3, gcc, pkg-config in nix shell
- NixOS without nix: hard error (broken install)
- Post-install tests: pytest (dev mode, fast subset) + replay verification
- Replay test: 30s timeout, exit 124 = success, ImportError detection
- --skip-tests / DIMOS_SKIP_TESTS to bypass post-install tests
- Updated quickstart: nix develop instructions + warning note
- Nix status shown in system info display
- Bumped installer version to 0.2.0
- replace y/n nix prompt with selectable choice (system packages vs nix)
- dry-run now implies non-interactive (no hanging on prompts)
- add disk space check with 10GB minimum warning
- skip disk space die in dry-run mode
- replace numbered list multi-select with interactive checkbox UI
  (arrow keys to move, space to toggle, enter to confirm)
- add 'ready to install?' confirmation after system info display
- fix apt daemon restart hang: DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a
- all items selected by default in multi-select
when piped from curl (stdin is not a TTY), saves script to temp file
and re-executes with bash so interactive prompts get proper TTY input.
fixes: curl -fsSL .../install.sh | bash
- add SIGINT trap that exits immediately with code 130
- restore terminal cursor visibility on any exit/interrupt
- prevents script from eating Ctrl+C during uv install
- prompt_choice now uses arrow keys + ● / ○ radio buttons (like @clack/prompts)
- fix curl pipe detection: only self-download when $0 is 'bash', not when
  running as 'bash script.sh | tail' (was eating stdin incorrectly)
- remove redundant 'ready to install?' confirm — first prompt is now setup
  method choice which makes intent clear
- flow: banner → sysinfo → setup method → system deps → uv → install mode →
  extras (checkboxes) → install → verify
Major rewrite of install.sh using charmbracelet/gum for interactive prompts:
- Auto-downloads gum binary (~4.5MB) at script start
- Falls back to basic prompts if download fails
- gum choose for single-select (arrow keys, enter)
- gum choose --no-limit for multi-select (checkboxes)
- gum confirm for Y/n prompts
- gum spin for spinners during apt/brew/uv operations
- gum style for the banner
- All gum commands handle Ctrl+C, cursor, cleanup natively
- Cross-platform: Linux x64/arm64, macOS x64/arm64

Adds scripts/uninstall.sh for rapid test iteration:
- Removes dimos-project/ and dimos/ dirs
- Removes system packages (apt)
- Removes uv
- Removes sysctl config
- Cleans tmp files
- Supports --all (no prompts) and --dry-run

v0.2.0 → v0.3.0, 1224 lines → 742 lines
uv venv prompts interactively when .venv exists, which we can't
wrap with gum. Set UV_VENV_CLEAR=1 to silently replace it.
detect existing .venv before creating a new one. prompt the user
with default=no so we never silently destroy someone's environment.
if they decline, skip venv creation and install into the existing one.
check each package with dpkg -s before running apt-get update/install.
if everything is present, skip entirely — saves 30-60s on repeat runs.
- prompt for install directory with gum input, default to pwd (library)
  or pwd/dimos (dev) — respects --project-dir flag
- nix installer: offer choice between Determinate Systems, official
  nixos.org, or skip. links to https://nixos.org/download/
- if user skips nix install, falls back to system packages gracefully
remove Determinate Systems option. use the official nix installer:
sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install) --daemon

simple Y/n confirm before running, with link to nixos.org/download/
…c fix

- prompt 'Run post-install verification tests?' before running anything
- pytest uses 'uv run pytest dimos' (matches README, pyproject.toml handles markers)
- replay only runs if unitree extras were installed
- replace subshells with pushd/popd for uv venv + uv pip install
  so SIGINT (Ctrl+C) propagates directly to uv process
- use global INSTALL_DIR instead of re-computing paths
…thing to test

- show the exact command being run: 'running: uv run pytest dimos (fast test suite)'
- use 'dimos --simulation run unitree-go2' if sim extras installed (MuJoCo, looks cooler)
- fall back to 'dimos --replay run unitree-go2' if unitree but no sim
- skip test prompt entirely if no testable extras installed (base-only)
- say 'no verification tests available' instead of fake 'all checks passed'
- report actual count: '2 check(s) passed' not just 'all'
library mode now defaults to $PWD/dimensional-applications instead of
bare $PWD (which dumped .venv into home dir)
gum exits 130 on SIGINT but $(command substitution) swallows the exit
code, causing the script to continue with empty/garbage selection.

fix: check exit code after every gum call. if non-zero (cancelled),
die immediately with 'cancelled' message. applies to:
- prompt_select (gum choose)
- prompt_multi (gum choose --no-limit)
- prompt_confirm (gum confirm, distinguish code 1=no vs 130=cancel)
- prompt_install_dir (gum input)
- fallback read prompts also handle EOF/cancel
open3d and mujoco need libGL.so.1 which comes from libgl1.
without it, dimos CLI crashes on import with:
  OSError: libGL.so.1: cannot open shared object file
…aths

- library install now shows the correct command for both nix and non-nix
  paths before asking 'Install dependencies now?'
- nix path shows: nix develop --command bash -c 'uv venv && uv pip install'
- manual fallback for nix users includes 'nix develop' first
- confirmation prompt was missing entirely from nix library path
SETUP_METHOD was set to 'nix' but USE_NIX stayed 0 — every subsequent
code path checks USE_NIX, not SETUP_METHOD. user selected nix, nix
got installed, then the entire install ran the non-nix path anyway.

now sets USE_NIX=1 in all three places SETUP_METHOD becomes 'nix'
- stops nix-daemon, removes systemd units, /nix, /etc/nix, profile.d
  scripts, nixbld users/group, ~/.nix-* and ~/.config/nix
- also removes ~/dimensional-applications (library install default dir)
- all behind should_remove prompts (or --all to skip)
nix installer backs up /etc/bash.bashrc to .backup-before-nix before
modifying it. if the backup file exists on reinstall, nix refuses to
proceed. uninstall now restores these backups.
- cd $HOME at script start (CWD may be deleted dir after uninstall)
- run nix installer from /tmp with </dev/tty so it gets TTY input
  (was showing 'No TTY, assuming yes' for every prompt)
- clean stale .backup-before-nix files before running nix installer
  (leftover from previous install blocks reinstall)
nix modifies /etc/bash.bashrc but current shell doesn't pick it up.
quickstart now says 'open a new terminal first' and offers
'exec bash -l' as alternative to reload the current shell.
users thought 'source .venv/bin/activate' runs outside nix shell.
now shows one-liner and two-step version making it clear the venv
activation happens INSIDE the nix develop shell.
nix develop sets LD_LIBRARY_PATH to nix's libs (glibc 2.38+) which
conflicts with pip wheels compiled against system glibc (2.35 on
ubuntu 22.04). numpy, open3d, etc all crash with GLIBC_2.38 not found.

nix only works when uv sync runs INSIDE nix develop (dev mode).
library mode now falls back to system packages if nix was selected,
with a clear warning explaining why.
nix + library install works fine on glibc >= 2.38 (ubuntu 24.04+,
macOS). only breaks on older glibc where nix's libstdc++ from GCC 14
conflicts with PyPI manylinux wheels.

now shows a warning with specific guidance instead of blocking:
- detects glibc version
- warns if < 2.38
- suggests system packages or ubuntu upgrade as alternatives
dimos is just a pip install into a venv. uninstall is rm -rf .venv/
or rm -rf the project dir. no script needed.
dimos is just a pip install into a venv. uninstall is rm -rf .venv/
or rm -rf the project dir. no script needed.
replace placeholder dimensional.ai/install.sh with actual github raw
URL pointing to dev branch. updates header comments, --help output,
and all usage examples.
interactive install is first thing under '# Installation'.
renamed 'System Install' to 'Manual System Install'.
@spomichter spomichter force-pushed the feat/dim-645-interactive-install branch from 1f86b5d to 877a4fa Compare March 3, 2026 16:57
- OS detection: check /etc/os-release for debian/ubuntu instead of
  catch-all assumption. Non-debian Linux distros now get a clear error.
- Package lists: moved to top-level constants (UBUNTU_PACKAGES,
  MACOS_PACKAGES) so they're easy to find and edit.
- System deps: always show what will be installed and ask for
  confirmation before running apt/brew. No more hidden installs.
- System deps: show live output (no spinner) so users see progress
  during long package installs instead of a frozen terminal.
- macOS parity: now checks which brew packages are already installed
  (matching Ubuntu's dpkg -s check) instead of blindly installing all.
- Banner: falls back to compact text on terminals narrower than 90 cols.
- Quickstart: removed click-nav example (may be renamed/merged).
paul-nechifor
paul-nechifor previously approved these changes Mar 4, 2026
- Use stty </dev/tty to detect terminal width in curl|bash (tput fails
  when stdin is a pipe)
- Add compact DimOS banner (41 cols) for 45-89 col terminals
- Full DIMENSIONAL banner still shows at >=90 cols
- Plain text fallback below 45 cols
The Nix-detected code path for prompt_setup_method was missing
|| die "cancelled" — Ctrl+C in gum exits the subshell but the
parent continued silently. Non-Nix path already had it.
Root cause: when running via curl|bash, bash reads from the pipe and
is NOT in the terminal's foreground process group. Ctrl+C only reaches
gum (reading /dev/tty), not bash. gum swallows SIGINT, returns the
highlighted item with exit 0, and the script continues.

Fix: prompt_select and prompt_multi no longer use $() subshell
capture. Gum writes to a tmpfile, result read into PROMPT_RESULT
global variable. This keeps gum in the current shell's process group
so SIGINT propagates correctly.

Also: stty </dev/tty for terminal width detection in pipes, and
three-tier banner (full DIMENSIONAL >=90, compact DimOS >=45, text).
Removed cd $HOME at script top — it overrode $PWD so install
dirs always went to ~/dimensional-applications or ~/dimos instead
of the directory the user ran curl from.
verify_nix_develop was capturing all output in $(), hiding download
and build progress. Now runs with live stderr output so users see
what's happening. Added message about first-run download time.
@spomichter spomichter merged commit 4ba0d02 into dev Mar 5, 2026
12 checks passed
@spomichter spomichter deleted the feat/dim-645-interactive-install branch March 5, 2026 18:44
@spomichter spomichter restored the feat/dim-645-interactive-install branch March 5, 2026 18:44
@spomichter spomichter mentioned this pull request Mar 11, 2026
1 task
spomichter added a commit that referenced this pull request Mar 12, 2026
Release v0.0.11

82 PRs, 10 contributors, 396 files changed.

This release brings a production CLI, MCP tooling, temporal memory, and first-class support for coding agents. Dask has been removed. The entire stack now runs from `dimos run` through `dimos stop`.

### Agent-Native Development

DimOS is now built to be driven by coding agents. Point OpenClaw, Claude Code, or Cursor at [AGENTS.md](AGENTS.md) and they can build, run, and debug Dimensional applications using the CLI and MCP interfaces directly.

- **AGENTS.md** — comprehensive onboarding doc: architecture, CLI reference, skill rules, blueprint quick-reference. Your agent reads this and starts coding.
- **MCP server** — all `@skill` methods exposed as HTTP tools. External agents call `dimos mcp call relative_move --arg forward=0.5` or connect via JSON-RPC.
- **MCP CLI** — `dimos mcp list-tools`, `dimos mcp call`, `dimos mcp status`, `dimos mcp modules`
- **Agent context logging** — MCP tool calls and agent messages logged to per-run JSONL for debugging and replay.

### CLI & Daemon

Full process lifecycle — no more Ctrl-C in tmux.

- `dimos run --daemon` — background execution with health checks and run registry
- `dimos stop [--force]` — graceful shutdown with SIGTERM → SIGKILL fallback
- `dimos restart` — replays the original CLI arguments
- `dimos status` — PID, blueprint, uptime, MCP port
- `dimos log -f` — structured per-run logs with follow, JSON output, filtering
- `dimos show-config` — resolved GlobalConfig with source tracing

### Temporal-Spatial Memory

Robots in physical space ingest hours of video and lidar. Temporal-spatial memory gives them a human-like understanding of the world — causal object relationships, entity tracking through time and physical space, and the ability to answer complex temporal queries:

*Who spends the most time in the kitchen? What time on average do I wake up? Which set of switches toggles the main lights? Who was at the office at 9am last Thursday?*

Traditional frame-level embeddings (CLIP, ViT) lose temporal context and don't scale beyond a handful of frames. Video transformers are expensive and don't operate in RGB-D. Dimensional agents work with video + lidar natively, tracking entities across hours and days.

```bash
dimos --replay --replay-dir unitree_go2_office_walk2 run unitree-go2-temporal-memory
```

### Interactive Viewer

Custom Rerun fork (`dimos-viewer`) is now the default. Click-to-navigate: click a point in the 3D view → PointStamped → A* planner → robot moves.

- Camera | 3D split layout on Go2, G1, and drone blueprints
- Native keyboard teleop in the viewer
- `--viewer rerun|rerun-web|rerun-connect|foxglove|none`

### Drone Support

Drone blueprints modernized to match Go2 composition pattern. `drone-basic` and `drone-agentic` work with replay, Rerun, and the full CLI.

```bash
dimos --replay run drone-basic
dimos --replay run drone-agentic
```

### More

- **Go2 fleet control** — multi-robot with `--robot-ips` (#1487)
- **Replay `--replay-dir`** — select dataset, loops by default (#1519, #1494)
- **Interactive install** — `curl -fsSL .../install.sh | bash` (#1395)
- **Nix on non-Debian Linux** (#1472)
- **Remove Dask** — native worker pool (#1365)
- **Remove asyncio dependency** (#1367)
- **Perceive loop** — continuous observation module for agents (#1411)
- **Worker resource monitor** — `dtop` TUI (#1378)
- **G1 agent wiring fix** (#1518)
- **Rerun rate limiting** — prevents viewer OOM on continuous streams (#1509, #1521)
- **RotatingFileHandler** — prevents unbounded log growth (#1492)
- **Test coverage** (#1397), draft PR CI skip (#1398), manipulation test fixes (#1522)

### Breaking Changes

- `--viewer-backend` renamed to `--viewer`
- Dask removed — blueprints using Dask workers need migration to native worker pool
- Default viewer changed from `rerun-web` to `rerun` (native dimos-viewer)

### Contributors

@spomichter, @PaulNechifor, @ruthwikdasyam, @summeryang, @MustafaBhadsorawala, @leshy, @sambull, @JeffHykin, @RadientBrain

## Contributor License Agreement

- [x] I have read and approved the [CLA](https://github.com/dimensionalOS/dimos/blob/main/CLA.md).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants