Documentação
Trackers and intake
Bringing issues, messages and requests onto the board.
Nesta página
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.
| Source | Tracker id | How it arrives |
|---|---|---|
| Linear | the issue identifier, e.g. LIG-42 | Bot poll, or manual import |
| GitHub issues | GH-118 | Manual import wizard |
| Jira | jira:ENG-9 | Manual import wizard |
| Todoist | todoist:<id> | Bot poll, or manual import |
| Slack | slack:<team>:<channel>:<root> | Slack triage bot |
| Telegram | telegram:<update_id> | Bot long-poll |
| account-scoped | Email 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.jsonand 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:
| Intent | Route |
|---|---|
QA | Run the first agent stage read-only, then stop at the human gate. |
RESEARCH | Same, with an exploration prompt. |
CODE | The 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:
tde task create "Investigate the flaky CI job" \
--project tde --agent Bot --priority high --runSee 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/:
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}.
"""| Field | Required | Meaning |
|---|---|---|
id | yes | A file with the same id as a built-in overrides it. |
label | yes | The button text. |
prompt | yes | The agent prompt. Placeholders are expanded. |
icon | no | A glyph before the label. |
requires | no | A CLI that must be on PATH for the button to work. |
install_hint | no | Shown when requires is missing. |
Four placeholders are substituted:
| Placeholder | Value |
|---|---|
{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.