Symptom: I have git projects on various places, so I tried to make symlinks to them from the directory Openfox find projects. But it does not see them.
The bug: Openfox checks that projects are real directories, but do not check if they are symlinks to directories
The fix: Just ask Deepseek flash under openfox to fix the bug.
It seems to work OK with the prompt I used:
openfox (we are in a local copy of its repo) seem to not see existing projects that are not real directories but symlinks to existing one.
Review the code to see if this bug is real, and propose a fix.
The fix should be portable on all the OS openfox runs in (Linux, MacOS, Windows, ...)
I am a bit wary of submitting a PR for this, as my Deepseek/Openfox setup (first time I use OpenFox, but I am impressed) made some refactoring decisions that may not be seen as desirable by Conrad. I guess it is simpler for him to just tell his system to fix the bug :-) ... just tell me
Anyways, here are some useful insights:
It created a new directory-checking function:
export async function isDirectoryEntry(parent: string, entry: Dirent): Promise<boolean> {
if (entry.isDirectory()) return true
if (!entry.isSymbolicLink()) return false
try { return (await stat(join(parent, entry.name))).isDirectory() }
catch { return false } // broken symlink
}
And there is a subtility in Windows for writing the tests:
Junction points on Windows: Windows also has junction points (directory junctions), which are like directory symlinks but don't require privileges (junctions can be created without admin via cmd /c mklink /J... actually junctions require no special privileges since Windows Vista? Let me recall: junctions can be created without admin rights. fs.symlink on Windows with type 'junction' doesn't require privileges). But how does Node report junctions in readdir? Junctions are reparse points. Dirent.isSymbolicLink() for a junction... Actually on Windows, junctions are reported as isSymbolicLink() returning... hmm. Let me recall Node behavior:
On Windows, fs.stat follows symlinks and junctions.
Dirent for a junction: Node classifies junctions as symlinks? Actually, in Node.js, for junction points, Dirent.isSymbolicLink() returns true? Let me think. The libuv uv_fs_scandir sets the type. For reparse points, libuv checks... Actually on Windows, junctions are reparse points (IO_REPARSE_TAG_MOUNT_POINT), symlinks are IO_REPARSE_TAG_SYMLINK. libuv's uv_dirent is set to UV_DIRENT_LINK for both? I believe libuv reports both as UV_DIRENT_LINK, so Dirent.isSymbolicLink() returns true for junctions too. And fs.stat follows both. So the fix handles junctions too.
Actually, I should be careful: there's a subtlety that on Windows, Dirent.isDirectory() for a junction might return... Let me recall: In Node, for a junction, Dirent.isSymbolicLink() returns true (they're reported as links). And fs.stat() on a junction resolves to the target's type. So our helper works.
Additional notes:
- Leave unchanged:
tools/read.ts still excludes symlinks deliberately — that's a symlink-loop guard, not a bug.
- Optional follow-up (separate PR):
projects.workdir is a UNIQUE exact-string key, so the same physical dir can be registered via both symlink path and realpath; normalize via realpath at creation/getProjectByWorkdir.
Symptom: I have git projects on various places, so I tried to make symlinks to them from the directory Openfox find projects. But it does not see them.
The bug: Openfox checks that projects are real directories, but do not check if they are symlinks to directories
The fix: Just ask Deepseek flash under openfox to fix the bug.
It seems to work OK with the prompt I used:
I am a bit wary of submitting a PR for this, as my Deepseek/Openfox setup (first time I use OpenFox, but I am impressed) made some refactoring decisions that may not be seen as desirable by Conrad. I guess it is simpler for him to just tell his system to fix the bug :-) ... just tell me
Anyways, here are some useful insights:
It created a new directory-checking function:
And there is a subtility in Windows for writing the tests:
Additional notes:
tools/read.tsstill excludes symlinks deliberately — that's a symlink-loop guard, not a bug.projects.workdiris aUNIQUEexact-string key, so the same physical dir can be registered via both symlink path and realpath; normalize viarealpathat creation/getProjectByWorkdir.