Skip to content

Latest commit

 

History

History
1532 lines (1130 loc) · 66 KB

File metadata and controls

1532 lines (1130 loc) · 66 KB

TaskYou reference

Start with your first task or choose a workflow. This manual covers the full command surface and configuration.

Find what you need

The TUI — first class

The terminal UI is TaskYou's primary interface — everything ships here first. Launch it with ty.

Kanban Board

Kanban Board The main view showing tasks organized across Backlog, In Progress, Blocked, and Done columns

List View

Press v to swap the four columns for one flat line per task — the same board, at a quarter of the vertical cost. Pair it with a saved view and the whole "what am I working on right now?" answer fits on one screen:

List view showing the Active saved view v for the list, with the Active view applied — in progress and blocked, nothing else

Rows carry the same badges as cards (PR state and diff, running dot, permission mode, host, pin, dependency lock) plus an age hint. Every key that works on a card works on a row — the selection is shared, so v never loses your place. B/P/L/D jump to the first task of a status instead of focusing a column.

Arranging the list

Press O. Two choices, previewed live as you cycle them:

Options
Group by status · project · none Sections, with a count per section
Sort urgency · updated · created · title Order inside each section

The arrange-list widget

The current arrangement is always on screen under the header, so it is never a setting you have to remember you changed. It persists with the rest of the board state (list_group_by, list_sort), and is shared with the GUI: the desktop app and ty serve read the same keys, so the board you left in one is the board you come back to in the other.

Whatever the grouping, pinned tasks lead the list in their own section: pinning means "keep this in sight", and scattering pinned tasks through project sections is what pinning exists to prevent.

Row height is not an option. A row is one line — except a running or blocked task, which grows a second, dim line carrying the same live activity the kanban card shows: what its agent is doing, or the stand it is waiting on. That is the one thing a card says that a line cannot, and it is only ever true of live tasks; a backlog item has nothing to report, so a second line there would buy nothing.

Redundancy is dropped rather than repeated: grouping by status keeps a coloured status glyph on each row but moves the word to the header, and grouping by project drops the per-row [project] tag entirely, giving the width to titles.

Saved Views

A view is a name plus a filter query. Press V for the picker:

The saved views picker

Key Action
enter Apply the highlighted view
n Save the current filter as a new view
d then y Delete a view
c Clear the filter
esc Cancel

The display mode, the filter, and the applied view name are persisted, so the board you left is the board you come back to. Typing over an applied view detaches it — a view is a starting point, not a lock.

Three starter views ship on first run: Active (status:in-progress status:blocked), Pinned (is:pinned), and In review (has:pr status:blocked). Delete one and it stays deleted.

Filter query grammar

The same grammar works in the filter bar (/), in a saved view, in ty list --filter, and over the HTTP API:

Token Matches
status:blocked, is:blocked One status (backlog, queued, processing, blocked, done, archived)
status:in-progress Queued and processing
status:open Anything not done or archived
is:pinned / is:unpinned Pin state
is:workflow / is:task Workflow steps vs standalone tasks
has:pr / no:pr Tasks with / without a pull request
tag:release Tasks carrying a tag
[offerlab] A project, by name or alias (repeatable; OR'd together)
anything else Free-text fuzzy search

Repeating status: ORs the statuses together; every other token ANDs. An unrecognised word:value is not a token — it stays searchable text rather than silently matching nothing.

Task Detail View

Task Detail View Viewing a task with Claude's output and shell access in split panes

Workflow handoff

Completed plan with implementation already processing The plan step is done; its dependent implementation task is processing.

New Task Form

New Task Form Creating a new task with project selection, type, executor, effort, permissions, and attachments

Show the focused task in your tab title

The TUI publishes the task you have open in the detail view as iTerm2 user variables, and blanks them the moment you leave it — so the board never names the task you last visited:

Variable Example
user.taskyouTask #5202 Fix login
user.taskyouTaskId 5202
user.taskyouTaskTitle Fix login

They are session variables. Badges and status bar components can use \(user.taskyouTask) directly. Tab titles are evaluated in tab scope, so reach the session through currentSession: to keep your own tab name and append the task, choose Edit Tab Title and enter ty \(currentSession.user.taskyouTask). Other terminals ignore the variables, so nothing changes unless you reference them.

The CLI

Everything the TUI can do, the CLI can do too — create, execute, retry, and inspect tasks, read executor output, even send keystrokes to a running executor. That makes TaskYou trivial to drive from scripts, cron jobs, and AI agents.

CLI Creating a task and checking the board without leaving your shell

See Full CLI Scriptability for the complete command surface.

The GUI

Web UI The same Kanban board in the desktop app or any browser

Just want the GUI? On macOS, install it with one command:

curl -fsSL taskyou.dev/install-macos.sh | bash

This downloads the latest DMG, verifies it, installs TaskYou.app to ~/Applications, and launches it — no Gatekeeper prompts, no sudo. Set TASKYOU_INSTALL_SYSTEM=1 to install to /Applications for all users instead.

Or grab a prebuilt bundle from the latest release:

  • macOS: TaskYou-macos-arm64.dmg (Apple Silicon only)
  • Linux: TaskYou-linux-x64.AppImage or .deb

The app is self-contained — it ships its own ty engine and starts the server and daemon for you. Two things must be installed on your machine: tmux (brew install tmux) and at least one executor CLI (e.g. Claude Code).

The macOS bundles are ad-hoc signed but not notarized, so macOS flags DMGs downloaded in a browser on first launch (the install script above avoids this entirely). If you installed from a browser-downloaded DMG, drag TaskYou.app to Applications, then either right-click it → Open → Open, or clear the download quarantine flag:

xattr -dr com.apple.quarantine /Applications/TaskYou.app

The same UI is also served in your browser at http://localhost:8080 whenever ty serve runs with the embedded UI (make build-ui build). Desktop gets a real PTY executor terminal; the browser falls back to a live terminal mirror. Source lives in desktop/.

Features

  • Kanban Board - Visual task management with 4 columns (Backlog, In Progress, Blocked, Done)
  • List View & Saved Views - v swaps the columns for a flat one-line-per-task list; V manages named filter views (status:in-progress status:blocked, is:pinned, [offerlab]). The filter and display mode persist across restarts (see List View)
  • Git Worktrees - Each task runs in an isolated worktree, no conflicts between parallel tasks
  • Pluggable Executors - Choose between Claude Code, OpenAI Codex, Gemini, Pi, OpenClaw, or OpenCode per task
  • Workflows - Turn one goal into a multi-step DAG (e.g. plan → code → parallel review → collect), each step on its own executor/model, advancing automatically (see Workflows)
  • Event Hooks & Plugins - Run scripts when tasks change state, or drop in self-contained plugins (see Event Hooks and Plugins)
  • Ghost Text Autocomplete - LLM-powered suggestions for task titles and descriptions as you type
  • VS Code-style Fuzzy Search - Quick task navigation with smart matching (e.g., "dsno" matches "diseno website")
  • Markdown Rendering - Task descriptions render with proper formatting in the detail view
  • Real-time Updates - Watch tasks execute live
  • Running Process Indicator - Green dot (●) shows which tasks have active shell processes (servers, watchers, etc.)
  • Auto-cleanup - Automatic cleanup of Claude processes for completed tasks (see maintenance commands for config cleanup)
  • Fully Scriptable CLI - 100% of Task You is controllable via CLI—agents can manage tasks, read executor output, and send input to running executors programmatically (see Full CLI Scriptability)
  • SSH Access - Run as an SSH server to access your tasks from anywhere (see SSH Access & Deployment)
  • Project Context Caching - AI agents automatically cache codebase exploration results and reuse them across tasks, eliminating redundant exploration (see Project Context)
  • Shell Completion - Tab completion for commands, task IDs, projects, statuses, and flags in bash, zsh, fish, and PowerShell (see Shell Completion)

Workflows

A workflow turns a single goal into a small DAG of step tasks that run on one shared git branch, each routed to its own executor and model, advancing automatically. Steps are sequential where they depend on each other and parallel where they don't.

Workflows come from two places: ones you install from a plugin (grab battle-tested ones like rpi with ty plugins add) and YAML files you write yourself. Nothing is compiled into the binary. For example, a plan-code-review workflow — shipped as an example plugin under examples/plugins/:

Plan ──▶ Code ──▶ Review A ─┐
                  Review B ─┴─▶ Collect ──▶ PR
Step Model Job
Plan Opus Explore, write PLAN.md, push. No code.
Code Sonnet Implement the plan, push.
Review A, Review B Opus, Sonnet Two independent reviewers in parallel — different models + independent context catch different issues and avoid self-review bias.
Collect Sonnet Read both reviews, apply the fixes worth applying, open the PR.

Steps advance with no human in the loop; a workflow only pauses when a step genuinely needs one — the final step opens a PR (landing in blocked for a human merge) or a step asks for input.

Running a workflow

# CLI — pick the kind with -d (there is no default workflow)
ty pipeline "Add rate limiting to the API" -p myapp -d plan-code-review
ty pipeline --list                 # show available workflows (the YAML files)
ty pipeline "..." -d <kind> --no-execute   # stage without starting

# TUI: in the new-task form (n), pick it in the "Kind" selector (types and workflows in one list).

On the board, a workflow shows as a single card (⇄ goal · Review ∥ · 3/5) instead of one card per step. It needs a project that uses git worktrees and has a remote to push to.

Authoring workflows

Workflows are plain YAML files — one per workflow — in ~/.config/task/workflows/*.yaml (override with $TY_WORKFLOWS_DIR), or per-project in .taskyou/workflows/. The file name is the kind name. You write only what each step does and its deps; the git handoff (which branch to push to, when to open the PR) is derived from the step's position in the DAG.

name: build-and-qa
description: Plan, build, then security review and QA in parallel, then finalize.
steps:
  - {name: Plan,     model: opus,   prompt: "Design a plan for {{goal}}; write PLAN.md."}
  - {name: Build,    deps: [Plan],  prompt: "Implement the plan."}
  - {name: Security, deps: [Build], prompt: "Security review; write findings to security.md."}
  - {name: QA,       deps: [Build], prompt: "Exercise the change; write results to qa.md."}
  - {name: Finalize, deps: [Security, QA], prompt: "Address the findings and finalize."}

Two steps with the same deps run in parallel; a step depending on several joins them; multiple root steps (no deps) are parallel entry points (e.g. try 3 approaches at once).

# Author a workflow from a plain-English description (LLM → YAML you can edit)
ty pipeline new "spike three approaches, pick the best, build it, review and test in parallel"

# Eject any workflow — built-in, plugin, or installed — to a local YAML file to tweak its models / prompts / steps
ty pipeline edit rpi               # writes ~/.config/task/workflows/rpi.yaml (shadows the built-in)

Custom workflows appear in ty pipeline --list, the --definition flag, and the TUI new-task selector automatically. Configuration lives entirely in these files — edit them by hand any time.

Reality gates — bind a step to your build and tests

By default a step is "done" when its agent says so. Add a verify: command and that claim has to survive contact with reality first: when the step tries to complete, TaskYou runs the command in the worktree and only advances the workflow if it passes (exit 0) — on the agent's own signal and on the daemon's git-completion sweep, so there's no path around it.

steps:
  - name: implement
    verify: go build ./... && go test ./...   # must be green before the DAG advances
    prompt: "Implement the plan."

A failing check keeps the step running and hands the command's output back to the agent, so it fixes the real problem instead of reporting a success it doesn't have. It's the antidote to an agent marking a step done on a red build — and it's what lets a simplify step cut a change down while the tests stay the safety net.

Kinds: a task type and a workflow are the same thing

A kind is what you pick when you make a task — code, writing, thinking, plan-code-review, rpi, or any you add. There is no separate "workflow" you choose instead: the same pick runs as a single task when nothing defines steps for that name, and as a multi-step workflow when a definition with steps exists for it.

pick "code"             → single task   (a kind with instructions, no steps)
pick "plan-code-review" → workflow      (a kind whose definition adds steps)

Picking a kind resolves by name, and two sources answer to that name — a definition wins over a DB task type:

Source Where it lives What it gives the kind
Definition plugin workflows/ → global ~/.config/task/workflows/ → project .taskyou/workflows/ (nothing is compiled into the binary) steps (→ workflow), or just instructions (→ single task)
DB task type the tasks database (code, writing, thinking, plus any you add) instructions (→ single task)

Definitions are layered lowest-to-highest and a later layer shadows an earlier one by name, so your own ~/.config/task/workflows/rpi.yaml overrides the built-in rpi, and a project file overrides everything. ty pipeline --list shows them all, labelled built-in or custom. Adding steps is the only thing that makes a kind a workflow: drop a code.yaml with steps beside the code type and that same pick upgrades from a single task to a DAG.

A workflow's steps can run other kinds by name — and if a referenced kind is itself a workflow (has a file), its steps are inlined at build time, so you compose big flows from small ones:

# ~/.config/task/workflows/ship.yaml
name: ship
steps:
  - {name: Build,  kind: plan-code-review}          # a whole workflow, inlined
  - {name: QA,     kind: code, deps: [Build]}        # a DB kind → sets the step's type
  - {name: Deploy, prompt: "Deploy it.", deps: [QA]}

A step's kind: sets that step's task type, so the kind's instructions apply — code, writing, or any kind is referenceable with no extra wiring. Cycles and runaway nesting are rejected at build time.

Project Context

TaskYou implements intelligent codebase caching to make AI agents dramatically more efficient across multiple tasks in the same project.

How It Works

When an AI agent starts a task, it can:

  1. Check for cached context via taskyou_get_project_context MCP tool
  2. Use existing context if available, skipping redundant exploration
  3. Explore once and save via taskyou_set_project_context for future tasks

This cached context is stored in the projects.context database column and persists across all tasks in that project.

Benefits

  • Faster task startup - No need to re-explore the codebase on every task
  • Consistent understanding - All tasks share the same baseline knowledge
  • Token efficiency - Avoids burning tokens on repeated exploration
  • Better continuity - Agents build on previous learnings

Example Usage

When an agent starts a task, it first checks for context:

Agent: taskyou_get_project_context()
TaskYou: "## Cached Project Context

This is a Go project using:
- Bubble Tea for TUI
- SQLite for storage
- Charm libraries for styling

Key directories:
- internal/db/ - Database layer
- internal/executor/ - Task execution
- internal/ui/ - UI components
..."

If no context exists, the agent explores once and saves it:

Agent: [explores codebase]
Agent: taskyou_set_project_context("...")
TaskYou: "Project context saved. Future tasks will use this."

Best Practices

What to include in context:

  • Project structure and key directories
  • Tech stack and frameworks used
  • Coding conventions and patterns
  • Important files and their purposes
  • Common development workflows

When to update:

  • After major refactorings
  • When new patterns are introduced
  • After significant file reorganization
  • When the tech stack changes

Context is per-project - Each project maintains its own cached context, preventing cross-contamination.

Related Features

  • Task types can have their own instructions that complement project context
  • Project-level instructions (in the database) add project-specific guidance
  • Both are automatically included in agent prompts alongside cached context

See the agent orchestration guide for using the CLI from an agent.

Prerequisites

  • Go 1.26.0+ - Required to build the project

Using mise (recommended)

If you use mise for dependency management, simply run:

mise install

This will install the correct Go version automatically.

Manual installation

Install Go 1.26.0 or later from go.dev/dl.

Installation

Quick Install (recommended)

curl -fsSL taskyou.dev/install.sh | bash

This downloads the latest release and installs ty (with taskyou as an alias) to ~/.local/bin.

You can also specify a custom install directory:

curl -fsSL https://taskyou.dev/install.sh | INSTALL_DIR=~/.local/bin bash

Upgrading

ty upgrade runs the same install script. If a ty daemon is running, the script then runs ty restart. The daemon restarts and open TUIs reload the new binary in place, with agents left running. To install without restarting:

curl -fsSL https://taskyou.dev/install.sh | bash -s -- --no-restart

Build from source

git clone https://github.com/bborn/taskyou
cd taskyou
make build

Usage

# Launch the TUI (auto-starts background daemon)
./bin/ty

# Launch straight into a task. An ID, #ID, task branch or GitHub PR URL opens
# its detail view (esc goes back to the board); other text opens the board
# with the go-to-task palette searching for it.
./bin/ty open 123
./bin/ty open https://github.com/org/repo/pull/456
./bin/ty open draft offers

In zsh with interactivecomments set, quote a leading # (ty open '#123'), or the shell drops it as a comment.

Daemon management

./bin/ty daemon         # Start daemon manually
./bin/ty daemon stop    # Stop the daemon
./bin/ty daemon status  # Check daemon status

Restarting without closing terminals

ty restart restarts the daemon and asks local TUIs using the same database to reload the current binary in place. Their tmux sessions stay open. Task selection, board filter, and the open detail view are restored, and borrowed agent panes are returned before reloading. Unsaved forms and pending task saves defer the reload.

TUIs started with an older build that lacks cooperative reload remain running; reopen those once with the updated build to enable future automatic reloads. POST /api/tui/reload requests the same cooperative TUI reload through the HTTP API. ty daemon restart only restarts the daemon. ty restart --hard remains an explicit destructive reset that kills TaskYou tmux sessions.

Upgrading does this for you: when a ty daemon is running, ty upgrade (and the install script it runs) finishes with ty restart.

Diagnosing an install

ty doctor checks everything a working install depends on — daemon, its build and environment against this binary, tmux and the agent server, a live task's generated Claude hooks and MCP config, the database and its schema, the status log, executor binaries, GitHub auth — and changes none of it. --json gives a stable machine-readable report and --strict exits non-zero on warnings too, for a fleet sweep.

ty doctor                 # human report
ty doctor --json          # {status, checks:[{id,status,summary,details}]}
ty doctor --strict        # exit non-zero on warnings as well as errors

The daemon also records its build, protocol and key environment where clients can read it, so a TUI or CLI on a different build says so instead of misbehaving quietly. See Diagnostics for the handshake, the protocol number, and what happens on a remote or placed host running an older ty.

Maintenance commands

./bin/ty purge-claude-config            # Remove stale ~/.claude.json entries
./bin/ty purge-claude-config --dry-run  # Preview what would be removed
./bin/ty claudes cleanup                # Kill orphaned Claude processes

Full CLI Scriptability

Task You is 100% scriptable. Every action you can perform in the TUI is available via the ty CLI, making it trivial for AI agents, scripts, or external orchestrators to control your entire task queue programmatically.

This includes:

  • Board state - ty board --json returns the full Kanban snapshot
  • Task management - ty create, ty execute, ty retry, ty status, ty pin, ty close, ty archive, ty delete
  • Direct executor interaction - ty input sends keystrokes/text to running executors, ty output reads their output
  • Session management - ty sessions list, ty sessions cleanup
  • Saved views - ty views lists them, ty views save <name> "<query>" creates or replaces one, ty views show <name> prints what it matches, ty views delete <name> removes it
  • Filtered listing - ty list --view active applies a saved view; ty list --filter "status:in-progress status:blocked" applies a query inline (same grammar as the TUI filter bar)
ty views save active "status:in-progress status:blocked"
ty views save offerlab "[offerlab] status:open"
ty list --view active --json
ty list --filter "has:pr status:blocked"      # waiting on review

Views are exposed over the HTTP API too: GET/POST /api/views and GET/PATCH/DELETE /api/views/{name}. GET /api/views/{name} returns the view plus the tasks it currently matches, so a client never has to reimplement the query grammar — which is exactly how the GUI applies a view.

In the GUI

The desktop app and ty serve have the same three controls: v toggles the list, V opens the saved views, and O arranges it — plus clickable equivalents in the toolbar above the list. Grouping, sort and the applied view persist to the same settings keys the TUI uses.

Because agents can send input to running executors via ty input, they can answer prompts, confirm dialogs, navigate menus, and fully control tasks mid-execution—no human intervention required.

See docs/orchestrator.md for a complete guide to building your own orchestration agent.

Auto-cleanup: The daemon automatically cleans up Claude processes for tasks that have been done for more than 30 minutes, preventing memory bloat from orphaned processes.

Note: Automatic cleanup currently only works for the Claude executor. When using other executors (Codex, Gemini, Pi, etc.), you may need to manually clean up processes using ty sessions cleanup to prevent memory bloat.

AI Agent Skill

Task You includes a /taskyou skill that teaches any AI agent how to orchestrate your task queue via CLI.

Automatic availability: The skill is automatically available when working inside the Task You project directory (via skills/taskyou/).

Global installation: To use the skill from any project:

./scripts/install-skill.sh

Once available, you can ask Claude things like:

  • "Show me my task board"
  • "Execute the top priority task"
  • "What's blocked right now?"
  • "Create a task to fix the login bug"

The skill works with Claude Code, Codex, Gemini, or any agent that can execute shell commands. It provides structured guidance for common orchestration patterns without needing to memorize CLI flags.

Keyboard Shortcuts

Kanban Board

Key Action
←/→ or h/l Navigate columns
↑/↓ or j/k Navigate tasks
Enter View task details
n Create new task
x Execute (queue) task
r Retry task with feedback
c Close task
a Archive task
d Delete task
t Pin/unpin task
o Open task's working directory
p Command palette (fuzzy search)
/ Filter tasks
v Toggle list / board view
V Saved views picker
O Arrange list (group / sort / density)
s Settings
m Plugin catalog (search, install, remove)
u Routines
? Toggle help
q Quit

Task Detail View

Key Action
e Edit task
x Execute task
r Retry with feedback
S Change task status
t Pin/unpin task
! Toggle dangerous/safe mode
\ Toggle shell pane visibility
Shift+↑/↓ Switch between panes
Alt+Shift+↑/↓ Jump to prev/next task (stays in executor pane)
c Close task
a Archive task
d Delete task
Esc Back to kanban

The agent/shell split is remembered per task: drag the divider in one task and only that task reopens at the new width. A task you have never resized opens at the even 50/50 split (or at the width you had set before widths became per-task).

Task Form (Autocomplete)

Key Action
Tab Accept ghost text suggestion
Escape Dismiss suggestion
Ctrl+Space Manually trigger suggestion

Task Lifecycle

backlog → queued → processing → done
                 ↘ blocked (needs input)
Status Description
backlog Created but not started
queued Waiting to be processed
processing Currently being executed
blocked Needs input/clarification
done Completed

Task Executors

Task You supports multiple AI executors for processing tasks. You can choose the executor when creating or editing a task.

Developers who want to add another backend should read docs/executor_interface.md for the full TaskExecutor contract.

Executor CLI Description
Claude (default) claude Claude Code - Anthropic's coding agent with session resumption
Codex codex OpenAI Codex CLI - OpenAI's coding assistant
Gemini gemini Gemini CLI - Google's Gemini-based coding assistant
Grok grok Grok CLI - xAI's coding assistant with session resumption
Cursor agent / cursor-agent Cursor CLI - Cursor's coding agent with session resumption
Pi pi Pi Coding Agent - Multi-provider AI coding agent with session continuity
OpenCode opencode OpenCode - Open-source AI coding assistant with multi-LLM support
OpenClaw openclaw OpenClaw - Open-source personal AI assistant with session resumption

All executors run in tmux windows with the same worktree isolation and environment variables. The main differences:

  • Claude Code, Grok, Cursor, Pi, and OpenClaw support session resumption - when you retry a task, they continue with full conversation history
  • Codex and Gemini start fresh on each execution but receive the full prompt with any feedback
  • OpenCode does not support session resumption

Installing Executors

At least one executor CLI must be installed for tasks to run:

# Claude Code (recommended)
# See https://claude.ai/claude-code for installation

# OpenAI Codex CLI
npm install -g @openai/codex

# Google Gemini CLI
# See https://ai.google.dev/gemini-api/docs/cli for installation instructions

# Grok CLI
curl -fsSL https://x.ai/cli/install.sh | bash

# Cursor Agent CLI
curl https://cursor.com/install -fsS | bash

# Pi Coding Agent
npm install -g @mariozechner/pi-coding-agent

# OpenClaw
npm install -g openclaw@latest
openclaw onboard  # Run setup wizard

How Task Executors Work

Understanding how Task You manages executor processes helps you debug issues and work with running tasks.

tmux-Based Architecture

Task executors run inside tmux windows within a daemon session:

task-daemon-{PID}              (tmux session)
├── _placeholder               (keeps session alive)
├── task-123                   (window for task 123)
│   ├── pane 0: Executor       (left - Claude/Codex output)
│   └── pane 1: Shell          (right - workdir access)
├── task-124                   (window for task 124)
└── ...

When you execute a task:

  1. The daemon ensures a task-daemon-* session exists
  2. Creates a new tmux window named task-{ID}
  3. Spawns the configured executor (Claude or Codex) with environment variables and the task prompt
  4. Creates a shell pane for manual intervention

Each pane is tagged with its task and role (@ty_task, and @ty_role set to agent or shell), so ty finds a task's panes by asking tmux instead of trusting a pane ID it stored earlier. Sessions nobody is looking at are sized 200×50, and ty sizes its own session to your terminal before attaching, so nothing reflows when you open it.

Opening a task never moves its panes. The detail view splits the TUI's own pane and runs a nested tmux client in it, attached to a throwaway session that is grouped with the daemon session and pointed at the task's window. The agent and shell stay in the daemon session the whole time. Quitting, reloading or crashing the TUI cannot take them with it, and several TUIs can show the same task at once. In the view:

  • Shift+↓ / Shift+→ go to the next pane and Shift+↑ / Shift+← to the previous one, round task details → agent → shell → task details, the same cycle as before the view existed. Clicking works too.
  • Every key goes to the agent or the shell: the view has no prefix key of its own. Scroll with the mouse wheel.
  • \ hides the shell. A hidden shell keeps running in a _hidden_shell_<id> window in the daemon session.
  • If the task's window closes (its agent was killed, it was suspended, or the tmux server went away), the view closes with it rather than show another task. What happens next depends on the task's status at that moment:
    • A queued or running task: ty waits up to a minute for the daemon's executor, then starts the agent itself and shows it again.
    • A blocked task is not restarted. The idle sweep suspends parked tasks to free their memory, and restarting one would undo that. The view says the session closed; open the task again to resume it.
    • A finished task is left alone.
  • If the TUI crashes or is killed, its view pane closes within a second. The agent keeps running.

Which tmux server

New installs run their agents on a private tmux server, tmux -L taskyou, so ty's sessions, options and key bindings never mix with your own tmux. An install whose agents were already on tmux's default server when it first ran this version keeps using the default server, so no running agent drops out of sight. The choice is recorded in tmux-socket next to the database (~/.local/share/task/tmux-socket). The desktop app reads the same file.

To Do
Attach to the agents by hand tmux -L taskyou attach -t task-daemon-<id> (on the default server, plain tmux attach)
Override the choice Set TASKYOU_TMUX_SOCKET=taskyou (or default) for every ty process
Move an existing install to the private server See below

To move an existing install to the private server, first stop ty's agents on the default server; otherwise they keep running there, out of ty's sight. Then record the choice while nothing of ty's is running:

  1. Quit every open ty.
  2. ty daemon stop
  3. tmux ls -F '#{session_name}' | grep -E '^task-(daemon|ui)-' | xargs -n1 tmux kill-session -t. This stops ty's sessions on the default server and leaves your own alone.
  4. echo taskyou > ~/.local/share/task/tmux-socket
  5. ty

Opening a task afterwards resumes its Claude session. ty restart --hard cannot stand in for steps 1–3: it relaunches ty at once, and that reads the old choice before step 4 can change it.

ty still works inside your own tmux: the TUI stays in your session, and the task view attaches across to the agent server.

Session Tracking

Each task tracks its executor state in the database:

Field Purpose
SessionID Executor session ID (Claude only, for resumption)
TmuxWindowID Unique window target for tmux commands
daemon_session Which task-daemon-* owns this task
ClaudePaneID, ShellPaneID The task's pane IDs, kept as a cache; the pane tags win when they disagree
Port Unique port (3100-4099) for the worktree

Managing Executor Processes

Inside the TUI:

  • The green dot (●) indicates tasks with active processes

From the command line:

# List all running executor processes, here and on the hosts tasks were placed on
./bin/ty sessions list

# Kill orphaned executor processes (and the side processes that outlived them)
./bin/ty sessions cleanup

# See exactly what would be killed, and why, without killing anything
./bin/ty sessions cleanup --dry-run

Remotely placed tasks. sessions list asks each host that currently holds placed tasks which of their agent windows are alive, so a task running elsewhere appears alongside the local ones with its host in the last column. Memory is only measured on this machine, and a host that cannot be reached is named in the listing rather than dropped — an empty list means "nothing is running", not "ty did not look". sessions cleanup and sessions suspend remain local-only: they kill processes, and they kill them here.

Orphaned side processes. Killing a task's tmux window only SIGHUPs the pane's foreground process group. A dev server that was backgrounded, disowned, or setsid'd has left that group, so once its parent shell dies it is reparented to launchd/init and survives every teardown, leaking gigabytes of swap over days. ty sessions cleanup therefore runs a second pass that finds those by the task worktree path on their command line and SIGTERMs (then SIGKILLs) them. ty sessions suspend does the same for the tasks it suspends.

The sweep is deliberately conservative:

  • Blocked tasks are live work. In ty, blocked usually means "waiting for a human". Their side processes are only reaped after a long stretch of no activity at all, measured from the last status change, log line, or UI visit. Their agent process is never reaped on staleness.
  • Absent is not deleted. A task that is not in this machine's database may have been placed here from another machine, so its processes are left alone.
  • Processing and queued tasks are never touched, nor is anything still running inside a live tmux pane.
Setting Default Meaning
reap_blocked_idle 24h Idle time before a blocked or backlog task's side processes are reaped. 0/disabled turns staleness reaping off.
reap_orphan_min_age 24h Minimum age for the no-worktree heuristic: a known JS dev server reparented to init with no terminal.
reap_orphan_dev_servers true Set to false to disable that heuristic entirely.

Direct executor interaction:

# See what the executor is outputting
./bin/ty output <id>              # Last 50 lines
./bin/ty output <id> --lines 100  # More history

# Send input directly to a running executor
./bin/ty input <id> "yes"         # Send text + Enter
./bin/ty input <id> --enter       # Just press Enter (confirm prompts)
./bin/ty input <id> --key Down --enter  # Navigate + confirm
echo "continue" | ./bin/ty input <id>   # Pipe input

Both work wherever the task is running. A task a placement plugin put on another host has its executor pane in a tmux server over there, and ty input and ty output reach it over ssh — the same connection ty show prints an ssh … tmux attach line for. When there is no pane to reach, the error names the host and tmux session that were checked, so a finished agent reads differently from a lookup on the wrong machine.

Inside a task worktree:

When working in a task's worktree directory, you can interact with the executor directly. For Claude tasks:

cd /path/to/project/.task-worktrees/123-my-task/

# List Claude sessions (shows any spawned for this directory)
claude -r

# Resume a specific session
claude --resume {session-id}

The claude -r command shows Claude sessions associated with the current directory. This is useful when:

  • Debugging why a task got stuck
  • Continuing work manually after a task completes
  • Checking what the executor was doing in a specific task

Session Resumption (Claude Only)

Claude Code supports session resumption - when you retry a task or press R, the executor reconnects to the existing conversation:

  1. First execution: Claude starts fresh, prints a session ID
  2. Task You captures: The session ID is stored in the database
  3. On retry/resume: Runs claude --resume {sessionID} with your feedback
  4. Full context preserved: Claude sees the entire conversation history

This means when you retry a blocked task with feedback, Claude doesn't start over—it continues the conversation with full awareness of what it already tried.

Note: Codex and Gemini do not support session resumption. When retrying these tasks, they receive the full prompt including any feedback, but start a fresh session. Claude Code and OpenClaw support full session resumption.

Lifecycle & Cleanup

Event Behavior
Task completes Process stays alive for 30 minutes, then auto-killed
Task blocked Process suspends after 6 hours of idle time
Task deleted (d) Window killed, task trashed — worktree kept on disk so it can be restored
Trash retention expires Worktree removed, teardown script runs (default 14 days)
Task archived, or stale-worktree sweep Worktree archived to a git ref and removed, teardown script runs (sweep default: 24h after completion)
Daemon restart Orphaned windows are cleaned up on next poll

Routines

Routines are named, unattended agent runs — scouts and monitors that watch something on a schedule and feed your queue. TaskYou deliberately has no scheduler: trigger runs with ty run <name> from cron, launchd, or anything else that can run a command. TaskYou owns everything around the run: state, logs, history, and failure alerting.

A routine is a directory under ~/.config/task/routines/<name>/:

  • prompt.md — the agent prompt, with optional frontmatter (model, project, timeout, permission-mode)
  • env.sh — optional; sourced before each run for secrets and fail-fast checks (a non-zero exit fails the run before the agent starts)
ty routines create my-scout     # scaffold a new routine
ty run my-scout                 # run it now (cron/launchd call this too)
ty routines                     # health: last run, status, duration
ty routines show my-scout       # config + recent run history
ty routines logs my-scout       # full log of the latest run
ty routines edit my-scout       # open prompt.md in $EDITOR (re-validates on save)
ty routines schedule my-scout --every 30m   # register with the OS scheduler
ty routines unschedule my-scout # remove the ty-managed scheduler entry
ty routines disable my-scout    # pause (ty run becomes a no-op)
ty routines delete my-scout     # remove routine, schedule, state, run history

In the TUI, press u for the routines fleet-health view: last run status per routine, enter to read the latest run log, d to enable/disable.

schedule writes the OS scheduler config and hands over the clock: a launchd agent on macOS (com.taskyou.routine.<name>) or a tagged crontab line, with your PATH captured so the agent can find ty and claude. ty keeps no schedule state of its own — show and the TUI read the OS entry live, so nothing can drift. Use --cron "0 8 * * 1-5" for calendar cadences, and --print to emit the config without installing it. Prefer your own scheduler? Skip schedule entirely and point anything at ty run <name>.

Each run executes claude -p headlessly (default model: sonnet, default timeout: 30m) with the prompt on stdin, working directory set to the routine's private state dir (~/.local/share/task/routines/<name>/, also exported as $ROUTINE_STATE_DIR) so cross-run state like seen-IDs has an obvious home. Output is logged per run and recorded in run history.

When a run fails — agent error, env.sh failure (expired credentials), or timeout — TaskYou pins a Routine failed: <name> task to your board (deduped while one is open) and fires a routine.failed event hook. Silent failure is the one thing a routine is not allowed to do.

Event Hooks

TaskYou runs scripts in ~/.config/task/hooks/ when tasks change state.

Setup

# Create a hook for completed tasks
cat > ~/.config/task/hooks/task.completed << 'EOF'
#!/bin/bash
osascript -e "display notification \"$TASK_TITLE\" with title \"Task Completed\""
EOF

chmod +x ~/.config/task/hooks/task.completed

Available Events

Event When Emitted
task.created New task created
task.updated Task fields changed (including status transitions)
task.deleted Task removed
task.started Execution begins
task.blocked Task needs user input (or agent failed)
task.completed Agent finished successfully (task moves to backlog for human review)
task.failed Agent execution failed
task.worktree_ready Worktree set up and ready for agent

Environment Variables

TASK_ID          # Task ID
TASK_TITLE       # Task title
TASK_STATUS      # Current status
TASK_PROJECT     # Project name
TASK_EVENT       # Event type
TASK_TIMESTAMP   # ISO 8601 timestamp

See examples/hooks/ for examples.

Distribute agents with ty-on

Run tasks on your desktop or servers while managing them from the same TaskYou board. The optional ty-on plugin picks a machine for each task; TaskYou creates an isolated worktree there, starts the agent over SSH, and tracks its progress. Remote execution supports Claude and Codex.

First, prepare each machine with SSH access, a checkout of your project, Git, tmux, and an authenticated Claude or Codex executable on its login shell PATH. TaskYou does not clone the initial checkout or copy agent credentials for you.

Add the machines to ~/.config/on/hosts.yaml. Repository keys must match the project name in TaskYou; paths point to existing checkouts on those machines:

hosts:
  desktop:
    ssh: desktop
    capabilities: ["executor:claude", "executor:codex"]
    repos:
      storefront: ~/Projects/storefront
  server:
    ssh: dev-server
    capabilities: ["executor:claude", "executor:codex"]
    repos:
      storefront: ~/projects/storefront

Install the on CLI to compare available memory across multiple machines. Then, from a TaskYou source checkout with Go installed:

make install-ty-on
ty plugins list

Queue tasks as usual. ty-on selects a host configured for the task's project and executor. With one eligible host, it selects that host directly. With several, it uses on ls to pick the reachable host with the most free memory. Task detail shows the selected host and the reason.

To choose the machine yourself, pick one in the Host selector the new-task form shows once hosts are configured (TUI advanced fields, GUI Advanced, or ty create --host <destination|local>); that overrides the automatic placement for that task. To move a task that already exists — which carries its work — use Change host in the desktop/browser, @ in the TUI, or ty place in the CLI.

Tasks fall back to local execution when no remote placement is available. To require a remote machine for a project, add this to its .taskyou.yml:

placement:
  remote_required: true

With that setting, an unavailable remote destination stops the launch instead of starting an agent locally. See the ty-on setup and placement rules and remote execution guide for details.

Plugins

A plugin is a self-contained directory under ~/.config/task/plugins/ with a plugin.yaml manifest. It can carry any mix of three things:

  • workflows (workflows/*.yaml) — new ty pipeline -d <name> definitions
  • hooks — scripts that fire on task events. Unlike the one-script-per-event hooks dir above, any number of plugins can handle the same event and all of them run
  • actions — user-invoked commands (ty plugins run <plugin> <action>)

One event is different: task.placement is consulted, not merely notified. Just before an executor spawns, ty asks any installed placement handler where the task should run — request on stdin, answer on stdout — and runs it there. An empty answer (and every way a handler can fail) means "run locally", which is what happens for everyone who has no placement plugin installed: nothing is asked, and nothing changes.

A placed task is watched over one standing connection per host rather than one poller per task, so a fleet of hundreds costs a handful of connections. ty holds that connection outbound — nothing listens on your machine and no port is opened. The agent reports its own outcome through it (.ty/signal done "…"), so a remote task finishes when it says it has finished, rather than when it has been quiet long enough to look finished.

Remote tasks support the workdir shell in every interface: \ toggles it in TUI detail view, and the desktop/browser terminal has a Shell tab. The shell runs on the placed host with the task's environment and survives closing the view. Shift-arrow keys cycle the TUI, agent, and shell panes; Alt-Shift-Up/Down switch tasks. Inside an attached remote pane, Ctrl-a is the remote tmux prefix. Desktop and browser remote terminals use the HTTP terminal bridge.

See docs/plugins.md and the reference resolver in extensions/ty-on.

Task placement is also available from the task detail view in the desktop and browser, and with @ in the TUI. See remote execution for executor eligibility, required remote placement, connection health, and shared HTTP placement endpoints.

Finding one

You should not have to know a repo URL to get a plugin. ty ships a catalog — a small JSON index of installable plugins, bundled into the binary and refreshed from taskyou.dev/registry.json — and every surface searches it:

  • TUI — press m on the board: type to search, enter installs, ctrl+d removes, tab switches between All / Installed / Available.
  • GUI / browser — the Plugins view (m, ⌘M, or the menu).
  • CLI —
ty plugins browse            # the whole catalog, grouped by category
ty plugins search slack      # find one
ty plugins info slack        # what it does, what it needs, where it comes from
ty plugins add slack         # install it by name

Installing by catalog name takes just that plugin, even when it lives in a repo with nine others.

Installing something that isn't in the catalog

ty plugins add taskyou/plugins                      # owner/repo shorthand
ty plugins add https://github.com/taskyou/plugins   # a git URL: installs every plugin in it
ty plugins add ./my-plugin                          # a local path
ty plugins list                                     # see what they provide
ty plugins update                                   # re-pull everything installed

ty plugins update knows where each plugin came from (recorded at install time), so it works for a single plugin lifted out of a collection as well as for a whole checkout. Or drop a directory into ~/.config/task/plugins/ by hand.

Why you'd care: the community collection

github.com/taskyou/plugins is the fastest way to feel what workflows-as-plugins buys you — install it and these show up in ty pipeline -d:

Workflow What it does
rpi Turns a goal into a PR: neutral research → goal-blind investigation → an approach you approve (human gate) → a plan you approve (human gate) → implement + simplify that must pass your build/tests (reality gate) → PR. A human okays the approach; the machine proves the code.
plan-code-review Plan → code → two independent reviewers in parallel → collect → PR. Different models with independent context catch different issues.
arc-solve An agent that plays a live ARC-AGI-3 game and beats a level — the verify gate replays its solution against the real game, so a win can't be faked. (recorded run + GIF.)

That last one is the point in miniature: a workflow whose completion is bound to a result the gate re-checks against reality, packaged so anyone gets it with one command.

See the collection README to browse or contribute, docs/plugins.md for the manifest format, examples/plugins/ for more (desktop-notify, slack, worktree), and docs/plugin-ideas.md for ideas.

Configuration

Settings

Manage settings with ty settings:

ty settings                              # View all settings
ty settings set <key> <value>            # Set a value
Setting Description
anthropic_api_key API key for ghost text autocomplete (optional, uses API credits)
autocomplete_enabled Enable/disable autocomplete (true/false)

Ghost Text Autocomplete

LLM-powered suggestions appear as you type task titles and descriptions, similar to GitHub Copilot:

  • Title suggestions - Autocomplete as you type the task title
  • Body suggestions - Auto-suggest a description when you tab from the title to an empty body field
  • Cursor-aware - Ghost text renders at cursor position for natural editing
  • Smart caching - Recent completions are cached for instant responses

Setup:

ty settings set anthropic_api_key sk-ant-your-key-here

Controls:

  • Tab - Accept suggestion
  • Escape - Dismiss suggestion
  • Ctrl+Space - Manually trigger suggestion

Get an API key at console.anthropic.com. This is optional and uses your API credits.

Environment Variables

Variable Description Default
WORKTREE_DB_PATH SQLite database path ~/.local/share/task/tasks.db
ANTHROPIC_API_KEY Fallback for autocomplete if not set in settings -

.taskyou.yml Configuration

You can configure per-project settings by creating a .taskyou.yml file in your project root:

worktree:
  init_script: bin/worktree-setup

Supported filenames (in order of precedence):

  • .taskyou.yml
  • .taskyou.yaml
  • taskyou.yml
  • taskyou.yaml

Configuration options:

Field Description Example
worktree.init_script Path to script that runs after worktree creation (relative or absolute) bin/worktree-setup
worktree.teardown_script Path to script that runs before a worktree is removed — on archive as well as delete (relative or absolute) bin/worktree-teardown

Projects

Configure projects in Settings (s):

  • Name - Project identifier (e.g., myproject)
  • Path - Local filesystem path to git repo
  • Aliases - Short names for quick reference
  • Instructions - Project-specific AI instructions
  • Claude Config Dir - Optional override for CLAUDE_CONFIG_DIR (use different Claude accounts per project)

Worktrees

Tasks run in isolated git worktrees at ~/.local/share/task/worktrees/{project}/task-{id}. This allows multiple tasks to run in parallel without conflicts. Press o to open a task's worktree.

Worktree Setup Script

You can configure a script to run automatically after each worktree is created. The setup script runs:

  • After the git worktree is created
  • Before the AI executor (Claude/Codex) starts working on the task
  • When reusing an existing worktree that has already been checked out

This is useful for:

  • Installing dependencies
  • Setting up databases
  • Copying configuration files
  • Running migrations

Two ways to configure:

  1. Conventional location - Create an executable script at bin/worktree-setup:
#!/bin/bash
# Example: bin/worktree-setup
bundle install
cp config/database.yml.example config/database.yml
  1. Custom location - Specify in .taskyou.yml:
worktree:
  init_script: scripts/my-setup.sh

The script runs in the worktree directory and has access to all worktree environment variables (WORKTREE_TASK_ID, WORKTREE_PORT, WORKTREE_PATH).

Worktree Teardown Script

You can configure a script to run automatically just before a worktree is removed. This is useful for releasing per-worktree resources:

  • Dropping task-specific databases
  • Freeing an allocated Redis DB, S3 prefix, or dev-server symlink
  • Stopping background services and docker containers
  • Removing temporary files

TaskYou removes a worktree in one of two ways — archive (worktree state, including uncommitted changes, is first saved to a git ref so the task can be unarchived later with everything restored) and delete — and the teardown script runs on both.

When it runs:

Trigger How the worktree goes away
Automatic stale-worktree sweep — the daemon archives and removes worktrees for done/archived tasks whose completion is older than the cleanup max age (default 24h, setting worktree_cleanup_max_age; set to 0/disabled to turn off) archive
ty worktrees cleanup (--max-age 0 sweeps every done/archived worktree now, --dry-run previews) archive
Archiving a task in the TUI (a) archive
Trash sweep — a trashed task's worktree is removed once the retention window expires (default 14 days, setting trash_retention) delete
ty delete --hard delete
Moving a task to another project (ty move, or the TUI move action) — the old worktree is removed delete

So a finished task releases its resources on its own: by default the sweep archives and tears down its worktree ~24 hours after it completes. You do not need to build a separate reaper.

Note that d in the TUI and plain ty delete trash a task rather than destroying it — the worktree is deliberately left on disk so ty restore works. Teardown for those runs later, when the trash sweep hard-deletes the task (or immediately if you pass --hard).

When it does not run:

  • You remove the worktree yourself, outside TaskYou (git worktree remove, rm -rf) — TaskYou never sees it happen.
  • Projects that don't use worktrees (the task runs in the project directory itself). Nothing per-task was created, so nothing is torn down.

Two ways to configure:

  1. Conventional location - Create an executable script at bin/worktree-teardown:
#!/bin/bash
# Example: bin/worktree-teardown
bin/rails db:drop
  1. Custom location - Specify in .taskyou.yml:
worktree:
  teardown_script: scripts/my-teardown.sh

The script is resolved from the project root but executed with the worktree as its working directory, with the same environment variables as the setup script (WORKTREE_TASK_ID, WORKTREE_PORT, WORKTREE_PATH). Its output is streamed into the task log, prefixed with [teardown].

Your teardown script must not refuse to run. A non-zero exit is logged as a warning and TaskYou removes the worktree anyway — cleanup never fails on your script. A script that guards itself (bailing out when the worktree is dirty, for example) will therefore leak whatever it was supposed to release, silently. Write it to be unconditional and idempotent. TaskYou also waits for the script to finish with no timeout, so keep it quick.

Note: Teardown is tied to worktree removal, not to task status, so it happens after the max-age delay rather than the moment a task finishes. If you need cleanup at the exact moment a task completes, use Event Hooks on the task.completed event — but be aware the worktree is still live at that point (the agent's changes may not be merged yet), and the teardown script will still run later when the worktree is actually removed.

Running Applications in Worktrees

Each task provides environment variables that applications can use to run in isolation:

Variable Description Example
WORKTREE_TASK_ID Unique task identifier 207
WORKTREE_PORT Unique port (3100-4099) 3100
WORKTREE_PATH Path to the worktree /path/to/project/.task-worktrees/207-my-task

Loading Environment Variables

Each worktree includes a .envrc file with these variables. To load them:

  • With direnv (recommended): Variables load automatically when you cd into the worktree. Run direnv allow the first time.
  • Without direnv: Run source .envrc manually.

These variables allow multiple tasks to run simultaneously without conflicts on ports or databases.

Example: Rails Application

Configure your Rails app to use worktree variables for complete isolation:

config/puma.rb:

port ENV.fetch("WORKTREE_PORT", 3000)

config/database.yml:

development:
  database: myapp_dev<%= ENV['WORKTREE_TASK_ID'] ? "_task#{ENV['WORKTREE_TASK_ID']}" : "" %>

Procfile.dev:

web: bin/rails server -p ${WORKTREE_PORT:-3000}

bin/worktree-setup:

#!/bin/bash
set -e

# Install dependencies
bundle install

# Create isolated database for this task
bin/rails db:create db:migrate

bin/worktree-teardown:

#!/bin/bash
# Drop the task-specific database
bin/rails db:drop

Now the AI executor (Claude or Codex) can:

  • Run your app with bin/dev
  • Access it at http://localhost:$WORKTREE_PORT
  • Work on multiple tasks in parallel without database or port conflicts

Example: Node.js Application

package.json:

{
  "scripts": {
    "dev": "next dev -p ${WORKTREE_PORT:-3000}"
  }
}

bin/worktree-setup:

#!/bin/bash
npm install
cp .env.example .env.local

Shell Completion

TaskYou supports tab completion for all CLI commands, subcommands, flags, and dynamic values (task IDs, project names, statuses, etc.).

Setup

Zsh (macOS default):

# Enable completion if not already done:
echo "autoload -U compinit; compinit" >> ~/.zshrc

# Generate and install the completion script:
ty completion zsh > "${fpath[1]}/_ty"

# Restart your shell or run:
source ~/.zshrc

Bash:

# Linux:
ty completion bash > /etc/bash_completion.d/ty

# macOS (with Homebrew):
ty completion bash > $(brew --prefix)/etc/bash_completion.d/ty

Fish:

ty completion fish > ~/.config/fish/completions/ty.fish

PowerShell:

ty completion powershell >> $PROFILE

What completes

  • Subcommands — ty <TAB> shows all available commands
  • Task IDs — ty show <TAB> lists tasks with their status and title
  • Statuses — ty status 42 <TAB> suggests backlog, queued, processing, etc.
  • Projects — ty move 42 <TAB> and --project <TAB> complete project names
  • Task types — --type <TAB> completes from your configured task types
  • Executors — --executor <TAB> suggests claude, codex, gemini, grok, etc.
  • Settings — ty settings set <TAB> shows available setting keys

SSH Access & Deployment

Task You can run as an SSH server, allowing you to access your task board from anywhere.

Running the SSH Server

The taskd daemon provides SSH access to the TUI:

# Start SSH server on default port (2222)
./bin/taskd

# Custom port
./bin/taskd -addr :22222

# Custom database location
./bin/taskd -db /path/to/tasks.db

# Custom SSH host key
./bin/taskd -host-key ~/.ssh/custom_key

Once running, connect from any machine:

ssh -p 2222 username@your-server.com

Replace your-server.com with your server's hostname or IP address. The SSH server accepts public key authentication (currently accepts all keys - see Security below).

Deployment

Building for Linux

If deploying from macOS to a Linux server:

make build-linux

This creates Linux binaries in ./bin/.

Installing as a Systemd Service

For persistent SSH access, install taskd as a systemd service:

./scripts/install-service.sh

This creates ~/.config/systemd/user/taskd.service and enables it to start on boot.

Manage the service with:

systemctl --user status taskd   # Check status
systemctl --user start taskd    # Start
systemctl --user stop taskd     # Stop
systemctl --user restart taskd  # Restart
journalctl --user -u taskd      # View logs

Security

Important: The SSH server currently accepts all public keys. For production use, edit internal/server/ssh.go:

wish.WithPublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool {
    // Compare key fingerprint against allowed list
    allowed := map[string]bool{
        "SHA256:your-allowed-key-fingerprint": true,
    }
    return allowed[ssh.FingerprintSHA256(key)]
})

Get your key fingerprint with:

ssh-keygen -lf ~/.ssh/id_ed25519.pub

Password authentication is disabled by default.

Extensions

ty-email

Email interface for TaskYou. Send emails to create tasks, reply to provide input, receive status updates—all from your phone or any email client.

cd extensions/ty-email
go build -o ty-email ./cmd
./ty-email init   # Interactive setup wizard
./ty-email serve  # Run daemon

See extensions/ty-email/README.md for full documentation.

ty-chrome

Chrome extension for visual product development in a loop. Annotate any page served by a task's dev server (point at elements, draw boxes, comment) and the context — selectors, DOM excerpts, a screenshot with your markers — lands directly in the task's executor, which makes the change while you watch its live output in the side panel. The executor can also see and drive your tab through the browser bridge (screenshot/snapshot/console/click/type) instead of launching its own browser, and the page auto-reloads when it finishes a turn.

Annotating a page with a region and comment

chrome://extensions → Developer mode → Load unpacked → extensions/ty-chrome
ty serve   # the extension auto-discovers it

See extensions/ty-chrome/README.md for full documentation.

Development

make build        # Build binaries
make test         # Run tests
make install      # Install to ~/go/bin

Tech Stack