feat: detect missing project paths + remap (port of upstream #35) - #20
Merged
Conversation
- 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)
JeanBaptisteRenard
added a commit
that referenced
this pull request
Aug 14, 2026
* docs: refresh README + project docs post-migration Credit doctly/switchboard upstream and highlight what the fork adds (new About-this-fork section). Fix stale devsuitup migration leftovers (download links, repo refs in .ai/). Correct the cp-is-safe claim that contradicted the 2026-06-04 appimagelauncherd incident. Add the missing user docs for schedules + triggers (docs/automation.md), document the chain field in the trigger-watcher context, extend the fork-features list past PR #20, refresh the release gotchas (ruleset approval, draft publish step) and the project-structure tree. * docs: fix review findings (PR ranges, stale counts, §2 heading, fork note) * docs: fix perf-campaign PR range — feature PRs, not release-bump PRs * docs: remove Skaleet-internal references (review feedback) * docs(ai): distill portable agent practices into the repo (post-import removal)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Port of doctly/switchboard#35 by @HaydnG, adapted to our heavily-diverged fork.
When users move their project directories, sessions become orphaned — they appear in the sidebar with no indication that anything is wrong. This PR makes that failure mode visible and fixable:
session-cache.jsflagsmissing: !fs.existsSync(projectPath)on each project row at cache-build time, and sorts missing projects to the bottom.sidebar.js+style.css): missing groups get amber warning icon, dimmed opacity (0.55, 0.8 on hover), auto-collapse, and a "Change path" upload button always visible on the header..project-group.missingget.disabledclass + tooltip directing users to "Change path".escapeHtml()(upstream fix, included).remap-projectIPC (main.js+preload.js): opens a folder-picker, rewritescwdin every.jsonlin the folder atomically (tmp + rename), then callsrefreshFolder()+notifyRendererProjectsChanged().Fork-divergence adaptations
The upstream diff touched the same files but our fork diverged substantially:
oldPath.replace(/[/_]/g, '-')encodeProjectPath(oldPath)(Claude CLI's actual encoding)encodeProjectPath()in the IPC handlerprojectMapkeyed onfolderprojectMapkeyed onprojectPath; two locations create entriesmissingflag to bothprojectMap.set()callsremove-projectinsertion pointdelete-worktreeIPC belowremove-project, beforedelete-worktreeNote on showSession sub-fix
The 4th part of upstream #35 (
showSession()onopenTerminalerror) was already ported separately in PR #19 (fix/openterminal-error-visible→ commit0d8f4f2) and is the first commit on this branch. It is NOT re-applied here.Tests
7 new tests in
test/remap-project.test.js(node:test, no jsdom needed for pure I/O logic):cwdin a single JSONL filecwdacross multiple JSONL files atomicallycwdfield verbatim.tmpfile is created and then removed by rename.jsonlfiles in the folder are ignoredAll 7 new tests pass. Pre-existing test suite: 47/53 pass (13 dom-sidebar failures are pre-existing — morphdom not installed in the isolated worktree environment, unrelated to this PR).
Lint: 0 errors (220 pre-existing warnings, unchanged).