nx
Nx is the task orchestration and local caching layer for this pnpm workspace. It sits on top of the existing tooling — `tsdown`, `electron-vite`, `vitest`, `oxlint`, `oxfmt` — and adds dependency-ordered execution, input hashing, and output caching without requiring any
How it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Nx is the task orchestration and local caching layer for this pnpm workspace. It sits on top of the existing tooling — `tsdown`, `electron-vite`, `vitest`, `oxlint`, `oxfmt` — and adds dependency-ordered execution, input hashing, and output caching without requiring any
Agent definition
nx.mdNx In This Monorepo
Nx is the task orchestration and local caching layer for this pnpm workspace. It sits on top of the existing tooling — `tsdown`, `electron-vite`, `vitest`, `oxlint`, `oxfmt` — and adds dependency-ordered execution, input hashing, and output caching without requiring any structural changes to packages.
No `project.json` files exist. Nx infers all five projects from `package.json` `workspace:*` dependencies and runs each project's existing `package.json` scripts as Nx targets.
The Nx MCP server is enabled for this workspace. In Cursor, agents can query the project graph, list targets, and run tasks through the MCP server directly without shelling out.
Project Graph
Nx derives this graph from `workspace:*` dependency references:
@emdash/shared (leaf)
@emdash/core -> shared
@emdash/plugins -> core -> shared
@emdash/ui (leaf)
@emdash/emdash-desktop -> shared, core, plugins, ui
The `dependsOn: ["^build"]` default in `nx.json` means "build all upstream packages before running this target." A bare `nx build @emdash/emdash-desktop` therefore builds shared, core, plugins, and ui first, in dependency order, with parallelism where the graph allows.
Common Commands
All of these run from the repo root.
**Run a target for every project:**
pnpm run build # nx run-many -t build --all
pnpm run test # nx run-many -t test --all
pnpm run lint # nx run-many -t lint --all
pnpm run typecheck # nx run-many -t typecheck --all
pnpm run format:check # nx run-many -t format:check --all
pnpm run format # nx run-many -t format --all
**Start the full dev setup:**
pnpm run dev # nx run-many -t dev --all --parallel=10
This builds upstream packages via the `dev -> ^build` dependency chain, then starts all `dev` targets (tsdown watches + electron-vite dev) in parallel.
**Run only affected projects (relative to the default base branch):**
pnpm run affected # nx affected -t lint typecheck test
**Visualize the project graph:**
pnpm run graph # opens nx graph in the browser
**Address a single project or target directly:**
nx build @emdash/core
nx test @emdash/shared
nx typecheck @emdash/emdash-desktop
nx package:mac @emdash/emdash-desktop
nx db:reset @emdash/emdash-desktop
nx storybook @emdash/ui
nx theme:build @emdash/ui
**Run affected with a custom base:**
nx affected -t lint typecheck --base=main --head=HEAD
**List all projects:**
nx show projects
**Inspect a project's resolved targets:**
nx show project @emdash/core
nx show project @emdash/emdash-desktop
Task Ordering
Nx uses the `dependsOn` declarations in `nx.json` to determine task order:
| Target | Waits for upstream `build` first? | Cached? | | -------------- | --------------------------------- | ------- | | `build` | yes (`^build`) | yes | | `typecheck` | yes (`^build`) | yes | | `test` | yes (`^build`) | yes | | `dev` | yes (`^build`) | no | | `lint` | no | yes | | `format:check` | no | yes | | `format` | no | no |
Targets not listed in `targetDefaults` (e.g. `package`, `rebuild`, `db:reset`, `db:generate`) have no dependency ordering or caching applied and run as plain `pnpm exec` calls.
Local Caching
Nx hashes each task's inputs — source files, config files, `pnpm-lock.yaml`, and `sharedGlobals` (`.oxlintrc.json`, `.oxfmtrc.json`) — and caches the output artifacts and terminal output in `.nx/cache/`. A cache hit replays the output instantly without re-running the task.
Cached output directories per project:
- `packages/*/dist/` — tsdown output
- `apps/emdash-desktop/out/` — electron-vite build output
**What is NOT cached** (intentionally, due to platform/environment sensitivity):
- `package`, `package:mac`, `package:linux`, `package:win` — electron-builder
produces native platform artifacts and handles its own incremental logic.
- `rebuild` — Electron native module rebuild depends on the local Electron ABI.
- `run:docker-ssh`, `db:generate`, `db:reset` — side-effecting operations.
- `dev`, `format` — long-running or write-output operations.
**Bust the cache when needed:**
nx reset # clears .nx/cache and .nx/workspace-data
The `.nx/` directory is gitignored and local to each machine.
CI Integration
The `code-consistency-check.yml` workflow uses `nrwl/nx-set-shas@v4` to set `NX_BASE` and `NX_HEAD` environment variables from the PR base and head SHAs, then runs:
pnpm nx affected -t format:check typecheck lint
This means only the projects touched by the PR (and their dependents) are checked. A PR that modifies only `packages/ui` will not re-run typecheck for the desktop app unless it actually depends on changed output.
The `fetch-depth: 0` checkout is required for `nx-set-shas` to walk the full commit history and determine which files changed relative to the base branch.
Adding a New Package
When a new package is added under `packages/` or `apps/` that follows the same script conventions (`build`, `test`, `lint`, `typecheck`, `format`, `format:check`), Nx automatically picks it up at the next run. No `nx.json` changes are needed unless the package needs non-default caching behavior (unusual output paths, skipped cache, or a different `dependsOn`).
To override defaults for a specific project, add a `"nx"` key to that package's `package.json`:
{
"nx": {
"targets": {
"build": {
"outputs": ["{projectRoot}/dist", "{projectRoot}/types"]
}
}
}
}Read more
Nx In This Monorepo
Nx is the task orchestration and local caching layer for this pnpm workspace. It sits on top of the existing tooling — `tsdown`, `electron-vite`, `vitest`, `oxlint`, `oxfmt` — and adds dependency-ordered execution, input hashing, and output caching without requiring any structural changes to packages.
No `project.json` files exist. Nx infers all five projects from `package.json` `workspace:*` dependencies and runs each project's existing `package.json` scripts as Nx targets.
The Nx MCP server is enabled for this workspace. In Cursor, agents can query the project graph, list targets, and run tasks through the MCP server directly without shelling out.
Project Graph
Nx derives this graph from `workspace:*` dependency references:
@emdash/shared (leaf) @emdash/core -> shared @emdash/plugins -> core -> shared @emdash/ui (leaf) @emdash/emdash-desktop -> shared, core, plugins, ui
The `dependsOn: ["^build"]` default in `nx.json` means "build all upstream packages before running this target." A bare `nx build @emdash/emdash-desktop` therefore builds shared, core, plugins, and ui first, in dependency order, with parallelism where the graph allows.
Common Commands
All of these run from the repo root.
**Run a target for every project:**
pnpm run build # nx run-many -t build --all pnpm run test # nx run-many -t test --all pnpm run lint # nx run-many -t lint --all pnpm run typecheck # nx run-many -t typecheck --all pnpm run format:check # nx run-many -t format:check --all pnpm run format # nx run-many -t format --all
**Start the full dev setup:**
pnpm run dev # nx run-many -t dev --all --parallel=10
This builds upstream packages via the `dev -> ^build` dependency chain, then starts all `dev` targets (tsdown watches + electron-vite dev) in parallel.
**Run only affected projects (relative to the default base branch):**
pnpm run affected # nx affected -t lint typecheck test
**Visualize the project graph:**
pnpm run graph # opens nx graph in the browser
**Address a single project or target directly:**
nx build @emdash/core nx test @emdash/shared nx typecheck @emdash/emdash-desktop nx package:mac @emdash/emdash-desktop nx db:reset @emdash/emdash-desktop nx storybook @emdash/ui nx theme:build @emdash/ui
**Run affected with a custom base:**
nx affected -t lint typecheck --base=main --head=HEAD
**List all projects:**
nx show projects
**Inspect a project's resolved targets:**
nx show project @emdash/core nx show project @emdash/emdash-desktop
Task Ordering
Nx uses the `dependsOn` declarations in `nx.json` to determine task order:
| Target | Waits for upstream `build` first? | Cached? | | -------------- | --------------------------------- | ------- | | `build` | yes (`^build`) | yes | | `typecheck` | yes (`^build`) | yes | | `test` | yes (`^build`) | yes | | `dev` | yes (`^build`) | no | | `lint` | no | yes | | `format:check` | no | yes | | `format` | no | no |
Targets not listed in `targetDefaults` (e.g. `package`, `rebuild`, `db:reset`, `db:generate`) have no dependency ordering or caching applied and run as plain `pnpm exec` calls.
Local Caching
Nx hashes each task's inputs — source files, config files, `pnpm-lock.yaml`, and `sharedGlobals` (`.oxlintrc.json`, `.oxfmtrc.json`) — and caches the output artifacts and terminal output in `.nx/cache/`. A cache hit replays the output instantly without re-running the task.
Cached output directories per project:
- `packages/*/dist/` — tsdown output
- `apps/emdash-desktop/out/` — electron-vite build output
**What is NOT cached** (intentionally, due to platform/environment sensitivity):
- `package`, `package:mac`, `package:linux`, `package:win` — electron-builder
produces native platform artifacts and handles its own incremental logic.
- `rebuild` — Electron native module rebuild depends on the local Electron ABI.
- `run:docker-ssh`, `db:generate`, `db:reset` — side-effecting operations.
- `dev`, `format` — long-running or write-output operations.
**Bust the cache when needed:**
nx reset # clears .nx/cache and .nx/workspace-data
The `.nx/` directory is gitignored and local to each machine.
CI Integration
The `code-consistency-check.yml` workflow uses `nrwl/nx-set-shas@v4` to set `NX_BASE` and `NX_HEAD` environment variables from the PR base and head SHAs, then runs:
pnpm nx affected -t format:check typecheck lint
This means only the projects touched by the PR (and their dependents) are checked. A PR that modifies only `packages/ui` will not re-run typecheck for the desktop app unless it actually depends on changed output.
The `fetch-depth: 0` checkout is required for `nx-set-shas` to walk the full commit history and determine which files changed relative to the base branch.
Adding a New Package
When a new package is added under `packages/` or `apps/` that follows the same script conventions (`build`, `test`, `lint`, `typecheck`, `format`, `format:check`), Nx automatically picks it up at the next run. No `nx.json` changes are needed unless the package needs non-default caching behavior (unusual output paths, skipped cache, or a different `dependsOn`).
To override defaults for a specific project, add a `"nx"` key to that package's `package.json`:
{
"nx": {
"targets": {
"build": {
"outputs": ["{projectRoot}/dist", "{projectRoot}/types"]
}
}
}
}Emdash is the Open-Source Agentic Development Environment (🧡 YC W26). Run multiple coding agents in parallel. Use any provider.
Repo: generalaction/emdash
Other agents on emdash.
- acp-runtime
The ACP runtime is the domain service that serves the ACP API contract. It owns the host-scoped dependencies needed to run provider ACP sessions, but it should not mix cross-session routing with per-session state projection.
Open agent - main-process
The main process is organized into domain modules under `src/main/core/`. Each domain typically has a `controller.ts` (RPC handlers) and service/implementation files.
Open agent - overview
All paths are relative to `apps/emdash-desktop/`.
Open agent - renderer
All paths are relative to `apps/emdash-desktop/`.
Open agent - shared
- Agent/provider DTOs: - `src/shared/core/agents/agent-payload.ts` - provider metadata and capabilities are sourced from `packages/plugins/src/agents/registry.ts` - IPC primitives: - `src/shared/ipc/rpc.ts` — typed RPC router, controller, and client - `src/shared/ipc/events.ts`
Open agent - workspace-server
The Workspace Server (`apps/workspace-server/`) is a Node daemon that runs on a remote machine and exposes workspace runtimes (git, files, deps, ACP, …) to Emdash clients over the `@emdash/wire` protocol. Clients connect over an SSH-forwarded Unix socket; the daemon is
Open agent

