CLI Reference
The UnderControl CLI (ud) is a command-line tool for managing tasks from the terminal. It supports both direct commands and an interactive TUI mode with vim-style keybindings.
Installation
npm (Recommended)
# Global install
npm install -g @oatnil/ud
# Or run directly without installing
npx @oatnil/ud --help
Homebrew (macOS/Linux)
brew tap oatnil-top/ud
brew install ud
Install Script
curl -fsSL https://get.oatnil.com/ud | bash
Manual Download
Download the appropriate version for your platform:
| Platform | Filename |
|---|---|
| macOS (Apple Silicon) | ud_x.x.x_darwin_arm64.tar.gz |
| macOS (Intel) | ud_x.x.x_darwin_amd64.tar.gz |
| Linux (x64) | ud_x.x.x_linux_amd64.tar.gz |
| Linux (ARM64) | ud_x.x.x_linux_arm64.tar.gz |
| Windows | ud_x.x.x_windows_amd64.zip |
macOS / Linux:
# Extract
tar -xzf ud_x.x.x_darwin_arm64.tar.gz
# Move to PATH
sudo mv ud /usr/local/bin/ud
# Verify
ud --version
Windows:
- Extract the
.zipfile - Move
ud.exeto a directory in your PATH - Or add the extracted directory to your system PATH
Authentication
Login
ud login
You'll be prompted for:
- Server URL: Your UnderControl server (e.g.,
https://api.undercontrol.app) - Username: Your account email
- Password: Your account password
Credentials are saved to ~/.config/ud/config.yaml.
Multi-Context Support
The CLI supports kubectl-style contexts for managing multiple accounts. See CLI Multi-Context Authentication for details.
# List contexts
ud config get-contexts
# Switch context
ud config use-context work
# Login to specific context
ud login --context work --api-url https://ud.company.com
Resource Commands (kubectl-style)
The CLI supports kubectl-style top-level verbs for managing resources. These are the recommended way to interact with resources.
Get Resources
ud get task [id] [--status <status>]
Display one or many tasks in a table format.
Options:
--status: Filter by status (todo,in-progress,pending,stale,done,archived)
Examples:
# List all tasks
ud get task
# List only todo tasks
ud get task --status todo
# Show a single task in table format
ud get task abc123
Describe Resource
ud describe task <id>
Show detailed information about a specific task, including title, description, status, tags, deadline, timestamps, linked tasks, attachments, and notes.
Examples:
# View full task details
ud describe task abc123
# Using short prefix
ud describe task 3de
All commands that accept a task ID support prefix matching. You can use the 8-character short IDs shown in get task output, or even shorter prefixes as long as they're unique.
ud describe task 3de9f82b # Full short ID from list
ud describe task 3de # Shorter prefix (if unique)
ud describe task 3de9f82b-fc49-4e84-b288-9ae3174f69ae # Full UUID also works
If a prefix matches multiple tasks, you'll see an error listing the matches:
Error: ambiguous ID prefix '3' matches 2 tasks:
3de9f82b (Task title one)
3fbf7c24 (Task title two)
Please use a longer prefix
Apply Resource from File
ud apply -f <file> # .md for tasks/notes, .yaml for other resources
ud apply -f - # Read from stdin (auto-detects format)
Create or update resources declaratively from files (kubectl-style). Supports all resource types:
| Format | Resources | Auto-detection |
|---|---|---|
.md | Task (default), Note (when task_id in frontmatter) | task_id present → Note |
.yaml / .yml | Board, Budget, Account, Expense, Income | kind field in YAML |
Quick examples:
# Task
echo '---
title: New Task
status: todo
---
Description here.' | ud apply -f -
# Note (auto-detected by task_id)
echo '---
task_id: abc123
---
Progress update.' | ud apply -f -
# Board (YAML)
ud apply -f board.yaml
# Multi-document YAML (multiple resources in one file)
ud apply -f setup.yaml
For the full schema reference, all supported fields, and YAML resource format details, see the Apply & Resource Schema guide.
Delete Resource
ud delete task <id>
Delete a task by ID.
Examples:
ud delete task abc123
ud delete task 3de9f82b
Task Commands
The following ud task subcommands are deprecated and will be removed in a future release. They still work but print a deprecation warning. Use the kubectl-style commands instead:
| Deprecated | Use instead |
|---|---|
ud task list | ud get task |
ud task view <id> | ud describe task <id> |
ud task apply -f <file> | ud apply -f <file> |
ud task delete <id> | ud delete task <id> |
Create Task
ud task create <title> [flags]
ud task create -f <file>
Flags:
-d, --description: Task description-s, --status: Initial status (default:todo)-f, --file: Create from file (first line = title, rest = description)
Examples:
# Simple task
ud task create "Fix login bug"
# With description
ud task create "Refactor API" -d "Update to v2 endpoints"
# With initial status
ud task create "Review PR" -s in-progress
# From file
ud task create -f requirements.md
File format for -f:
Task title goes here
The rest of the file
becomes the description.
Mark Task Done
ud task done <id>
Shortcut to set task status to done.
Edit Task
ud task edit <id>
Opens the task in your $EDITOR (defaults to vi). The file format is:
- First line: title
- Blank line
- Rest: description
Query Tasks
ud query "<query>" [flags]
Query tasks using SQL-like syntax.
Flags:
--page: Page number (default: 1)--limit: Items per page (default: 50)--sort: Sort field (title,deadline,created_at,updated_at)--order: Sort direction (asc,desc)
Examples:
# Find todo tasks
ud query "status = 'todo'"
# Search by title
ud query "title ILIKE '%api%'"
# Find tasks due this week
ud query "deadline BETWEEN 'today' AND '+7d'"
# Find tagged tasks
ud query "tags = 'urgent'"
# Complex query
ud query "(status = 'todo' OR status = 'in-progress') AND deadline <= 'today'"
Note Commands
Notes allow you to add comments, progress updates, and context to tasks. They're useful for tracking work history and AI agent collaboration.
Add Note
ud task note add <task-id> "<content>"
ud task note add <task-id> -f <file>
echo "content" | ud task note add <task-id> -
Flags:
-f, --file: Read note content from file
Examples:
# Add inline note
ud task note add abc123 "Started implementation"
# Add progress update
ud task note add abc123 "✓ Auth middleware done"
# From file
ud task note add abc123 -f progress.md
# From stdin
echo "Completed review" | ud task note add abc123 -
List Notes
ud task note list <task-id>
ud task note ls <task-id> # Alias
Output format:
[4223db11] 2025-01-31 11:08
✓ Auth middleware done
---
[3150c5ce] 2025-01-31 10:45
Started implementation
Delete Note
ud task note delete <task-id> <note-id>
ud task note rm <task-id> <note-id> # Alias
Example:
ud task note delete abc123 4223db11
AI Agent Workflow
Notes enable seamless collaboration between humans and AI agents:
# AI creates task from plan
ud task create -f plan.md
# Created task: abc12345
# Human reviews in UI, adds context via notes
# AI fetches task and logs progress
ud task view abc123
ud task note add abc123 "✓ Completed step 1: Database schema"
ud task note add abc123 "✓ Completed step 2: API endpoints"
ud task note add abc123 "⚠️ Blocked: Need API key for external service"
# Human sees progress, unblocks AI
# AI continues and completes
ud task note add abc123 "✓ All steps completed"
ud task done abc123
File Upload & Attachment Commands
Upload files as resources and optionally attach them to entities like tasks or expenses. Files are uploaded via presigned URLs directly to cloud storage.
Upload a File
ud upload resource <file-path> [flags]
Upload a file as a resource. Optionally attach it to an entity in a single step.
Flags:
-t, --entity-type: Entity type to attach to (e.g.,todolist,expense)-e, --entity-id: Entity ID to attach to (supports prefix matching for tasks)
Examples:
# Upload a standalone file
ud upload resource ./receipt.png
# Upload and attach to a task
ud upload resource ./design.pdf --entity-type todolist --entity-id abc123
# Short flags
ud upload resource ./photo.jpg -t todolist -e abc123
# Upload a document to a task (partial ID)
ud upload resource ./notes.txt -t todolist -e 3de
Output:
Uploading ./receipt.png...
Uploaded: receipt.png
ID: 2a2e542e-0711-4e7f-aafb-09a432e71860
Type: image
Size: 102.4 KB
MIME: image/png
The CLI automatically detects MIME types from file extensions. Common mappings:
- Images:
.png,.jpg,.gif,.webp,.svg→image - Documents:
.pdf,.doc,.docx,.txt,.csv→document - Diagrams:
.drawio,.drawio.png→diagram - Other: all other extensions →
other
Attach Existing Resource
ud attach resource <resource-id> --entity-type <type> --entity-id <id>
Link an already-uploaded resource to an entity. Both --entity-type and --entity-id are required.
Flags:
-t, --entity-type: Entity type (required)-e, --entity-id: Entity ID (required, supports prefix matching for tasks)
Supported entity types:
| Entity Type | Description |
|---|---|
todolist | Tasks |
expense | Expenses |
budget | Budgets |
account | Accounts |
Examples:
# Attach resource to a task
ud attach resource 2a2e542e-0711-4e7f-aafb-09a432e71860 -t todolist -e abc123
# Attach to an expense
ud attach resource 2a2e542e -t expense -e def456
Download a Resource
To download a resource, use ud entity get to retrieve the presigned download URL, then download with curl:
# Get resource details (includes presigned download URL)
ud entity get 2a2e542e-0711-4e7f-aafb-09a432e71860
# Download using the presigned URL from the response
curl -o receipt.png "https://storage.example.com/...?signature=..."
Upload Workflow Example
A typical workflow for attaching files to tasks:
# 1. Find the task
ud get task --status in-progress
# 2. Upload and attach a file
ud upload resource ./screenshot.png -t todolist -e 3de9f82b
# 3. Verify the attachment
ud describe task 3de9f82b
# Shows: [2a2e542e] screenshot.png (image/png, 102.4 KB)
# 4. Later, download the file
ud entity get 2a2e542e
# Copy the presignedUrl from the output
curl -o screenshot.png "<presigned-url>"
TUI Mode
Run ud without arguments to enter the interactive terminal UI.
List View Keybindings
| Key | Action |
|---|---|
j / k | Move down/up |
gg | Jump to top |
G | Jump to bottom |
Enter | View task details |
i | Create new task |
e | Edit task (uses $EDITOR) |
x | Toggle task status |
dd | Delete task |
/ | Search |
n / N | Next/previous search result |
r | Refresh list |
f | Open file picker |
q | Quit |
? | Show help |
Detail View Keybindings
| Key | Action |
|---|---|
j / k | Scroll content |
x | Toggle task status |
e | Edit task |
dd | Delete task |
Esc / q | Return to list |
File Picker
Press f in list view to open an fzf-like file picker:
- Fuzzy search files in current directory
- Select file to create task
- First line = title, rest = description
- Binary files are skipped
Configuration Commands
View Configuration
ud config view
Shows the full configuration with tokens partially masked.
List Contexts
ud config get-contexts
Switch Context
ud config use-context <name>
Show Current Context
ud config current-context
Create/Update Context
ud config set-context <name> [flags]
Flags:
--api-url: API server URL--api-key: API key (for CI/CD)
Delete Context
ud config delete-context <name>
Rename Context
ud config rename-context <old-name> <new-name>
Environment Variables
| Variable | Description |
|---|---|
UD_CONTEXT | Override current context |
UD_API_URL | Override API URL |
UD_API_KEY | Override API key |
UD_TOKEN | Override auth token |
EDITOR | Editor for task edit command |
Examples:
# Use different context for one command
UD_CONTEXT=staging ud task list
# Override API URL
UD_API_URL=http://localhost:4000 ud task list
# Set editor
export EDITOR=vim
Common Workflows
AI Agent Integration
Create .claude/instructions.md or .cursorrules in your project:
# Task Management
Use UnderControl CLI to manage project tasks:
- List tasks: `ud get task`
- View task details: `ud describe task <id>`
- Create task: `ud task create "title" -d "description"`
- Complete task: `ud task done <id>`
- Update task: `ud apply -f task.md`
- Delete task: `ud delete task <id>`
Before implementing features, check related tasks for context.
Batch Updates with Apply
Create a template file and apply to multiple tasks:
# Create status update template for each task
for id in abc123 def456 ghi789; do
echo "---
id: $id
status: done
---" | ud apply -f -
done
Export and Edit Workflow
# View task, copy content
ud describe task abc123
# Create markdown file with updates (include id for update)
cat > update.md << 'EOF'
---
id: abc123
title: Updated Title
status: in-progress
tags:
- reviewed
- approved
---
Updated description with new requirements.
EOF
# Apply changes
ud apply -f update.md
Troubleshooting
Login Failed
Problem: API error: Invalid credentials
Solutions:
- Verify username and password
- Check server URL is correct
- Try logging in via web to verify account
Connection Timeout
Problem: connection timeout
Solutions:
- Check network connection
- Verify server URL is accessible
- Check firewall settings
Token Expired
Problem: API error: Token expired
Solution: Run ud login to re-authenticate.
Editor Not Working
Problem: task edit has no effect
Solution: Set the EDITOR environment variable:
export EDITOR=vim # or nano, code, etc.
Invalid Status Error
Problem: API error: An unexpected error occurred when using apply
Solution: Ensure status is one of: todo, in-progress, pending, stale, done, archived
Context Not Found
Problem: context "work" not found
Solution: Create the context first:
ud config set-context work --api-url https://ud.company.com
ud login --context work