A unified control plane for running, managing, and collaborating with AI workspaces across local and remote machines

English | 简体中文

TaskHandoff brings Codex and other AI development work into one control plane. It connects AI sessions spread across machines, workspaces, and chat platforms while managing node enrollment, instance lifecycles, sessions, applications, and message routing.

Beta: Task Handoff is under active development. Breaking changes may land between releases.

Light mode:

Dark mode, with a Story session and a browser running in the container:

For more interface screenshots, see the Interface and Workbench guide.

- Multi-node management — Connect local and remote nodes and inspect their resources and managed instances from one place.

- Managed workspaces — Create, start, stop, and restore isolated workspaces, with Docker as the primary runtime today.

- Image market and custom images — Choose from a read-only built-in catalog or separately managed custom images through one instance creation flow.

- Environment templates — Save a Docker instance's installed tools and container configuration as a node-local reusable environment, then combine it with any project or local-folder workspace.

- AI session center — View and control sessions across instances with real-time state delivered over WebSocket.

- Repository workflows — Inspect files, changes, branches, and worktrees, with conservative remote delivery for Git repositories.

- Managed Git credentials — Scope HTTPS tokens or pinned SSH keys to remotes, use them for one-time provisioning, or retain them for Agent, Terminal, App, and Repository Git commands.

- Chat integrations — Route messages, approvals, and actions from Telegram, DingTalk, WeChat, and Feishu/Lark to a selected instance.

- Application management — Install, remove, and run applications on target instances through a trusted built-in catalog.

- Mobile client — Connect an iOS or Android device directly to a user-managed Control Plane for AI sessions, instance operations, applications, and terminals.

- Desktop and server deployment — Run TaskHandoff as a mobile or desktop application, or as systemd services on Debian and Ubuntu.

- English and Chinese UI — Switch languages instantly or follow the browser language automatically.

Browser / Desktop / Mobile / Chat platforms

│

▼

Control Plane

UI, API, and chat gateway

│

▼

Node Agent

Node resources and instance lifecycle

│

▼

Controlled Instance

Workspace, applications, and AI sessions

TaskHandoff is organized into three runtime layers:

- Control Plane provides the Web/API management surface and owns the node inventory, instance board, chat gateway, and cross-instance AI session views.

- Node Agent runs on each managed machine and owns node-local configuration, runtime resources, folder inventory, and controlled instance lifecycles. Instances continue running when the control plane is stopped or restarted.

- Controlled Instance hosts a workspace, applications, AI sessions, triggers, and metadata. It can run standalone; in a managed deployment, its lifecycle and access are owned by the Node Agent.

Chat and AI Session state form a cross-layer path: the Control Plane owns chat credentials, bindings, command parsing, and routing, while each target AI Session remains the source of truth for conversation state.

Docker is the primary isolated runtime and supports multiple instances on one node. A built-in Local Runtime is also available on supported non-Windows nodes for one controlled instance per host user. Runtime capabilities and adapters keep the same model extensible to Kubernetes without creating a separate UI flow.

An environment template is a node-local Docker image created from an existing instance with docker commit. Registry images and environment templates are peer environment sources in the instance creation flow. Workspace selection remains independent, so either source can be combined with a Git project or a local-folder workspace.

Templates capture only the container writable layer, such as installed system packages and tools. They exclude /workspace, /data, /home/agent, every other bind mount or volume, memory, processes, and network state. Derived instances always receive a new identity, registration token, port, and managed volumes. The node agent briefly pauses the source container during commit and rejects a template if Docker Config contains instance-private credentials.

Every Docker instance has managed volumes for /data and /home/agent; Git workspaces also have a managed /workspace volume, while local folders use an external bind mount. The instance deletion dialog uses one option, selected by default, to delete all managed data. Clearing it retains every managed volume and reports its name; retained volumes are never attached automatically to another instance.

The source node owns both the template record and its Docker image, so a template can be used only on that node while it is ready. Deleting a template removes its internal template tag. A content-addressed internal lease keeps the image recoverable while derived instances reference it, and the image is garbage-collected after the final reference is removed.

- Node.js >= 24.15.0 < 25

- pnpm 9.15.3

- Docker, when using Docker Runtime, building container images, or running the standalone Compose profile

pnpm install

pnpm run build:all

pnpm cli helpStart the Control Plane API and development UI in separate terminals. The disabled authentication mode is intended only for loopback development:

pnpm cli control-plane --auth-mode disabled

pnpm run control-plane-ui:devCommon development commands:

# Start the control-plane UI

pnpm run control-plane-ui:dev

# Type-check and build

pnpm run typecheck

pnpm run web:typecheck

pnpm run build:all

# Run tests

pnpm test

# Inspect the npm package contents

pnpm run pack:dryTo run a standalone Browser-profile controlled instance instead of the Control Plane development stack:

docker compose up -d --buildThe current directory is mounted at /workspace by default. Set TASK_HANDOFF_WORKSPACE_HOST to mount a different host directory. This Compose service is a standalone controlled instance, not a Control Plane and Node Agent deployment.

Server deployments install the Control Plane and the server-local Node Agent as independent systemd services. The control plane can stop or restart without terminating instances managed by the agent.

On a Debian or Ubuntu server running systemd, run the latest stable installer as root:

curl -fsSL https://github.com/edgestorage/task-handoff/releases/latest/download/install-server.sh | sudo shThe script checks the host, installs Node.js 24 and Docker when needed, installs the latest stable @task-handoff/server package from npm, and then creates and starts the Control Plane and Node Agent systemd services. The default auto source profile uses Tsinghua APT mirrors and npmmirror for Chinese locale or timezone environments, and also falls back to those mirrors when the official Node.js source is unreachable. Its temporary APT source list does not overwrite the host's source configuration. By default, the control plane listens on port 8081 with password authentication enabled. Installer options can change the port, authentication mode, release channel, and other service settings.

Use --install-source china or --install-source official to select a source profile explicitly:

curl -fsSL https://github.com/edgestorage/task-handoff/releases/latest/download/install-server.sh | sudo sh -s -- --install-source chinasudo npm install -g @task-handoff/server@latest

sudo task-handoff installManage services and updates:

sudo task-handoff start

sudo task-handoff stop

sudo task-handoff restart

task-handoff check

sudo task-handoff updateThe installation creates:

task-handoff-node-agent.service

task-handoff-control-plane.service

See scripts/install-server.sh for supported installer options.

Remote machines only need the Node Agent. Generate a one-time join token in the Control Plane and prefer the exact installation command shown there. Its package version is resolved from the running Control Plane release. The equivalent form is:

curl -fsSL https://CONTROL_PLANE_HOST/install-node-agent.sh | sudo sh -s -- \

--control-plane https://CONTROL_PLANE_HOST \

--join-token JOIN_TOKEN \

--npm-package @task-handoff/node-agent \

--controlled-instance-package @task-handoff/controlled-instance \

--version RELEASE_VERSIONOn Debian and Ubuntu, the remote-node installer bootstraps the required Node.js

24 and npm on a fresh host. It uses the same automatic source selection; append

--install-source china to force Chinese mirrors. The selected npm registry is

preserved in the Node Agent service environment for subsequent managed updates.

Replace RELEASE_VERSION with the Control Plane's runtime package version so the Node Agent and controlled-instance runtime use the same release.

An installed Node Agent can also generate a one-time invitation directly on the node:

sudo task-handoff-node-agent invite --ipc-path /run/task-handoff/node-agent.sockAdd --json for automation-friendly output. Remote TCP access still requires an invitation and paired HMAC authentication.

To remove a standalone Node Agent installation:

sudo task-handoff-node-agent uninstallThe command removes the systemd service and runtime packages, then asks whether to delete the Node Agent data directory. The default is No. Use --keep-data or --delete-data for non-interactive execution. Managed Docker volumes are preserved.

@task-handoff/server provides the unified task-handoff command:

task-handoff control-plane

task-handoff node-agent

task-handoff node-agent-invite

task-handoff web

task-handoff helpUse pnpm cli help during development. Chat adapters, bindings, AI session messages, queues, and approvals are managed by the control plane.

The control-plane UI supports English (en-US) and Simplified Chinese (zh-CN). Open Settings → Appearance → Language to follow the system language or choose a language explicitly. The interface updates without reloading control-plane data.

The preference is stored only in the current browser. Terminal output, logs, AI messages, repository content, and other user- or provider-supplied data are never translated.

apps/cli/ CLI entry point

apps/desktop-shell/ Electron desktop shell

apps/mobile/ Expo iOS and Android client

packages/control-plane/ Control plane, Node Agent, and chat gateway

packages/control-plane-client/ Shared Control Plane API and realtime client

packages/control-plane-ui/ Control-plane Vue UI

packages/controlled-instance/ Controlled-instance HTTP/WebSocket API

packages/controlled-instance-ui/ Frozen controlled-instance Vue UI

packages/ai-session-runtime/ AI session runtime

packages/app-runtime/ Managed application runtime and catalog

packages/protocol/ Cross-component protocols and data models

packages/core/ Shared capabilities, diagnostics, and storage

packages/web-theme/ Web theme and Markdown rendering

scripts/ Installation, build, and runtime scripts

A semantic version tag such as v1.2.3 builds the controlled-instance runtime artifacts, publishes @task-handoff/control-plane, @task-handoff/node-agent, @task-handoff/controlled-instance, and @task-handoff/server, and attaches the installer and immutable artifacts to the GitHub Release. alpha and beta versions use their matching npm dist-tags; stable versions update latest.

The six public base images and their independent docker-vX.Y.Z release

workflow are maintained in the

TaskHandoff Images repository.

They contain system dependencies and developer tools, but not the

controlled-instance runtime. Node Agent remains the authority for mounting the

bootstrap bundle and installing the desired runtime artifact.

The Control Plane image market uses the bundled snapshot by default; once a

verification key is configured it pulls its catalog from

https://images.thandoff.com/market/v1/catalog.json and degrades through

remote, local cache, then the bundled snapshot; the cache lives at

market/catalog-cache.json inside the data directory. The issued catalog is

authoritative for the repositories it references: remote responses must pass

schema validation and mandatory ed25519 verification, and remote loading stays

disabled while no public key is configured. Configuration:

- TASK_HANDOFF_MARKET_CATALOG_URLoverrides the catalog URL (official URL by default); set it to- off/- 0to disable remote loading.

- TASK_HANDOFF_MARKET_REFRESH_INTERVALsets the refresh interval in seconds (six hours by default);- 0keeps manual refresh only.

- TASK_HANDOFF_MARKET_CATALOG_PUBLIC_KEYis required to enable remote loading: the ed25519 key (PEM or base64 SPKI).- TASK_HANDOFF_MARKET_CATALOG_KEY_IDoptionally pins the key identifier carried by the catalog signature.

- TASK_HANDOFF_MARKET_ALLOWED_REPOSITORIESis an optional comma-separated repository allowlist (matched on repository path boundaries) for deployments that want to restrict the catalog to their own registry.

Semantic version tags build macOS arm64/x64, Windows arm64/x64, and Linux x64 installers and publish them to GitHub Releases. Versions with an alpha or beta suffix are marked as prereleases. macOS artifacts are signed, notarized, stapled, and verified with Gatekeeper. Windows code signing is not enabled yet.

Closing the Desktop control-panel window keeps TaskHandoff running in the system tray. The tray shows the current Control Plane and Node Agent service status and can reopen the existing window without restarting either service. Choose Quit TaskHandoff from the tray or the platform application menu to stop the Desktop services. A graceful Node Agent shutdown stops Local Runtime controlled instances so they can be restored on the next launch; Docker Runtime controlled instances keep running and are rediscovered when the Node Agent returns.

A stable tag in the exact form mobile-vX.Y.Z runs the mobile release checks and starts independent Android and iOS release jobs. GitHub-hosted Linux and macOS runners build and sign both native applications. Android attaches an APK to the corresponding GitHub Release; after approval through the ios-production environment, iOS uploads directly to App Store Connect/TestFlight. Final App Store review remains a manual action, and Android is not submitted to Google Play by this workflow.

See apps/mobile/README.md for the client boundary and development commands, and apps/mobile/RELEASE.md for credentials, first-build setup, and release operations.

TaskHandoff is licensed under the Apache License 2.0. See NOTICE for attribution information.