Guide for AI agents working in this repository.
See also: DEVELOPMENT.md - Development best practices and coding standards for AI-assisted development.
This is Task You - a personal task management system with:
- SQLite storage for tasks and projects
- SSH-accessible TUI via Wish
- Background executor with support for multiple AI coding agents (Claude, Codex, Gemini, Pi, OpenClaw, OpenCode)
- Beautiful terminal UI built with Charm libraries (Kanban board)
- Git worktree isolation for parallel task execution
- Task lifecycle hooks for real-time task state tracking
┌─────────────────────────────────────────────────────────────────┐
│ Local / Server │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ Wish SSH │───▶│ Bubble Tea │───▶│ SQLite │ │
│ │ :2222 │ │ TUI │ │ tasks.db │ │
│ └──────────────┘ └──────┬───────┘ └───────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Background │ │
│ │ Executor │ │
│ │ (goroutine) │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Claude Code │ │
│ │ (in tmux) │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Local: ty -l (launches TUI + daemon)
Remote: ssh -p 2222 user@server
workflow/
├── cmd/
│ ├── task/
│ │ └── main.go # Local CLI + TUI + daemon management
│ └── taskd/
│ └── main.go # SSH daemon + executor
├── internal/
│ ├── config/
│ │ └── config.go # Configuration management
│ ├── db/
│ │ ├── sqlite.go # Database connection, migrations
│ │ └── tasks.go # Task CRUD operations
│ ├── executor/
│ │ ├── executor.go # Background Claude runner + hooks
│ │ └── project_config.go # .taskyou.yml configuration
│ ├── github/
│ │ └── github.go # PR status tracking
│ ├── hooks/
│ │ └── hooks.go # Task lifecycle hooks
│ ├── mcp/
│ │ └── mcp.go # MCP server integration
│ ├── server/
│ │ └── ssh.go # Wish SSH server
│ └── ui/
│ ├── app.go # Main Bubble Tea app + key bindings
│ ├── kanban.go # Kanban board view (4 columns)
│ ├── detail.go # Task detail view with logs
│ ├── form.go # New/edit task forms (Huh)
│ ├── retry.go # Retry task with feedback
│ ├── settings.go # Settings view
│ ├── command_palette.go # Quick task navigation
│ ├── attachments.go # File attachment handling
│ ├── filebrowser.go # File browser component
│ ├── theme.go # Theme configuration
│ ├── styles.go # Lip Gloss styles
│ └── url_parser.go # URL detection in text
├── scripts/
│ └── install-service.sh # Systemd service installer
├── go.mod
├── go.sum
├── Makefile
└── README.md
make build # Build bin/ty and bin/taskd
make build-ty # Build just the CLI
make build-taskd # Build just the daemon
make install # Install to ~/go/bin
make test # Run tests
make lint # Run linter
make fmt # Format code./bin/ty -l # Launch TUI locally (starts daemon)
./bin/ty daemon # Start background executor
./bin/ty daemon stop # Stop daemon
./bin/ty daemon status # Check daemon status
./bin/ty daemon restart # Restart daemon
./bin/ty claudes list # List running Claude sessions./bin/taskd # Start SSH server on :2222
./bin/taskd -addr :22222 # Custom port
./bin/taskd -db /path/to/tasks.db # Custom databasessh -p 2222 user@server # Opens TUI directlyCREATE TABLE tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
body TEXT DEFAULT '',
status TEXT DEFAULT 'backlog', -- backlog, queued, processing, blocked, done
type TEXT DEFAULT '', -- Customizable via task_types table
project TEXT DEFAULT '',
worktree_path TEXT DEFAULT '', -- Path to git worktree
branch_name TEXT DEFAULT '', -- Git branch name
port INTEGER DEFAULT 0, -- Unique port (3100-4099)
claude_session_id TEXT DEFAULT '',-- For resuming Claude conversations
daemon_session TEXT DEFAULT '', -- tmux session name
dangerous_mode INTEGER DEFAULT 0,-- Skip Claude permissions
pr_url TEXT DEFAULT '', -- Pull request URL
pr_number INTEGER DEFAULT 0, -- Pull request number
scheduled_at DATETIME, -- When to next run
recurrence TEXT DEFAULT '', -- Deprecated recurrence pattern (kept for legacy display)
last_run_at DATETIME, -- Last scheduled execution time
created_at DATETIME,
updated_at DATETIME,
started_at DATETIME,
completed_at DATETIME
);
CREATE TABLE task_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
line_type TEXT DEFAULT 'output', -- system, text, tool, error, output
content TEXT NOT NULL,
created_at DATETIME
);
CREATE TABLE projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
path TEXT NOT NULL,
aliases TEXT DEFAULT '',
instructions TEXT DEFAULT '', -- Project-specific AI instructions
actions TEXT DEFAULT '[]', -- Custom actions
color TEXT DEFAULT '', -- Hex color for label
created_at DATETIME
);
CREATE TABLE task_types (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
label TEXT NOT NULL,
instructions TEXT DEFAULT '', -- Type-specific AI instructions
sort_order INTEGER DEFAULT 0,
is_builtin INTEGER DEFAULT 0,
created_at DATETIME
);
CREATE TABLE task_attachments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
filename TEXT NOT NULL,
mime_type TEXT DEFAULT '',
size INTEGER DEFAULT 0,
data BLOB NOT NULL,
created_at DATETIME
);
CREATE TABLE settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);Database location: ~/.local/share/task/tasks.db (configurable via WORKTREE_DB_PATH)
backlog → queued → processing → done
↘ blocked (needs input)
blocked can return to processing via retry
- backlog - Created but not yet started
- queued - Waiting in executor queue
- processing - Claude is actively executing
- blocked - Waiting for user input/clarification
- done - Completed successfully
Recurring scheduling has been removed from TaskYou. Use external schedulers (cron, calendar apps, etc.) to invoke the CLI whenever a task should repeat.
| Key | Action |
|---|---|
←/→ or h/l |
Navigate columns |
↑/↓ or j/k |
Navigate tasks |
Enter |
View task details |
n |
New task |
e |
Edit task |
x |
Execute (queue) selected task |
r |
Retry task with feedback |
c |
Close selected task |
d |
Delete selected task |
t |
Pin/unpin selected task |
s |
Settings |
S |
Change task status |
R |
Refresh list |
p / ctrl+p |
Command palette (go to task) |
! |
Toggle dangerous mode |
B |
Focus Backlog column |
P |
Focus In Progress column |
L |
Focus Blocked column |
D |
Focus Done column |
? |
Toggle help |
q / esc |
Back / Quit |
ctrl+c |
Force quit |
- Bubble Tea - TUI framework (Elm architecture)
- Bubbles - Components (help, textinput, viewport)
- Lip Gloss - Styling and layout
- Glamour - Markdown rendering
- Huh - Forms
- Wish - SSH server
The background executor (internal/executor/executor.go):
- Polls for
queuedtasks every 2 seconds - Creates isolated git worktrees for each task
- Runs AI coding agents in tmux windows with hooks
- Streams output to
task_logstable - Supports real-time watching via subscriptions
- Handles task suspension and resumption
- Manages scheduled tasks (recurring runs must now be handled externally via CLI automation)
TaskYou supports multiple AI coding agent backends:
- claude (default) - Claude Code CLI with hooks and session resume
- codex - OpenAI Codex CLI with dangerous mode support
- gemini - Google Gemini CLI with configurable dangerous mode flags
- pi - Pi coding agent with session continuity
- openclaw - OpenClaw AI assistant
- opencode - OpenCode AI assistant
Each task can specify its executor in the task form. The executor runs in an isolated git worktree with environment variables for task context.
Tasks run in tmux windows with hooks that track state:
- PreToolUse - Before tool execution, ensures task is "processing"
- PostToolUse - After tool completes, ensures task stays "processing"
- Notification - When idle or needs permission, marks task "blocked"
- Stop - When Claude finishes responding, updates state accordingly
Each task gets an isolated git worktree:
~/.local/share/task/worktrees/{project}/task-{id}
Environment variables available in worktrees:
WORKTREE_TASK_ID- Task identifierWORKTREE_PORT- Unique port (3100-4099)WORKTREE_PATH- Worktree directory pathWORKTREE_SESSION_ID- tmux session IDWORKTREE_DANGEROUS_MODE- If permissions are skipped
Prompts are built with:
- Task-type-specific instructions
- Project-specific instructions
- Previous conversation history (on retry/resume)
- File attachments
- Task title and body
⚡ IMPORTANT: TaskYou caches codebase exploration results to avoid redundant work.
Best Practice Workflow:
- Start every task by calling
taskyou_get_project_contextMCP tool - If context exists: Use it to understand the codebase, skip exploration
- If empty: Explore the codebase once, then save via
taskyou_set_project_context - Future tasks will reuse this context, saving time and tokens
Example:
Agent: taskyou_get_project_context()
TaskYou: "## Cached Project Context\n\nThis is a Go project using Bubble Tea..."
[Agent uses the context to work efficiently]
Or if no context exists:
Agent: taskyou_get_project_context()
TaskYou: "No cached project context found. Please explore and save a summary."
Agent: [explores key files and directories]
Agent: taskyou_set_project_context("This is a Go project using:
- Bubble Tea for TUI
- SQLite for storage
Key directories: internal/db/, internal/executor/, internal/ui/...")
TaskYou: "Project context saved. Future tasks will use this."
What to include in context:
- Project structure and key directories
- Tech stack and frameworks
- Coding conventions and patterns
- Important files and their purposes
- Development workflows
When to update context:
- After major refactorings
- When new patterns are introduced
- After significant file reorganization
This feature is inspired by Boris Cherny's Claude Code improvements and dramatically improves multi-task efficiency.
-
Build for Linux:
make build-linux
-
Deploy to server:
make deploy
-
Install systemd service:
./scripts/install-service.sh
Currently accepts all keys. To restrict, edit internal/server/ssh.go:
wish.WithPublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool {
// Compare key fingerprint against allowed list
return allowed[ssh.FingerprintSHA256(key)]
})| Variable | Description | Default |
|---|---|---|
WORKTREE_DB_PATH |
SQLite database path | ~/.local/share/task/tasks.db |
TASK_EXECUTOR |
Overrides the executor name shown in the UI (e.g., codex) |
Claude |
WORKTREE_TASK_ID |
Current task ID (set by executor) | - |
WORKTREE_PORT |
Task-specific port | - |
WORKTREE_PATH |
Worktree directory | - |
WORKTREE_SESSION_ID |
tmux session ID | - |
WORKTREE_DANGEROUS_MODE |
Skip Claude permissions | - |
WORKTREE_CWD |
Working directory for project detection | - |
GEMINI_DANGEROUS_ARGS |
Overrides the Gemini CLI flags used when dangerous mode is enabled | --dangerously-allow-run |
Set TASK_EXECUTOR before launching task -l/task daemon to change the executor label shown in the UI (e.g., TASK_EXECUTOR=codex). For compatibility, WORKFLOW_EXECUTOR, TASKYOU_EXECUTOR, and WORKTREE_EXECUTOR are also recognized.
Create .taskyou.yml in your project root:
worktree:
init_script: bin/worktree-setupThe init script runs after worktree creation for setup tasks like:
- Installing dependencies
- Setting up databases
- Copying configuration files
- Running migrations