Guide
Dex helps your AI agent act as a master coordinator for complex work—breaking down tasks, tracking progress, and preserving context across sessions.
The Core Idea
When you tell Claude "use dex" or invoke /dex, you're asking it to create persistent tickets that survive beyond the current session. Unlike Claude's built-in task tracking (which disappears when the session ends), dex tasks are stored as files in your repository.
This means:
- You can close your session and pick up exactly where you left off
- Context, decisions, and progress are preserved
- Multiple sessions (or agents) can coordinate on the same work
- Task history lives alongside your code in git
When to Use Dex
Use dex when:
- Work spans multiple sessions or days
- You need to break down a complex feature into steps
- You want to preserve decisions and context for later
- Work might be handed off or revisited
- You want to build up a backlog of work before executing it
Skip dex when:
- It's a quick, single-session task
- No context needs to be preserved
- The overhead isn't worth it
dex vs Built-in Task Tools
Some AI agents (like Claude Code) have built-in task tools (TaskCreate, TaskUpdate, TaskList). These are not the same as dex.
| dex | Built-in Task Tools | |
|---|---|---|
| Persistence | Persists in .dex/ files | Session-only, lost when session ends |
| Context | Rich (description + context + result) | Basic (subject + description) |
| Hierarchy | 3-level (epic → task → subtask) | Flat dependencies only |
| Collaboration | Git-trackable, shareable | Not shareable |
Rule of thumb: Use dex for work that needs to persist, be handed off, or tracked across sessions. Use built-in task tools only for ephemeral in-session tracking (like a scratchpad).
Basic Workflow
Starting Work
Tell Claude what you want to accomplish and ask it to track with dex:
> Add JWT authentication to the API. Use dex to track the work. Claude will create a task with rich context—not just "add auth" but the full requirements, approach, and acceptance criteria. Under the hood, it runs something like:
$ dex create "Add JWT authentication" --description "Implement JWT-based
auth for the API. Need: token generation on login, verification
middleware for protected routes, refresh token flow. Use jsonwebtoken
library. Protect /api/users/* and /api/admin/* routes..." For larger work, Claude breaks it into subtasks automatically:
$ dex create "Create auth middleware" --parent abc123 --description "..." $ dex create "Add login endpoint" --parent abc123 --description "..." $ dex create "Add token refresh flow" --parent abc123 --description "..."
Resuming Work
In a new session, ask Claude to continue:
> Continue working on the auth implementation. Claude checks what's pending and reads the context:
$ dex list [ ] abc123: Add JWT authentication ├── [x] def456: Create auth middleware ├── [ ] ghi789: Add login endpoint └── [ ] jkl012: Add token refresh flow $ dex show ghi789 [ ] ghi789: Add login endpoint Context: POST /api/auth/login endpoint. Accept email/password, verify against database, return JWT token pair (access + refresh). Use bcrypt for password verification. Return 401 for invalid credentials with generic error message...
The context tells Claude exactly what to do without you re-explaining.
Completing Work
When Claude finishes a task, it records what was done:
$ dex complete ghi789 -r "Added POST /api/auth/login endpoint.
Verifies credentials with bcrypt, returns JWT access token (15m)
and refresh token (7d). Tested with valid/invalid credentials.
All 24 tests passing." This result becomes part of the permanent record—useful for understanding what happened later.
Building a Backlog
One of the most powerful uses of dex is building up a backlog of work before executing it. This separates planning from doing, letting you think through multiple work items in a focused planning session.
Planning Session Workflow
Start by brainstorming with Claude about what needs to be done:
> Let's plan out what we need to do for the v2 API migration.
I want to capture all the work items but not start any of them yet. Claude can help you think through the work, identify dependencies, and break things down. As you discuss each item, tell Claude to add it to dex:
> Add that as a dex task. > Create a task for the database migration piece we just discussed. > That should be three separate tasks - add them all to dex.
This creates a queue of well-defined work that you can execute later—in this session, in future sessions, or delegate to other agents.
From Plans to Tasks
If you've already written a plan (in Claude's plan mode or as a markdown doc), convert it directly to tasks:
> /dex-plan Claude reads the plan file and creates tasks with appropriate breakdown—simple plans become single tasks, complex plans become hierarchies with subtasks.
Quick Backlog Building
For rapid capture, you can also use the CLI directly:
$ dex create "Migrate users table to v2 schema" --description "..." $ dex create "Update API serializers for v2 format" --description "..." $ dex create "Add v2 authentication endpoints" --description "..." $ dex create "Write migration guide for API consumers" --description "..."
Then review your backlog and start working:
$ dex list [ ] abc123: Migrate users table to v2 schema [ ] def456: Update API serializers for v2 format [ ] ghi789: Add v2 authentication endpoints [ ] jkl012: Write migration guide for API consumers > Work on the next task.
Why Separate Planning from Execution?
- Better task quality: When you're not context-switching to implementation, you can think more clearly about scope and requirements
- Visible scope: See all the work before committing to any of it
- Flexible execution: Work the backlog in any order, across sessions, or hand off to others
- Interruptible: Stop planning anytime—your backlog is saved
What Good Looks Like
Good Task Context
Context should contain everything needed to do the work without asking questions:
- What needs to be done (specific, not vague)
- Why it's needed (background, motivation)
- How to approach it (files to modify, patterns to follow)
- Done when (acceptance criteria)
Good:
"Add rate limiting to /api/auth endpoints. Use express-rate-limit, 5 requests per minute per IP for /login, 20/min for /refresh. Return 429 with Retry-After header. Add to src/middleware/rate-limit.ts, apply in src/routes/auth.ts."
Bad:
"Add rate limiting"
Good Task Results
Results should capture what was actually done, not just "done":
- What changed (implementation summary)
- Key decisions (and why)
- Verification (tests passing, manual testing done)
Good:
"Added rate limiting with express-rate-limit. Login: 5/min, refresh: 20/min. Configured per-IP tracking with custom key generator for proxy support. Returns 429 with Retry-After header. Added 6 tests for rate limit scenarios. All 30 tests passing."
Bad:
"Added rate limiting"
Verification is Critical
Before marking any task complete, Claude must verify the work. Verification separates "I think it's done" from "it's actually done."
Strong verification includes:
- Test results: "All 60 tests passing" (with actual count)
- Build status: "Build successful"
- Manual testing: "Tested with valid/invalid inputs, both cases work"
Weak verification to avoid:
- "Should work now" — "should" means not verified
- "Made the changes" — no evidence it works
- "Added tests" — did the tests pass?
Good results always include explicit evidence: test counts, build output, manual testing outcomes.
Task Hierarchy
Dex supports three levels for organizing work:
- Epic
- Large initiatives (5+ tasks). Example: "Add user authentication system"
- Task
- Significant work items. Example: "Implement JWT middleware"
- Subtask
- Atomic steps. Example: "Add token verification function"
Most work is a single task or a task with subtasks. Epics are for larger initiatives spanning multiple sessions.
Dependencies
Some tasks must be done in order. Tell Claude about dependencies:
> The deployment task should be blocked by the testing task. Claude uses --blocked-by to create the dependency. Blocked tasks show an indicator in the list:
[ ] abc123: Run integration tests [ ] def456 [B: abc123]: Deploy to production
Integration with GitHub
Local dex tasks are ephemeral—working notes that evolve and get deleted as you go. When you sync to GitHub Issues, you create a permanent record of the work: what was planned, how it was broken down, and what was actually done.
Why Sync?
For permanent records:
- Local tasks get deleted as work evolves; GitHub Issues persist indefinitely
- Context, decisions, and results are preserved in a searchable history
- Commit metadata embeds in closed issues, tying work to actual code
For large or long-running work:
- GitHub Issues survive repo clones, machine changes, and team transitions
- Use GitHub's project boards and milestones for higher-level organization
For team visibility:
- Team members see progress without needing the AI agent
- GitHub notifications keep everyone informed
Task IDs vs Issue Numbers
Dex task IDs (abc123) are ephemeral—they change, get deleted, and become meaningless. Never put task IDs in commits, PRs, or documentation.
GitHub issue numbers (#42) are permanent. Once synced, reference the issue number in your commits and PRs, not the dex task ID.
Enabling Sync
Configure your repository in config. Dex authenticates via the gh CLI or GITHUB_TOKEN environment variable.
By default, tasks sync automatically whenever you create, update, or complete a task. You can disable this to sync only manually or periodically—see auto-sync settings.
What Gets Synced
When you sync a task:
- Task description → issue title
- Task context → issue body
- Subtasks → expandable checklists with context and results
- Completion result → comment when the issue closes
- Commit metadata (SHA, branch, URL) → embedded in closed tasks
Manual Sync
Push local tasks to GitHub Issues:
$ dex sync Syncing 3 task(s) to owner/repo... [1/3] + abc123: Add JWT authentication [2/3] ↻ def456: Fix login redirect [3/3] ∙ ghi789: Add rate limiting Synced 3 task(s) to owner/repo (1 created, 1 updated, 1 unchanged)
Use --dry-run to preview what would sync without making changes.
Importing from GitHub
Pull GitHub Issues into local tasks:
$ dex import #42 Imported issue #42 as task xyz789: "Add password reset flow" Created 3 subtask(s)
Use --all to import all open issues at once.
Sync-on-Push
Issues only close when their completion commits reach the remote. This creates a reliable record: a closed GitHub Issue means the work is actually shipped, not just marked done locally.
Why this matters:
You complete a task locally, but your branch isn't merged yet. Without sync-on-push, the issue would close immediately—a "closed" issue with no shipped code. With sync-on-push, the GitHub record accurately reflects reality: the issue closes only when your work is actually in the repository.
$ dex complete abc123 -r "Added JWT middleware. All tests passing." [x] abc123: Add JWT authentication $ dex sync [1/1] ↻ abc123: Add JWT authentication Synced 1 task(s) (issue stays open until pushed) $ git push && dex sync [1/1] ↻ abc123: Add JWT authentication Synced 1 task(s) (issue now closed)
Note: If .dex/ is in your .gitignore, sync-on-push detection is disabled since dex can't determine push status.
Integration with Shortcut
Shortcut sync works similarly to GitHub sync, but with some key differences in how tasks map to Shortcut's data model.
Key Differences from GitHub
| Feature | GitHub | Shortcut |
|---|---|---|
| Subtasks | Checklist items in issue body | Real sub-tasks (separate stories linked to parent) |
| Blocked-by | Not synced | Story links ("blocked by" relationship) |
| Workflow | Open/Closed | Full workflow states (e.g., "In Progress", "Done") |
Enabling Shortcut Sync
Configure your repository in config. Set SHORTCUT_API_TOKEN environment variable with your Shortcut API token.
$ export SHORTCUT_API_TOKEN=your-token-here What Gets Synced
When you sync a task to Shortcut:
- Task name → Story title
- Task context → Story description
- Subtasks → Sub-task stories (linked to parent)
- Blocked-by relationships → Story links
- Completion → Story moved to "done" workflow state
Syncing Tasks
Push local tasks to Shortcut Stories:
$ dex sync --shortcut Syncing 3 task(s) to Shortcut... [1/3] + abc123: Add JWT authentication [2/3] ↻ def456: Fix login redirect [3/3] ∙ ghi789: Add rate limiting Synced 3 task(s) to Shortcut (1 created, 1 updated, 1 unchanged)
Importing from Shortcut
Pull Shortcut Stories into local tasks:
$ dex import sc#123 Imported story sc#123 as task xyz789: "Add password reset flow" Created 2 subtask(s) $ dex import https://app.shortcut.com/workspace/story/123 Imported story sc#123 as task xyz789: "Add password reset flow" $ dex import --all --shortcut Importing all stories from Shortcut... Imported 5 story(s)
Behavior Notes
A few behaviors to be aware of:
- Subtasks must complete first: A task with pending subtasks cannot be completed. Complete all children before the parent.
- Blockers are soft enforcement: Blocked tasks can be completed, but Claude will see a warning. This allows flexibility while communicating intended order.
- Delete cascades to children: Deleting a parent task also deletes all its subtasks.
- Maximum depth is 3 levels: Epic → Task → Subtask. Attempting to create a child of a subtask will fail.
Tips for Working with Claude
- "Use dex" — Tells Claude to track work persistently
- "What's next?" — Claude checks pending tasks and continues
- "Break this down" — Claude creates subtasks for complex work
- "Mark that complete" — Claude records the result
- "/dex-plan" — Converts a plan file to tracked tasks
You don't need to know the CLI commands—Claude handles that. Focus on describing what you want to accomplish.