Skip to main content

Development Workflow

This guide covers day-to-day development commands, debugging strategies, and code quality practices for working on the Ever Works Platform.

Development Commands​

All commands are run from the monorepo root unless otherwise noted. Turborepo orchestrates task execution across all workspace packages.

Starting Dev Servers​

# Start every app in watch mode -- API, Web and MCP in parallel
# (all of apps/* except docs, desktop, desktop-node and node)
pnpm dev:apps

# Start only the API (NestJS, port 3100)
pnpm dev:api

# Start only the Web dashboard (Next.js, port 3000)
pnpm dev:web

# Start only the documentation site (Docusaurus)
pnpm dev:docs

# Start the Trigger.dev dev server (background jobs)
pnpm dev:trigger

There is no root pnpm dev script -- pick the target you want from the list above.

Under the hood, these map to Turborepo filters:

CommandTurborepo Equivalent
pnpm dev:appsturbo dev --filter=./apps/* --filter=!./apps/docs --filter=!./apps/desktop --filter=!./apps/desktop-node --filter=!./apps/node
pnpm dev:apiturbo dev --filter=ever-works-api
pnpm dev:webturbo dev --filter=ever-works-web
pnpm dev:docsturbo dev --filter=ever-works-docs
pnpm dev:triggerturbo dev:trigger --filter=@ever-works/trigger-tasks

Building​

# Build everything (Turborepo handles dependency order via ^build)
pnpm build

# Build only apps
pnpm build:apps

# Build only shared packages
pnpm build:packages

# Build the plugin system and all plugins
pnpm build:plugins

# Build a single package
turbo build --filter=ever-works-api
turbo build --filter=@ever-works/agent
turbo build --filter=@ever-works/plugin

The build task in turbo.json declares "dependsOn": ["^build"], which means Turborepo automatically builds dependencies before their consumers. Output works (dist/, build/, .next/) are cached.

Build Order​

Turborepo resolves the dependency graph automatically. A typical build proceeds as follows:

Hot-Reloading Behavior​

API (NestJS + SWC)​

The API uses nest start -b swc --watch, which provides fast recompilation via SWC:

  • File changes in apps/api/src/ trigger automatic restart
  • SWC compilation is significantly faster than the default TypeScript compiler
  • Changes to workspace dependencies (e.g., @ever-works/agent) require rebuilding that package separately or restarting the dev server

Web (Next.js + Turbopack)​

The Web app uses next dev --turbopack for development:

  • React Fast Refresh preserves component state on save
  • Turbopack provides near-instant hot module replacement
  • Server components recompile on file changes automatically
  • Changes to @ever-works/contracts or @ever-works/plugin are picked up if those packages are also in watch mode

Cross-Package Changes​

When editing a shared package (e.g., @ever-works/contracts) while apps are running:

  1. Option A -- Rebuild the package manually:

    turbo build --filter=@ever-works/contracts

    Then restart the consuming app.

  2. Option B -- Run the apps together with pnpm dev:apps, which starts every app except docs, desktop, desktop-node and node in watch mode. Note that this starts the apps, not the shared packages: a changed workspace package still needs the turbo build --filter=... from Option A unless that package has its own dev script (@ever-works/agent does -- see Working with Multiple Packages).

Debugging with VS Code​

API Debugging​

The API supports the --debug flag for Node.js inspector:

# From the monorepo root
cd apps/api && pnpm start:debug

This runs nest start -b swc --debug --watch, which enables the Node.js debugger on port 9229.

Create or update .vscode/launch.json:

{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to API",
"type": "node",
"request": "attach",
"port": 9229,
"restart": true,
"sourceMaps": true,
"skipFiles": ["<node_internals>/**"]
},
{
"name": "Debug API Tests",
"type": "node",
"request": "launch",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["test:debug"],
"cwd": "${workspaceFolder}/apps/api",
"console": "integratedTerminal"
},
{
"name": "Debug Agent Tests",
"type": "node",
"request": "launch",
"runtimeExecutable": "npx",
"runtimeArgs": ["jest", "--runInBand", "${relativeFile}"],
"cwd": "${workspaceFolder}/packages/agent",
"console": "integratedTerminal"
}
]
}

Web Debugging​

Next.js debugging works through the browser DevTools or VS Code:

{
"name": "Debug Web (Chrome)",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}/apps/web/src"
}

Environment Variable Management​

Environment files are scoped per app:

FilePurposeCommitted?
apps/api/.env.exampleAPI template with all variablesYes
apps/api/.envActive API configurationNo
apps/web/.env.exampleWeb template with all variablesYes
apps/web/.env.localActive Web configurationNo
.env.composeDocker Compose shared configYes (template)

Variable Precedence​

  • API: Loaded by @nestjs/config via dotenv. System environment variables take precedence over .env file values.
  • Web: Loaded by Next.js. Variables prefixed with NEXT_PUBLIC_ are available in the browser. Server-only variables (no prefix) are only accessible in server components and API routes.

Switching Environments​

For testing with different configurations:

# Use a specific env file
cp apps/api/.env.production apps/api/.env

# Or set inline
DATABASE_TYPE=postgres pnpm dev:api

Working with Multiple Packages​

A common workflow involves editing a shared package and an app simultaneously.

Example: Editing @ever-works/agent + API​

# Terminal 1: Watch and rebuild the agent package
cd packages/agent && pnpm dev

# Terminal 2: Start the API (will pick up agent changes on restart)
pnpm dev:api

Example: Editing a Plugin​

# Build and test a single plugin
cd packages/plugins/openai
pnpm build
pnpm test

# Run a specific test file
npx vitest run src/openai.spec.ts

Testing​

Running Tests​

# All tests across the monorepo
pnpm test

# API tests (Jest)
cd apps/api && pnpm test

# Agent package tests (Jest, 26 suites, 719+ tests)
cd packages/agent && pnpm test
cd packages/agent && pnpm test:watch # Watch mode
cd packages/agent && pnpm test:cov # With coverage

# Run a specific test pattern
cd packages/agent && npx jest --testPathPattern='generators'

# Plugin tests (Vitest)
cd packages/plugins/openai && pnpm test
cd packages/plugins/openai && npx vitest run src/openai.spec.ts

Test Frameworks by Package​

PackageFrameworkConfig
apps/apiJestjest.config.js
packages/agentJestjest.config.js with module name mappings
packages/plugins/*Vitestvitest.config.ts
note

Some packages require their workspace dependencies to be built first. If you get import resolution errors, run pnpm build from the root before testing.

Code Quality Commands​

Linting​

# Lint all packages
pnpm lint

# Lint a specific app
turbo lint --filter=ever-works-api
turbo lint --filter=ever-works-web

Type-Checking​

# Type-check all packages
pnpm type-check

Formatting​

Prettier is configured in the root package.json with these settings:

  • Print width: 120
  • Indentation: tabs (width 4), except SCSS and YAML which use spaces (width 2)
  • Single quotes, semicolons always, no trailing commas
# Format all files
pnpm format

# Check formatting without changing files
pnpm format:check

Commit Conventions​

Commits follow the Conventional Commits standard. This is a convention held by hand — .husky/commit-msg has been commented out since 2026-02-11 (ee573da0d) and no hook checks it:

feat: add new work template engine
fix: resolve JWT refresh token race condition
docs: update environment variable reference
refactor: extract plugin loader into separate module
test: add missing generator edge case tests
chore: bump turbo to 2.8.12

Database Migrations​

When modifying TypeORM entities, generate and run migrations from the apps/api/ work:

cd apps/api

# Generate a migration from entity changes
pnpm migration:generate src/migrations/AddUserPreferences

# Apply pending migrations
pnpm migration:run

# Revert the last migration
pnpm migration:revert

# Show migration status
pnpm migration:show

Trigger.dev (Background Jobs)​

For developing background tasks:

# Start the Trigger.dev dev server
pnpm dev:trigger

# Deploy tasks to Trigger.dev Cloud
pnpm deploy:trigger

Next Steps​