Documentation menu

Documentation

Trackers and intake

Bringing issues, messages and requests onto the board.

On this page

Getting work onto the board

Work arrives from wherever your team already talks about it. TDE normalizes every source into the same shape — a tracker id, a title, a body, labels — and files it as a board card.

SourceTracker idHow it arrives
Linearthe issue identifier, e.g. LIG-42Bot poll, or manual import
GitHub issuesGH-118Manual import wizard
Jirajira:ENG-9Manual import wizard
Todoisttodoist:<id>Bot poll, or manual import
Slackslack:<team>:<channel>:<root>Slack triage bot
Telegramtelegram:<update_id>Bot long-poll
Emailaccount-scopedEmail triage bot

The tracker id is what makes intake idempotent: filing an item that already has a card updates it instead of creating a second one.

Automatic intake

Polling is done by bots, not by a background thread you cannot see:

  • Linear sync, every 30 minutes. It keeps a cursor in ~/.tde/linear_sync.json and re-polls with a five-minute overlap so a crash mid-ingest cannot skip an issue. The first ever poll starts from now — it never backfills your existing backlog.
  • Todoist sync, every 30 minutes, over open tasks.
  • Slack triage, every 15 minutes.
  • Email triage, every 5 minutes.

Each is gated on the matching project integration or connector actually being configured. See Connectors.

Telegram

Messages that are not bot commands go through the same path as Linear sync: the message becomes a TrackerIssue with id telegram:<update_id>, is triaged by an agent, and comes back as a confirmation in the chat. See Slack and Telegram.

Slack

Slack intake is deliberately more conservative, because a Slack message can ask for something irreversible. A mention is classified into one of Reply, ReadOnlyRun, TaskStatus, Clarify or Change — and a Change is represented only as a blocked task carrying a plan question. It never starts an agent run at intake time.

The plan is posted with two buttons, Aprovar plano and Rejeitar. Only the explicit approve option unlocks the task; a rejection, an empty selection or an unknown id leaves it blocked, because clearing the question would let the scheduler resume a state-changing request nobody approved.

Slack threads collapse onto one card by design — the tracker id excludes the event id, so later messages in the same thread land on the task that already exists. While that task is still in its first stage, new messages are appended as comments.

Classification

Filing a card does not decide how it runs. Intake writes the card; the triage agent decides the route at run time, inside the worktree, using the task's title and description only:

IntentRoute
QARun the first agent stage read-only, then stop at the human gate.
RESEARCHSame, with an exploration prompt.
CODEThe full pipeline.

This is intentionally free of keyword lists so it works in any language. See Pipeline and stages.

Manual import

The new-task flow offers a blank task or an import from GitHub, Linear, Jira or Todoist. Issue lists are fetched in the background so the wizard stays responsive. Imported cards keep both a tracker id and a provider-scoped external id — owner/repo#118 for GitHub, the jira:KEY string for Jira — so a later automatic sync recognizes them instead of duplicating.

From a shell:

bash
tde task create "Investigate the flaky CI job" \
  --project tde --agent Bot --priority high --run

See tde task.

Task widgets

A task widget is an action button on the task detail screen. Pressing it expands a template into a full agent prompt, posts it as a comment authored by widget:<id> — which the activity feed renders with a 🧩 icon — and runs the task. To the agent it reads as a human request, because that is exactly what it is.

Widgets are TOML files in ~/.config/tde/widgets/:

~/.config/tde/widgets/screenshots.toml
id = "screenshots"
label = "Screenshots"
icon = "📸"
requires = "agent-browser"
install_hint = "npm install -g agent-browser"
prompt = """
Capture the three main screens of {task} ({tracker}).
Worktree: {worktree}
Write the images into {demo_dir}.
"""
FieldRequiredMeaning
idyesA file with the same id as a built-in overrides it.
labelyesThe button text.
promptyesThe agent prompt. Placeholders are expanded.
iconnoA glyph before the label.
requiresnoA CLI that must be on PATH for the button to work.
install_hintnoShown when requires is missing.

Four placeholders are substituted:

PlaceholderValue
{worktree}The task's git worktree, or the project root.
{demo_dir}{worktree}/demo
{task}The task title.
{tracker}The tracker id, e.g. LIG-42.

Exactly one widget is built in: demo, which requires agent-browser and drives a supervised browser session that records a demo of the task's change into a timestamped folder under demo/ in the worktree.