Windshift v0.8.0 — "Shiplaunch"
Windshift 0.8.0 takes the coding agents introduced in 0.7.2 and turns them into a real platform. Agent runs now execute on runner pools — fleets of machines you register with one command — while every credential a run needs (Git access, model API keys, secrets) stays on the server and is never copied to a runner. Agents can continue their own pull requests, be started with a simple @mention, carry a persona and a library of skills, and reach a much bigger toolbox. And it's not only about agents: 0.8.0 adds two-way Todoist sync for personal tasks, a faster Pages module, a refreshed admin, and a long list of security and integration work.
Highlights
Run agents anywhere with runner pools
In 0.7.x, agent runs executed on the Windshift host itself. With 0.8.0 the server orchestrates runs and dispatches them to runner machines you register:
- One-command install. Mint a registration token and the dialog hands you a copy-paste command that installs and starts a runner on any machine with Docker. The runner registers itself, picks up work, streams progress back, and shuts down cleanly.
- Built for fleets. Each pool has a concurrency limit, reports its queue depth (useful as an autoscaling signal), and runs can be cancelled remotely. If a runner machine dies mid-run, Windshift notices, marks the affected runs as failed, and removes the dead runner — nothing hangs forever.
- Single host is still one command. You don't need a separate fleet to get started: the deployment bundle can co-locate a runner alongside Windshift on the same host and the same Docker network, so a one-box install behaves just like before — it's simply the first member of the same system.
Your credentials never leave the server
Runner machines — and the agents running on them — never receive your actual credentials. When a run starts, Windshift works out exactly what that run is allowed to touch, and every sensitive operation goes through the server:
- Git access is proxied: the agent can fetch its repository and push its work branch, and nothing else, without ever holding a Git token. Each push is checked branch-by-branch against what the run was granted.
- Model API calls are proxied with the provider key added server-side — no key ever enters the agent's container.
- Secrets and outbound web requests are brokered and allow-listed the same way.
A run's Git activity now also carries the right identity: when someone triggers an agent on a workspace connected via OAuth, the branch and draft pull request are created as that person, not as a shared service identity. Expiring Git OAuth tokens are refreshed automatically, so long-lived agent setups don't fail on a stale token.
Agents that continue their own pull requests
Agent work is no longer one-and-done. When you @mention a bound agent on an item that already has an open pull request, the agent continues that PR — it pushes new commits to the existing branch instead of opening a competing one, and the comment you wrote becomes its instructions for the follow-up run. The agent's closing summary is posted as a note on the pull request and as a comment on the work item, so the next reader sees what changed and why. Mention the agent on a PR comment and Windshift picks that up too.
Shape your agents
- Skills library. Each workspace can maintain a library of Markdown knowledge packs and attach them to agents. Agents see a short index of their skills and fetch the full text only when relevant — so a large library doesn't slow anything down.
- Custom instructions. Give each agent binding a persona or extra ground rules. These are added on top of the standard operating rules, never instead of them.
- @mention to start a run. Mentioning a bound agent in a comment starts a run on that item — lighter than assignment, with no assignee or status change. Duplicate mentions and self-mentions are handled sensibly, and an agent already working on the item won't be started twice.
A bigger toolbox for agents
Agents and integrations can now do far more through the API and the MCP server, with each tool gated on its own token scope (behind mcp:access):
- Links — list, add, and remove links between items, pages, and test cases.
- Tests — read test cases, start runs, and record results.
- Comments and users — edit and delete comments, and look up users (with emails and roles masked for non-admins).
- Stable addressing — every item-scoped tool now accepts a human-readable item key (e.g.
WI-42) as well as a numeric id, and agent writes are audit-tagged with their source. - Richer context — the in-product AI chat now understands the work item you're looking at, and tools expose full item descriptions with an explicit truncation marker.
The ws CLI grew to match: new ws label, ws search, and ws task history verbs, a ws task parent command with parent/children shown in ws task get, and --custom-field, --iteration, and --project flags on ws task create/edit.
See what your agents are doing
- A live Agent log tab on the work item shows the run's progress as it happens.
- Runs that hit an unrecovered tool-use failure are flagged for review with a banner that explains what went wrong, and an item-editor can re-run the agent from the same tab in one click.
- Assignment pickers now show whether an agent is actually available to take work.
- A runner pool health panel in admin Diagnostics shows each pool's runners, capacity, and queue.
- Configuration problems surface early: Windshift checks an agent's Git and model access at trigger time and fails visibly with a clear error instead of starting a run that was never going to work.
Two-way Todoist sync for personal tasks
Connect your Todoist account and keep your personal task list in step with Windshift. Tasks created, edited, or completed in either place are reflected in the other on a five-minute cycle, with a Sync now button and a last-sync status when you want it immediately. Enable it per-user under your personal settings; choose to sync everything or just a single Todoist project.
Safer networking out of the box
Agent containers run on a dedicated egress network so they can't reach anything you haven't allowed. The simplest setup needs no firewall at all — when Windshift and its runner are co-located, the network is declared internal, which lets agents reach Windshift and nothing else. For runners on a separate host, a bundled helper sets up a firewall allowlist so agents can only reach the destinations you choose. Server-side request forgery (SSRF) protection covers all outbound traffic, with a single operator switch (--allow-local-connections) for deployments that genuinely need to reach private addresses.
More than coding agents
The same dispatch system now also runs plain container jobs from action automations, so scheduled or triggered containers can execute on a runner pool too.
Smaller wins worth noting
- Faster Pages. Large page trees load and scroll noticeably faster — bodies are kept out of the tree query and only the visible rows are rendered.
- Refreshed workspace admin. Settings move from tabs to a folded sidebar, and agent bindings and skills are now managed through consistent modal dialogs.
- Command palette: recently viewed. Open the palette and the first entry jumps you into your recently viewed work items.
- Desktop app. Settings and About now open as in-app modals, including a Pomodoro settings panel.
- New model provider. Z.AI's Coding Plan endpoint is selectable alongside the existing Z.AI provider.
- Subpath deployments. Windshift can be served under a path prefix (for example
https://example.com/windshift/) behind a reverse proxy.
Also in 0.8.0
- Built for integrations — the REST API is ready to back third-party embeds: a
collections:readtoken scope for read-only report access, a ready-made entry in the OAuth client setup, and a newexclude_personalAPI parameter so integrations can guarantee your personal-workspace items never appear on shared surfaces. - Asset management API & CLI — assets get full REST endpoints, token scopes, CSV import, and new
ws assetcommands (deleting via API is opt-in). - Jira import grows — the importer now covers Jira/Insight assets, boards and sprints, and custom fields; a migration-readiness analyser reports what will and won't come across; and an import can be re-run safely without creating duplicates.
- Time tracking integrity — one active timer per user is now enforced, worklogs require permission to view the item, and several permission gaps in projects and categories were closed.
Security
This release includes fixes from dedicated security reviews — of the remote runner system and across the whole codebase:
- Runner registration tokens are single-use, expire by default, and require HTTPS; each runner gets its own credential.
- A finished run can't be tampered with afterwards: late events and repeated finalization are rejected, and Git pushes are checked branch-by-branch against what the run was granted.
- OAuth hardening: the authorization flow now requires PKCE
S256(plain and omitted methods are rejected), disabling an OAuth client immediately revokes the tokens issued through it, and public decode paths are size-capped. - Attachment downloads are confined to the storage root (no symlink or
..escapes) and filenames are formatted safely intoContent-Disposition. - SSRF protection now covers all outbound traffic, with one explicit operator switch (
--allow-local-connections) for deployments that genuinely need to reach private addresses. - Portal magic-link tokens are stored hashed, secrets no longer appear in the host process table, and several cross-workspace information leaks were closed.
- User input is consistently sanitized across both API surfaces without corrupting stored HTML, and anything the server had to clean up is reported back in the response.
Bug fixes
- Agent runs that produce no commits no longer push an empty branch or open an empty pull request.
- The mention picker now handles keyboard navigation correctly and consumes Enter/Tab/Escape while open.
- Pressing Enter confirms the page move dialog, notification toasts appear above modal dialogs, and the Pages navigation tree no longer flickers on every autosave.
- Fresh installs and upgraded databases now end up with exactly the same schema.
Upgrade notes
Coding agents
Setting up runners and turning on the agent harness are two separate steps:
- Runner pools work out of the box. You can create a pool under Admin → Capabilities, mint a registration token, and register runners at any time — this does not require the harness flag. Runners just stay idle until there is work to claim.
CODING_AGENT_ENABLEDturns on orchestration. It is off by default. With it off, the harness runs in observer mode: agent bindings can be created and triggers are logged, but no run is ever queued (so registered runners get nothing to do). SetCODING_AGENT_ENABLED=true(or pass--enable-coding-agent) to have triggers enqueue runs. When enabled, the Windshift server orchestrates runs — queuing them, handing them to runners, and finalizing results — but executes nothing itself; every run is dispatched to a runner.
To actually get agents working you need both: the flag on, and at least one runner registered.
- Single host: uncomment the bundled
windshift-runnerservice in the deployment compose file. It joins Windshift on aninternalDocker network, so agent containers can reach the server and nothing else — no firewall rules required. - Separate hosts / pools: run the install command shown in the registration-token dialog on each runner machine (Docker required). For runners not co-located with Windshift, use the bundled firewall helper to allowlist their egress.
- If agent containers can't reach your public
BASE_URL(for example alocalhostURL), setCODING_AGENT_WS_API_URLto an address they can reach — it must end in/api.
New operator flags
--allow-local-connections(ALLOW_LOCAL_CONNECTIONS) — let server-side requests reach loopback and private addresses, for self-hosted SCM, Jira Data Center, or a local model gateway. Off by default.--allow-insecure-http(ALLOW_INSECURE_HTTP) — permit credentialed access over plain HTTP from non-localhost origins, for trusted LANs and testing only. Off by default.--context-path(WINDSHIFT_CONTEXT_PATH) — serve Windshift under a path prefix behind a reverse proxy.