Skip to content

Repository files navigation

Task Router

Removes the need to remember which project you are in before you write a task.

You type the task. If it belongs to the project that is already selected, nothing happens — press Enter as usual. If it clearly belongs to a different one, a single line appears above the composer:

Looks like this is Project B, not Project A. Open in Project B

The button starts the thread in that project with the same text. If the project was never registered with Tendo, it is registered at that moment — never before.

When the plugin is not confident, it says nothing. A wrong suggestion hands a decision back to the user, which is the exact cost this removes.

What it is built on

Piece Surface
The line above the composer app.composer.customize({ banners }), scoped to root compose
The draft it reads useComposerView().draft.text — reactive, read-only
The project it compares against ComposerView.scope.projectId — read-only
Starting the thread bb.sdk.projects.create + bb.sdk.threads.spawn

Why it proposes instead of switching

The composer's plugin surface cannot intercept a send and cannot set a project. ComposerCustomization offers actions, banners, plusMenu and richText and nothing else; PluginComposerApi writes text, mentions and locks, but has no project setter. So the honest shape is a proposal accepted with one click. Doing it any other way means reaching into the host's own DOM, which breaks on the next Tendo release.

Identity is the remote URL, not the path

A checkout and its worktrees are one project. The census reads each working tree's git config — following .git files through commondir for worktrees — and groups by normalized remote URL, so a checkout at ~/dev/project-a and a worktree at ~/dev/project-a-worktrees/feature-x are recognised as the same project and no suggestion is made between them.

How the matching works

Version 1 is deterministic — no model call, so it costs nothing and never invents a project:

  • an explicit path in the text (strongest)
  • the project's name, on word boundaries, with separators normalized so acme-web-app, Acme Web App and acme web app all match
  • names shorter than four characters, ordinary words (health, personal) and names of daily tools (miro, figma, notion) never match on their own
  • a tie between two projects reports nothing

A suggestion appears only when exactly one project reaches the threshold and it differs from the selected one.

The census

hosts.directory walks the workspace root three levels deep, then hosts.pathsExist asks in batches which of those folders contain .git. It is not files.listPaths: that walks recursively and applies its limit only after the walk, which over a workspace root means descending into every node_modules on the disk.

The result is cached for 30 minutes, warmed when the plugin starts, and a stale census is served immediately while a fresh one is built behind it — the composer never waits on disk.

Setting: Workspace root — configure in Settings to the folder your projects live in (e.g. ~/dev or ~/Projects). Empty by default; the plugin stays silent until it is set.

Threads started in projects whose name has a space

Tendo derives a managed worktree's directory name from the repository folder name and rejects anything outside [A-Za-z0-9._-]. So a thread opened in a project folder named "Client Kickoff Deck" runs in the checkout itself rather than a worktree; a thread opened in acme-web-app gets the project's normal default. Checking this before spawning is what keeps one click from producing a thread that fails while provisioning.

Inspecting it without the interface

bb task-router census                 # projects found, and how many trees each has
bb task-router classify "<text>"      # which project a text resolves to, if any
bb task-router suggest --project <id> "<text>"   # what the composer would say
bb task-router open --path <repo> [--from <projectId>] "<text>"

suggest and open call the same handlers the composer's banner and button call — a diagnostic that ran different code would prove nothing about the button.

Building

npm install
npm test        # matching rules
npm run typecheck
npm run build    # requires the bb CLI

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages