Connect a tracker
Your tracker says what an issue is and whether it is finished. The plugin says how far the work has got. Connecting a tracker is what puts issues on the board before anybody opens an editor.
Who owns what
Two sources write to a ticket, and they never overlap.
| Owner | What it knows | What it sets |
|---|---|---|
| The plugin and your CI | what is happening to the code: edits, tests, audits, merges, builds, deploys | every delivery stage from Local Dev to Verified, and the rework loops |
| Your tracker | what is happening to the issue: that it exists, who has it, which column it is in, whether it is done | Backlog and Prod Review, plus the title, assignee, status name and labels |
Five rules keep them from fighting:
- The plugin wins on delivery stages. A tracker event never moves a ticket backwards or sideways through the delivery stages. Your tracker saying "In Progress" about a ticket already in dev test is your tracker being behind. Before anything has been reported, the tracker is all there is, so an in-progress issue starts in Local Dev.
- The tracker wins on existence and completion. Done moves the ticket to Prod Review and starts the delivered clock. Cancelled or deleted takes it off the columns and keeps its history.
- Metadata is the tracker's. Title, assignee, status name and labels come from the tracker and overwrite whatever was guessed from a branch name.
- Reopened is a rework. An issue reopened after being done is drawn as a rework loop back from Prod Review, so you can see why it came back.
- Nothing is inferred from silence. No event means no change.
Your own status names are never columns. "Ready for QA" is what one team calls what another calls "In Review", so it is shown on the card and nowhere else. The columns stay the delivery stages every organisation shares.
Connect GitHub
GitHub is installed, not authorised. There is one TeamFlow GitHub App.
- On the members page, press Install on GitHub.
- GitHub shows you its own installer. Choose the account or organisation.
- Choose every repository, or pick the ones you want.
- Install. You land back on the members page with the connection live and the repositories listed under it.
Nothing is pasted anywhere, and there is no second trip for the second repository. What TeamFlow may read is exactly the App's permissions — issues, pull requests, checks and metadata, all read-only — on exactly the repositories you ticked. GitHub shows you that before you install and again whenever you look.
The credential is minted per installation and expires in an hour, so there is no long-lived token of yours anywhere.
Disconnecting forgets TeamFlow's half. The installation is yours to remove in GitHub's own settings, under Applications and then Installed GitHub Apps.
Connect Linear
Linear is authorised. There is nothing to paste.
- On the members page, name the team if you want only that one.
- Press Connect Linear.
- Approve on Linear's consent screen.
- You land back on the members page with the connection live.
TeamFlow creates the webhook in your workspace itself, with a signing secret it generates and nobody ever sees. It subscribes to issues only.
The person who authorises must be an admin of the Linear workspace. If they are not, the consent still succeeds and the members page then says so.
From a terminal instead, which prints the URL to open:
npx -y github:macleodlabs-ai/teamflow-plugin trackers connect linear --filter ENG
Disconnecting deletes the webhook from your workspace, revokes the token and then forgets the connection. If Linear refuses the delete — the workspace changed hands, the token was revoked there first — the connection still goes and the page tells you what is left to remove by hand.
Connect Jira
Jira cannot be authorised yet, so it connects by hand, under Advanced on the members page. The button for the authorise flow is greyed out and says so rather than offering one that fails.
- Press the paste-connect button for Jira. TeamFlow gives you a webhook URL and a secret, and shows the secret once. Copy both before you leave the page.
- In Jira, go to Settings, then System, then WebHooks, then Create a WebHook. You need Jira administrator rights.
- Name it
TeamFlowand set its status to enabled. - Paste the URL and the secret.
- Under issue related events, tick created, updated and deleted. Leave everything else unticked: comments, worklogs and attachments are not used and are dropped.
- Optionally set a JQL filter, such as
project = DAEMON, to send one project only.
If you lose the secret, remove the connection and make another.
A connection made this way says Remove rather than Disconnect: TeamFlow holds no token for your tracker, so it forgets its own half and the webhook is yours to delete.
The same path exists for a self-hosted Jira, for a Linear workspace where you are not an admin, and for a GitHub repository nobody may install an App on.
Filling the board: imports and backfill
A webhook only says what is happening now. Connected on a Tuesday, it says nothing about the Monday — so without an import a new organisation looks at an empty board until somebody moves a ticket.
Connecting queues an import of every open issue the connection can see. It runs in the background and sends your browser straight back, because an import of a large workspace is minutes of work and no web request waits that long. Issues appear on the board as they arrive rather than all at the end.
Three moments run the same import:
| When | What it does |
|---|---|
| On connect | queued by the consent or the installation |
| Backfill now | the button beside each connection on the members page. Starts one at once |
| Nightly | 03:00 UTC, every connection that holds a credential, asking only for what changed |
The line beside the connection says what is happening — how many issues so far while it runs, or the reason it stopped. Pressing Backfill now while one is already running does nothing: the import in flight carries on from where it had got to.
An import cannot undo a delivery. TeamFlow keeps the newer of what it holds and what arrives, so an import that overlaps live work loses to the live work. Running one twice is free.
Linear and GitHub import; a pasted-in webhook and Jira do not. A backfill reads your tracker's API with a credential the connection holds, and a webhook you created by hand leaves none. The members page offers no import button for those rather than one that always fails.
Narrowing what a tracker sends
Every provider can be scoped, and a narrow scope is also the commonest way a ticket goes missing.
- Linear: name the team when you connect, or pass
--filter ENG. Without one, every public team is covered. - GitHub: pick the repositories in GitHub's own installer. You can change them later in GitHub, and TeamFlow follows.
- Jira: a JQL filter on the webhook, such as
project = DAEMON.
A connection filtered to one project or one team drops everything else silently. That is the point of a filter, and it is also how it hides a ticket.
Checking it works
Each connection has a Send a test event button. It stores a synthetic issue under a key of its own, and that ticket appears on the board within a refresh. It proves TeamFlow's half is alive; it does not prove your tracker can reach us.
From a terminal:
npx -y github:macleodlabs-ai/teamflow-plugin status
That prints a line per connection with its filter and its last delivery. teamflow doctor warns when the repository's tracker is not among them.
What TeamFlow keeps
Only the key, the provider, the event, the status name, the title, the assignee, the labels and the timestamps, plus the structure around the issue — its priority, estimate, parent, children and declared relations.
Issue descriptions, comments, attachments and custom fields never leave the webhook handler. On an import they are not asked for in the first place.