Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .superset/lib/setup/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ setup_main() {
step_failed "Seed local DB"
fi

# Step 5: Seed auth token into superset-dev-data/
# Step 5: Seed host-service DBs into superset-dev-data/host/
if ! step_seed_host_dbs; then
step_failed "Seed host-service DBs"
fi

# Step 6: Seed auth token into superset-dev-data/
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: step_seed_renderer_state is missing from setup_main, so renderer Local Storage seeding no longer runs before auth token seeding.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .superset/lib/setup/main.sh, line 44:

<comment>`step_seed_renderer_state` is missing from `setup_main`, so renderer Local Storage seeding no longer runs before auth token seeding.</comment>

<file context>
@@ -41,12 +41,7 @@ setup_main() {
-  fi
-
-  # Step 7: Seed auth token into superset-dev-data/
+  # Step 6: Seed auth token into superset-dev-data/
   if ! step_seed_auth_token; then
     step_failed "Seed auth token"
</file context>
Suggested change
# Step 6: Seed auth token into superset-dev-data/
# Step 6: Seed Electron renderer Local Storage from prod userData
if ! step_seed_renderer_state; then
step_failed "Seed renderer state"
fi
# Step 7: Seed auth token into superset-dev-data/
Fix with Cubic

if ! step_seed_auth_token; then
step_failed "Seed auth token"
fi
Expand Down
90 changes: 90 additions & 0 deletions .superset/lib/setup/steps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,96 @@ step_seed_auth_token() {
return 0
}

step_seed_host_dbs() {
echo "🛰️ Seeding host-service DBs into superset-dev-data/host/..."

local source_root="$HOME/.superset/host"
local dev_data_dir="superset-dev-data"
local dest_root="$dev_data_dir/host"
local force_overwrite="$FORCE_OVERWRITE_DATA"

if [ ! -d "$source_root" ]; then
warn "No host-service DBs found at $source_root — skipping (host-service will create fresh DBs per org)"
step_skipped "Seed host-service DBs (no source dir)"
return 0
fi

local org_dirs=()
for org_dir in "$source_root"/*/; do
[ -d "$org_dir" ] || continue
local org_id
org_id="$(basename "$org_dir")"
if [ -f "${org_dir}host.db" ]; then
org_dirs+=("$org_id")
fi
done

if [ ${#org_dirs[@]} -eq 0 ]; then
warn "No host.db files under $source_root — skipping"
step_skipped "Seed host-service DBs (no host.db files)"
return 0
fi

mkdir -p "$dest_root"
chmod 700 "$dev_data_dir" "$dest_root"

local seeded=0
local skipped=0
for org_id in "${org_dirs[@]}"; do
local source_db="$source_root/$org_id/host.db"
local dest_org_dir="$dest_root/$org_id"
local dest_db="$dest_org_dir/host.db"

if [ -f "$dest_db" ] && [ "$force_overwrite" != "1" ]; then
warn "Host DB already exists at $dest_db — skipping (use -f/--force)"
skipped=$((skipped + 1))
continue
fi

mkdir -p "$dest_org_dir"
chmod 700 "$dest_org_dir"

# Clear stale WAL siblings when overwriting so we don't mix old WAL
# data with a freshly-copied DB (their page pointers won't match).
if [ "$force_overwrite" = "1" ]; then
rm -f "$dest_db" "${dest_db}-shm" "${dest_db}-wal"
fi

# Copy all SQLite files so WAL data isn't lost when source is held open.
local copy_failed=0
for ext in "" "-shm" "-wal"; do
local source_file="${source_db}${ext}"
local dest_file="${dest_db}${ext}"

if [ -f "$source_file" ]; then
if ! cp "$source_file" "$dest_file"; then
error "Failed to copy $source_file to $dest_file"
copy_failed=1
break
fi
chmod 600 "$dest_file"
fi
done

if [ "$copy_failed" = "1" ]; then
# A lone host.db without its -wal/-shm siblings would make the next
# non-force run think this org is already seeded and skip it.
rm -f "$dest_db" "${dest_db}-shm" "${dest_db}-wal"
return 1
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# Checkpoint the copy's WAL (no lock contention since nothing else has it open).
if command -v sqlite3 &> /dev/null; then
sqlite3 "$dest_db" "PRAGMA wal_checkpoint(TRUNCATE);" &> /dev/null || true
fi

seeded=$((seeded + 1))
done

success "Host-service DBs seeded ($seeded copied, $skipped skipped) from $source_root"
return 0
}

step_seed_local_db() {
echo "💾 Seeding local DB into superset-dev-data/..."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useIsV2CloudEnabled } from "renderer/hooks/useIsV2CloudEnabled";
import { useHotkey } from "renderer/hotkeys";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { DashboardSidebar } from "renderer/routes/_authenticated/_dashboard/components/DashboardSidebar";
import { useDevSeedV2Sidebar } from "renderer/routes/_authenticated/hooks/useDevSeedV2Sidebar";
import { ResizablePanel } from "renderer/screens/main/components/ResizablePanel";
import { WorkspaceSidebar } from "renderer/screens/main/components/WorkspaceSidebar";
import { DeleteWorkspaceDialog } from "renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components";
Expand All @@ -30,6 +31,7 @@ function DashboardLayout() {
const navigate = useNavigate();
const openNewWorkspaceModal = useOpenNewWorkspaceModal();
const { isV2CloudEnabled } = useIsV2CloudEnabled();
useDevSeedV2Sidebar();
// Get current workspace from route to pre-select project in new workspace modal
const matchRoute = useMatchRoute();
const currentWorkspaceMatch = matchRoute({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useDevSeedV2Sidebar } from "./useDevSeedV2Sidebar";
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useEffect } from "react";
import { env } from "renderer/env.renderer";
import { useAccessibleV2Workspaces } from "renderer/routes/_authenticated/_dashboard/v2-workspaces/hooks/useAccessibleV2Workspaces";
import { useDashboardSidebarState } from "renderer/routes/_authenticated/hooks/useDashboardSidebarState";
import { useCollections } from "renderer/routes/_authenticated/providers/CollectionsProvider";

const SEED_FLAG_KEY = "superset:dev:v2-sidebar-seeded";

/**
* Auto-pins accessible v2 workspaces in dev so a fresh worktree's sidebar
* isn't blank. Chromium's localStorage is per-origin: the dev Vite origin
* (`http://localhost:<port>`) can't share data with the packaged `file://`
* origin, so copying prod's leveldb seeds the wrong namespace. We pin at
* runtime instead. The flag prevents re-pinning workspaces the user later
* unpins.
*/
export function useDevSeedV2Sidebar(): void {
const collections = useCollections();
const { ensureWorkspaceInSidebar } = useDashboardSidebarState();
const { all: accessibleWorkspaces } = useAccessibleV2Workspaces();

useEffect(() => {
if (env.NODE_ENV !== "development") return;
if (window.localStorage.getItem(SEED_FLAG_KEY) === "1") return;
if (accessibleWorkspaces.length === 0) return;
if (collections.v2WorkspaceLocalState.state.size > 0) {
window.localStorage.setItem(SEED_FLAG_KEY, "1");
return;
}

for (const workspace of accessibleWorkspaces) {
ensureWorkspaceInSidebar(workspace.id, workspace.projectId);
}
window.localStorage.setItem(SEED_FLAG_KEY, "1");
}, [accessibleWorkspaces, collections, ensureWorkspaceInSidebar]);
}
Loading