Skip to content

Detect missing project paths and allow remapping#35

Open
HaydnG wants to merge 2 commits into
doctly:mainfrom
HaydnG:fix/detect-missing-project-paths
Open

Detect missing project paths and allow remapping#35
HaydnG wants to merge 2 commits into
doctly:mainfrom
HaydnG:fix/detect-missing-project-paths

Conversation

@HaydnG

@HaydnG HaydnG commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Summary

When users move their project directories (e.g. ~/dev/~/Projects/), sessions become orphaned — they appear in the sidebar but clicking them fails silently because the stored cwd path no longer exists. There's no visual indication that anything is wrong.

This PR adds:

  • Detection: Projects with non-existent paths are flagged as missing during cache build
  • Visual feedback: Amber warning icon, dimmed opacity, auto-collapsed, sorted to bottom
  • Remap action: "Change path" button (always visible on missing projects) opens a folder picker to remap the project to its new location
  • JSONL rewrite: Updates the cwd in session files so claude --resume from CLI also works after remapping
  • Safety: Uses atomic file writes (tmp + rename) for the JSONL rewrite
  • Error visibility: openTerminal failures now call showSession() so the error message is displayed in the terminal panel instead of silently hidden
  • Disabled sessions: Sessions under missing projects are dimmed and non-clickable, with a tooltip directing users to the "Change path" button

Screenshots

image

Files changed

File Change
session-cache.js Add missing flag to buildProjectsFromCache(), sort missing to bottom
main.js Add remap-project IPC handler with atomic JSONL cwd rewrite
preload.js Expose remapProject API to renderer
public/sidebar.js Warning icon, remap button, auto-collapse, confirmation dialog, disable clicks on missing sessions
public/app.js Show terminal panel on openTerminal error so user sees the error message
public/style.css Styles for missing state, disabled sessions, always-visible remap button

Test plan

  • Move a project directory to a new path, restart Switchboard — project should show with amber warning icon, dimmed, auto-collapsed
  • Sessions under missing project should be dimmed and non-clickable with a tooltip
  • Click "Change path" on a missing project — should open OS folder picker
  • Select new location — confirmation dialog should appear
  • After confirming, sessions should become openable again
  • Verify claude --resume <session-id> works from CLI after remapping
  • Open a session pointing at a path that was deleted mid-session — error should appear in the terminal panel (not silently hidden)
  • Existing projects with valid paths should be completely unaffected

When users move their project directories (e.g. ~/dev/ to ~/Projects/),
sessions become orphaned — visible in the sidebar but unable to open.
This adds detection, visual feedback, and a fix:

- Mark projects with non-existent paths as "missing" during cache build
- Show amber warning icon and dimmed state for missing projects
- Auto-collapse missing projects and sort them to the bottom
- Add "Change path" button that lets users remap to the new location
- Rewrite session JSONL cwd entries so CLI --resume also works
- Use atomic file writes (tmp + rename) for safety
@HaydnG HaydnG marked this pull request as ready for review April 24, 2026 10:56
@HaydnG

HaydnG commented Apr 24, 2026

Copy link
Copy Markdown
Contributor Author

Reasoning behind this. I move my dev directories, and it completely corrupt everything in switchboard. I know this may not be a standard usecase, but these changes should make it more resilient

…sing projects

When openTerminal returns an error (e.g. project path no longer exists),
the error was written to a terminal widget that was never made visible.
Now calls showSession() so the user sees the error message.

Sessions under missing projects are disabled with a tooltip directing
users to the "Change path" remap button, which is now always visible
instead of hover-only.
@HaydnG

HaydnG commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

@navedr

JeanBaptisteRenard referenced this pull request in JeanBaptisteRenard/switchboard May 30, 2026
* fix(app): showSession() on openTerminal error path

* feat(sidebar): detect missing project paths

* feat(main): remap-project IPC with atomic JSONL rewrite

* fix(remap-project): address CRITICAL review findings

- CRITICAL-1: replace flat readdirSync with enumerateSessionFiles so
  subagent transcripts under <uuid>/subagents/*.jsonl and the legacy
  <uuid>/*.jsonl layout are also rewritten
- CRITICAL-2: add active-sessions guard — refuse remap if any non-exited
  PTY session has projectPath matching the folder (avoids concurrent-writer
  data loss); also re-check fs.existsSync(oldPath) at handler entry so a
  path that came back does not get clobbered
- Extract rewriteJsonlAtomic helper that cleans up orphan .tmp files on
  error (try/catch around writeFileSync + renameSync)
- Switch statSync → lstatSync on newPath to make symlink intent explicit
- Tests: add subagent layout (preferred + legacy), orphan .tmp cleanup,
  and active-sessions guard tests (4 new tests, total 51 passing / 64)
ymajoros pushed a commit to ymajoros/switchboard that referenced this pull request Jun 4, 2026
…tchers-polling

perf: cut idle CPU from leaked watchers and unconditional polling
aaaronmiller pushed a commit to aaaronmiller/switchboard that referenced this pull request Jun 4, 2026
- Path sandbox restored for read/save-file-for-panel with symlink resolution
  via fs.realpathSync (FULL-AUDIT #4/doctly#32 + IMPROVEMENTS B6). Allowed roots:
  Claude data dirs + active session project paths. Blocked reads are logged.
- Restored the missing watch-session-file / unwatch-session-file IPC handlers
  (lost in refactor) — tails session JSONL and emits session-activity events for
  cross-CLI sparklines — and clean them up on PTY exit (B4: no watcher leak).
- MCP openDiff now times out after 5 min so an unanswered diff can't pin the RPC
  open forever (B7); timeout resolves as DIFF_REJECTED + closes the tab.
- set-setting validates key/shape/size (rejects non-object or >256KB) (doctly#35).
- get-agent-stats returns errorMessage instead of a silent error flag (B10).

https://claude.ai/code/session_012RHiNTayAUjwj9byNCwhwh
kreaddis-julien pushed a commit to kreaddis-julien/switchboard that referenced this pull request Jun 7, 2026
- doctly#35: detect projects whose folder no longer exists on disk (repo moved/renamed),
  show a "!" badge, and add a "Relocate…" action in project settings that points
  the project at a new path (persisted as global.projectPathRemap, applied in
  buildProjectsFromCache).
- Project groups: assign a project to a named group (project settings → Group);
  the sidebar renders grouped projects under a labeled divider.
kreaddis-julien pushed a commit to kreaddis-julien/switchboard that referenced this pull request Jun 7, 2026
kreaddis-julien pushed a commit to kreaddis-julien/switchboard that referenced this pull request Jun 7, 2026
…ses, hardened migration; throttle reconcile

Pre-push review of 8b021f9..HEAD:
- jsonl-viewer cleanTranscriptText: bound the <system-reminder> match ({0,20000})
  to kill an O(n²) ReDoS (measured ~90s freeze on a multi-MB block), and only
  strip internal XML OUTSIDE fenced code blocks so tag names shown as code survive.
- session-cache: apply the doctly#35 remap in the empty-dir and active-terminal loops
  too (a relocated project whose old folder still exists no longer shows a ghost
  duplicate entry).
- main.js remap-project: follow the remap chain so re-relocating an already-moved
  project actually moves it (was a silent no-op).
- db.js migration v5: add only missing columns via PRAGMA table_info instead of
  swallowing the ALTER error — a real failure now aborts before db_version is
  bumped, so a half-applied schema can't brick boot (cacheUpsert depends on the cols).
- log token-analytics failures (main + stats-view) instead of silently rendering nothing.
- perf: throttle reconcileCacheFromFilesystem (1s) — loadProjects fires get-projects
  twice per paint, which ran the fs sweep back-to-back. (ported from JeanBaptisteRenard doctly#38)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant