Merge pull request #567: fix(cases): only refuse the cases folder and its direct children for a custom-folder case

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-10-18 08:16:42 +02:00
commit 7504a2bc8b
5 files changed
+50 -6

No files matched your search

+13 -4
View File
@@ -12,8 +12,10 @@
* its symlink-resolved form, against both the given and the symlink-resolved roots (a home reached
* through a link, macOS's `/etc` -> `/private/etc`), so a link into a blocked tree is not a way
* around it;
* - it must not be, or be inside, a cases directory: a case there is a plain Create New, and the same
* folder listed both as a local case and as a linked one would make deleting it remove files;
* - it must not be a cases directory or a direct child of one: those are what `GET /api/cases` lists
* as local cases, so a case there is a plain Create New, and the same folder listed both as a local
* case and as a linked one would make deleting it remove files. A folder further down is not
* listed and is allowed;
* - its parent must already exist (one folder is created, never a whole chain), and the folder
* itself must not exist or must be an EMPTY directory (a folder with contents is Link Existing's
* job, and silently scaffolding into someone's project is the one thing this must never do);
@@ -98,9 +100,16 @@ export function blockedReason(
const firstSegment = absPath.slice(ctx.home.length + 1).split(sep)[0];
if (/^\.codeman/.test(firstSegment)) return "Codeman's own data folder cannot be a case";
}
// Only the cases folder itself and its DIRECT children are listed as local cases (GET /api/cases reads
// that one level), so only those would be registered twice. A deeper folder is not listed and is a
// perfectly good linked case: with CODEMAN_CASES_PATH pointing at a broad root such as /mnt/user/Scripts,
// refusing everything below it blocked most of the tree.
for (const dir of ctx.casesDirs ?? []) {
if (isWithin(absPath, dir)) {
return 'That folder is inside the cases folder; create a case there with plain Create New (no custom folder)';
if (absPath === dir) {
return `That is the cases folder itself (${dir}); create a case inside it with plain Create New (no custom folder)`;
}
if (dirname(absPath) === dir) {
return `That folder is directly in the cases folder (${dir}), where it is listed as a local case; create it there with plain Create New (no custom folder)`;
}
}
return null;