Skip to content

Add 'refresh' verb to playwright-server / vitest-server / logs-server to flush in-place without re-taking ownership from a running TUI #59

Description

@DawidWraga

Problem

When an agent (Claude Code, etc.) needs to invalidate cached state inside a running daemon — most commonly the playwright-server module cache after editing a non-spec .ts file (UI model, fixture helper) — the only tool available today is shutdown + re-serve. That works, but it has a nasty side effect when the user is running davstack start (the TUI):

  1. The TUI launches the daemons and adopts their PIDs.
  2. The agent runs playwright-server shutdown → the TUI's child dies.
  3. The agent runs playwright-server serve → a new daemon starts, owned by the agent's shell, not the TUI.
  4. The TUI's panel now shows "not running" until the user manually restarts it, and stdout/stderr is going to the agent's terminal instead of the TUI's log panel.

In other words: an agent doing routine cache-busting silently steals the daemon out of the user's TUI session. The user has to notice and re-claim.

Concrete cases

  • playwright-server: spec files get cache-busted via ?t=${Date.now()} (see session.ts:323), but any module a spec imports (*.ui.ts, fixtures/*.ts) is held in the worker's ESM cache forever. After editing a UI model, the daemon serves stale code until someone restarts.
  • vitest-server: similar story for non-test code edits the vitest daemon doesn't pick up.
  • logs-server: less impacted by code reload, but config edits or schema migrations to the per-session SQLite still need a clean way to flush without killing the process.

Proposal

Add a refresh verb to each of the three servers that does in-place reinitialisation without exiting:

playwright-server refresh        # flushes spec-module ESM cache; re-reads config; reseats warm context if storageStatePath changed
vitest-server refresh            # restarts the vitest worker pool / clears transform cache; re-reads config
logs-server refresh              # re-reads config (cors, ports), reopens DB handles, flushes per-session SQLite cache

HTTP shape (mirrors existing shutdown / refresh-auth):

POST /refresh
→ { ok: true, refreshedAt: <iso> }

CLI shape:

playwright-server refresh        # exits 0 on success
playwright-server refresh --hard # equivalent to today's shutdown + serve, for the rare case it's actually wanted

Implementation notes (playwright-server, by way of example)

  • The cache problem is mostly the Node ESM loader. Two viable strategies:
    1. Re-register the loader hook with a new revision so subsequent dynamic imports get a fresh URL — ?t=${Date.now()} applied to ALL imports under the spec, not just the spec itself. Simplest; doesn't free memory but kills the stale-module problem.
    2. Spawn a fresh worker to host the spec module evaluation and discard the old one. Cleaner; more moving parts.
  • Either way the warm Chromium context, persistent profile, and HTTP socket stay alive across the refresh. That's the whole value prop: the TUI's adopted PID never changes, the chromium window doesn't flash, and any in-flight goto/runFile requests either complete or get a clean 503.
  • check should learn a refreshedAt field so the TUI can surface "last refreshed 12s ago" in its status panel.

Why this matters

Agentic loops over playwright-server land somewhere around 10-30 edit-rerun cycles for a feature. Today every cache-stale rerun forces either a noisy diagnostic ("why is my test still failing?") or a shutdown+serve that breaks the user's TUI session. A refresh verb closes that gap without making the agent and the human fight over daemon ownership.

Related

  • packages/playwright-server/src/session.ts:323 — current spec-only cache bust
  • packages/playwright-server/src/spec-runner.ts — registration-intercept module loader
  • packages/playwright-server/src/http.ts — existing /refresh-auth + /shutdown endpoints
  • packages/vitest-server/src/http.ts — same shape
  • packages/logs-server/src/server.ts — server entry; would need a refresh hook into config + db-cache

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions