The run dock
Run your project's build, test, and dev-server commands from a dock at the bottom of the workspace side panel -- on your own machine or any host in your org.
- Topic
- Run Tasks & Services
- Available on
- Available onDesktopWeb Portal
- Reviewed
- October 15, 2026
On this page
Every worktree in Glueprint gets a run dock — a collapsible panel pinned to the bottom of the workspace side panel that knows the project’s runnable commands and can start, watch, and stop them without leaving the session view. It handles one-shot jobs (tests, builds, linters) and long-running services (dev servers, watchers) with readiness detection, live output, and hand-off of failures straight into an agent session.
The dock is scoped to the worktree you’re looking at. Switch worktrees and the dock switches with you — its task catalog, its running jobs, and its terminal tabs all belong to that worktree.
The dock’s Debug tab, next to Run, is where you debug that worktree: see Debugger.
Where tasks come from
The dock discovers commands from the sources below and shows them as groups in the Tasks tab:
| Group | Source | What’s discovered |
|---|---|---|
| Configured | .glueprint/tasks.json | Commands your team defines by hand — see Configuring tasks |
| Package scripts | package.json | Every entry in the root scripts block |
| Project tasks | Cargo.toml | cargo build / test / check / clippy, plus cargo run --bin per binary; both the root manifest and src-tauri/Cargo.toml are probed |
| Python tasks | pyproject.toml, tox.ini | Poe, Hatch, and PDM scripts, plus tox environments |
| Go tasks | go.mod, go.work | go build / test / vet / fmt, plus go run per main package |
| Composer scripts | composer.json | Every entry in the scripts block, minus Composer’s own lifecycle events |
| Taskfile tasks | Taskfile.yml | Every non-internal task in the first Taskfile found (eight standard names, go-task’s search order) |
| .NET tasks | .sln, .slnx, .csproj, .fsproj | dotnet restore / build / test / format per solution, plus dotnet run for runnable projects |
| VS Code tasks | .vscode/tasks.json | Imported shell and process tasks |
| Nx | nx.json, project.json | Every target each Nx project declares, grouped by project and run as nx run <project>:<target> |
Monorepos and workspaces
Discovery follows workspace declarations, so a monorepo’s packages show up without any configuration.
- JavaScript workspaces come from the root
workspacesfield or frompnpm-workspace.yaml. Each member’s scripts land in their own group named after the package —Package scripts: @your/portal— falling back to the member’s path when the package has no name. - Cargo workspaces come from the
[workspace]table, withexcludehonored. Each member’s runnable tasks land inProject tasks: <package>, and the members’ build, check, and test tasks collect into a sharedProject tasks: package checksgroup. A workspace root also gains acargo fmt --alltask and workspace-wide variants (separate rows for non-virtual roots; folded into the base tasks for virtual roots).
JavaScript commands use the root packageManager field first. Without it,
lockfiles are checked in pnpm, yarn, bun, then npm order; no match falls back
to npm with a diagnostic. Every member inherits that root choice, and a
member’s own packageManager field is ignored.
Workspace member groups start collapsed so a large catalog opens to a short
list; click a group header to expand it. Group order is fixed: configured
tasks, package scripts, project tasks, Python tasks, Go tasks, Composer scripts,
Taskfile tasks, .NET tasks, VS Code tasks, then Nx targets, with each workspace member
grouped contiguously. A workspace-member package header with one shared
directory shows the name its manifest declares — @your/portal, or the crate
name — with the manifest’s path beneath it, falling back to the directory when
the manifest declares none.
Scripts named like servers — dev, start, serve, watch, preview, or
prefixed versions like dev:web — are treated as services (long-running,
with a Stop button and readiness detection). Everything else is a one-shot. If
the guess is wrong for your project, a one-line entry in
.glueprint/tasks.json overrides it.
.NET projects
Solutions are found in the worktree root. Projects are found by a bounded scan
that skips bin, obj, node_modules, packages, and TestResults.
A solution owns the projects it declares. Those projects contribute only
dotnet run; their restore, build, and format commands live on the solution so
the same command is not offered twice. A project no solution covers gets
restore, build, and format commands of its own.
dotnet test appears for every solution and for an uncovered project that
references the test SDK or sets IsTestProject. dotnet run appears only for
a runnable project, and counts as a service rather than a one-shot for the Web
and Worker SDKs.
Only SDK-style projects are read. A project with no Sdk attribute is skipped
with a diagnostic.
Nx workspaces
A worktree with an nx.json at its root is an Nx workspace. Its projects are
found by a bounded scan for project.json files that skips dot directories,
node_modules, and build-output folders such as dist, plus any JavaScript
workspace member whose package.json declares targets under nx.targets. Each
project gets its own group under Nx, headed by the project name with its
project.json path beneath it, so search finds a target by project or target
name.
A project’s name comes from project.json, then its package.json, then its
directory, the same order Nx uses. Targets run from the workspace root through
the workspace’s package manager: pnpm exec nx run web:build, yarn nx run,
bun x nx run, or npx nx run. Targets Nx marks continuous, targets named
like servers, and targets whose executor is a dev server count as services.
Those settings are read the way Nx combines them: a target’s own settings
win, then the same target in the project’s package.json, then the matching
targetDefaults entry in nx.json. A few forms need Nx’s full project graph
and are not taken into account: targetDefaults entries filtered by
projects or plugin, '...' spread entries, and glob-named targets in
project.json.
Discovery reads these files and never runs Nx, and it never follows a
symbolic link: a linked nx.json, project.json, or package.json is reported
and skipped. Targets that only a plugin in
nx.json adds — lint from @nx/eslint/plugin, test from
@nx/jest/plugin — are not listed, and a diagnostic names those plugins. A
target your project.json declares is listed even when a plugin supplies its
executor. package.json scripts stay under Package scripts rather than
appearing a second time. Configurations such as :production, nx affected,
and nx run-many are not listed; add the ones you use to
.glueprint/tasks.json.
The Nx catalog stops at 500 targets, and the scan at 400 projects or 20,000 directory entries, each with a diagnostic.
Limits, diagnostics, and refresh
Discovery is bounded so a pathological repository can never hang the dock. Member tasks are truncated so each catalog stays near 200 tasks, but root tasks are always kept even when that takes the catalog over 200. At most 400 member manifests are read per workspace, and any single config file over 1 MB is skipped. The dock shows a Catalog truncated notice naming how many member tasks were omitted.
Unparseable JSON, TOML, or YAML and bad workspace patterns surface as diagnostics in the Tasks tab, invalid globs included, positive or negated. A JavaScript member without a package name silently uses its relative directory; a Cargo member without a usable name is silently skipped. A malformed file in one source never empties the others.
Results are cached per worktree for 30 seconds. Changes to already-known files
and brand-new root-level files such as .glueprint/tasks.json or lockfiles are
seen immediately. Only a brand-new member directory, or a manifest that appears
later in a matched member directory, can take up to 30 seconds. The refresh
button always re-scans: it skips the cache for that request and stores what
it finds, so a brand-new member directory shows up the moment you ask.
Anatomy
- Tab strip — the Tasks tab, one tab per run (with a live status dot), and any terminal tabs you’ve docked. Tabs that don’t fit collect in an overflow menu.
- Run button — opens the launch menu: every discovered task grouped by source, plus shortcuts to create or browse tasks. If a service is already running, its entry becomes “Open running” and focuses the existing run instead of starting a second one.
+menu — edit the task configuration in the IDE, or open a new terminal directly in the dock.- Resize / collapse — drag the top edge (double-click resets), or collapse the dock to a slim bar. Height and collapse state persist across restarts.
Keyboard
| Surface | Shortcut | Action |
|---|---|---|
| Desktop | Cmd/Ctrl+R | Start the selected task, or stop it if it is already running. With no task selected, the dock opens on the Tasks tab so you can pick one |
| Desktop | Cmd/Ctrl+J | Show or hide the dock |
| Desktop | Command palette: Open Run Menu | Open the side panel, expand the dock, and focus the Tasks tab without starting anything |
| Portal | Alt+R | Start or stop the selected task (plain Cmd+R stays the browser’s reload) |
| Portal | Cmd+Alt+R (Ctrl+Alt+R) | Open the Run menu without starting anything |
See Keyboard shortcuts for rebinding.
Local, remote, and plans
On desktop, tasks in local worktrees run directly on your machine — no plan requirements, works offline.
Worktrees on other hosts use the cloud relay for the task catalog, runs, and live output, with command payloads end-to-end encrypted. Lite covers the mobile app; Pro or higher adds the web portal and multiple hosts. Cross-host task control needs Pro or higher. On Free and Lite, the portal is status-only. Permission prompts and questions remain actionable, but the task dock stays collapsed with an upgrade prompt and sends no task-control requests.
If a host goes offline mid-run, the dock keeps what it knows: cached tasks and output stay visible under an “offline” banner, running jobs show Connection lost, and everything reconciles automatically when the host comes back.