refactor: delete the v1 desktop surface and the Electron hook server

SA
1mo ago
+5079-109107

Links

Summary

v1 is retired (1.30.x: ~3,000 weekly people on v2, ~200 still auto-migrating), so this removes everything that only existed for it, and the v2 prefix that only existed to tell the two apart.

  1. v1 surface gone — v1 routes, stores, Electron routers (workspaces, projects, changes, config, ports, filesystem), the git worker, 32 v1 settings procedures, every useIsV2CloudEnabled gate, the command palette's workspace-kind split, the settings variant registry.
  2. v2 prefix gone — /v2-workspace(s) → /workspace(s), ~175 identifiers and 88 paths lose V2/v2. The desktop rewrites persisted history and incoming deep links minted under the old names; the CLI mints superset://workspace/.
  3. Electron hook server trimmed — /hook/complete, the notification manager, SUPERSET_AGENT_HOOK_PORT/VERSION, SUPERSET_PORT, SUPERSET_HOOK_VERSION and the v1 fallback blocks in all four hook templates. Every template already posts to host-service first, so only the fallback is lost.
  4. Cloud API re-homed — v2Workspace/v2Project become workspace/project; the old names stay as aliases (TODO(2026-10-24), same convention as v2Host). support.sendMigrationReport is deleted (last caller desktop 1.8.6).

Kept on purpose: the v1 importer (V1AutoMigration, V1ImportModal, lib/v1-migration, the migration router and local.db's v1 tables) for the ~100 users still on v1, with a dated TODO in routers/migration/index.ts naming the drain signal. @superset/local-db itself stays: settings, presets, browser history and the CLI settings registry read it.

Backwards compatibility

Measured, not read — details and the replay suite are on the linked page.

  • Cloud tRPC: exact _def.procedures diff against HEAD. One removal (sendMigrationReport). The eight v1-era v2Workspace no-ops are restored in router/workspace/legacy.ts under the alias only, because host-services shipped with desktop ≤1.20 still call them. trackCreated and findByGitHubRemote are byte-identical under both names.
  • Every cloud path any released client calls (host-service, CLI, renderer, mobile, web, MCP, SDK at desktop 1.12.5 / 1.20.2 / 1.29.0 / 1.30.x / HEAD) still exists. Replayed against the dev API with the exact old input shapes: 12/12.
  • Host-service tRPC surface identical (193 procedures).
  • Persisted keys unchanged; removed writers' keys are in DEAD_KEYS.
  • Analytics keep a constant surface: "v2" super/person property because nine saved insights filter on it.

Pre-existing, not from this PR: desktops ≤1.28 poll v2Host.list with no input and get BAD_REQUEST since #7442; #7786 gates them.

Manual QA (dev stack over CDP, signed in, real mouse input, zero console errors)

  • Sidebar: Workspaces board, Tasks, Pull requests, Pages, Plugins, Automations
  • Settings: Projects (moved ProjectSettings), Experimental (Import from v1 + Open importer), Terminal, Agents, Hosts, Usage
  • Open a live workspace from the sidebar; Open Terminal spawns a shell in the worktree
  • Restart on a persisted v1 route (/project/…, /workspace?tab=1) → dashboard; persisted /v2-workspace(s) → renamed routes; persisted /workspace/<v1 id> → in-app "Workspace not found"
  • OS deep links: v2-workspaces, v2-workspace/<id>, workspace/<id>
  • Electron notifications server: /health ok, /hook/complete 404
  • Not exercised: cold-profile sign-in, the importer against real v1 rows, remote hosts, cloud sandboxes, mobile

Testing

  • bun run lint, bun run typecheck (42 packages), bun run check:i18n
  • bunx turbo test — 25/25 packages green after merging main (desktop 6,890 tests)
  • Removed one host-service adversarial git-status test (long converging sequence of mixed batches) that failed identically at HEAD, per Satya

Follow-ups (separate PRs)

  • Drop cloud tables projects, workspaces, agent_commands via drizzle after this deploys
  • Drop the importer chain + local.db v1 tables once v1_auto_migration_completed with first_completion is quiet for a month (TODO 2026-10-24)
  • Remove the v2Workspace/v2Project aliases and the legacy no-ops (TODO 2026-10-24)
  • v1 terminal daemon chain (blocked on CommandTerminal), unused desktop deps, unread flags, v1 plan docs

Rollback

Revert the squash. The aliases mean no client depends on the new procedure names yet; the desktop rewrites both route spellings, so a downgrade reads the new persisted history fine.


Summary by cubic

v1 desktop is retired (~3,000 weekly v2 users vs ~200 still auto-migrating), so this deletes everything that only served it and drops the v2 prefix that existed to distinguish the two.

Changes

  • Removes the v1 surface: routes, stores, Electron routers (workspaces, projects, changes, config, ports, filesystem), the git worker, 32 v1 settings procedures, and every v1-vs-v2 gate.
  • /v2-workspace(s) becomes /workspace(s); ~175 identifiers lose the V2/v2 prefix. The desktop rewrites persisted history and incoming deep links minted under the old names; the CLI mints superset://workspace/.
  • Trims the Electron hook server: /hook/complete, the notification manager, and the hook-related env vars are gone. Agent hooks already post to host-service first, so only the fallback is lost.
  • Re-homes cloud API procedures: v2Workspace/v2Project become workspace/project with the old names kept as aliases, since host-services shipped with desktop ≤1.20 still call them; support.sendMigrationReport is deleted (last caller desktop 1.8.6).
  • Keeps the v1 importer (V1AutoMigration, V1ImportModal, lib/v1-migration, the migration router, local.db's v1 tables) for the ~100 users still on v1, with a dated TODO naming the drain signal. @superset/local-db stays because settings, presets, browser history, and the CLI settings registry read it.

Compatibility

  • Verified by replay, not inspection: the cloud tRPC surface matches HEAD except for sendMigrationReport, host-service tRPC is identical (193 procedures), and every released-client path replays on the dev API.
  • Persisted keys are unchanged; removed writers' keys are in DEAD_KEYS. Analytics keep a constant surface: "v2" because nine saved insights filter on it.
  • Rollback is a revert of the squash; aliases and route rewriting mean no client depends on the new names yet.