Skip to main content

Overview

The Dex CLI provides a Terminal User Interface (TUI) dashboard for interactive entry management and content operations. The TUI is built with Ink (React for CLIs) and offers a full-screen menu system with keyboard navigation.
Launch the dashboard with dex (no arguments) or dex dashboard.

Dashboard Layout

┌──────────────────────────────────────────────────────────────┐
│                    ██████╗ ███████╗██╗  ██╗                 │
│                    ██╔══██╗██╔════╝╚██╗██╔╝                 │
│                    ██║  ██║█████╗   ╚███╔╝                  │
│                    ██║  ██║██╔══╝   ██╔██╗                  │
│                    ██████╔╝███████╗██╔╝ ██╗                 │
│                    ╚═════╝ ╚══════╝╚═╝  ╚═╝                 │
│              entry creation tool    dev                      │
│            DEX CO-OP CORP, FOR INTERNAL USE ONLY            │
│                   Last updated: 2026-02-20                  │
│         Workspace (site): /Users/staff/dexdsl/site          │
│    Tip: dex setup --reset to reconfigure workspace roots    │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Commands                                                     │
│ [Entry Commands]                                             │
│ ▶ Init — Create a new entry via wizard                      │
│   Update — Rehydrate and edit an existing entry             │
│   Doctor — Health and drift checks with safe repair         │
│   Entry Audit — Run entry runtime production-readiness      │
│                                                              │
│ [Content Commands]                                           │
│   Catalog — Manage catalog manifest and spotlight           │
│   Home — Manage featured home entries                        │
│   Notes — Manage Dex Notes markdown pages                    │
│   ...                                                        │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│    Enter run   ↑/↓ move   ? palette   Ctrl+Q quit           │
└──────────────────────────────────────────────────────────────┘
The dashboard has three sections:
  1. Header: Logo, version, workspace info
  2. Workspace: Command menu or active wizard/manager
  3. Footer: Keyboard shortcuts

Keyboard Navigation

KeyAction
/ Navigate menu items
EnterActivate selected item
?Open command palette
EscClose palette / Cancel wizard
Ctrl+QQuit dashboard
Ctrl+CForce exit
All TUI components support standard terminal resize. The layout adapts to your terminal dimensions.

Command Palette

Press ? to open the command palette:
┌────────────────── Command palette ──────────────────┐
│ > init                                              │
│                                                     │
│ ▶ init                                              │
│   update                                            │
│   doctor                                            │
│   entry-audit                                       │
│   catalog                                           │
│   home                                              │
│   notes                                             │
│   ...                                               │
└─────────────────────────────────────────────────────┘
  • Type to filter commands
  • / to navigate results
  • Enter to activate
  • Backspace to edit query
  • Esc to close

Entry Commands

Init

Launch the entry creation wizard. Guides you through all required fields, video configuration, credits, and download setup.

Update

Rehydrate an existing entry. Reads entry.json, prompts for changes, and regenerates index.html.

Doctor

Run health checks on all entries. Detects drift (JSON vs HTML differences) and offers safe auto-repair.

Entry Audit

Production-readiness audit. Validates schemas, asset references, download availability, and runtime requirements.

Content Commands

Catalog

Interactive catalog manager. Stage entries, edit manifest, set spotlight, diff against environments, and publish.

Home

Home featured entries manager. Configure homepage spotlights and featured entry carousels.

Notes

Dex Notes manager. Create and edit markdown blog posts with editorial workflow.

Polls

Polls catalog inspector. View in-repo polls data and submission tracking.

Calls

IN DEX calls registry. Manage submission calls, active states, and deadline tracking.

Newsletter

Newsletter manager. Draft campaigns, manage segments, schedule sends, and view stats.

Infrastructure Commands

Links

Open staff operational links in browser (monitoring dashboards, admin panels, etc.).

Assets

Protected assets manager. Validate and publish asset lookup configurations.

Status

Status incidents manager. Create incident pages, update status, and manage service health.

Deploy

Quick deploy shortcut. Runs preflight checks and pushes current branch to origin.

View

Launch localhost viewer. Opens generated entries in your browser at http://localhost:4173.

Init Wizard Flow

The Init wizard is the most complex TUI component:

Wizard Stages

1

Basic Info

  • Slug (auto-generated from title)
  • Title
  • Description
  • Series (dex, inDex, dexFest)
  • Selected buckets (A-E, X)
2

Video Configuration

  • Video mode (URL or Embed)
  • Video URL or embed HTML
  • Validation of video source
3

Credits

  • Artists (comma-separated)
  • Instruments (comma-separated)
  • Video crew (director, cinematography, editing)
  • Audio crew (recording, mix, master)
  • Year, season, location
4

Credit Links

  • Enable instrument links (optional)
  • Add links per person
  • Link validation (must be http/https)
5

Download Setup

  • File specs (bit depth, sample rate, channels)
  • Audio/video URLs per bucket and format
  • Metadata (sample length, tags)
6

Recording Index

  • PDF reference token (lookup: or asset:)
  • Bundle reference token (bundle:)
  • Google Sheets source URL
  • Import from spreadsheet (Ctrl+I)
7

Review

  • Preview all collected data
  • Edit any field by navigating back
  • Confirm and generate

Wizard Keyboard Shortcuts

KeyAction
EnterAdvance to next field
TabNext field (multi-field screens)
Shift+TabPrevious field
Ctrl+NNext section
Ctrl+PPrevious section
Ctrl+SSave and generate
Ctrl+IImport recording index (on import screen)
EscCancel wizard
Canceling the wizard discards all progress. There’s no draft save functionality.

Update Wizard Flow

The Update wizard rehydrates existing entries:
  1. Select Entry: Choose from entries directory
  2. Load Data: Read entry.json and populate forms
  3. Edit Fields: Modify any section (preserves unchanged fields)
  4. Regenerate: Write updated entry.json and regenerate index.html
The Update wizard preserves the original publishedAt timestamp and only updates updatedAt.

Manager Components

Managers are full-screen TUI apps for content operations:

Catalog Manager

┌─────────────── Catalog Manager ────────────────┐
│ Manifest (42 entries)                          │
│ ▶ john-doe-piano     A.Pl S4 01    active      │
│   jane-smith-guitar  A.Gt S4 02    active      │
│   alex-bass          A.Bs S3 15    archived    │
│                                                 │
│ [A] Add  [E] Edit  [R] Retire  [V] Validate   │
│ [D] Diff  [P] Publish  [Q] Quit                │
└─────────────────────────────────────────────────┘
Actions:
  • A: Add entry to manifest (prompts for details)
  • E: Edit selected entry metadata
  • R: Retire selected entry (set status=archived)
  • V: Run validation checks
  • D: Diff local vs remote (prompts for env)
  • P: Publish to environment (prompts for env and confirmation)

Home Manager

Similar to Catalog Manager but for homepage featured entries:
# Featured entries list
# Reorder by drag-and-drop (coming soon)
# Edit spotlight config
# Publish to test/prod

Notes Manager

Markdown editor for Dex Notes:
# List notes
# Create new note
# Edit existing note (opens $EDITOR)
# Preview HTML output
# Publish to live site

TUI Component Architecture

The TUI is built with React components via Ink:
// From scripts/ui/dashboard.mjs:104
function DashboardApp({ initialPaletteOpen, initialMode, version, workspace }) {
  const { exit } = useApp();
  const { stdout } = useStdout();
  const [dimensions, setDimensions] = useState({ cols: 80, rows: 24 });
  const [tick, setTick] = useState(0);  // Animation ticker
  const [selected, setSelected] = useState(0);
  const [paletteOpen, setPaletteOpen] = useState(false);
  const [mode, setMode] = useState(initialMode);
  
  useInput((input, key) => {
    if (key.ctrl && (input === 'q' || input === 'Q')) { exit(); return; }
    // Handle navigation and commands...
  });
  
  return (
    <Box flexDirection="column" width={cols} height={rows}>
      <Header logoLines={logoLines} version={version} workspace={workspace} />
      <Workspace mode={mode} onCancel={() => setMode('menu')} />
      <Footer />
      {paletteOpen && <Palette />}
    </Box>
  );
}

Key Components

Dashboard

ui/dashboard.mjs - Main dashboard container with menu and routing.

Init Wizard

ui/init-wizard.mjs - Multi-stage entry creation wizard with form validation.

Update Wizard

ui/update-wizard.mjs - Entry rehydration and edit workflow.

Catalog Manager

ui/catalog-manager.mjs - Interactive catalog manifest editor.

Logo Animation

The ASCII logo has animated HSV color cycling:
// From scripts/ui/dashboard.mjs:87
function renderLogoLine(line, y, tick) {
  let out = '';
  for (let x = 0; x < line.length; x += 1) {
    const ch = line[x];
    if (ch === ' ') { out += ' '; continue; }
    const intensity = 0.55 + 0.45 * Math.sin(tick * 0.18 + x * 0.27 + y * 0.51);
    const hue = (210 + x * 5 + tick * 2.4 + y * 8) % 360;
    const { r, g, b } = hsvToRgb(hue, 0.7, Math.min(1, Math.max(0, 0.3 + intensity * 0.7)));
    out += chalk.rgb(r, g, b)(ch);
  }
  return out;
}
Disable animations with DEX_NO_ANIM=1 dex for better performance on slower terminals.

Responsive Layout

The TUI adapts to terminal dimensions:
useEffect(() => {
  const onResize = () => setDimensions({ 
    cols: stdout?.columns || 80, 
    rows: stdout?.rows || 24 
  });
  stdout?.on('resize', onResize);
  return () => stdout?.off('resize', onResize);
}, [stdout]);

const headerHeight = 13;
const footerHeight = 3;
const workspaceHeight = Math.max(6, rows - headerHeight - footerHeight);
Minimum dimensions:
  • Width: 60 columns
  • Height: 22 rows
Smaller terminals may clip content. Maximize your terminal for best experience.

Input Guard System

The TUI uses an input guard to sanitize keyboard input:
// From scripts/lib/input-guard.mjs:11
export function shouldAppendWizardChar(input, key) {
  if (key.ctrl || key.meta) return false;
  if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) return false;
  if (key.return || key.escape || key.tab) return false;
  const code = input.charCodeAt(0);
  if (code < 32 || code === 127) return false;  // Control chars
  return true;
}

export function sanitizePastedInputChunk(chunk) {
  return String(chunk || '')
    .replace(/[\r\n\t]/g, ' ')    // Newlines → spaces
    .replace(/[\x00-\x1F\x7F]/g, '')  // Strip control chars
    .slice(0, 500);  // Limit length
}
This prevents accidental control character injection and handles paste events.

Non-Interactive Mode

The TUI only launches when stdin/stdout are TTYs:
// From scripts/ui/dashboard.mjs:421
export async function runDashboard({ paletteOpen, initialMode, version, workspace } = {}) {
  if (!process.stdout.isTTY || !process.stdin.isTTY) return { action: null };
  
  cliCursor.hide();
  try {
    const instance = render(React.createElement(DashboardApp, { /* ... */ }));
    await instance.waitUntilExit();
  } finally {
    cliCursor.show();
  }
}
When piped or in CI:
  • Dashboard doesn’t launch
  • Falls back to non-interactive CLI mode
  • Commands must specify all required flags

Best Practices

Keyboard First

The TUI is optimized for keyboard navigation. Memorize shortcuts for faster workflows.

Terminal Size

Use fullscreen terminal (min 80x24). Smaller sizes clip content and break layouts.

Disable Animations

Set DEX_NO_ANIM=1 on slow terminals or during screen recording to reduce CPU usage.

Review Before Save

Always review wizard screens before confirming. Canceling loses all progress.

Troubleshooting

Dashboard Won’t Launch

If dex doesn’t show the TUI:
  1. Check if stdin/stdout are TTYs: tty
  2. Verify terminal supports ANSI: echo $TERM
  3. Try explicit launch: dex dashboard
  4. Check for piping: dex | cat will disable TUI

Layout Corruption

If the layout looks broken:
  1. Resize terminal to at least 80x24
  2. Clear screen: clear or Ctrl+L
  3. Restart dashboard: Ctrl+Q then dex
  4. Update terminal emulator (older versions have rendering bugs)

Keyboard Input Not Working

If keys don’t respond:
  1. Check terminal raw mode: stty -a | grep -i echo
  2. Verify no conflicting keybindings in terminal emulator
  3. Try different terminal (iTerm2, Alacritty, etc.)
  4. Check Ink version: npm list ink

Animation Lag

If logo animation is choppy:
# Disable animations
export DEX_NO_ANIM=1
dex
Animation lag usually indicates terminal emulator performance issues, not CLI problems.

Build docs developers (and LLMs) love