refactor: delete the v1 desktop surface and the Electron hook server
Links
- Compatibility checklist + old-client replay suite: https://app.superset.sh/page/v1-deletion-compatibility-checklist-4rariw
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.
- v1 surface gone — v1 routes, stores, Electron routers (
workspaces,projects,changes,config,ports,filesystem), the git worker, 32 v1 settings procedures, everyuseIsV2CloudEnabledgate, the command palette's workspace-kind split, the settings variant registry. - v2 prefix gone —
/v2-workspace(s)→/workspace(s), ~175 identifiers and 88 paths loseV2/v2. The desktop rewrites persisted history and incoming deep links minted under the old names; the CLI mintssuperset://workspace/. - Electron hook server trimmed —
/hook/complete, the notification manager,SUPERSET_AGENT_HOOK_PORT/VERSION,SUPERSET_PORT,SUPERSET_HOOK_VERSIONand the v1 fallback blocks in all four hook templates. Every template already posts to host-service first, so only the fallback is lost. - Cloud API re-homed —
v2Workspace/v2Projectbecomeworkspace/project; the old names stay as aliases (TODO(2026-10-24), same convention asv2Host).support.sendMigrationReportis 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.proceduresdiff against HEAD. One removal (sendMigrationReport). The eight v1-erav2Workspaceno-ops are restored inrouter/workspace/legacy.tsunder the alias only, because host-services shipped with desktop ≤1.20 still call them.trackCreatedandfindByGitHubRemoteare 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:
/healthok,/hook/complete404 - 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:i18nbunx 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_commandsvia drizzle after this deploys - Drop the importer chain + local.db v1 tables once
v1_auto_migration_completedwithfirst_completionis quiet for a month (TODO 2026-10-24) - Remove the
v2Workspace/v2Projectaliases 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 theV2/v2prefix. The desktop rewrites persisted history and incoming deep links minted under the old names; the CLI mintssuperset://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/v2Projectbecomeworkspace/projectwith the old names kept as aliases, since host-services shipped with desktop ≤1.20 still call them;support.sendMigrationReportis deleted (last caller desktop 1.8.6). - Keeps the v1 importer (
V1AutoMigration,V1ImportModal,lib/v1-migration, themigrationrouter, local.db's v1 tables) for the ~100 users still on v1, with a dated TODO naming the drain signal.@superset/local-dbstays 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 constantsurface: "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.