Load file content from GitHub for cloud runs#2395
Open
k11kirky wants to merge 2 commits into
Open
Conversation
Clicking a file reference in a cloud run's chat showed "File content not available" whenever the agent only ran `grep`/`find` against it (never `Read`/`Edit`/`Write`).
Now, when the file isn't in the agent's tool calls but we know the repo and branch, fetch the content from GitHub at that branch via `gh api /repos/{owner}/{repo}/contents/{path}?ref=...` with `Accept: application/vnd.github.raw` and render it in the same editor. Falls back to a "View on GitHub" button if the fetch returns null (404, private without `gh` auth, etc.).
Closes #2390
Generated-By: PostHog Code
Task-Id: 215cdb33-aeaf-40b8-8fcc-70a0024e69bd
Contributor
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
apps/code/src/renderer/features/code-editor/components/CodeEditorPanel.tsx:71-81
`lastIndexOf` incorrectly strips the path when a subdirectory inside the repo shares the repo's short name — a very common pattern in Python projects (e.g., a `posthog` repo that contains a `posthog/` package directory). For an absolute path like `/workspace/runner/abc/posthog/posthog/utils.py`, `lastIndexOf("/posthog/")` matches at the *inner* segment, returning `utils.py` instead of `posthog/utils.py`. The GitHub API call then fetches the wrong file (or a 404), and the blob URL is equally broken.
```suggestion
function toRepoRelativePath(
repoShortName: string | null,
path: string,
): string | null {
if (!path.startsWith("/")) return path;
if (!repoShortName) return null;
const marker = `/${repoShortName}/`;
const idx = path.indexOf(marker);
if (idx < 0) return null;
return path.slice(idx + marker.length);
}
```
### Issue 2 of 2
apps/code/src/renderer/features/code-editor/components/CodeEditorPanel.tsx:156
The `repoRelativePath` in `blobUrl` is not URL-encoded, so paths containing spaces, `#`, or `?` will produce a malformed URL. The "View on GitHub" fallback button would silently open a broken link for those files.
```suggestion
blobUrl: `https://github.com/${owner}/${name}/blob/${branch}/${repoRelativePath.split("/").map(encodeURIComponent).join("/")}`,
```
Reviews (1): Last reviewed commit: "Load file content from GitHub for cloud ..." | Re-trigger Greptile |
Comment on lines
+71
to
+81
| function toRepoRelativePath( | ||
| repoShortName: string | null, | ||
| path: string, | ||
| ): string | null { | ||
| if (!path.startsWith("/")) return path; | ||
| if (!repoShortName) return null; | ||
| const marker = `/${repoShortName}/`; | ||
| const idx = path.lastIndexOf(marker); | ||
| if (idx < 0) return null; | ||
| return path.slice(idx + marker.length); | ||
| } |
Contributor
There was a problem hiding this comment.
lastIndexOf incorrectly strips the path when a subdirectory inside the repo shares the repo's short name — a very common pattern in Python projects (e.g., a posthog repo that contains a posthog/ package directory). For an absolute path like /workspace/runner/abc/posthog/posthog/utils.py, lastIndexOf("/posthog/") matches at the inner segment, returning utils.py instead of posthog/utils.py. The GitHub API call then fetches the wrong file (or a 404), and the blob URL is equally broken.
Suggested change
| function toRepoRelativePath( | |
| repoShortName: string | null, | |
| path: string, | |
| ): string | null { | |
| if (!path.startsWith("/")) return path; | |
| if (!repoShortName) return null; | |
| const marker = `/${repoShortName}/`; | |
| const idx = path.lastIndexOf(marker); | |
| if (idx < 0) return null; | |
| return path.slice(idx + marker.length); | |
| } | |
| function toRepoRelativePath( | |
| repoShortName: string | null, | |
| path: string, | |
| ): string | null { | |
| if (!path.startsWith("/")) return path; | |
| if (!repoShortName) return null; | |
| const marker = `/${repoShortName}/`; | |
| const idx = path.indexOf(marker); | |
| if (idx < 0) return null; | |
| return path.slice(idx + marker.length); | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/code-editor/components/CodeEditorPanel.tsx
Line: 71-81
Comment:
`lastIndexOf` incorrectly strips the path when a subdirectory inside the repo shares the repo's short name — a very common pattern in Python projects (e.g., a `posthog` repo that contains a `posthog/` package directory). For an absolute path like `/workspace/runner/abc/posthog/posthog/utils.py`, `lastIndexOf("/posthog/")` matches at the *inner* segment, returning `utils.py` instead of `posthog/utils.py`. The GitHub API call then fetches the wrong file (or a 404), and the blob URL is equally broken.
```suggestion
function toRepoRelativePath(
repoShortName: string | null,
path: string,
): string | null {
if (!path.startsWith("/")) return path;
if (!repoShortName) return null;
const marker = `/${repoShortName}/`;
const idx = path.indexOf(marker);
if (idx < 0) return null;
return path.slice(idx + marker.length);
}
```
How can I resolve this? If you propose a fix, please make it concise.Address Greptile review feedback:
- Replace ambiguous `lastIndexOf("/<repo-name>/")` heuristic with the exact cloud sandbox prefix `/tmp/workspace/repos/<owner>/<repo>/`. This handles repos whose name matches an inner subdirectory (e.g. `posthog` repo with a `posthog/` package directory) deterministically — the prior heuristic would have stripped one level too many.
- URL-encode each segment of `repoRelativePath` (and the branch) when constructing the GitHub blob URL, so paths with spaces, `#`, or `?` produce a valid link.
Generated-By: PostHog Code
Task-Id: 215cdb33-aeaf-40b8-8fcc-70a0024e69bd
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
Closes #2390. In cloud runs, clicking a file reference in the chat showed "File content not available" when the agent only ran
grep/find(neverRead/Edit/Write) against it — leaving no way to see the file.Now, when the file isn't in the agent's tool calls but we know the repo and branch, fetch the content from GitHub at that branch and render it in the same CodeMirror/markdown editor. Falls back to a "View on GitHub" button if the fetch returns null (404, private without
ghauth, etc.).Implementation
GitService.getGithubFileContent(owner, repo, filePath, ref)usinggh api /repos/{owner}/{repo}/contents/{path}?ref=...withAccept: application/vnd.github.rawand URL-encoded path segments.git.getGithubFileContent.CodeEditorPanelresolvesowner/repo/branch/pathfrom the task + cloud session, strips the sandbox prefix by locating the last/<repo-short-name>/segment, and renders the fetched content via the same editor used for local files.Test plan
grep-ed a file (didn'tReadit). Click the file mention — the file content loads in the editor.Read/Edit— still uses the existing in-memory tool-call content (no GitHub round-trip).ghauth → "View on GitHub" fallback button appears and opens the blob URL.