Skip to content

fix(repositories): read workspaces from the branch-scoped layout - #397

Open
jirisacha wants to merge 1 commit into
AIDotNet:mainfrom
jirisacha:fix/mcp-workspace-branch-path
Open

fix(repositories): read workspaces from the branch-scoped layout#397
jirisacha wants to merge 1 commit into
AIDotNet:mainfrom
jirisacha:fix/mcp-workspace-branch-path

Conversation

@jirisacha

Copy link
Copy Markdown
Contributor

Problem

On a current build, the MCP file tools never work:

{"error":true,"message":"Repository workspace not found on server"}

read_file and get_repo_structure return this for every repository, no matter how
it was indexed, while search_doc and the wiki keep working — so it looks like a partial
index rather than a bug. The same root cause silently degrades two more features:

  • search_doc attaches GitTool only when the workspace exists, so its AI summaries are
    generated without ever reading the source.
  • the chat assistant and the embedded chat widget do the same, and fall back to a
    documentation-only conversation.

Root cause

0254c3c ("fix: isolate branch generation workspaces", #375) moved clones from

{RepositoriesDirectory}/{organization}/{name}/tree/

to

{RepositoriesDirectory}/{organization}/{name}/branches/{branch}/tree/

in RepositoryAnalyzer.GetWorkingDirectory, but the readers were not updated. Nothing
writes the flat path any more, so Directory.Exists is always false for:

Reader Effect
McpRepositoryTools.GetRepoStructure / ReadFile hard failure, the message above
McpRepositoryTools.SearchDoc no GitTool — summaries never see the code
ChatAssistantService.GetRepositoryPath no GitTool in chat
EmbedService.GetRepositoryPath no GitTool in the embedded widget

Each of the four had its own copy of the path expression, which is how they drifted apart
from the writer in the first place.

Fix

RepositoryWorkspacePath — one resolver shared by the writer and all readers:

  • ForBranch(options, org, repo, branch) — the branch workspace path, existing or not;
    RepositoryAnalyzer.GetWorkingDirectory now delegates to it (behaviour unchanged, its
    stricter validation stays where it is).
  • Resolve(options, org, repo, branch?) — best existing workspace for a reader:
    the requested branch, then (when the caller has no branch context) the most recently
    written branch workspace, then the legacy flat layout so workspaces created before
    0254c3c keep working.

SearchDoc passes the RepositoryBranch it already loads. GetRepoStructure and
ReadFile now load it too — the MCP scope carries owner/repo only — and tolerate its
absence. Both chat services pass the branch they already have (Context.Branch /
request.Branch, the latter optional). The stale RepositoryWorkspace.WorkingDirectory
doc comment is corrected as well.

Tests

New RepositoryWorkspacePathTests covers the branch-scoped layout, path-traversal
sanitisation, branch preference, the newest-workspace fallback, the legacy fallback and
the "nothing exists" case. No test asserted the workspace path shape before.

dotnet test tests/OpenDeepWiki.Tests/OpenDeepWiki.Tests.csproj

Note, not part of this PR

CheckoutBranch in both chat services runs git checkout inside the shared clone and, if
the requested branch is missing, looks for a branch literally named tree — that is the
workspace directory name, never a branch, so the fallback is dead code. With per-branch
workspaces the whole checkout step looks unnecessary; happy to follow up separately.

Since 0254c3c ("fix: isolate branch generation workspaces") repositories are
cloned to {RepositoriesDirectory}/{org}/{repo}/branches/{branch}/tree, but every
reader still resolved the pre-existing flat path {RepositoriesDirectory}/{org}/
{repo}/tree, which nothing writes any more:

- McpRepositoryTools.ReadFile and GetRepoStructure always answer "Repository
  workspace not found on server".
- McpRepositoryTools.SearchDoc silently attaches no GitTool, so its summaries
  never see the source.
- ChatAssistantService and EmbedService fall back to a documentation-only chat
  for the same reason.

Add RepositoryWorkspacePath, a single resolver shared by the analyzer and the
readers, and use it everywhere. It prefers the requested branch workspace, falls
back to the most recently written one when the caller has no branch context, and
finally to the legacy flat layout so workspaces created before 0254c3c keep
working.
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