Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Automated ProcessesNew to Visual Studio Code? Get it now.
Automated Processes

Automated Processes

Rodrigo Scola

| (0) | Free
Per-branch PostgreSQL databases and one-click project scripts.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Automated Processes

A VS Code extension that gives each git branch its own PostgreSQL or SQLite database and turns project scripts into sidebar buttons. It knows nothing about any particular project: everything project-specific is a setting, edited in the Configure panel or as automatedProcesses.* in settings.json.

  • Per-branch databases. New Database copies the main database for the current branch and runs migrations on it. Switching branches switches the database. Export Data copies any database into any other. Databases of merged branches are dropped (or kept, by setting).
  • No .env editing. The current database is passed to scripts, new terminals and debug sessions as environment variables, which override .env in most frameworks.
  • Works on Windows. With loadEnvFileIntoCommands (on by default), every value from .env is passed to commands, for tools that only read real environment variables.
  • Script buttons. Steps run one after another as VS Code tasks and stop at the first failure. The sidebar shows each step's state.
  • Servers. Run, debug, restart and stop buttons for your app's servers. Every launch configuration in .vscode/launch.json is one, listed first.

The design and decisions are in PLAN.md.

Configure panel

The gear in the sidebar (or Automated Processes: Configure Database, Servers and Scripts) opens an editor tab with three tabs:

  • Database: the engine (PostgreSQL, SQLite or detect from the URL), where the connection URL comes from (the env file, or typed in; a typed URL is kept in VS Code's secret storage), where the PostgreSQL tools run (this machine, a Docker container or a Compose service), and the main branches. Test connection checks it.
  • Servers: add, edit and delete servers (name, run command, launch.json configuration to debug with, restart on database change). launch.json configurations show up by themselves; editing one adds a run command to it.
  • Scripts: add, edit, reorder and delete scripts and their steps, variables and dropdowns.

What you save there is kept in the extension's storage for this workspace, on your machine, and overrides the same keys from settings.json. Nothing in the repository changes. Each tab has Use settings.json instead to go back.

The sidebar lists only the main and the current database; Show all databases lists the rest.

Requirements

  • PostgreSQL, either in Docker (database.dockerContainer or database.dockerComposeService; nothing to install locally) or with psql, pg_dump and pg_restore on PATH. In Docker, a stopped database container is started when the extension starts; if Docker itself isn't running, the sidebar shows a Retry button for when it is. The user in the database URL needs the CREATEDB permission.
  • Or SQLite: nothing to install. Each database is a file next to the main one, with the same extension (app.db → app_347.db); copies are file copies. Only Sync Migrations needs the sqlite3 command line tool.

Settings

Setting Default What it does
envFile .env Env file with the database URL (read only)
loadEnvFileIntoCommands true Pass env file values to every command
loadEnvFileIntoTerminals true Also pass them to new terminals and debug sessions; off = only the database URL variables and env
env {} Extra variables for every command (placeholders allowed)
applyToTerminals true Current database in new terminals
applyToDebugSessions true Current database in debug sessions of this folder (overrides the launch configuration's envFile)
echoCommands true Print each command, placeholders filled in, at the top of its terminal
database.engine auto auto (SQLite for SQLite URLs, else PostgreSQL) / postgres / sqlite
database.urlVariables ["DATABASE_URL"] Variables pointed at the current database; the first defines main
database.sqliteFolder "" SQLite: folder relative paths start from (e.g. prisma); empty = workspace
database.mainBranches ["main"] Branches that use the main database
database.dockerContainer "" Run Postgres tools in this container (docker exec)
database.dockerComposeService "" Or in this Compose service (docker compose exec)
database.autoStartContainer true Start a stopped database container on startup and Retry without asking
database.warnIfPortExposed true Warn when the container publishes its port on every network interface
database.hidePatterns ["postgres"] Databases hidden from the list (globs)
database.newNamePattern {main}_{branchShort} Suggested new database name ({main}, {branch}, {branchShort}, {issue})
database.importDataOnCreate true New Database imports the main database (schema and data); off = empty database + migrations
database.onBranchMerged delete delete or keep databases of merged/deleted branches
testDatabase.envFile "" Env file with the test URL (empty = envFile)
testDatabase.urlVariables [] Variables pointed at the per-branch test database
testDatabase.nameSuffix _test Test database = branch database + suffix
migrations.command "" Command that applies migrations
migrations.onBranchChange ask off / ask / always
migrations.afterCopy true Run migrations after Export Data
migrations.streams [] Migration histories for Sync Migrations (see below)
servers [] Servers in the sidebar (label, command, debugConfiguration, restartOnDatabaseChange), each with run, debug, restart and stop
server.command "" Single-server shortcut, used only when servers is empty
onGitUpdate.script "" Script to run when the branch gets new commits (pull, merge, rebase)
onGitUpdate.mode always always / ask / off
onGitUpdate.whenFilesChange [] Only when these files changed (e.g. uv.lock, package-lock.json)
onGitUpdate.skipMainBranches false Don't run it on the main branches
server.onDatabaseChange restart restart / ask / off: restart the server and running debug sessions when the database changes
server.includeLaunchConfigurations true launch.json launch configurations are servers too (listed first)
scripts [] Sidebar script buttons

Placeholders in commands and env: ${db.name}, ${db.url}, ${db.mainName}, ${db.mainUrl}, ${testDb.name}, ${testDb.url}, ${env:NAME}, ${input:NAME}, ${branch}.

What can leak (env file secrets, the database password, an exposed database port) and the settings that control it are in SECURITY-REPORT.md.

Example

{
  "automatedProcesses.database.urlVariables": ["DATABASE_URL", "DATABASE_ADMIN_URL"],
  "automatedProcesses.database.mainBranches": ["staging"],
  "automatedProcesses.database.dockerContainer": "carli-db-1",
  "automatedProcesses.database.hidePatterns": ["postgres", "*_test", "*_test_gw*"],
  "automatedProcesses.database.newNamePattern": "{main}_{issue}",
  "automatedProcesses.testDatabase.envFile": ".env.test",
  "automatedProcesses.testDatabase.urlVariables": ["TEST_DATABASE_URL"],
  "automatedProcesses.migrations.command": "uv run python -m carli_core.migrations.runner",
  "automatedProcesses.server.command": "uv run uvicorn carli_api.main:app --reload --port 8000",
  "automatedProcesses.migrations.streams": [
    {
      "name": "tenant",
      "versionQuery": "SELECT version_num FROM goodoaks.alembic_version",
      "versionsPath": "backend/migrations/versions",
      "cwd": "backend",
      "downgradeCommand": "uv run --no-sync alembic downgrade ${revision}",
      "env": { "UV_PROJECT_ENVIRONMENT": "${workspaceFolder}/.venv" }
    },
    {
      "name": "public",
      "versionQuery": "SELECT version_num FROM public.alembic_version_public",
      "versionsPath": "backend/migrations_public/versions",
      "cwd": "backend",
      "downgradeCommand": "uv run --no-sync alembic -c alembic_public.ini downgrade ${revision}",
      "env": { "UV_PROJECT_ENVIRONMENT": "${workspaceFolder}/.venv" }
    }
  ],
  "automatedProcesses.scripts": [
    {
      "id": "setup", "label": "Setup", "icon": "tools",
      "steps": [
        { "label": "Create .env", "copyFile": { "from": ".env.example", "to": ".env", "ifMissing": true } },
        { "label": "Python dependencies", "run": "uv sync --frozen" },
        { "label": "Node dependencies", "run": "npm ci" },
        { "label": "Start database", "run": "docker compose up --build --detach --wait db" },
        { "label": "Migrations", "run": "uv run python -m carli_core.migrations.runner" },
        { "label": "Seed", "run": "uv run python -m carli_platform.scripts.seed_local" }
      ]
    },
    {
      "id": "seed", "label": "Seed", "icon": "sparkle",
      "steps": [{ "label": "Seed", "run": "uv run python -m carli_platform.scripts.seed_local" }]
    },
    {
      "id": "ci", "label": "Check CI", "icon": "checklist",
      "inputs": { "suite": { "options": ["backend", "application", "api", "audit-auth", "solver", "frontend", "all"], "default": "backend" } },
      "env": { "MIGRATION_SMOKE_ADMIN_URL": "${db.url}" },
      "steps": [
        { "label": "Architecture", "run": "uv run python scripts/check_architecture.py" },
        { "label": "Lint", "run": "uv run ruff check backend scripts tests" },
        { "label": "Types (Python)", "run": "uv run pyright backend/carli_api" },
        { "label": "Frontend typecheck", "run": "npm run typecheck" },
        { "label": "Frontend tests", "run": "npm test" },
        { "label": "Frontend build", "run": "npm run build" },
        { "label": "Harness", "run": "uv run python scripts/ci/run_harness.py ${input:suite}" },
        { "label": "Database harness", "run": "uv run python scripts/ci/run_harness.py database" }
      ]
    }
  ]
}

Sync Migrations

When a database got migrated from another branch, Sync Migrations puts it back:

  1. For each stream, it reads the applied revisions (versionQuery) and the migration files of this branch (versionsPath). Applied revisions this branch doesn't have are foreign.
  2. It finds the branch that added them (git log -S), reads that branch's files and follows down_revision back to the last revision this branch knows.
  3. After you confirm, it checks that branch out into a temporary git worktree and runs downgradeCommand there with ${revision} = that last known revision. Only the other branch's code can undo its own migrations. Your checkout isn't touched; the worktree is removed afterwards.
  4. It runs this branch's migrations.command.

List the streams in the order they should be reverted (for Alembic with two streams: the one that depends on the other first). In the example, UV_PROJECT_ENVIRONMENT makes the worktree reuse the main checkout's virtualenv instead of creating a new one.

Development

Command What it does
npm run compile Type-check, lint, bundle the extension and the sidebar
npm run test:unit Unit tests (Node, no VS Code), about a second
npm test Integration tests in a downloaded VS Code, against test/fixtures/workspace
npm run test:pg Opt-in tests against a real PostgreSQL server (see below)

test:pg only creates and drops databases named ap_selftest_*:

$env:AP_PG_ROOT = 'D:\code\carli'; $env:AP_PG_CONTAINER = 'carli-db-1'   # or AP_PG_SERVICE = 'db'
$env:AP_PG_COPY_MAIN = '1'   # optional: also pg_dump the main database (read-only) into a scratch copy
npm run test:pg

Press F5 and pick Run Extension on ../carli to try it on a project.

Layout

  • src/core/: all logic, no vscode imports (settings, URLs, names, env building, branch rules, Postgres, script runner, the Controller with every user flow).
  • src/vscode/: thin VS Code adapters (dialogs, git, tasks, terminals/debug env, settings, sidebar, status bar).
  • src/webview/: sidebar UI. render.ts is a pure state → HTML function.
  • src/shared/protocol.ts: messages between the extension and the sidebar.

License

MIT

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft