Skip to content
Agent Workspaces
Agent

worktrees

- `packages/core/src/runtimes/workspace-registry/` (creation pipeline, lifecycle steps, activation) - `packages/core/src/runtimes/scripts/` (lifecycle script execution) - `packages/core/src/runtimes/host-settings/` (per-host defaults) - `src/core/features/workspaces/` (desktop

From plugin
emdash
6.3k33 skills33 agents

Agent definition

worktrees.md

Worktrees

Main Files

  • `packages/core/src/runtimes/workspace-registry/` (creation pipeline, lifecycle steps, activation)
  • `packages/core/src/runtimes/scripts/` (lifecycle script execution)
  • `packages/core/src/runtimes/host-settings/` (per-host defaults)
  • `src/core/features/workspaces/` (desktop wire controllers and UI)
  • `.emdash.json`

Current Behavior

  • task worktrees are created under the project's DB-backed worktree directory setting
  • branch prefix defaults to `emdash` and is configurable in app settings
  • generated task branch names use the configured prefix plus a random suffix by default; app repository settings can disable only the random suffix
  • worktree creation is managed by the project provider pattern
  • creation runs a fast foreground pipeline (`inspect → resolve-base → add-worktree → verify`);

the base ref is fetched only when it is not locally resolvable

  • registry verbs that wait on host work with no fixed bound (creation, activation, deactivation,

removal, update, step retry, usage, artifact cleaning) declare `callTimeoutMs: 0` in the contract, so desktop, automation, and workspace-server callers wait for the result instead of timing out after 30s; a lost connection still fails the call

  • a `createWorktree` for a workspace whose creation is still running joins that run (same

result, no second git pipeline); completed and interrupted creations replay as before

  • when a stale git registration (worktree directory deleted out-of-band) blocks the requested

path or branch, `inspect` runs `git worktree prune`; locked registrations are kept, and working-tree files are never deleted (removing by path could hit a concurrent recreation)

  • newly created task branches use `git worktree add --no-track`; the selected base ref is a

starting point, not the branch's upstream

  • gitignored files named in `preservePatterns` are copied from the repository into the new

worktree as a durable background step, using copy-on-write (`cp -c` on APFS, `--reflink=auto` on Linux) with a plain-copy fallback; nothing is copied without configured patterns

  • there are no built-in preserve defaults: the `.env` family is no longer copied

automatically — projects that relied on it must add `preservePatterns` (behavior change in workspace-lifecycle-v2; `excludePatterns` was removed at the same time and stale keys are silently ignored)

  • branch publication carries the resolved project `pushRemote` as an explicit durable target;

a successful push establishes that remote's same-named branch as upstream

  • branch publication and ref freshening run as durable background steps; a failed push surfaces

as a "branch not pushed" task state with a manual retry

  • Workspaces-view disk usage is measured by the registry: one walk per workspace, shared by

concurrent callers and cached for 5 minutes; a workspace nested inside another one measured in the same request counts only in its own row; closing the view cancels walks still running

`.emdash.json`

`.emdash.json` stores optional shareable project settings. Supported runtime keys:

  • `preservePatterns` (gitignored files deliberately carried into new worktrees; empty unless configured)
  • `scripts.prepare`
  • `scripts.setup`
  • `scripts.run`
  • `scripts.teardown`
  • `shellSetup` (per-workspace override of the host-settings default; the per-project DB

field was retired)

Base project settings are DB-backed Project Settings, not runtime `.emdash.json` keys:

  • `worktreeDirectory`
  • `defaultBranch`
  • `baseRemote`
  • `pushRemote`
  • `tmux`

Host-local project settings are stored by the workspace registry and are not written to `.emdash.json`:

  • `env` (variables injected into new task terminals, lifecycle scripts, and TUI/ACP agent

processes; Emdash-owned `EMDASH_*` task metadata takes precedence)

Host-level defaults (`shellSetup`, `worktreeRoot`, `tmux`) live in the host-settings runtime (`packages/core/src/runtimes/host-settings/`), stored as a JSON file in the host's emdash data directory and editable from the machines/system settings UI. Precedence is per-project DB override, then host settings, then app defaults.

Rules

  • do not hardcode worktree paths; use service helpers
  • use lifecycle config for repo-specific bootstrap and teardown behavior
  • `scripts.prepare` is blocking and runs after the workspace exists but before task providers,

conversations, setup scripts, or run scripts start; keep it idempotent

  • `scripts.prepare`, `scripts.setup`, and `scripts.run` wait for the background artifact copy to

settle before running, since they may consume preserved files

  • `scripts.setup` and `scripts.run` are runtime-triggered after `scripts.prepare` succeeds; they do

not block task readiness

  • lifecycle scripts execute in the dedicated scripts runtime

(`packages/core/src/runtimes/scripts/`) on the host: PTY-backed, one run per (workspace, script), with provenance (`activation`/`manual`/`retry`), per-run timeouts, and a stop verb; the workspace registry observes runs and mirrors them into durable lifecycle steps for the Activity timeline

  • project environment variables are resolved by the workspace registry and passed explicitly to

every launch path; exports performed by one lifecycle shell do not mutate sibling or later processes

  • `shellSetup` runs inside each PTY before the interactive shell starts; the workspace's

`.emdash.json` value overrides the host-settings default. Lifecycle commands and `shellSetup` are opaque strings run together in the default shell selected by the host-owned runtime at execution time; repository authors own their portability.

  • tmux wrapping has an app level default but is also project-configurable in Project Settings

and affects PTY lifecycle behavior. It is always disabled for local Windows sessions without deleting the stored preference.

  • `preservePatterns` never copies tracked files or `.emdash.json`
Read more
@generalaction
Ships withemdash

Emdash is the Open-Source Agentic Development Environment (🧡 YC W26). Run multiple coding agents in parallel. Use any provider.

Stars on GitHub

Momentum

stars in total
6.3k
Star history of generalaction/emdash on GitHub, a chart by star-history.com

Other agents on emdash.

acp-runtime

acp-runtime

Agent

The ACP runtime is the domain service that serves the ACP API contract. It owns the host-scoped dependencies needed to run…

core-modules

core-modules

Agent

This page defines the target organization of `packages/core/src/`. Core is organized by module type so that shared domain APIs…

git-runtime

git-runtime

Agent

Git is split into a transport contract and a host-scoped runtime. Renderer, desktop, and workspace-server code share the Wire…

main-process

main-process

Agent

The main process is organized into domain modules under `src/main/core/`. Each domain typically has a `controller.ts` (RPC…

path-system

path-system

Agent

`@emdash/core/primitives/path/api` is the source of truth for portable file identity and lexical path operations. The detailed…

More agents from other plugins.

api-builder

api-builder

Agent

Deprecated placeholder. Do not use; follow root AGENTS.md and package instructions instead.

happier6d2.2k
@happier-dev@happier-devInstall Agent

Questions about worktrees.

Which coding agents can use worktrees?
worktrees installs in Claude Code and Cursor: each loads subagents from .claude/agents, so copy the file there. Flowy's auto-invocation runs in Claude Code only.