Skip to content

Commit ad50076

Browse files
refactor(server): share the project-directory check between session and main-checkout paths
AI-assisted; verified with the tests and tools listed above.
1 parent 433343b commit ad50076

2 files changed

Lines changed: 19 additions & 25 deletions

File tree

‎apps/server/src/project/AgentSessionScanner.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,12 +977,12 @@ it.layer(NodeServices.layer)("AgentSessionScanner", (it) => {
977977
threadCount: 1,
978978
},
979979
{
980-
threadCount: 1,
981980
path: submodule,
982981
git: {
983982
remoteKey: "gitlab.com/pingdotgg/libs/vendor",
984983
repository: "pingdotgg/libs/vendor",
985984
},
985+
threadCount: 1,
986986
},
987987
{ path: noRemote, git: { remoteKey: null, repository: null }, threadCount: 1 },
988988
{ path: plain, git: null, threadCount: 1 },

‎apps/server/src/project/AgentSessionScanner.ts‎

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,20 @@ export const make = Effect.gen(function* () {
876876
return `path:${normalizeProjectPathForComparison(realPath)}`;
877877
});
878878

879+
/** Stats a directory that may be offered as a project, or none when it is missing or excluded. */
880+
const projectDirectoryStats = Effect.fn("AgentSessionScanner.projectDirectoryStats")(function* (
881+
directory: string,
882+
) {
883+
if (isExcludedProjectPath(directory)) return Option.none<FileSystem.File.Info>();
884+
const stats = yield* statOption(directory);
885+
if (Option.isNone(stats) || stats.value.type !== "Directory") return Option.none();
886+
const realPath = yield* fileSystem
887+
.realPath(directory)
888+
.pipe(Effect.orElseSucceed(() => directory));
889+
// Symlinks can disguise excluded worktree paths; re-check their targets.
890+
return isExcludedProjectPath(realPath) ? Option.none() : stats;
891+
});
892+
879893
// Paths whose own read outlived the deadline, mapped to when they may be read
880894
// again. Without this every later scan would wait out the deadline again for
881895
// each phase that touches them.
@@ -1711,17 +1725,8 @@ export const make = Effect.gen(function* () {
17111725
const expanded = expandHomePath(candidate.cwd.trim(), homeDir);
17121726
if (!path.isAbsolute(expanded)) continue;
17131727
const resolved = path.resolve(expanded);
1714-
if (directories.has(resolved) || isExcludedProjectPath(resolved)) continue;
1715-
const stats = yield* statOption(resolved);
1716-
if (Option.isNone(stats) || stats.value.type !== "Directory") {
1717-
directories.set(resolved, Option.none());
1718-
continue;
1719-
}
1720-
const realPath = yield* fileSystem
1721-
.realPath(resolved)
1722-
.pipe(Effect.orElseSucceed(() => resolved));
1723-
// Symlinks can disguise excluded worktree paths; re-check their targets.
1724-
directories.set(resolved, isExcludedProjectPath(realPath) ? Option.none() : stats);
1728+
if (directories.has(resolved)) continue;
1729+
directories.set(resolved, yield* projectDirectoryStats(resolved));
17251730
}
17261731
const directoryGitIdentities = yield* readGitIdentities(
17271732
Array.from(directories).flatMap(([directory, stats]) =>
@@ -1752,21 +1757,10 @@ export const make = Effect.gen(function* () {
17521757
} else if (gitIdentity._tag === "Worktree") {
17531758
// A linked worktree's sessions count toward its main checkout's project.
17541759
const { mainCheckout } = gitIdentity;
1755-
// Symlinks can disguise excluded paths here too; re-check the target.
17561760
const mainStats =
1757-
mainCheckout === null ||
1758-
isExcludedProjectPath(mainCheckout) ||
1759-
isExcludedProjectPath(
1760-
yield* fileSystem
1761-
.realPath(mainCheckout)
1762-
.pipe(Effect.orElseSucceed(() => mainCheckout)),
1763-
)
1764-
? Option.none()
1765-
: yield* statOption(mainCheckout);
1761+
mainCheckout === null ? Option.none() : yield* projectDirectoryStats(mainCheckout);
17661762
project =
1767-
mainCheckout !== null &&
1768-
Option.isSome(mainStats) &&
1769-
mainStats.value.type === "Directory"
1763+
mainCheckout !== null && Option.isSome(mainStats)
17701764
? {
17711765
key: yield* directoryIdentity(mainCheckout, mainStats.value),
17721766
path: mainCheckout,

0 commit comments

Comments
 (0)